From ef2e26c91b80556af033d3335e55f5dfa6fff31d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 01:53:07 +0000 Subject: first public release of samba4 code (This used to be commit b0510b5428b3461aeb9bbe3cc95f62fc73e2b97f) --- source4/libcli/.cvsignore | 3 + source4/libcli/cliconnect.c | 207 +++++ source4/libcli/clideltree.c | 117 +++ source4/libcli/clidfs.c | 558 +++++++++++++ source4/libcli/clifile.c | 647 +++++++++++++++ source4/libcli/clilist.c | 313 +++++++ source4/libcli/climessage.c | 93 +++ source4/libcli/clireadwrite.c | 155 ++++ source4/libcli/clisecdesc.c | 121 +++ source4/libcli/clitrans2.c | 221 +++++ source4/libcli/namecache.c | 246 ++++++ source4/libcli/namequery.c | 1333 ++++++++++++++++++++++++++++++ source4/libcli/namequery_dc.c | 104 +++ source4/libcli/nmblib.c | 1287 +++++++++++++++++++++++++++++ source4/libcli/ntlmssp.c | 625 ++++++++++++++ source4/libcli/ntlmssp_parse.c | 303 +++++++ source4/libcli/raw/README | 5 + source4/libcli/raw/clikrb5.c | 399 +++++++++ source4/libcli/raw/clioplock.c | 57 ++ source4/libcli/raw/clirewrite.c | 22 + source4/libcli/raw/clisession.c | 444 ++++++++++ source4/libcli/raw/clisocket.c | 148 ++++ source4/libcli/raw/clispnego.c | 533 ++++++++++++ source4/libcli/raw/clitransport.c | 218 +++++ source4/libcli/raw/clitree.c | 290 +++++++ source4/libcli/raw/raweas.c | 147 ++++ source4/libcli/raw/rawfile.c | 687 ++++++++++++++++ source4/libcli/raw/rawfileinfo.c | 527 ++++++++++++ source4/libcli/raw/rawfsinfo.c | 282 +++++++ source4/libcli/raw/rawioctl.c | 118 +++ source4/libcli/raw/rawnegotiate.c | 157 ++++ source4/libcli/raw/rawnotify.c | 116 +++ source4/libcli/raw/rawreadwrite.c | 321 ++++++++ source4/libcli/raw/rawrequest.c | 1019 +++++++++++++++++++++++ source4/libcli/raw/rawsearch.c | 569 +++++++++++++ source4/libcli/raw/rawsetfileinfo.c | 335 ++++++++ source4/libcli/raw/rawtrans.c | 489 +++++++++++ source4/libcli/raw/smb_signing.c | 341 ++++++++ source4/libcli/unexpected.c | 172 ++++ source4/libcli/util/asn1.c | 428 ++++++++++ source4/libcli/util/clierror.c | 99 +++ source4/libcli/util/cliutil.c | 110 +++ source4/libcli/util/credentials.c | 215 +++++ source4/libcli/util/doserr.c | 91 +++ source4/libcli/util/errormap.c | 1546 +++++++++++++++++++++++++++++++++++ source4/libcli/util/nterr.c | 715 ++++++++++++++++ source4/libcli/util/ntlmssp_sign.c | 226 +++++ source4/libcli/util/pwd_cache.c | 72 ++ source4/libcli/util/smbdes.c | 415 ++++++++++ source4/libcli/util/smbencrypt.c | 418 ++++++++++ source4/libcli/util/smberr.c | 181 ++++ 51 files changed, 18245 insertions(+) create mode 100644 source4/libcli/.cvsignore create mode 100644 source4/libcli/cliconnect.c create mode 100644 source4/libcli/clideltree.c create mode 100644 source4/libcli/clidfs.c create mode 100644 source4/libcli/clifile.c create mode 100644 source4/libcli/clilist.c create mode 100644 source4/libcli/climessage.c create mode 100644 source4/libcli/clireadwrite.c create mode 100644 source4/libcli/clisecdesc.c create mode 100644 source4/libcli/clitrans2.c create mode 100644 source4/libcli/namecache.c create mode 100644 source4/libcli/namequery.c create mode 100644 source4/libcli/namequery_dc.c create mode 100644 source4/libcli/nmblib.c create mode 100644 source4/libcli/ntlmssp.c create mode 100644 source4/libcli/ntlmssp_parse.c create mode 100644 source4/libcli/raw/README create mode 100644 source4/libcli/raw/clikrb5.c create mode 100644 source4/libcli/raw/clioplock.c create mode 100644 source4/libcli/raw/clirewrite.c create mode 100644 source4/libcli/raw/clisession.c create mode 100644 source4/libcli/raw/clisocket.c create mode 100644 source4/libcli/raw/clispnego.c create mode 100644 source4/libcli/raw/clitransport.c create mode 100644 source4/libcli/raw/clitree.c create mode 100644 source4/libcli/raw/raweas.c create mode 100644 source4/libcli/raw/rawfile.c create mode 100644 source4/libcli/raw/rawfileinfo.c create mode 100644 source4/libcli/raw/rawfsinfo.c create mode 100644 source4/libcli/raw/rawioctl.c create mode 100644 source4/libcli/raw/rawnegotiate.c create mode 100644 source4/libcli/raw/rawnotify.c create mode 100644 source4/libcli/raw/rawreadwrite.c create mode 100644 source4/libcli/raw/rawrequest.c create mode 100644 source4/libcli/raw/rawsearch.c create mode 100644 source4/libcli/raw/rawsetfileinfo.c create mode 100644 source4/libcli/raw/rawtrans.c create mode 100644 source4/libcli/raw/smb_signing.c create mode 100644 source4/libcli/unexpected.c create mode 100644 source4/libcli/util/asn1.c create mode 100644 source4/libcli/util/clierror.c create mode 100644 source4/libcli/util/cliutil.c create mode 100644 source4/libcli/util/credentials.c create mode 100644 source4/libcli/util/doserr.c create mode 100644 source4/libcli/util/errormap.c create mode 100644 source4/libcli/util/nterr.c create mode 100644 source4/libcli/util/ntlmssp_sign.c create mode 100644 source4/libcli/util/pwd_cache.c create mode 100644 source4/libcli/util/smbdes.c create mode 100644 source4/libcli/util/smbencrypt.c create mode 100644 source4/libcli/util/smberr.c (limited to 'source4/libcli') diff --git a/source4/libcli/.cvsignore b/source4/libcli/.cvsignore new file mode 100644 index 0000000000..2588860f65 --- /dev/null +++ b/source4/libcli/.cvsignore @@ -0,0 +1,3 @@ +*.po +*.po32 + diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c new file mode 100644 index 0000000000..da8a842dae --- /dev/null +++ b/source4/libcli/cliconnect.c @@ -0,0 +1,207 @@ +/* + Unix SMB/CIFS implementation. + client connect/disconnect routines + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* + wrapper around cli_sock_connect() +*/ +BOOL cli_socket_connect(struct cli_state *cli, const char *server, struct in_addr *ip) +{ + struct cli_socket *sock; + + sock = cli_sock_init(); + if (!sock) return False; + + if (!cli_sock_connect_byname(sock, server, 0)) { + cli_sock_close(sock); + return False; + } + + cli->transport = cli_transport_init(sock); + if (!cli->transport) { + cli_sock_close(sock); + return False; + } + + return True; +} + +/* wrapper around cli_transport_connect() */ +BOOL cli_transport_establish(struct cli_state *cli, + struct nmb_name *calling, + struct nmb_name *called) +{ + return cli_transport_connect(cli->transport, calling, called); +} + +/* wrapper around smb_raw_negotiate() */ +BOOL cli_negprot(struct cli_state *cli) +{ + NTSTATUS status; + status = smb_raw_negotiate(cli->transport); + return NT_STATUS_IS_OK(status); +} + +/* wrapper around smb_raw_session_setup() */ +BOOL cli_session_setup(struct cli_state *cli, + const char *user, + const char *password, + const char *domain) +{ + union smb_sesssetup setup; + NTSTATUS status; + TALLOC_CTX *mem_ctx; + + cli->session = cli_session_init(cli->transport); + if (!cli->session) return False; + + mem_ctx = talloc_init("cli_session_setup"); + if (!mem_ctx) return False; + + setup.generic.level = RAW_SESSSETUP_GENERIC; + setup.generic.in.sesskey = cli->transport->negotiate.sesskey; + setup.generic.in.capabilities = CAP_UNICODE | CAP_STATUS32 | + CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | + CAP_W2K_SMBS | CAP_LARGE_READX | CAP_LARGE_WRITEX; + setup.generic.in.password = password; + setup.generic.in.user = user; + setup.generic.in.domain = domain; + + status = smb_raw_session_setup(cli->session, mem_ctx, &setup); + + cli->session->vuid = setup.generic.out.vuid; + + talloc_destroy(mem_ctx); + + return NT_STATUS_IS_OK(status); +} + +/* wrapper around smb_tree_connect() */ +BOOL cli_send_tconX(struct cli_state *cli, const char *sharename, const char *devtype, + const char *password) +{ + union smb_tcon tcon; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + cli->tree = cli_tree_init(cli->session); + if (!cli->tree) return False; + + cli->tree->reference_count++; + + /* setup a tree connect */ + tcon.generic.level = RAW_TCON_TCONX; + tcon.tconx.in.flags = 0; + tcon.tconx.in.password = data_blob(password, strlen(password)+1); + tcon.tconx.in.path = sharename; + tcon.tconx.in.device = devtype; + + mem_ctx = talloc_init("tcon"); + if (!mem_ctx) { + return False; + } + + status = smb_tree_connect(cli->tree, mem_ctx, &tcon); + + cli->tree->tid = tcon.tconx.out.cnum; + + talloc_destroy(mem_ctx); + + return NT_STATUS_IS_OK(status); +} + + +/* + easy way to get to a fully connected cli_state in one call +*/ +NTSTATUS cli_full_connection(struct cli_state **ret_cli, + const char *myname, + const char *host, + struct in_addr *ip, + const char *sharename, + const char *devtype, + const char *username, + const char *domain, + const char *password, + uint_t flags, + BOOL *retry) +{ + struct cli_tree *tree; + NTSTATUS status; + + *ret_cli = NULL; + + status = cli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, + username, domain, password); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + (*ret_cli) = cli_state_init(); + + (*ret_cli)->tree = tree; + (*ret_cli)->session = tree->session; + (*ret_cli)->transport = tree->session->transport; + tree->reference_count++; + + return status; +} + + +/* + disconnect the tree +*/ +BOOL cli_tdis(struct cli_state *cli) +{ + NTSTATUS status; + status = smb_tree_disconnect(cli->tree); + return NT_STATUS_IS_OK(status); +} + +/**************************************************************************** + Initialise a client state structure. +****************************************************************************/ +struct cli_state *cli_state_init(void) +{ + struct cli_state *cli; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("cli_state"); + if (!mem_ctx) return NULL; + + cli = talloc_zero(mem_ctx, sizeof(*cli)); + cli->mem_ctx = mem_ctx; + + return cli; +} + +/**************************************************************************** + Shutdown a client structure. +****************************************************************************/ +void cli_shutdown(struct cli_state *cli) +{ + if (!cli) return; + cli->tree->reference_count++; + cli_tree_close(cli->tree); + if (cli->mem_ctx) { + talloc_destroy(cli->mem_ctx); + } +} diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c new file mode 100644 index 0000000000..8769b8dfa7 --- /dev/null +++ b/source4/libcli/clideltree.c @@ -0,0 +1,117 @@ +/* + Unix SMB/CIFS implementation. + useful function for deleting a whole directory tree + Copyright (C) Andrew Tridgell 2003 + + 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" + +struct delete_state { + struct cli_state *cli; + int total_deleted; + BOOL failed; +}; + +/* + callback function for torture_deltree() +*/ +static void delete_fn(file_info *finfo, const char *name, void *state) +{ + struct delete_state *dstate = state; + char *s, *n; + if (strcmp(finfo->name, ".") == 0 || + strcmp(finfo->name, "..") == 0) return; + + n = strdup(name); + n[strlen(n)-1] = 0; + asprintf(&s, "%s%s", n, finfo->name); + + if (finfo->mode & FILE_ATTRIBUTE_READONLY) { + if (!cli_setatr(dstate->cli, s, 0, 0)) { + DEBUG(2,("Failed to remove READONLY on %s - %s\n", + s, cli_errstr(dstate->cli))); + } + } + + if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { + char *s2; + asprintf(&s2, "%s\\*", s); + cli_unlink(dstate->cli, s2); + cli_list(dstate->cli, s2, + FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, + delete_fn, state); + free(s2); + if (!cli_rmdir(dstate->cli, s)) { + DEBUG(2,("Failed to delete %s - %s\n", + s, cli_errstr(dstate->cli))); + dstate->failed = True; + } + dstate->total_deleted++; + } else { + if (!cli_unlink(dstate->cli, s)) { + DEBUG(2,("Failed to delete %s - %s\n", + s, cli_errstr(dstate->cli))); + dstate->failed = True; + } + dstate->total_deleted++; + } + free(s); + free(n); +} + +/* + recursively descend a tree deleting all files + returns the number of files deleted, or -1 on error +*/ +int cli_deltree(struct cli_state *cli, const char *dname) +{ + char *mask; + struct delete_state dstate; + + dstate.cli = cli; + dstate.total_deleted = 0; + dstate.failed = False; + + /* it might be a file */ + if (cli_unlink(cli, dname)) { + return 1; + } + if (NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_OBJECT_NAME_NOT_FOUND) || + NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_OBJECT_PATH_NOT_FOUND) || + NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_NO_SUCH_FILE)) { + return 0; + } + + asprintf(&mask, "%s\\*", dname); + cli_unlink(cli, mask); + cli_list(dstate.cli, mask, + FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, + delete_fn, &dstate); + free(mask); + if (!cli_rmdir(dstate.cli, dname)) { + DEBUG(2,("Failed to delete %s - %s\n", + dname, cli_errstr(dstate.cli))); + return -1; + } + dstate.total_deleted++; + + if (dstate.failed) { + return -1; + } + + return dstate.total_deleted; +} diff --git a/source4/libcli/clidfs.c b/source4/libcli/clidfs.c new file mode 100644 index 0000000000..fc24cccf54 --- /dev/null +++ b/source4/libcli/clidfs.c @@ -0,0 +1,558 @@ +/* + Unix SMB/CIFS implementation. + Dfs routines + Copyright (C) James Myers 2003 + + 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" + +BOOL cli_client_initialize(struct cli_client* context, + const char* sockops, + char* username, char* password, char* workgroup, + int flags) +{ + int i; + for (i=0; i < DFS_MAX_CLUSTER_SIZE ; i++) { + context->cli[i] = cli_raw_initialise(); + } + context->sockops = sockops; + context->username = username; + context->password = password; + context->workgroup = workgroup; + context->connection_flags = flags; + if (flags & CLI_FULL_CONNECTION_USE_DFS) + context->use_dfs = True; + context->number_members = DFS_MAX_CLUSTER_SIZE; + return True; +} + +/**************************************************************************** + Interpret a Dfs referral structure. + The length of the structure is returned + The structure of a Dfs referral depends on the info level. +****************************************************************************/ + +static int interpret_referral(struct cli_state *cli, + int level,char *p,referral_info *rinfo) +{ + char* q; + int version, size; + + version = SVAL(p,0); + size = SVAL(p,2); + rinfo->server_type = SVAL(p,4); + rinfo->referral_flags = SVAL(p,6); + rinfo->proximity = SVAL(p,8); + rinfo->ttl = SVAL(p,10); + rinfo->pathOffset = SVAL(p,12); + rinfo->altPathOffset = SVAL(p,14); + rinfo->nodeOffset = SVAL(p,16); + DEBUG(3,("referral version=%d, size=%d, server_type=%d, flags=0x%x, proximity=%d, ttl=%d, pathOffset=%d, altPathOffset=%d, nodeOffset=%d\n", + version, size, rinfo->server_type, rinfo->referral_flags, + rinfo->proximity, rinfo->ttl, rinfo->pathOffset, + rinfo->altPathOffset, rinfo->nodeOffset)); + + q = (char*)(p + (rinfo->pathOffset)); + //printf("p=%p, q=%p, offset=%d\n", p, q, rinfo->pathOffset); + //printf("hex=0x%x, string=%s\n", q, q); + clistr_pull(cli, rinfo->path, q, + sizeof(rinfo->path), + -1, STR_TERMINATE); + DEBUG(4,("referral path=%s\n", rinfo->path)); + q = (char*)(p + (rinfo->altPathOffset)/sizeof(char)); + if (rinfo->altPathOffset > 0) + clistr_pull(cli, rinfo->altPath, q, + sizeof(rinfo->altPath), + -1, STR_TERMINATE); + DEBUG(4,("referral alt path=%s\n", rinfo->altPath)); + q = (char*)(p + (rinfo->nodeOffset)/sizeof(char)); + if (rinfo->nodeOffset > 0) + clistr_pull(cli, rinfo->node, q, + sizeof(rinfo->node), + -1, STR_TERMINATE); + DEBUG(4,("referral node=%s\n", rinfo->node)); + fstrcpy(rinfo->host, &rinfo->node[1]); + p = strchr_m(&rinfo->host[1],'\\'); + if (!p) { + printf("invalid referral node %s\n", rinfo->node); + return -1; + } + *p = 0; + rinfo->share = talloc_strdup(cli->mem_ctx, p+1); + DEBUG(3,("referral host=%s share=%s\n", + rinfo->host, rinfo->share)); + return size; +} + +#if 0 +int cli_select_dfs_referral(struct cli_state *cli, dfs_info* dinfo) +{ + return (int)sys_random()%dinfo->number_referrals; +} + +int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinfo) +{ + struct smb_trans2 parms; + int info_level; + char *p; + pstring fname; + int i; + char *rparam=NULL, *rdata=NULL; + int param_len, data_len; + uint16 setup; + pstring param; + DATA_BLOB trans_param, trans_data; + + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; + + pstrcpy(fname,Fname); + + setup = TRANSACT2_GET_DFS_REFERRAL ; + SSVAL(param,0,CLI_DFS_MAX_REFERRAL_LEVEL); /* attribute */ + p = param+2; + p += clistr_push(cli, param+2, fname, -1, + STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + DEBUG(3,("cli_get_dfs_referral: sending request\n")); + + trans_param.length = param_len; + trans_param.data = param; + trans_data.length = 0; + trans_data.data = NULL; + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* Name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + &trans_param, 10, /* param, length, max */ + &trans_data, + cli->max_xmit /* data, length, max */ + )) { + return 0; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len) && + cli_is_dos_error(cli)) { + return 0; + } + //printf("cli_get_dfs_referral: received response, rdata=%p, rparam=%p\n", + // rdata, rparam); + + if (cli_is_error(cli) || !rdata) + return 0; + + /* parse out some important return info */ + //printf("cli_get_dfs_referral: valid response\n"); + p = rdata; + dinfo->path_consumed = SVAL(p,0); + dinfo->number_referrals = SVAL(p,2); + dinfo->referral_flags = SVAL(p,4); + DEBUG(3,("cli_get_dfs_referral: path_consumed=%d, # referrals=%d, flags=0x%x\n", + dinfo->path_consumed, dinfo->number_referrals, + dinfo->referral_flags)); + + /* point to the referral bytes */ + p+=8; + for (i=0; i < dinfo->number_referrals; i++) { + p += interpret_referral(cli,info_level,p,&dinfo->referrals[i]); + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + DEBUG(3,("received %d Dfs referrals\n", + dinfo->number_referrals)); + + dinfo->selected_referral = cli_select_dfs_referral(cli, dinfo); + DEBUG(3, ("selected Dfs referral %d %s\n", + dinfo->selected_referral, dinfo->referrals[dinfo->selected_referral].node)); + + return(dinfo->number_referrals); +} +#endif + +/* check if the server produced Dfs redirect */ +BOOL cli_check_dfs_redirect(struct cli_state* c, char* fname, + dfs_info* dinfo) +{ + //printf("check_dfs_redirect: error %s\n", + // cli_errstr(c)); + if (cli_is_dos_error(c)) { + printf("got dos error\n"); + return False; + + } else { + NTSTATUS status; + + /* Check NT error */ + + status = cli_nt_error(c); + //printf("got nt error 0x%x\n", status); + + if (NT_STATUS_V(NT_STATUS_PATH_NOT_COVERED) != NT_STATUS_V(status)) { + return False; + } + } + /* execute trans2 getdfsreferral */ + //printf("check_dfs_redirect: process referral\n"); + //cli_get_dfs_referral(c, fname, dinfo); + return True; +} + +int cli_dfs_open_connection(struct cli_client* cluster, + char* host, char* share, int flags) +{ + int i; + BOOL retry; + struct cli_state* c; + + // check if already connected + for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { + if (cluster->cli[i]->in_use && strequal(host, cli_state_get_host(cluster->cli[i])) + && strequal(share, cli_state_get_share(cluster->cli[i]))) { + DEBUG(3,("cli_dfs_open_connection: already connected to \\\\%s\\%s\n", host, share)); + return i; + } + } + // open connection + DEBUG(3,("cli_dfs_open_connection: opening \\\\%s\\%s %s@%s\n", + host, share, cluster->username, cluster->workgroup)); + for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { + if (!cluster->cli[i]->in_use) { + break; + } + } + if (i >= DFS_MAX_CLUSTER_SIZE) + return -1; + + c = cluster->cli[i]; + if (NT_STATUS_IS_ERR(cli_full_connection(&c, + NULL, host, NULL, 0, + share, "?????", + cluster->username, cluster->workgroup, + cluster->password, flags, + &retry))) + return -1; + cli_state_set_sockopt(cluster->cli[i], cluster->sockops); + cli_state_set_host(cluster->cli[i], host); + cli_state_set_share(cluster->cli[i], share); + cluster->cli[i]->in_use = True; + DEBUG(3,("cli_dfs_open_connection: connected \\\\%s\\%s (%d) %s@%s\n", + cli_state_get_host(cluster->cli[i]), cli_state_get_share(cluster->cli[i]), i, + cluster->username, cluster->workgroup)); + + return i; +} + +/********************************************************************** + Parse the pathname of the form \hostname\service\reqpath + into the dfs_path structure + **********************************************************************/ + +BOOL cli_parse_dfs_path(char* pathname, struct dfs_path* pdp) +{ + pstring pathname_local; + char* p,*temp; + + pstrcpy(pathname_local,pathname); + p = temp = pathname_local; + + ZERO_STRUCTP(pdp); + + trim_string(temp,"\\","\\"); + DEBUG(10,("temp in cli_parse_dfs_path: .%s. after trimming \\'s\n",temp)); + + /* now tokenize */ + /* parse out hostname */ + p = strchr(temp,'\\'); + if(p == NULL) + return False; + *p = '\0'; + pstrcpy(pdp->hostname,temp); + DEBUG(10,("hostname: %s\n",pdp->hostname)); + + /* parse out servicename */ + temp = p+1; + p = strchr(temp,'\\'); + if(p == NULL) { + pstrcpy(pdp->servicename,temp); + pdp->reqpath[0] = '\0'; + return True; + } + *p = '\0'; + pstrcpy(pdp->servicename,temp); + DEBUG(10,("servicename: %s\n",pdp->servicename)); + + /* rest is reqpath */ + pstrcpy(pdp->reqpath, p+1); + + DEBUG(10,("rest of the path: %s\n",pdp->reqpath)); + return True; +} + +char* rebuild_filename(char *referral_fname, struct cli_state* c, + char* fname, int path_consumed) +{ + const char *template = "\\\\%s\\%s\\%s"; + struct dfs_path dp; + + // TODO: handle consumed length + DEBUG(3,("rebuild_filename: %s, %d consumed of %d\n", + fname, path_consumed, strlen(fname))); + if (cli_parse_dfs_path(fname, &dp)) { + DEBUG(3,("rebuild_filename: reqpath=%s\n", + dp.reqpath)); + asprintf(&referral_fname, + template, cli_state_get_host(c), + cli_state_get_share(c), dp.reqpath); + } + else + return NULL; + DEBUG(3,("rebuild_filename: %s -> %s\n", fname, referral_fname)); + return referral_fname; +} + +/**************************************************************************** + Open a file (allowing for Dfs referral). +****************************************************************************/ + +int cli_dfs_open(struct cli_client* cluster, int *server, + char *fname_src, int flags, int share_mode) +{ + int referral_number; + dfs_info dinfo; + char *referral_fname; + int fnum; + + DEBUG(3,("cli_dfs_open: open %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + cluster->cli[*server]->dfs_referral = *server; + if ((fnum = cli_open(cluster->cli[*server], fname_src, flags, share_mode)) < 0) { + if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + // choose referral, check if already connected, open if not + referral_number = dinfo.selected_referral; + DEBUG(3,("cli_dfs_open: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + dinfo.referrals[referral_number].host, + dinfo.referrals[referral_number].share, + cluster->connection_flags); + *server = cluster->cli[*server]->dfs_referral; + if (server < 0) + return False; + // rebuild file name and retry operation. + if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) + return False; + fname_src = referral_fname; + DEBUG(3,("cli_dfs_open: Dfs open %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + fnum = cli_open(cluster->cli[*server], fname_src, flags, share_mode); + } + if (cli_is_error(cluster->cli[*server])) { + printf("cli_dfs_open: open of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + return -1; + } + } + DEBUG(3,("cli_dfs_open: open %s fnum=%d\n", + fname_src, fnum)); + return fnum; +} + +/**************************************************************************** + Delete a file (allowing for Dfs referral). +****************************************************************************/ + +NTSTATUS cli_nt_unlink(struct cli_client* cluster, int *server, + char *fname_src, uint16 FileAttributes) +{ + int referral_number; + dfs_info dinfo; + char *referral_fname; + struct smb_unlink parms; + + DEBUG(3,("cli_nt_unlink: delete %s on server %s(%d), attributes=0x%x\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server, + FileAttributes)); + cluster->cli[*server]->dfs_referral = *server; + parms.in.pattern = fname_src; + parms.in.dirtype = FileAttributes; + if (NT_STATUS_IS_ERR(cli_raw_unlink(cluster->cli[*server], &parms))) { + printf("cli_nt_unlink: delete of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + // choose referral, check if already connected, open if not + referral_number = dinfo.selected_referral; + DEBUG(3,("cli_nt_unlink: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + dinfo.referrals[referral_number].host, + dinfo.referrals[referral_number].share, + cluster->connection_flags); + *server = cluster->cli[*server]->dfs_referral; + if (server < 0) + return NT_STATUS_INTERNAL_ERROR; + // rebuild file name and retry operation. + if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) + return NT_STATUS_INTERNAL_ERROR; + fname_src = referral_fname; + DEBUG(3,("cli_nt_unlink: Dfs delete %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + cli_raw_unlink(cluster->cli[*server], &parms); + } + if (cli_is_error(cluster->cli[*server])) { + printf("cli_nt_unlink: delete of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + } + } + return cli_nt_error(cluster->cli[*server]); +} + +/**************************************************************************** + Rename a file (allowing for Dfs referral). +****************************************************************************/ + +BOOL cli_dfs_rename(struct cli_client* cluster, int *server, + char *fname_src, char *fname_dst) +{ + int referral_number; + dfs_info dinfo; + char *referral_fname; + + DEBUG(3,("cli_dfs_rename: rename %s to %s on server %s(%d)\n", + fname_src, fname_dst, cli_state_get_host(cluster->cli[*server]), *server)); + cluster->cli[*server]->dfs_referral = *server; + if (!cli_rename(cluster->cli[*server], fname_src, fname_dst)) { + if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + // choose referral, check if already connected, open if not + referral_number = dinfo.selected_referral; + DEBUG(3,("cli_dfs_rename: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + dinfo.referrals[referral_number].host, + dinfo.referrals[referral_number].share, + cluster->connection_flags); + *server = cluster->cli[*server]->dfs_referral; + if (server < 0) + return False; + // rebuild file name and retry operation. + if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) + return False; + fname_src = referral_fname; + DEBUG(3,("cli_dfs_rename: Dfs rename %s to %s on server %s(%d)\n", + fname_src, fname_dst, cli_state_get_host(cluster->cli[*server]), *server)); + cli_rename(cluster->cli[*server], fname_src, fname_dst); + } + if (cli_is_error(cluster->cli[*server])) { + printf("cli_dfs_rename: rename of %s to %s failed (%s)\n", + fname_src, fname_dst, cli_errstr(cluster->cli[*server])); + return False; + } + } + return True; +} + +/**************************************************************************** + Make directory (allowing for Dfs referral). +****************************************************************************/ + +BOOL cli_dfs_mkdir(struct cli_client* cluster, int *server, + char *fname_src) +{ + int referral_number; + dfs_info dinfo; + char *referral_fname; + + DEBUG(3,("cli_dfs_mkdir: mkdir %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + cluster->cli[*server]->dfs_referral = *server; + if (!cli_mkdir(cluster->cli[*server], fname_src)) { + printf("cli_dfs_mkdir: mkdir of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + // choose referral, check if already connected, open if not + referral_number = dinfo.selected_referral; + DEBUG(3,("cli_dfs_mkdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + dinfo.referrals[referral_number].host, + dinfo.referrals[referral_number].share, + cluster->connection_flags); + *server = cluster->cli[*server]->dfs_referral; + if (server < 0) + return False; + // rebuild file name and retry operation. + if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) + return False; + fname_src = referral_fname; + DEBUG(3,("cli_dfs_mkdir: Dfs mkdir %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + cli_mkdir(cluster->cli[*server], fname_src); + } + if (cli_is_error(cluster->cli[*server])) { + printf("cli_dfs_mkdir: mkdir of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + return False; + } + } + return True; +} + +/**************************************************************************** + Remove directory (allowing for Dfs referral). +****************************************************************************/ + +BOOL cli_dfs_rmdir(struct cli_client* cluster, int *server, + char *fname_src) +{ + int referral_number; + dfs_info dinfo; + char *referral_fname; + + DEBUG(3,("cli_dfs_rmdir: rmdir %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + cluster->cli[*server]->dfs_referral = *server; + if (!cli_rmdir(cluster->cli[*server], fname_src)) { + printf("cli_dfs_rmdir: rmdir of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + // choose referral, check if already connected, open if not + referral_number = dinfo.selected_referral; + DEBUG(3,("cli_dfs_rmdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + dinfo.referrals[referral_number].host, + dinfo.referrals[referral_number].share, + cluster->connection_flags); + *server = cluster->cli[*server]->dfs_referral; + if (server < 0) + return False; + // rebuild file name and retry operation. + if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) + return False; + fname_src = referral_fname; + DEBUG(3,("cli_dfs_rmdir: Dfs rmdir %s on server %s(%d)\n", + fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + cli_rmdir(cluster->cli[*server], fname_src); + } + if (cli_is_error(cluster->cli[*server])) { + printf("cli_dfs_rmdir: rmdir of %s failed (%s)\n", + fname_src, cli_errstr(cluster->cli[*server])); + return False; + } + } + return True; +} diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c new file mode 100644 index 0000000000..c203e4633d --- /dev/null +++ b/source4/libcli/clifile.c @@ -0,0 +1,647 @@ +/* + Unix SMB/CIFS implementation. + client file operations + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jeremy Allison 2001-2002 + Copyright (C) James Myers 2003 + + 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" + +/**************************************************************************** + Hard/Symlink a file (UNIX extensions). +****************************************************************************/ + +static BOOL cli_link_internal(struct cli_state *cli, + const char *fname_src, + const char *fname_dst, BOOL hard_link) +{ + union smb_setfileinfo parms; + NTSTATUS status; + + if (hard_link) { + parms.generic.level = SMB_SFILEINFO_UNIX_HLINK; + parms.unix_hlink.file.fname = fname_src; + parms.unix_hlink.in.link_dest = fname_dst; + } else { + parms.generic.level = SMB_SFILEINFO_UNIX_LINK; + parms.unix_link.file.fname = fname_src; + parms.unix_link.in.link_dest = fname_dst; + } + + status = smb_raw_setpathinfo(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + +/**************************************************************************** + Map standard UNIX permissions onto wire representations. +****************************************************************************/ +static uint32 unix_perms_to_wire(mode_t perms) +{ + unsigned int ret = 0; + + ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); + ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); + ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0); + ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0); + ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0); + ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0); + ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0); + ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0); + ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0); +#ifdef S_ISVTX + ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0); +#endif +#ifdef S_ISGID + ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); +#endif +#ifdef S_ISUID + ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0); +#endif + return ret; +} + +/**************************************************************************** + Symlink a file (UNIX extensions). +****************************************************************************/ +BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + return cli_link_internal(cli, fname_src, fname_dst, False); +} + +/**************************************************************************** + Hard a file (UNIX extensions). +****************************************************************************/ +BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + return cli_link_internal(cli, fname_src, fname_dst, True); +} + + +/**************************************************************************** + Chmod or chown a file internal (UNIX extensions). +****************************************************************************/ +static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, + uint32 mode, uint32 uid, uint32 gid) +{ + union smb_setfileinfo parms; + NTSTATUS status; + + parms.generic.level = SMB_SFILEINFO_UNIX_BASIC; + parms.unix_basic.file.fname = fname; + parms.unix_basic.in.uid = uid; + parms.unix_basic.in.gid = gid; + parms.unix_basic.in.mode = mode; + + status = smb_raw_setpathinfo(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + +/**************************************************************************** + chmod a file (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) +{ + return cli_unix_chmod_chown_internal(cli, fname, + unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); +} + +/**************************************************************************** + chown a file (UNIX extensions). +****************************************************************************/ +BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) +{ + return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); +} + + +/**************************************************************************** + Rename a file. +****************************************************************************/ +BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + struct smb_rename parms; + + parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; + parms.in.pattern1 = fname_src; + parms.in.pattern2 = fname_dst; + return NT_STATUS_IS_OK(smb_raw_rename(cli->tree, &parms)); +} + + +/**************************************************************************** + Delete a file. +****************************************************************************/ +BOOL cli_unlink(struct cli_state *cli, const char *fname) +{ + struct smb_unlink parms; + + parms.in.pattern = fname; + if (strchr(fname, '*')) { + parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; + } else { + parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; + } + return NT_STATUS_IS_OK(smb_raw_unlink(cli->tree, &parms)); +} + +/**************************************************************************** + Create a directory. +****************************************************************************/ +BOOL cli_mkdir(struct cli_state *cli, const char *dname) +{ + union smb_mkdir parms; + + parms.mkdir.level = RAW_MKDIR_MKDIR; + parms.mkdir.in.path = dname; + + return NT_STATUS_IS_OK(smb_raw_mkdir(cli->tree, &parms)); +} + + +/**************************************************************************** + Remove a directory. +****************************************************************************/ +BOOL cli_rmdir(struct cli_state *cli, const char *dname) +{ + struct smb_rmdir parms; + + parms.in.path = dname; + return NT_STATUS_IS_OK(smb_raw_rmdir(cli->tree, &parms)); +} + + +/**************************************************************************** + Set or clear the delete on close flag. +****************************************************************************/ +BOOL cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) +{ + union smb_setfileinfo parms; + NTSTATUS status; + + parms.disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFO; + parms.disposition_info.file.fnum = fnum; + parms.disposition_info.in.delete_on_close = flag; + + status = smb_raw_setfileinfo(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Create/open a file - exposing the full horror of the NT API :-). + Used in CIFS-on-CIFS NTVFS. +****************************************************************************/ +int cli_nt_create_full(struct cli_state *cli, const char *fname, + uint32 CreatFlags, uint32 DesiredAccess, + uint32 FileAttributes, uint32 ShareAccess, + uint32 CreateDisposition, uint32 CreateOptions, + uint8 SecurityFlags) +{ + union smb_open open_parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("raw_open"); + if (!mem_ctx) return -1; + + open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX; + open_parms.ntcreatex.in.flags = CreatFlags; + open_parms.ntcreatex.in.root_fid = 0; + open_parms.ntcreatex.in.access_mask = DesiredAccess; + open_parms.ntcreatex.in.file_attr = FileAttributes; + open_parms.ntcreatex.in.alloc_size = 0; + open_parms.ntcreatex.in.share_access = ShareAccess; + open_parms.ntcreatex.in.open_disposition = CreateDisposition; + open_parms.ntcreatex.in.create_options = CreateOptions; + open_parms.ntcreatex.in.impersonation = 0; + open_parms.ntcreatex.in.security_flags = SecurityFlags; + open_parms.ntcreatex.in.fname = fname; + + status = smb_raw_open(cli->tree, mem_ctx, &open_parms); + talloc_destroy(mem_ctx); + + if (NT_STATUS_IS_OK(status)) { + return open_parms.ntcreatex.out.fnum; + } + + return -1; +} + + +/**************************************************************************** + Open a file (using SMBopenx) + WARNING: if you open with O_WRONLY then getattrE won't work! +****************************************************************************/ +int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) +{ + union smb_open open_parms; + unsigned openfn=0; + unsigned accessmode=0; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("raw_open"); + if (!mem_ctx) return -1; + + if (flags & O_CREAT) { + openfn |= OPENX_OPEN_FUNC_CREATE; + } + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) { + openfn |= OPENX_OPEN_FUNC_TRUNC; + } else { + openfn |= OPENX_OPEN_FUNC_OPEN; + } + } + + accessmode = (share_mode<tree, mem_ctx, &open_parms); + talloc_destroy(mem_ctx); + + if (NT_STATUS_IS_OK(status)) { + return open_parms.openx.out.fnum; + } + + return -1; +} + + +/**************************************************************************** + Close a file. +****************************************************************************/ +BOOL cli_close(struct cli_state *cli, int fnum) +{ + union smb_close close_parms; + NTSTATUS status; + + close_parms.close.level = RAW_CLOSE_CLOSE; + close_parms.close.in.fnum = fnum; + close_parms.close.in.write_time = 0; + status = smb_raw_close(cli->tree, &close_parms); + return NT_STATUS_IS_OK(status); +} + +/**************************************************************************** + send a lock with a specified locktype + this is used for testing LOCKING_ANDX_CANCEL_LOCK +****************************************************************************/ +NTSTATUS cli_locktype(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, unsigned char locktype) +{ + union smb_lock parms; + struct smb_lock_entry lock[1]; + NTSTATUS status; + + parms.lockx.level = RAW_LOCK_LOCKX; + parms.lockx.in.fnum = fnum; + parms.lockx.in.mode = locktype; + parms.lockx.in.timeout = timeout; + parms.lockx.in.ulock_cnt = 0; + parms.lockx.in.lock_cnt = 1; + lock[0].pid = cli->session->pid; + lock[0].offset = offset; + lock[0].count = len; + parms.lockx.in.locks = &lock[0]; + + status = smb_raw_lock(cli->tree, &parms); + + return status; +} + + +/**************************************************************************** + Lock a file. +****************************************************************************/ +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type) +{ + union smb_lock parms; + struct smb_lock_entry lock[1]; + NTSTATUS status; + + parms.lockx.level = RAW_LOCK_LOCKX; + parms.lockx.in.fnum = fnum; + parms.lockx.in.mode = (lock_type == READ_LOCK? 1 : 0); + parms.lockx.in.timeout = timeout; + parms.lockx.in.ulock_cnt = 0; + parms.lockx.in.lock_cnt = 1; + lock[0].pid = cli->session->pid; + lock[0].offset = offset; + lock[0].count = len; + parms.lockx.in.locks = &lock[0]; + + status = smb_raw_lock(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Unlock a file. +****************************************************************************/ +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) +{ + union smb_lock parms; + struct smb_lock_entry lock[1]; + NTSTATUS status; + + parms.lockx.level = RAW_LOCK_LOCKX; + parms.lockx.in.fnum = fnum; + parms.lockx.in.mode = 0; + parms.lockx.in.timeout = 0; + parms.lockx.in.ulock_cnt = 1; + parms.lockx.in.lock_cnt = 0; + lock[0].pid = cli->session->pid; + lock[0].offset = offset; + lock[0].count = len; + parms.lockx.in.locks = &lock[0]; + + status = smb_raw_lock(cli->tree, &parms); + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Lock a file with 64 bit offsets. +****************************************************************************/ +BOOL cli_lock64(struct cli_state *cli, int fnum, + SMB_OFF_T offset, SMB_OFF_T len, int timeout, enum brl_type lock_type) +{ + union smb_lock parms; + int ltype; + struct smb_lock_entry lock[1]; + NTSTATUS status; + + if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { + return cli_lock(cli, fnum, offset, len, timeout, lock_type); + } + + parms.lockx.level = RAW_LOCK_LOCKX; + parms.lockx.in.fnum = fnum; + + ltype = (lock_type == READ_LOCK? 1 : 0); + ltype |= LOCKING_ANDX_LARGE_FILES; + parms.lockx.in.mode = ltype; + parms.lockx.in.timeout = timeout; + parms.lockx.in.ulock_cnt = 0; + parms.lockx.in.lock_cnt = 1; + lock[0].pid = cli->session->pid; + lock[0].offset = offset; + lock[0].count = len; + parms.lockx.in.locks = &lock[0]; + + status = smb_raw_lock(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Unlock a file with 64 bit offsets. +****************************************************************************/ +BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_OFF_T offset, SMB_OFF_T len) +{ + union smb_lock parms; + struct smb_lock_entry lock[1]; + NTSTATUS status; + + if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { + return cli_unlock(cli, fnum, offset, len); + } + + parms.lockx.level = RAW_LOCK_LOCKX; + parms.lockx.in.fnum = fnum; + parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + parms.lockx.in.timeout = 0; + parms.lockx.in.ulock_cnt = 1; + parms.lockx.in.lock_cnt = 0; + lock[0].pid = cli->session->pid; + lock[0].offset = offset; + lock[0].count = len; + parms.lockx.in.locks = &lock[0]; + + status = smb_raw_lock(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Do a SMBgetattrE call. +****************************************************************************/ +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time) +{ + union smb_fileinfo parms; + NTSTATUS status; + + parms.getattre.level = RAW_FILEINFO_GETATTRE; + parms.getattre.in.fnum = fd; + + status = smb_raw_fileinfo(cli->tree, NULL, &parms); + + if (!NT_STATUS_IS_OK(status)) + return False; + + if (size) { + *size = parms.getattre.out.size; + } + + if (attr) { + *attr = parms.getattre.out.attrib; + } + + if (c_time) { + *c_time = parms.getattre.out.create_time; + } + + if (a_time) { + *a_time = &parms.getattre.out.access_time; + } + + if (m_time) { + *m_time = &parms.getattre.out.write_time; + } + + return True; +} + +/**************************************************************************** + Do a SMBgetatr call +****************************************************************************/ +BOOL cli_getatr(struct cli_state *cli, const char *fname, + uint16 *attr, size_t *size, time_t *t) +{ + union smb_fileinfo parms; + NTSTATUS status; + + parms.getattr.level = RAW_FILEINFO_GETATTR; + parms.getattr.in.fname = fname; + + status = smb_raw_pathinfo(cli->tree, NULL, &parms); + + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + if (size) { + *size = parms.getattr.out.size; + } + + if (t) { + *t = parms.getattr.out.write_time; + } + + if (attr) { + *attr = parms.getattr.out.attrib; + } + + return True; +} + + +/**************************************************************************** + Do a SMBsetatr call. +****************************************************************************/ +BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 mode, time_t t) +{ + union smb_setfileinfo parms; + NTSTATUS status; + + parms.setattr.level = RAW_SFILEINFO_SETATTR; + parms.setattr.in.attrib = mode; + parms.setattr.in.write_time = t; + parms.setattr.file.fname = fname; + + status = smb_raw_setpathinfo(cli->tree, &parms); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Check for existence of a dir. +****************************************************************************/ +BOOL cli_chkpath(struct cli_state *cli, const char *path) +{ + struct smb_chkpath parms; + char *path2; + NTSTATUS status; + + path2 = strdup(path); + trim_string(path2,NULL,"\\"); + if (!*path2) { + free(path2); + path2 = strdup("\\"); + } + + parms.in.path = path2; + + status = smb_raw_chkpath(cli->tree, &parms); + + free(path2); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Query disk space. +****************************************************************************/ +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) +{ + union smb_fsinfo fsinfo_parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("cli_dskattr"); + + fsinfo_parms.dskattr.level = RAW_QFS_DSKATTR; + status = smb_raw_fsinfo(cli->tree, mem_ctx, &fsinfo_parms); + if (NT_STATUS_IS_OK(status)) { + *bsize = fsinfo_parms.dskattr.out.block_size; + *total = fsinfo_parms.dskattr.out.units_total; + *avail = fsinfo_parms.dskattr.out.units_free; + } + + talloc_destroy(mem_ctx); + + return NT_STATUS_IS_OK(status); +} + + +/**************************************************************************** + Create and open a temporary file. +****************************************************************************/ +int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) +{ + union smb_open open_parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("raw_open"); + if (!mem_ctx) return -1; + + open_parms.openx.level = RAW_OPEN_CTEMP; + open_parms.ctemp.in.attrib = 0; + open_parms.ctemp.in.directory = path; + + status = smb_raw_open(cli->tree, mem_ctx, &open_parms); + if (tmp_path) { + *tmp_path = strdup(open_parms.ctemp.out.name); + } + talloc_destroy(mem_ctx); + if (NT_STATUS_IS_OK(status)) { + return open_parms.ctemp.out.fnum; + } + return -1; +} + diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c new file mode 100644 index 0000000000..620e4382f4 --- /dev/null +++ b/source4/libcli/clilist.c @@ -0,0 +1,313 @@ +/* + Unix SMB/CIFS implementation. + client directory list routines + Copyright (C) Andrew Tridgell 1994-2003 + Copyright (C) James Myers 2003 + + 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" + +struct search_private { + file_info *dirlist; + TALLOC_CTX *mem_ctx; + int dirlist_len; + int ff_searchcount; /* total received in 1 server trip */ + int total_received; /* total received all together */ + int info_level; + DATA_BLOB status; /* used for old-style search */ +}; + + +/**************************************************************************** + Interpret a long filename structure. +****************************************************************************/ +static BOOL interpret_long_filename(int level, + union smb_search_data *info, + file_info *finfo) +{ + file_info finfo2; + + if (!finfo) finfo = &finfo2; + ZERO_STRUCTP(finfo); + + finfo->size = info->both_directory_info.size; + finfo->ctime = nt_time_to_unix(&info->both_directory_info.create_time); + finfo->atime = nt_time_to_unix(&info->both_directory_info.access_time); + finfo->mtime = nt_time_to_unix(&info->both_directory_info.write_time); + finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */ + if (info->both_directory_info.short_name.s) { + strncpy(finfo->short_name, info->both_directory_info.short_name.s, + sizeof(finfo->short_name)-1); + } + finfo->name = info->both_directory_info.name.s; + return True; +} + +/* callback function used for trans2 search */ +static BOOL cli_list_new_callback(void *private, union smb_search_data *file) +{ + struct search_private *state = (struct search_private*) private; + file_info *tdl; + + /* add file info to the dirlist pool */ + tdl = talloc_realloc(state->mem_ctx, state->dirlist, + state->dirlist_len + sizeof(struct file_info)); + + if (!tdl) { + return False; + } + state->dirlist = tdl; + state->dirlist_len += sizeof(struct file_info); + + interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]); + + state->total_received++; + state->ff_searchcount++; + + return True; +} + +int cli_list_new(struct cli_state *cli, const char *Mask, uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *caller_state) +{ + union smb_search_first first_parms; + union smb_search_next next_parms; + struct search_private state; /* for callbacks */ + int received = 0; + BOOL first = True; + int num_received = 0; + int max_matches = 512; + char *mask; + int ff_eos = 0, i, ff_searchcount; + int ff_dir_handle=0; + int level; + + /* initialize state for search */ + state.dirlist = NULL; + state.mem_ctx = talloc_init("cli_list_new"); + state.dirlist_len = 0; + state.total_received = 0; + + mask = talloc_strdup(state.mem_ctx, Mask); + + if (cli->transport->negotiate.capabilities & CAP_NT_SMBS) { + level = RAW_SEARCH_BOTH_DIRECTORY_INFO; + } else { + level = RAW_SEARCH_STANDARD; + } + + while (1) { + state.ff_searchcount = 0; + if (first) { + NTSTATUS status; + + first_parms.t2ffirst.level = level; + first_parms.t2ffirst.in.max_count = max_matches; + first_parms.t2ffirst.in.search_attrib = attribute; + first_parms.t2ffirst.in.pattern = mask; + first_parms.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE_IF_END; + first_parms.t2ffirst.in.storage_type = 0; + + status = smb_raw_search_first(cli->tree, + state.mem_ctx, &first_parms, + (void*)&state, cli_list_new_callback); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(state.mem_ctx); + return -1; + } + + ff_dir_handle = first_parms.t2ffirst.out.handle; + ff_searchcount = first_parms.t2ffirst.out.count; + ff_eos = first_parms.t2ffirst.out.end_of_search; + + received = first_parms.t2ffirst.out.count; + if (received <= 0) break; + if (ff_eos) break; + first = False; + } else { + NTSTATUS status; + + next_parms.t2fnext.level = level; + next_parms.t2fnext.in.max_count = max_matches; + next_parms.t2fnext.in.last_name = mask; + next_parms.t2fnext.in.handle = ff_dir_handle; + next_parms.t2fnext.in.resume_key = 0; + next_parms.t2fnext.in.flags = FLAG_TRANS2_FIND_CONTINUE | FLAG_TRANS2_FIND_CLOSE_IF_END; + + status = smb_raw_search_next(cli->tree, + state.mem_ctx, + &next_parms, + (void*)&state, + cli_list_new_callback); + + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + ff_searchcount = next_parms.t2fnext.out.count; + ff_eos = next_parms.t2fnext.out.end_of_search; + received = next_parms.t2fnext.out.count; + if (received <= 0) break; + if (ff_eos) break; + } + + num_received += received; + } + + for (i=0;ictime = info->search.write_time; + finfo->atime = info->search.write_time; + finfo->mtime = info->search.write_time; + finfo->size = info->search.size; + finfo->mode = info->search.attrib; + finfo->name = info->search.name; + return True; +} + +/* callback function used for smb_search */ +static BOOL cli_list_old_callback(void *private, union smb_search_data *file) +{ + struct search_private *state = (struct search_private*) private; + file_info *tdl; + + /* add file info to the dirlist pool */ + tdl = talloc_realloc(state->mem_ctx, state->dirlist, + state->dirlist_len + sizeof(struct file_info)); + + if (!tdl) { + return False; + } + state->dirlist = tdl; + state->dirlist_len += sizeof(struct file_info); + + interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]); + + state->total_received++; + state->ff_searchcount++; + state->status = file->search.search_id; /* return resume info */ + + return True; +} + +int cli_list_old(struct cli_state *cli, const char *Mask, uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *caller_state) +{ + union smb_search_first first_parms; + union smb_search_next next_parms; + struct search_private state; /* for callbacks */ + const int num_asked = 500; + int received = 0; + BOOL first = True; + int num_received = 0; + char *mask; + int i; + + /* initialize state for search */ + state.dirlist = NULL; + state.mem_ctx = talloc_init("cli_list_old"); + state.dirlist_len = 0; + state.total_received = 0; + + mask = talloc_strdup(state.mem_ctx, Mask); + + while (1) { + state.ff_searchcount = 0; + if (first) { + NTSTATUS status; + + first_parms.search_first.level = RAW_SEARCH_SEARCH; + first_parms.search_first.in.max_count = num_asked; + first_parms.search_first.in.search_attrib = attribute; + first_parms.search_first.in.pattern = mask; + + status = smb_raw_search_first(cli->tree, state.mem_ctx, + &first_parms, + (void*)&state, + cli_list_old_callback); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(state.mem_ctx); + return -1; + } + + received = first_parms.search_first.out.count; + if (received <= 0) break; + first = False; + } else { + NTSTATUS status; + + next_parms.search_next.level = RAW_SEARCH_SEARCH; + next_parms.search_next.in.max_count = num_asked; + next_parms.search_next.in.search_attrib = attribute; + next_parms.search_next.in.search_id = state.status; + + status = smb_raw_search_next(cli->tree, state.mem_ctx, + &next_parms, + (void*)&state, + cli_list_old_callback); + + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(state.mem_ctx); + return -1; + } + received = next_parms.search_next.out.count; + if (received <= 0) break; + } + + num_received += received; + } + + for (i=0;itransport->negotiate.protocol <= PROTOCOL_LANMAN1) + return cli_list_old(cli, Mask, attribute, fn, state); + return cli_list_new(cli, Mask, attribute, fn, state); +} diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c new file mode 100644 index 0000000000..ad5d41545b --- /dev/null +++ b/source4/libcli/climessage.c @@ -0,0 +1,93 @@ +/* + Unix SMB/CIFS implementation. + client message handling routines + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James J Myers 2003 + + 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" + + +/**************************************************************************** +start a message sequence +****************************************************************************/ +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp) +{ + struct cli_request *req; + + req = cli_request_setup(cli->tree, SMBsendstrt, 0, 0); + cli_req_append_string(req, username, STR_TERMINATE); + cli_req_append_string(req, host, STR_TERMINATE); + if (!cli_request_send(req) || + !cli_request_receive(req) || + cli_is_error(cli)) { + cli_request_destroy(req); + return False; + } + + *grp = SVAL(req->in.vwv, VWV(0)); + cli_request_destroy(req); + + return True; +} + + +/**************************************************************************** +send a message +****************************************************************************/ +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +{ + struct cli_request *req; + + req = cli_request_setup(cli->tree, SMBsendtxt, 1, 0); + SSVAL(req->out.vwv, VWV(0), grp); + + cli_req_append_bytes(req, msg, len); + + if (!cli_request_send(req) || + !cli_request_receive(req) || + cli_is_error(cli)) { + cli_request_destroy(req); + return False; + } + + cli_request_destroy(req); + return True; +} + +/**************************************************************************** +end a message +****************************************************************************/ +BOOL cli_message_end(struct cli_state *cli, int grp) +{ + struct cli_request *req; + + req = cli_request_setup(cli->tree, SMBsendend, 1, 0); + SSVAL(req->out.vwv, VWV(0), grp); + + if (!cli_request_send(req) || + !cli_request_receive(req) || + cli_is_error(cli)) { + cli_request_destroy(req); + return False; + } + + cli_request_destroy(req); + return True; +} + diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c new file mode 100644 index 0000000000..e1d154b283 --- /dev/null +++ b/source4/libcli/clireadwrite.c @@ -0,0 +1,155 @@ +/* + Unix SMB/CIFS implementation. + client file read/write routines + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + +/**************************************************************************** + Read size bytes at offset offset using SMBreadX. +****************************************************************************/ +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +{ + union smb_read parms; + int readsize; + ssize_t total = 0; + + if (size == 0) { + return 0; + } + + parms.readx.level = RAW_READ_READX; + parms.readx.in.fnum = fnum; + + /* + * Set readsize to the maximum size we can handle in one readX, + * rounded down to a multiple of 1024. + */ + readsize = (cli->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; + + while (total < size) { + NTSTATUS status; + + readsize = MIN(readsize, size-total); + + parms.readx.in.offset = offset; + parms.readx.in.mincnt = readsize; + parms.readx.in.maxcnt = readsize; + parms.readx.in.remaining = size - total; + parms.readx.out.data = buf + total; + + status = smb_raw_read(cli->tree, &parms); + + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + + total += parms.readx.out.nread; + offset += parms.readx.out.nread; + + /* If the server returned less than we asked for we're at EOF */ + if (parms.readx.out.nread < readsize) + break; + } + + return total; +} + + +/**************************************************************************** + write to a file + write_mode: 0x0001 disallow write cacheing + 0x0002 return bytes remaining + 0x0004 use raw named pipe protocol + 0x0008 start of message mode named pipe protocol +****************************************************************************/ +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + const char *buf, off_t offset, size_t size) +{ + union smb_write parms; + int block = (cli->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; + ssize_t total = 0; + + if (size == 0) { + return 0; + } + + parms.writex.level = RAW_WRITE_WRITEX; + parms.writex.in.fnum = fnum; + parms.writex.in.wmode = write_mode; + parms.writex.in.remaining = 0; + + while (total < size) { + NTSTATUS status; + + block = MIN(block, size - total); + + parms.writex.in.offset = offset; + parms.writex.in.count = block; + parms.writex.in.data = buf; + + status = smb_raw_write(cli->tree, &parms); + + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + + offset += parms.writex.out.nwritten; + total += parms.writex.out.nwritten; + buf += parms.writex.out.nwritten; + } + + return total; +} + +/**************************************************************************** + write to a file using a SMBwrite and not bypassing 0 byte writes +****************************************************************************/ +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1) +{ + union smb_write parms; + ssize_t total = 0; + + parms.write.level = RAW_WRITE_WRITE; + parms.write.in.remaining = 0; + + do { + size_t size = MIN(size1, cli->transport->negotiate.max_xmit - 48); + + parms.write.in.fnum = fnum; + parms.write.in.offset = offset; + parms.write.in.count = size; + parms.write.in.data = buf + total; + + if (NT_STATUS_IS_ERR(smb_raw_write(cli->tree, &parms))) + return -1; + + size = parms.write.out.nwritten; + if (size == 0) + break; + + size1 -= size; + total += size; + offset += size; + } while (size1); + + return total; +} diff --git a/source4/libcli/clisecdesc.c b/source4/libcli/clisecdesc.c new file mode 100644 index 0000000000..66272251ec --- /dev/null +++ b/source4/libcli/clisecdesc.c @@ -0,0 +1,121 @@ +/* + Unix SMB/CIFS implementation. + client security descriptor functions + Copyright (C) Andrew Tridgell 2000 + Copyright (C) James J Myers 2003 + + 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" + +/**************************************************************************** + query the security descriptor for a open file + ****************************************************************************/ +SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, + TALLOC_CTX *mem_ctx) +{ + struct smb_nttrans parms; + char param[8]; + DATA_BLOB param_blob; + prs_struct pd; + SEC_DESC *psd = NULL; + NTSTATUS status; + + param_blob.length = 8; + param_blob.data = ¶m[0]; + + SIVAL(param, 0, fnum); + SSVAL(param, 4, 0x7); + + parms.in.max_param = 1024; + parms.in.max_data = 1024; + parms.in.max_setup = 0; + parms.in.setup_count = 18; + parms.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; + parms.in.params = param_blob; + parms.in.data = data_blob(NULL, 0); + + status = smb_raw_nttrans(cli->tree, mem_ctx, &parms); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); + goto cleanup; + } + + prs_init(&pd, parms.out.data.length, mem_ctx, UNMARSHALL); + prs_copy_data_in(&pd, parms.out.data.data, parms.out.data.length); + prs_set_offset(&pd,0); + + if (!sec_io_desc("sd data", &psd, &pd, 1)) { + DEBUG(1,("Failed to parse secdesc\n")); + goto cleanup; + } + + cleanup: + prs_mem_free(&pd); + return psd; +} + +/**************************************************************************** + set the security descriptor for a open file + ****************************************************************************/ +BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) +{ + struct smb_nttrans parms; + char param[8]; + DATA_BLOB param_blob; + prs_struct pd; + BOOL ret = False; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("cli_set_secdesc"); + + prs_init(&pd, 0, mem_ctx, MARSHALL); + prs_give_memory(&pd, NULL, 0, True); + + if (!sec_io_desc("sd data", &sd, &pd, 1)) { + DEBUG(1,("Failed to marshall secdesc\n")); + goto cleanup; + } + + param_blob.length = 8; + param_blob.data = ¶m[0]; + + SIVAL(param, 0, fnum); + SSVAL(param, 4, 0x7); + + parms.in.max_param = 1000; + parms.in.max_data = 1000; + parms.in.max_setup = 0; + parms.in.setup_count = 18; + parms.in.function = NT_TRANSACT_SET_SECURITY_DESC; + parms.in.params = param_blob; + parms.in.data = data_blob(NULL, 0); + + status = smb_raw_nttrans(cli->tree, mem_ctx, &parms); + + if (NT_STATUS_IS_ERR(status)) { + DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); + goto cleanup; + } + ret = True; + + cleanup: + prs_mem_free(&pd); + talloc_destroy(mem_ctx); + return ret; +} diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c new file mode 100644 index 0000000000..6fd5c2ce28 --- /dev/null +++ b/source4/libcli/clitrans2.c @@ -0,0 +1,221 @@ +/* + Unix SMB/CIFS implementation. + client trans2 calls + Copyright (C) James J Myers 2003 + + 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" + +/**************************************************************************** +send a qpathinfo call +****************************************************************************/ +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode) +{ + union smb_fileinfo parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("cli_qpathinfo"); + if (!mem_ctx) return False; + + parms.standard.level = RAW_FILEINFO_STANDARD; + parms.standard.in.fname = fname; + + status = smb_raw_pathinfo(cli->tree, mem_ctx, &parms); + talloc_destroy(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + if (c_time) { + *c_time = parms.standard.out.create_time; + } + if (a_time) { + *a_time = parms.standard.out.access_time; + } + if (m_time) { + *m_time = parms.standard.out.write_time; + } + if (size) { + *size = parms.standard.out.size; + } + if (mode) { + *mode = parms.standard.out.attrib; + } + + return True; +} + +/**************************************************************************** +send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level +****************************************************************************/ +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino) +{ + union smb_fileinfo parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("cli_qfilename"); + if (!mem_ctx) return False; + + parms.all_info.level = RAW_FILEINFO_ALL_INFO; + parms.all_info.in.fname = fname; + + status = smb_raw_pathinfo(cli->tree, mem_ctx, &parms); + talloc_destroy(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + if (c_time) { + *c_time = nt_time_to_unix(&parms.all_info.out.create_time); + } + if (a_time) { + *a_time = nt_time_to_unix(&parms.all_info.out.access_time); + } + if (m_time) { + *m_time = nt_time_to_unix(&parms.all_info.out.change_time); + } + if (w_time) { + *w_time = nt_time_to_unix(&parms.all_info.out.write_time); + } + if (size) { + *size = parms.all_info.out.size; + } + if (mode) { + *mode = parms.all_info.out.attrib; + } + + return True; +} + + +/**************************************************************************** +send a qfileinfo QUERY_FILE_NAME_INFO call +****************************************************************************/ +BOOL cli_qfilename(struct cli_state *cli, int fnum, + const char **name) +{ + union smb_fileinfo parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("cli_qfilename"); + if (!mem_ctx) return False; + + parms.name_info.level = RAW_FILEINFO_NAME_INFO; + parms.name_info.in.fnum = fnum; + + status = smb_raw_fileinfo(cli->tree, mem_ctx, &parms); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + *name = NULL; + return False; + } + + *name = strdup(parms.name_info.out.fname.s); + + talloc_destroy(mem_ctx); + + return True; +} + + +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino) +{ + union smb_fileinfo parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("cli_qfileinfo"); + if (!mem_ctx) return False; + + parms.all_info.level = RAW_FILEINFO_ALL_INFO; + parms.all_info.in.fnum = fnum; + + status = smb_raw_fileinfo(cli->tree, mem_ctx, &parms); + talloc_destroy(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + if (c_time) { + *c_time = nt_time_to_unix(&parms.all_info.out.create_time); + } + if (a_time) { + *a_time = nt_time_to_unix(&parms.all_info.out.access_time); + } + if (m_time) { + *m_time = nt_time_to_unix(&parms.all_info.out.change_time); + } + if (w_time) { + *w_time = nt_time_to_unix(&parms.all_info.out.write_time); + } + if (mode) { + *mode = parms.all_info.out.attrib; + } + if (size) { + *size = (size_t)parms.all_info.out.size; + } + if (ino) { + *ino = 0; + } + + return True; +} + + +/**************************************************************************** +send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call +****************************************************************************/ +NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, + const char **alt_name) +{ + union smb_fileinfo parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + parms.alt_name_info.level = RAW_FILEINFO_ALT_NAME_INFO; + parms.alt_name_info.in.fname = fname; + + mem_ctx = talloc_init("cli_qpathinfo_alt_name"); + if (!mem_ctx) return NT_STATUS_NO_MEMORY; + + status = smb_raw_pathinfo(cli->tree, mem_ctx, &parms); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + *alt_name = NULL; + return cli_nt_error(cli); + } + + *alt_name = strdup(parms.alt_name_info.out.fname.s); + + talloc_destroy(mem_ctx); + + return NT_STATUS_OK; +} diff --git a/source4/libcli/namecache.c b/source4/libcli/namecache.c new file mode 100644 index 0000000000..9f4796af1a --- /dev/null +++ b/source4/libcli/namecache.c @@ -0,0 +1,246 @@ +/* + Unix SMB/CIFS implementation. + + NetBIOS name cache module on top of gencache mechanism. + + Copyright (C) Tim Potter 2002 + Copyright (C) Rafal Szczesniak 2002 + + 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" + +#define NBTKEY_FMT "NBT/%s#%02X" + + +/** + * Initialise namecache system. Function calls gencache + * initialisation function to perform necessary actions + * + * @return true upon successful initialisation of the cache or + * false on failure + **/ + +BOOL namecache_enableTODO(void) +{ + /* + * Check if name caching disabled by setting the name cache + * timeout to zero. + */ + + if (lp_name_cache_timeout() == 0) { + DEBUG(5, ("namecache_enable: disabling netbios name cache\n")); + return False; + } + + /* Init namecache by calling gencache initialisation */ + + if (!gencache_init()) { + DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n")); + return False; + } + + /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */ + DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " + "seconds\n", lp_name_cache_timeout())); + + return True; +} + + +/** + * Shutdown namecache. Routine calls gencache close function + * to safely close gencache file. + * + * @return true upon successful shutdown of the cache or + * false on failure + **/ + +BOOL namecache_shutdownTODO(void) +{ + if (!gencache_shutdown()) { + DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n")); + return False; + } + + DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n")); + return True; +} + + +/** + * Generates a key for netbios name lookups on basis of + * netbios name and type. + * The caller must free returned key string when finished. + * + * @param name netbios name string (case insensitive) + * @param name_type netbios type of the name being looked up + * + * @return string consisted of uppercased name and appended + * type number + */ + +static char* namecache_key(TALLOC_CTX *mem_ctx, const char *name, int name_type) +{ + char *keystr; + asprintf(&keystr, NBTKEY_FMT, strupper_talloc(mem_ctx, name), name_type); + + return keystr; +} + + +/** + * Store a name(s) in the name cache + * + * @param name netbios names array + * @param name_type integer netbios name type + * @param num_names number of names being stored + * @param ip_list array of in_addr structures containing + * ip addresses being stored + **/ + +BOOL namecache_store(TALLOC_CTX *mem_ctx, const char *name, int name_type, + int num_names, struct in_addr *ip_list) +{ + time_t expiry; + char *key, *value_string; + int i; + + /* + * we use gecache call to avoid annoying debug messages about + * initialised namecache again and again... + */ + if (!gencache_init()) return False; + + DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", + num_names, num_names == 1 ? "": "es", name, name_type)); + + for (i = 0; i < num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), + i == (num_names - 1) ? "" : ", ")); + + DEBUGADD(5, ("\n")); + + key = namecache_key(mem_ctx, name, name_type); + + /* + * Cache pdc location or dc lists for only a little while + * otherwise if we lock on to a bad DC we can potentially be + * out of action for the entire cache timeout time! + */ + + if (name_type == 0x1b || name_type == 0x1c) + expiry = time(NULL) + 10; + else + expiry = time(NULL) + lp_name_cache_timeout(); + + /* + * Generate string representation of ip addresses list + * First, store the number of ip addresses and then + * place each single ip + */ + ipstr_list_make(&value_string, ip_list, num_names); + + /* set the entry */ + return (gencache_set(key, value_string, expiry)); +} + + +/** + * Look up a name in the cache. + * + * @param name netbios name to look up for + * @param name_type netbios name type of @param name + * @param ip_list mallocated list of IP addresses if found in the cache, + * NULL otherwise + * @param num_names number of entries found + * + * @return true upon successful fetch or + * false if name isn't found in the cache or has expired + **/ + +BOOL namecache_fetch(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct in_addr **ip_list, + int *num_names) +{ + char *key, *value; + time_t timeout; + + *num_names = 0; + + /* exit now if null pointers were passed as they're required further */ + if (!ip_list || !num_names) return False; + + if (!gencache_init()) + return False; + + /* + * Use gencache interface - lookup the key + */ + key = namecache_key(mem_ctx, name, name_type); + + if (!gencache_get(key, &value, &timeout)) { + DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); + SAFE_FREE(key); + return False; + } else { + DEBUG(5, ("name %s#%02X found.\n", name, name_type)); + } + + /* + * Split up the stored value into the list of IP adresses + */ + *num_names = ipstr_list_parse(value, ip_list); + + SAFE_FREE(key); + SAFE_FREE(value); + return *num_names > 0; /* true only if some ip has been fetched */ +} + + +/** + * Delete single namecache entry. Look at the + * gencache_iterate definition. + * + **/ + +static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr) +{ + gencache_del(key); + DEBUG(5, ("Deleting entry %s\n", key)); +} + + +/** + * Flush all names from the name cache. + * It's done by gencache_iterate() + * + * @return True upon successful deletion or + * False in case of an error + **/ + +void namecache_flush(void) +{ + if (!gencache_init()) + return; + + /* + * iterate through each NBT cache's entry and flush it + * by flush_netbios_name function + */ + gencache_iterate(flush_netbios_name, NULL, "NBT/*"); + DEBUG(5, ("Namecache flushed\n")); +} + diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c new file mode 100644 index 0000000000..2f6343dcaf --- /dev/null +++ b/source4/libcli/namequery.c @@ -0,0 +1,1333 @@ +/* + Unix SMB/CIFS implementation. + name query routines + Copyright (C) Andrew Tridgell 1994-1998 + + 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" + +/* nmbd.c sets this to True. */ +BOOL global_in_nmbd = False; + +/**************************************************************************** +generate a random trn_id +****************************************************************************/ +static int generate_trn_id(void) +{ + static int trn_id; + + if (trn_id == 0) { + sys_srandom(getpid()); + } + + trn_id = sys_random(); + + return trn_id % (unsigned)0x7FFF; +} + + +/**************************************************************************** + parse a node status response into an array of structures +****************************************************************************/ +static struct node_status *parse_node_status(char *p, int *num_names) +{ + struct node_status *ret; + int i; + + *num_names = CVAL(p,0); + + if (*num_names == 0) return NULL; + + ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names)); + if (!ret) return NULL; + + p++; + for (i=0;i< *num_names;i++) { + StrnCpy(ret[i].name,p,15); + trim_string(ret[i].name,NULL," "); + ret[i].type = CVAL(p,15); + ret[i].flags = p[16]; + p += 18; + DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, + ret[i].type, ret[i].flags)); + } + return ret; +} + + +/**************************************************************************** +do a NBT node status query on an open socket and return an array of +structures holding the returned names or NULL if the query failed +**************************************************************************/ +struct node_status *node_status_query(int fd,struct nmb_name *name, + struct in_addr to_ip, int *num_names) +{ + BOOL found=False; + int retries = 2; + int retry_time = 2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct node_status *ret; + + ZERO_STRUCT(p); + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = False; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + nmb->question.question_name = *name; + nmb->question.question_type = 0x21; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return NULL; + + retries--; + + while (1) { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount || + nmb2->answers->rr_type != 0x21) { + /* XXXX what do we do with this? could be a + redirect, but we'll discard it for the + moment */ + free_packet(p2); + continue; + } + + ret = parse_node_status(&nmb2->answers->rdata[0], num_names); + free_packet(p2); + return ret; + } + } + + return NULL; +} + + +/**************************************************************************** +find the first type XX name in a node status reply - used for finding +a servers name given its IP +return the matched name in *name +**************************************************************************/ + +BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) +{ + struct node_status *status = NULL; + struct nmb_name nname; + int count, i; + int sock; + BOOL result = False; + + if (lp_disable_netbios()) { + DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); + return False; + } + + DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, + q_type, inet_ntoa(to_ip))); + + sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); + if (sock == -1) + goto done; + + /* W2K PDC's seem not to respond to '*'#0. JRA */ + make_nmb_name(&nname, q_name, q_type); + status = node_status_query(sock, &nname, to_ip, &count); + close(sock); + if (!status) + goto done; + + for (i=0;is_addr, (uchar *)&ip.s_addr); + bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr); + max_bits1 = MAX(bits1, max_bits1); + max_bits2 = MAX(bits2, max_bits2); + } + + /* bias towards directly reachable IPs */ + if (iface_local(*ip1)) { + max_bits1 += 32; + } + if (iface_local(*ip2)) { + max_bits2 += 32; + } + + return max_bits2 - max_bits1; +} + +/* + sort an IP list so that names that are close to one of our interfaces + are at the top. This prevents the problem where a WINS server returns an IP that + is not reachable from our subnet as the first match +*/ +static void sort_ip_list(struct in_addr *iplist, int count) +{ + if (count <= 1) { + return; + } + + qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); +} + + +/**************************************************************************** + Do a netbios name query to find someones IP. + Returns an array of IP addresses or NULL if none. + *count will be set to the number of addresses returned. + *timed_out is set if we failed by timing out +****************************************************************************/ +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count, int *flags, + BOOL *timed_out) +{ + BOOL found=False; + int i, retries = 3; + int retry_time = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct in_addr *ip_list = NULL; + + if (lp_disable_netbios()) { + DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type)); + return NULL; + } + + if (timed_out) { + *timed_out = False; + } + + memset((char *)&p,'\0',sizeof(p)); + (*count) = 0; + (*flags) = 0; + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return NULL; + + retries--; + + while (1) { + struct timeval tval2; + struct in_addr *tmp_ip_list; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + /* If we get a Negative Name Query Response from a WINS + * server, we should report it and give up. + */ + if( 0 == nmb2->header.opcode /* A query response */ + && !(bcast) /* from a WINS server */ + && nmb2->header.rcode /* Error returned */ + ) { + + if (DEBUGLVL(3)) { + /* Only executed if DEBUGLEVEL >= 3 */ + DEBUG(3,("Negative name query response, rcode 0x%02x: ", nmb2->header.rcode )); + switch( nmb2->header.rcode ) { + case 0x01: + DEBUG(3,("Request was invalidly formatted.\n" )); + break; + case 0x02: + DEBUG(3,("Problem with NBNS, cannot process name.\n")); + break; + case 0x03: + DEBUG(3,("The name requested does not exist.\n" )); + break; + case 0x04: + DEBUG(3,("Unsupported request error.\n" )); + break; + case 0x05: + DEBUG(3,("Query refused error.\n" )); + break; + default: + DEBUG(3,("Unrecognized error code.\n" )); + break; + } + } + free_packet(p2); + return( NULL ); + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* + * XXXX what do we do with this? Could be a + * redirect, but we'll discard it for the + * moment. + */ + free_packet(p2); + continue; + } + + tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) + * ( (*count) + nmb2->answers->rdlength/6 ) ); + + if (!tmp_ip_list) { + DEBUG(0,("name_query: Realloc failed.\n")); + SAFE_FREE(ip_list); + } + + ip_list = tmp_ip_list; + + if (ip_list) { + DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); + for (i=0;ianswers->rdlength/6;i++) { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; + } + DEBUGADD(2,(")\n")); + } + + found=True; + retries=0; + /* We add the flags back ... */ + if (nmb2->header.response) + (*flags) |= NM_FLAGS_RS; + if (nmb2->header.nm_flags.authoritative) + (*flags) |= NM_FLAGS_AA; + if (nmb2->header.nm_flags.trunc) + (*flags) |= NM_FLAGS_TC; + if (nmb2->header.nm_flags.recursion_desired) + (*flags) |= NM_FLAGS_RD; + if (nmb2->header.nm_flags.recursion_available) + (*flags) |= NM_FLAGS_RA; + if (nmb2->header.nm_flags.bcast) + (*flags) |= NM_FLAGS_B; + free_packet(p2); + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if(!bcast && found) + break; + } + } + + if (timed_out) { + *timed_out = True; + } + + /* sort the ip list so we choose close servers first if possible */ + sort_ip_list(ip_list, *count); + + return ip_list; +} + +/******************************************************** + Start parsing the lmhosts file. +*********************************************************/ + +XFILE *startlmhosts(char *fname) +{ + XFILE *fp = x_fopen(fname,O_RDONLY, 0); + if (!fp) { + DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", + fname, strerror(errno))); + return NULL; + } + return fp; +} + +/******************************************************** + Parse the next line in the lmhosts file. +*********************************************************/ + +BOOL getlmhostsent( TALLOC_CTX *mem_ctx, + XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) +{ + pstring line; + + while(!x_feof(fp) && !x_ferror(fp)) { + pstring ip,flags,extra; + const char *ptr; + char *ptr1; + int count = 0; + + *name_type = -1; + + if (!fgets_slash(line,sizeof(pstring),fp)) + continue; + + if (*line == '#') + continue; + + pstrcpy(ip,""); + pstrcpy(name,""); + pstrcpy(flags,""); + + ptr = line; + + if (next_token(&ptr,ip ,NULL,sizeof(ip))) + ++count; + if (next_token(&ptr,name ,NULL, sizeof(pstring))) + ++count; + if (next_token(&ptr,flags,NULL, sizeof(flags))) + ++count; + if (next_token(&ptr,extra,NULL, sizeof(extra))) + ++count; + + if (count <= 0) + continue; + + if (count > 0 && count < 2) + { + DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); + continue; + } + + if (count >= 4) + { + DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); + continue; + } + + DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); + + if (strchr_m(flags,'G') || strchr_m(flags,'S')) + { + DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); + continue; + } + + *ipaddr = *interpret_addr2(mem_ctx, ip); + + /* Extra feature. If the name ends in '#XX', where XX is a hex number, + then only add that name type. */ + if((ptr1 = strchr_m(name, '#')) != NULL) + { + char *endptr; + + ptr1++; + *name_type = (int)strtol(ptr1, &endptr, 16); + + if(!*ptr1 || (endptr == ptr1)) + { + DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); + continue; + } + + *(--ptr1) = '\0'; /* Truncate at the '#' */ + } + + return True; + } + + return False; +} + +/******************************************************** + Finish parsing the lmhosts file. +*********************************************************/ + +void endlmhosts(XFILE *fp) +{ + x_fclose(fp); +} + + +/******************************************************** + Resolve via "bcast" method. +*********************************************************/ + +BOOL name_resolve_bcast(const char *name, int name_type, + struct in_addr **return_ip_list, int *return_count) +{ + int sock, i; + int num_interfaces = iface_count(); + + if (lp_disable_netbios()) { + DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + + *return_ip_list = NULL; + *return_count = 0; + + /* + * "bcast" means do a broadcast lookup on all the local interfaces. + */ + + DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); + + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()), True ); + + if (sock == -1) return False; + + set_socket_options(sock,"SO_BROADCAST"); + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for( i = num_interfaces-1; i >= 0; i--) { + struct in_addr sendto_ip; + int flags; + /* Done this way to fix compiler error on IRIX 5.x */ + sendto_ip = *iface_n_bcast(i); + *return_ip_list = name_query(sock, name, name_type, True, + True, sendto_ip, return_count, &flags, NULL); + if(*return_ip_list != NULL) { + close(sock); + return True; + } + } + + close(sock); + return False; +} + +/******************************************************** + Resolve via "wins" method. +*********************************************************/ +BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) +{ + int sock, t, i; + char **wins_tags; + struct in_addr src_ip; + + if (lp_disable_netbios()) { + DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + + *return_iplist = NULL; + *return_count = 0; + + DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); + + if (wins_srv_count() < 1) { + DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); + return False; + } + + /* we try a lookup on each of the WINS tags in turn */ + wins_tags = wins_srv_tags(); + + if (!wins_tags) { + /* huh? no tags?? give up in disgust */ + return False; + } + + /* the address we will be sending from */ + src_ip = *interpret_addr2(mem_ctx, lp_socket_address()); + + /* in the worst case we will try every wins server with every + tag! */ + for (t=0; wins_tags && wins_tags[t]; t++) { + int srv_count = wins_srv_count_tag(wins_tags[t]); + for (i=0; i\n", name)); + + if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + struct in_addr return_ip; + putip((char *)&return_ip,(char *)hp->h_addr); + *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + if(*return_iplist == NULL) { + DEBUG(3,("resolve_hosts: malloc fail !\n")); + return False; + } + **return_iplist = return_ip; + *return_count = 1; + return True; + } + return False; +} + +/******************************************************** + Internal interface to resolve a name into an IP address. + Use this function if the string is either an IP address, DNS + or host name or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ + +static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) +{ + char *name_resolve_list; + fstring tok; + const char *ptr; + BOOL allones = (strcmp(name,"255.255.255.255") == 0); + BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); + BOOL is_address = is_ipaddress(name); + BOOL result = False; + struct in_addr *nodupes_iplist; + int i; + + *return_iplist = NULL; + *return_count = 0; + + DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); + + if (allzeros || allones || is_address) { + *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + if(*return_iplist == NULL) { + DEBUG(3,("internal_resolve_name: malloc fail !\n")); + return False; + } + if(is_address) { + /* if it's in the form of an IP address then get the lib to interpret it */ + if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){ + DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); + return False; + } + } else { + (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0; + *return_count = 1; + } + return True; + } + + /* Check netbios name cache */ + + if (namecache_fetch(mem_ctx, name, name_type, return_iplist, return_count)) { + + /* This could be a negative response */ + + return (*return_count > 0); + } + + name_resolve_list = talloc_strdup(mem_ctx, lp_name_resolve_order()); + ptr = name_resolve_list; + if (!ptr || !*ptr) + ptr = "host"; + + while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { + if((strequal(tok, "host") || strequal(tok, "hosts"))) { + if (name_type == 0x20) { + if (resolve_hosts(name, return_iplist, return_count)) { + result = True; + goto done; + } + } + } else if(strequal( tok, "lmhosts")) { + /* REWRITE: add back in? */ + DEBUG(0,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok)); + } else if(strequal( tok, "wins")) { + /* don't resolve 1D via WINS */ + if (name_type != 0x1D && + resolve_wins(mem_ctx, name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "bcast")) { + if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else { + DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); + } + } + + /* All of the resolve_* functions above have returned false. */ + + SAFE_FREE(*return_iplist); + *return_count = 0; + + return False; + + done: + + /* Remove duplicate entries. Some queries, notably #1c (domain + controllers) return the PDC in iplist[0] and then all domain + controllers including the PDC in iplist[1..n]. Iterating over + the iplist when the PDC is down will cause two sets of timeouts. */ + + if (*return_count && (nodupes_iplist = (struct in_addr *) + malloc(sizeof(struct in_addr) * (*return_count)))) { + int nodupes_count = 0; + + /* Iterate over return_iplist looking for duplicates */ + + for (i = 0; i < *return_count; i++) { + BOOL is_dupe = False; + int j; + + for (j = i + 1; j < *return_count; j++) { + if (ip_equal((*return_iplist)[i], + (*return_iplist)[j])) { + is_dupe = True; + break; + } + } + + if (!is_dupe) { + + /* This one not a duplicate */ + + nodupes_iplist[nodupes_count] = (*return_iplist)[i]; + nodupes_count++; + } + } + + /* Switcheroo with original list */ + + free(*return_iplist); + + *return_iplist = nodupes_iplist; + *return_count = nodupes_count; + } + + /* Save in name cache */ + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) + DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, + name_type, inet_ntoa((*return_iplist)[i]))); + + namecache_store(mem_ctx, name, name_type, *return_count, *return_iplist); + + /* Display some debugging info */ + + DEBUG(10, ("internal_resolve_name: returning %d addresses: ", + *return_count)); + + for (i = 0; i < *return_count; i++) + DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i]))); + + DEBUG(10, ("\n")); + + return result; +} + +/******************************************************** + Internal interface to resolve a name into one IP address. + Use this function if the string is either an IP address, DNS + or host name or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ +BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ip, int name_type) +{ + struct in_addr *ip_list = NULL; + int count = 0; + + if (is_ipaddress(name)) { + *return_ip = *interpret_addr2(mem_ctx, name); + return True; + } + + if (internal_resolve_name(mem_ctx, name, name_type, &ip_list, &count)) { + int i; + /* only return valid addresses for TCP connections */ + for (i=0; iheader.msg_type = 0x10; + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = dgm_id; + dgram->header.source_ip = *iface_ip(*pdc_ip); + dgram->header.source_port = ntohs(sock_name.sin_port); + dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,0); + make_nmb_name(&dgram->dest_name,domain,0x1C); + + ptr = &dgram->data[0]; + + /* Setup the smb part. */ + ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + pstrcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buffer,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ + + p.ip = *pdc_ip; + p.port = DGRAM_PORT; + p.fd = sock; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + + retries--; + + while (1) { + struct timeval tval2; + struct packet_struct *p_ret; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + GetTimeOfDay(&tval); + retries--; + } + + if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) { + struct dgram_packet *dgram2 = &p_ret->packet.dgram; + char *buf; + char *buf2; + + buf = &dgram2->data[0]; + buf -= 4; + + if (CVAL(buf,smb_com) != SMBtrans) { + DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int) + CVAL(buf,smb_com), (unsigned int)SMBtrans )); + free_packet(p_ret); + continue; + } + + len = SVAL(buf,smb_vwv11); + buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); + + if (len <= 0) { + DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); + free_packet(p_ret); + continue; + } + + DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", + nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), + inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); + + if(SVAL(buf2,0) != QUERYFORPDC_R) { + DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", + (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); + free_packet(p_ret); + continue; + } + + buf2 += 2; + /* Note this is safe as it is a bounded strcpy. */ + fstrcpy(ret_name, buf2); + ret_name[sizeof(fstring)-1] = '\0'; + close(sock); + free_packet(p_ret); + return True; + } + } + + close(sock); + return False; +#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ +} + +/******************************************************** + Get the IP address list of the primary domain controller + for a domain. +*********************************************************/ + +BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr *ip) +{ + struct in_addr *ip_list; + int count; + int i = 0; + + /* Look up #1B name */ + + if (!internal_resolve_name(mem_ctx, domain, 0x1b, &ip_list, &count)) + return False; + + /* if we get more than 1 IP back we have to assume it is a + multi-homed PDC and not a mess up */ + + if ( count > 1 ) { + DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); + + /* look for a local net */ + for ( i=0; i 1) ) { + qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare); + } + + for (i = 0; i < count; i++) { + if (is_zero_ip(ip_list[i])) + continue; + + if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { + dc_ip = ip_list[i]; + goto done; + } + } + + + SAFE_FREE(ip_list); + + return False; +done: + /* We have the netbios name and IP address of a domain controller. + Ideally we should sent a SAMLOGON request to determine whether + the DC is alive and kicking. If we can catch a dead DC before + performing a cli_connect() we can avoid a 30-second timeout. */ + + DEBUG(3, ("rpc_find_dc: Returning DC %s (%s) for domain %s\n", srv_name, + inet_ntoa(dc_ip), domain)); + + *ip_out = dc_ip; + + SAFE_FREE(ip_list); + + return True; +} + diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c new file mode 100644 index 0000000000..a875f4652e --- /dev/null +++ b/source4/libcli/nmblib.c @@ -0,0 +1,1287 @@ +/* + Unix SMB/CIFS implementation. + NBT netbios library routines + Copyright (C) Andrew Tridgell 1994-1998 + + 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" + +static const struct opcode_names { + const char *nmb_opcode_name; + int opcode; +} nmb_header_opcode_names[] = { + {"Query", 0 }, + {"Registration", 5 }, + {"Release", 6 }, + {"WACK", 7 }, + {"Refresh", 8 }, + {"Refresh(altcode)", 9 }, + {"Multi-homed Registration", 15 }, + {0, -1 } +}; + +/**************************************************************************** + * Lookup a nmb opcode name. + ****************************************************************************/ +static const char *lookup_opcode_name( int opcode ) +{ + const struct opcode_names *op_namep; + int i; + + for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { + op_namep = &nmb_header_opcode_names[i]; + if(opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + } + return ""; +} + +/**************************************************************************** + print out a res_rec structure + ****************************************************************************/ +static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) +{ + int i, j; + + DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + nmb_namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl ) ); + + if( res->rdlength == 0 || res->rdata == NULL ) + return; + + for (i = 0; i < res->rdlength; i+= 16) + { + DEBUGADD(4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < 16; j++) + { + uchar x = res->rdata[i+j]; + if (x < 32 || x > 127) x = '.'; + + if (i+j >= res->rdlength) break; + DEBUGADD(4, ("%c", x)); + } + + DEBUGADD(4, (" hex ")); + + for (j = 0; j < 16; j++) + { + if (i+j >= res->rdlength) break; + DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); + } + + DEBUGADD(4, ("\n")); + } +} + +/**************************************************************************** + process a nmb packet + ****************************************************************************/ +void debug_nmb_packet(struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + + if (DEBUGLVL(4)) { + DEBUG(4, ("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode, + BOOLSTR(nmb->header.response))); + DEBUG(4, (" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative))); + DEBUG(4, (" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount)); + } + + if (nmb->header.qdcount) + { + DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", + nmb_namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class) ); + } + + if (nmb->answers && nmb->header.ancount) + { + debug_nmb_res_rec(nmb->answers,"answers"); + } + if (nmb->nsrecs && nmb->header.nscount) + { + debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); + } + if (nmb->additional && nmb->header.arcount) + { + debug_nmb_res_rec(nmb->additional,"additional"); + } +} + +/******************************************************************* + handle "compressed" name pointers + ******************************************************************/ +static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, + BOOL *got_pointer,int *ret) +{ + int loop_count=0; + + while ((ubuf[*offset] & 0xC0) == 0xC0) { + if (!*got_pointer) (*ret) += 2; + (*got_pointer)=True; + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { + return(False); + } + } + return(True); +} + +/******************************************************************* + parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid + ******************************************************************/ +static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) +{ + int m,n=0; + uchar *ubuf = (uchar *)inbuf; + int ret = 0; + BOOL got_pointer=False; + int loop_count=0; + int offset = ofs; + + if (length - offset < 2) + return(0); + + /* handle initial name pointers */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); + + m = ubuf[offset]; + + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); + + memset((char *)name,'\0',sizeof(*name)); + + /* the "compressed" part */ + if (!got_pointer) + ret += m + 2; + offset++; + while (m > 0) { + uchar c1,c2; + c1 = ubuf[offset++]-'A'; + c2 = ubuf[offset++]-'A'; + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); + name->name[n++] = (c1<<4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n==16) { + /* parse out the name type, + its always in the 16th byte of the name */ + name->name_type = ((uchar)name->name[15]) & 0xff; + + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') + name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while (ubuf[offset]) { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); + + m = ubuf[offset]; + /* + * Don't allow null domain parts. + */ + if (!m) + return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); + offset++; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; + + /* + * Watch for malicious loops. + */ + if (loop_count++ == 10) + return 0; + } + name->scope[n++] = 0; + + return(ret); +} + + +/******************************************************************* + put a compressed nmb name into a buffer. return the length of the + compressed name + + compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. + ******************************************************************/ +static int put_nmb_name(char *buf,int offset,struct nmb_name *name) +{ + int ret,m; + fstring buf1; + char *p; + + if (strcmp(name->name,"*") == 0) { + /* special case for wildcard name */ + memset(buf1,'\0',20); + buf1[0] = '*'; + buf1[15] = name->name_type; + } else { + slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m=0;m<16;m++) { + buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) { + /* XXXX this scope handling needs testing */ + ret += strlen(name->scope) + 1; + pstrcpy(&buf[offset+1],name->scope); + + p = &buf[offset+1]; + while ((p = strchr_m(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); + } + + return(ret); +} + +/******************************************************************* + useful for debugging messages + ******************************************************************/ +char *nmb_namestr(struct nmb_name *n) +{ + static int i=0; + static fstring ret[4]; + char *p = ret[i]; + + if (!n->scope[0]) + slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); + else + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); + + i = (i+1)%4; + return(p); +} + +/******************************************************************* + allocate and parse some resource records + ******************************************************************/ +static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, + struct res_rec **recs, int count) +{ + int i; + *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + if (!*recs) return(False); + + memset((char *)*recs,'\0',sizeof(**recs)*count); + + for (i=0;i length) { + SAFE_FREE(*recs); + return(False); + } + (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); + (*offset) += 10; + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + (*offset)+(*recs)[i].rdlength > length) { + SAFE_FREE(*recs); + return(False); + } + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return(True); +} + +/******************************************************************* + put a resource record into a packet + ******************************************************************/ +static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) +{ + int ret=0; + int i; + + for (i=0;i> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + offset += 10+rec->rdlength; + ret += 10+rec->rdlength; + + return(ret); +} + +/******************************************************************* + parse a dgram packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise + + this is documented in section 4.4.1 of RFC1002 + ******************************************************************/ +static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) +{ + int offset; + int flags; + + memset((char *)dgram,'\0',sizeof(*dgram)); + + if (length < 14) return(False); + + dgram->header.msg_type = CVAL(inbuf,0); + flags = CVAL(inbuf,1); + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); + if (flags & 1) dgram->header.flags.more = True; + if (flags & 2) dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL(inbuf,2); + putip((char *)&dgram->header.source_ip,inbuf+4); + dgram->header.source_port = RSVAL(inbuf,8); + dgram->header.dgm_length = RSVAL(inbuf,10); + dgram->header.packet_offset = RSVAL(inbuf,12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + } + + if (offset >= length || (length-offset > sizeof(dgram->data))) + return(False); + + dgram->datasize = length-offset; + memcpy(dgram->data,inbuf+offset,dgram->datasize); + + return(True); +} + + +/******************************************************************* + parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise + ******************************************************************/ +static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) +{ + int nm_flags,offset; + + memset((char *)nmb,'\0',sizeof(*nmb)); + + if (length < 12) return(False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.rcode = CVAL(inbuf,3) & 0xF; + nmb->header.qdcount = RSVAL(inbuf,4); + nmb->header.ancount = RSVAL(inbuf,6); + nmb->header.nscount = RSVAL(inbuf,8); + nmb->header.arcount = RSVAL(inbuf,10); + + if (nmb->header.qdcount) { + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + if (!offset) return(False); + + if (length - (12+offset) < 4) return(False); + nmb->question.question_type = RSVAL(inbuf,12+offset); + nmb->question.question_class = RSVAL(inbuf,12+offset+2); + + offset += 12+4; + } else { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + nmb->header.ancount)) + return(False); + + if (nmb->header.nscount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + nmb->header.nscount)) + return(False); + + if (nmb->header.arcount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, + nmb->header.arcount)) + return(False); + + return(True); +} + +/******************************************************************* + 'Copy constructor' for an nmb packet + ******************************************************************/ +static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) +{ + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + { + DEBUG(0,("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) + { + if((copy_nmb->answers = (struct res_rec *) + malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + nmb->header.ancount * sizeof(struct res_rec)); + } + if (nmb->nsrecs) + { + if((copy_nmb->nsrecs = (struct res_rec *) + malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + nmb->header.nscount * sizeof(struct res_rec)); + } + if (nmb->additional) + { + if((copy_nmb->additional = (struct res_rec *) + malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + nmb->header.arcount * sizeof(struct res_rec)); + } + + return pkt_copy; + +free_and_exit: + + SAFE_FREE(copy_nmb->answers); + SAFE_FREE(copy_nmb->nsrecs); + SAFE_FREE(copy_nmb->additional); + SAFE_FREE(pkt_copy); + + DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; +} + +/******************************************************************* + 'Copy constructor' for a dgram packet + ******************************************************************/ +static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) +{ + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + { + DEBUG(0,("copy_dgram_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; +} + +/******************************************************************* + 'Copy constructor' for a generic packet + ******************************************************************/ +struct packet_struct *copy_packet(struct packet_struct *packet) +{ + if(packet->packet_type == NMB_PACKET) + return copy_nmb_packet(packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet(packet); + return NULL; +} + +/******************************************************************* + free up any resources associated with an nmb packet + ******************************************************************/ +static void free_nmb_packet(struct nmb_packet *nmb) +{ + SAFE_FREE(nmb->answers); + SAFE_FREE(nmb->nsrecs); + SAFE_FREE(nmb->additional); +} + +/******************************************************************* + free up any resources associated with a dgram packet + ******************************************************************/ +static void free_dgram_packet(struct dgram_packet *nmb) +{ + /* We have nothing to do for a dgram packet. */ +} + +/******************************************************************* + free up any resources associated with a packet + ******************************************************************/ +void free_packet(struct packet_struct *packet) +{ + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet(&packet->packet.dgram); + ZERO_STRUCTPN(packet); + SAFE_FREE(packet); +} + +/******************************************************************* +parse a packet buffer into a packet structure + ******************************************************************/ +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type) +{ + struct packet_struct *p; + BOOL ok=False; + + p = (struct packet_struct *)malloc(sizeof(*p)); + if (!p) return(NULL); + + p->next = NULL; + p->prev = NULL; + p->locked = False; + p->timestamp = time(NULL); + p->packet_type = packet_type; + + switch (packet_type) { + case NMB_PACKET: + ok = parse_nmb(buf,length,&p->packet.nmb); + break; + + case DGRAM_PACKET: + ok = parse_dgram(buf,length,&p->packet.dgram); + break; + } + + if (!ok) { + free_packet(p); + return NULL; + } + + return p; +} + +/******************************************************************* + read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket + ******************************************************************/ +struct packet_struct *read_packet(int fd,enum packet_type packet_type) +{ + struct packet_struct *packet; + char buf[MAX_DGRAM_SIZE]; + int length; + struct in_addr addr; + int port; + + length = read_udp_socket(fd, buf, sizeof(buf), &addr, &port); + if (length < MIN_DGRAM_SIZE) return(NULL); + + packet = parse_packet(buf, length, packet_type); + if (!packet) return NULL; + + packet->fd = fd; + packet->ip = addr; + packet->port = port; + + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", + length, inet_ntoa(packet->ip), packet->port)); + + return packet; +} + + +/******************************************************************* + send a udp packet on a already open socket + ******************************************************************/ +static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) +{ + BOOL ret = False; + int i; + struct sockaddr_in sock_out; + + /* set the address and port */ + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; + + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", + len, inet_ntoa(ip), port ) ); + + /* + * Patch to fix asynch error notifications from Linux kernel. + */ + + for (i = 0; i < 5; i++) { + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + if (ret || errno != ECONNREFUSED) + break; + } + + if (!ret) + DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); + + return(ret); +} + +/******************************************************************* + build a dgram packet ready for sending + + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. + + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + + ******************************************************************/ +static int build_dgram(char *buf,struct packet_struct *p) +{ + struct dgram_packet *dgram = &p->packet.dgram; + uchar *ubuf = (uchar *)buf; + int offset=0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) ubuf[1] |= 1; + if (dgram->header.flags.first) ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + } + + memcpy(ubuf+offset,dgram->data,dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); + RSSVAL(ubuf,10,dgram->header.dgm_length); + + return(offset); +} + +/******************************************************************* + Build a nmb name +*******************************************************************/ + +void make_nmb_name( struct nmb_name *n, const char *name, int type) +{ + memset( (char *)n, '\0', sizeof(struct nmb_name) ); + push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); + n->name_type = (unsigned int)type & 0xFF; + StrnCpy( n->scope, lp_netbios_scope(), 63 ); + strupper( n->scope ); +} + +/******************************************************************* + Compare two nmb names + ******************************************************************/ + +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) +{ + return ((n1->name_type == n2->name_type) && + strequal(n1->name ,n2->name ) && + strequal(n1->scope,n2->scope)); +} + +/******************************************************************* + build a nmb packet ready for sending + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) + ******************************************************************/ +static int build_nmb(char *buf,struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + uchar *ubuf = (uchar *)buf; + int offset=0; + + /* put in the header */ + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative && + nmb->header.response) ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); + + offset += 12; + if (nmb->header.qdcount) { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec((char *)ubuf,offset,nmb->answers, + nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + nmb->header.nscount); + + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); + + } else if (nmb->header.arcount) { + offset += put_res_rec((char *)ubuf,offset,nmb->additional, + nmb->header.arcount); + } + return(offset); +} + + +/******************************************************************* +linearise a packet + ******************************************************************/ +int build_packet(char *buf, struct packet_struct *p) +{ + int len = 0; + + switch (p->packet_type) { + case NMB_PACKET: + len = build_nmb(buf,p); + break; + + case DGRAM_PACKET: + len = build_dgram(buf,p); + break; + } + + return len; +} + +/******************************************************************* + send a packet_struct + ******************************************************************/ +BOOL send_packet(struct packet_struct *p) +{ + char buf[1024]; + int len=0; + + memset(buf,'\0',sizeof(buf)); + + len = build_packet(buf, p); + + if (!len) return(False); + + return(send_udp(p->fd,buf,len,p->ip,p->port)); +} + +/**************************************************************************** + receive a packet with timeout on a open UDP filedescriptor + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_packet(int fd,enum packet_type type,int t) +{ + fd_set fds; + struct timeval timeout; + int ret; + + FD_ZERO(&fds); + FD_SET(fd,&fds); + timeout.tv_sec = t/1000; + timeout.tv_usec = 1000*(t%1000); + + if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) { + /* errno should be EBADF or EINVAL. */ + DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); + return NULL; + } + + if (ret == 0) /* timeout */ + return NULL; + + if (FD_ISSET(fd,&fds)) + return(read_packet(fd,type)); + + return(NULL); +} + + +/**************************************************************************** + receive a UDP/137 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified trn_id + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) +{ + struct packet_struct *p; + + p = receive_packet(fd, NMB_PACKET, t); + + if (p && p->packet.nmb.header.response && + p->packet.nmb.header.name_trn_id == trn_id) { + return p; + } + if (p) free_packet(p); + + /* try the unexpected packet queue */ + return receive_unexpected(NMB_PACKET, trn_id, NULL); +} + +/**************************************************************************** + receive a UDP/138 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified mailslot name + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) +{ + struct packet_struct *p; + + p = receive_packet(fd, DGRAM_PACKET, t); + + if (p && match_mailslot_name(p, mailslot_name)) { + return p; + } + if (p) free_packet(p); + + /* try the unexpected packet queue */ + return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); +} + + +/**************************************************************************** + see if a datagram has the right mailslot name +***************************************************************************/ +BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) +{ + struct dgram_packet *dgram = &p->packet.dgram; + char *buf; + + buf = &dgram->data[0]; + buf -= 4; + + buf = smb_buf(buf); + + if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) { + return True; + } + + return False; +} + + +/**************************************************************************** +return the number of bits that match between two 4 character buffers + ***************************************************************************/ +int matching_quad_bits(uchar *p1, uchar *p2) +{ + int i, j, ret = 0; + for (i=0; i<4; i++) { + if (p1[i] != p2[i]) break; + ret += 8; + } + + if (i==4) return ret; + + for (j=0; j<8; j++) { + if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; + ret++; + } + + return ret; +} + + +static uchar sort_ip[4]; + +/**************************************************************************** +compare two query reply records + ***************************************************************************/ +static int name_query_comp(uchar *p1, uchar *p2) +{ + return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); +} + +/**************************************************************************** +sort a set of 6 byte name query response records so that the IPs that +have the most leading bits in common with the specified address come first + ***************************************************************************/ +void sort_query_replies(char *data, int n, struct in_addr ip) +{ + if (n <= 1) return; + + putip(sort_ip, (char *)&ip); + + qsort(data, n, 6, QSORT_CAST name_query_comp); +} + + +#define TRUNCATE_NETBIOS_NAME 1 + +/******************************************************************* + convert, possibly using a stupid microsoft-ism which has destroyed + the transport independence of netbios (for CIFS vendors that usually + use the Win95-type methods, not for NT to NT communication, which uses + DCE/RPC and therefore full-length unicode strings...) a dns name into + a netbios name. + + the netbios name (NOT necessarily null-terminated) is truncated to 15 + characters. + + ******************************************************************/ +char *dns_to_netbios_name(char *dns_name) +{ + static char netbios_name[16]; + int i; + StrnCpy(netbios_name, dns_name, 15); + netbios_name[15] = 0; + +#ifdef TRUNCATE_NETBIOS_NAME + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' this even applies, by + mistake, to workgroup (domain) names, which is _really_ daft. + */ + for (i = 15; i >= 0; i--) + { + if (netbios_name[i] == '.') + { + netbios_name[i] = 0; + break; + } + } +#endif /* TRUNCATE_NETBIOS_NAME */ + + return netbios_name; +} + + +/**************************************************************************** +interpret the weird netbios "name". Return the name type +****************************************************************************/ +static int name_interpret(char *in,char *out) +{ + int ret; + int len = (*in++) / 2; + + *out=0; + + if (len > 30 || len<1) return(0); + + while (len--) + { + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + *out = 0; + ret = out[-1]; + +#ifdef NETBIOS_SCOPE + /* Handle any scope names */ + while(*in) + { + *out++ = '.'; /* Scope names are separated by periods */ + len = *(uchar *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } +#endif + return(ret); +} + + +/**************************************************************************** +return the number of bytes that would be occupied by the result of +name_mangle() +****************************************************************************/ +uint_t nbt_mangled_name_len(void) +{ + const char *scope = lp_netbios_scope(); + uint_t ret = 34; + if (scope && *scope) { + ret += strlen(scope) + 1; + } + return ret; +} + +/**************************************************************************** +mangle a name into netbios format + + Note: must be nbt_mangled_name_len() in length +****************************************************************************/ +int name_mangle(char *In, char *Out, char name_type) +{ + int i; + int c; + int len; + char buf[20]; + char *p = Out; + const char *scope = lp_netbios_scope(); + + /* Safely copy the input string, In, into buf[]. */ + memset( buf, 0, 20 ); + if (strcmp(In,"*") == 0) { + buf[0] = '*'; + } else { + slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type); + } + + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; + + /* Now convert the name to the rfc1001/1002 format. */ + for ( i = 0; i < 16; i++ ) { + c = toupper( buf[i] ); + p[i*2] = ( (c >> 4) & 0xF ) + 'A'; + p[(i*2)+1] = (c & 0xF) + 'A'; + } + p += 32; + p[0] = '\0'; + + if (!scope || !*scope) { + return name_len(Out); + } + + /* Add the scope string. */ + for (i = 0, len = 0; scope[i]; i++, len++) { + switch(scope[i]) { + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len+1] = scope[i]; + break; + } + } + + p[0] = len; + if (len > 0) { + p[len+1] = 0; + } + + return name_len(Out); +} + +/**************************************************************************** +find a pointer to a netbios name +****************************************************************************/ +static char *name_ptr(char *buf,int ofs) +{ + uchar c = *(uchar *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) + { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } + else + return(buf+ofs); +} + +/**************************************************************************** +extract a netbios name from a buf +****************************************************************************/ +int name_extract(char *buf,int ofs,char *name) +{ + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + pstrcpy(name,""); + if (d < -50 || d > 50) return(0); + return(name_interpret(p,name)); +} + +/**************************************************************************** +return the total storage length of a mangled name +****************************************************************************/ +int name_len(char *s1) +{ + /* NOTE: this argument _must_ be unsigned */ + uchar *s = (uchar *)s1; + int len; + + /* If the two high bits of the byte are set, return 2. */ + if (0xC0 == (*s & 0xC0)) + return(2); + + /* Add up the length bytes. */ + for (len = 1; (*s); s += (*s) + 1) { + len += *s + 1; + SMB_ASSERT(len < 80); + } + + return(len); +} /* name_len */ diff --git a/source4/libcli/ntlmssp.c b/source4/libcli/ntlmssp.c new file mode 100644 index 0000000000..c4ad260a1a --- /dev/null +++ b/source4/libcli/ntlmssp.c @@ -0,0 +1,625 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + handle NLTMSSP, server side + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001-2003 + + 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" + +/** + * Print out the NTLMSSP flags for debugging + * @param neg_flags The flags from the packet + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + +/** + * Default challenge generation code. + * + */ + +static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) +{ + static uchar chal[8]; + generate_random_buffer(chal, sizeof(chal), False); + + return chal; +} + +/** + * Determine correct target name flags for reply, given server role + * and negoitated falgs + * + * @param ntlmssp_state NTLMSSP State + * @param neg_flags The flags from the packet + * @param chal_flags The flags to be set in the reply packet + * @return The 'target name' string. + */ + +static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, + uint32 neg_flags, uint32 *chal_flags) +{ + if (neg_flags & NTLMSSP_REQUEST_TARGET) { + *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; + *chal_flags |= NTLMSSP_REQUEST_TARGET; + if (ntlmssp_state->server_role == ROLE_STANDALONE) { + *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; + return ntlmssp_state->get_global_myname(); + } else { + *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; + return ntlmssp_state->get_domain(); + }; + } else { + return ""; + } +} + +/** + * Next state function for the Negotiate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. + */ + +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB struct_blob; + fstring dnsname, dnsdomname; + uint32 ntlmssp_command, neg_flags, chal_flags; + char *cliname=NULL, *domname=NULL; + const uint8 *cryptkey; + const char *target_name; + + /* parse the NTLMSSP packet */ +#if 0 + file_save("ntlmssp_negotiate.dat", request.data, request.length); +#endif + + if (!msrpc_parse(&request, "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname)) { + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(cliname); + SAFE_FREE(domname); + + debug_ntlmssp_flags(neg_flags); + + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + + data_blob_free(&ntlmssp_state->chal); + ntlmssp_state->chal = data_blob(cryptkey, 8); + + /* Give them the challenge. For now, ignore neg_flags and just + return the flags we want. Obviously this is not correct */ + + chal_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM; + + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + chal_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->unicode = True; + } else { + chal_flags |= NTLMSSP_NEGOTIATE_OEM; + } + + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + + /* This should be a 'netbios domain -> DNS domain' mapping */ + dnsdomname[0] = '\0'; + get_mydomname(dnsdomname); + strlower(dnsdomname); + + dnsname[0] = '\0'; + get_myfullname(dnsname); + strlower(dnsname); + + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) + { + const char *target_name_dns = ""; + if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { + target_name_dns = dnsdomname; + } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { + target_name_dns = dnsname; + } + + /* the numbers here are the string type flags */ + msrpc_gen(&struct_blob, "aaaaa", + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name, + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, target_name_dns, + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname, + ntlmssp_state->unicode, 0, ""); + } else { + struct_blob = data_blob(NULL, 0); + } + + { + const char *gen_string; + if (ntlmssp_state->unicode) { + gen_string = "CdUdbddB"; + } else { + gen_string = "CdAdbddB"; + } + + msrpc_gen(reply, gen_string, + "NTLMSSP", + NTLMSSP_CHALLENGE, + target_name, + chal_flags, + cryptkey, 8, + 0, 0, + struct_blob.data, struct_blob.length); + } + + data_blob_free(&struct_blob); + + ntlmssp_state->expected_state = NTLMSSP_AUTH; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * Next state function for the Authenticate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB sess_key; + uint32 ntlmssp_command, neg_flags; + NTSTATUS nt_status; + + const char *parse_string; + + /* parse the NTLMSSP packet */ +#if 0 + file_save("ntlmssp_auth.dat", request.data, request.length); +#endif + + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUUBd"; + } else { + parse_string = "CdBBAAABd"; + } + + data_blob_free(&ntlmssp_state->lm_resp); + data_blob_free(&ntlmssp_state->nt_resp); + + SAFE_FREE(ntlmssp_state->user); + SAFE_FREE(ntlmssp_state->domain); + SAFE_FREE(ntlmssp_state->workstation); + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &ntlmssp_state->domain, + &ntlmssp_state->user, + &ntlmssp_state->workstation, + &sess_key, + &neg_flags)) { + return NT_STATUS_INVALID_PARAMETER; + } + + data_blob_free(&sess_key); + + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%d len2=%d\n", + ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length)); + +#if 0 + file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); + file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); +#endif + + nt_status = ntlmssp_state->check_password(ntlmssp_state); + + *reply = data_blob(NULL, 0); + + return nt_status; +} + +/** + * Create an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, allocated by this funciton + */ + +NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*ntlmssp_state)->mem_ctx = mem_ctx; + (*ntlmssp_state)->get_challenge = get_challenge; + + (*ntlmssp_state)->get_global_myname = lp_netbios_name; + (*ntlmssp_state)->get_domain = lp_workgroup; + (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ + + (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; + + return NT_STATUS_OK; +} + +/** + * End an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, free()ed by this funciton + */ + +NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + SAFE_FREE((*ntlmssp_state)->user); + SAFE_FREE((*ntlmssp_state)->domain); + SAFE_FREE((*ntlmssp_state)->workstation); + + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +/** + * Next state function for the NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + */ + +NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + uint32 ntlmssp_command; + *reply = data_blob(NULL, 0); + + if (!msrpc_parse(&request, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command != ntlmssp_state->expected_state) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command == NTLMSSP_NEGOTIATE) { + return ntlmssp_server_negotiate(ntlmssp_state, request, reply); + } else if (ntlmssp_command == NTLMSSP_AUTH) { + return ntlmssp_server_auth(ntlmssp_state, request, reply); + } else { + return NT_STATUS_INVALID_PARAMETER; + } +} + +/********************************************************************* + Client side NTLMSSP +*********************************************************************/ + +/** + * Next state function for the Initial packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + if (ntlmssp_state->unicode) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(next_request, "CddAA", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + ntlmssp_state->neg_flags, + ntlmssp_state->get_domain(), + ntlmssp_state->get_global_myname()); + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * Next state function for the Challenge Packet. Generate an auth packet. + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 chal_flags, ntlmssp_command, unkn1, unkn2; + DATA_BLOB server_domain_blob; + DATA_BLOB challenge_blob; + DATA_BLOB struct_blob; + char *server_domain; + const char *chal_parse_string; + const char *auth_gen_string; + DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB nt_response = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + uint8 datagram_sess_key[16]; + + ZERO_STRUCT(datagram_sess_key); + + if (!msrpc_parse(&reply, "CdBd", + "NTLMSSP", + &ntlmssp_command, + &server_domain_blob, + &chal_flags)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + data_blob_free(&server_domain_blob); + + if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { + chal_parse_string = "CdUdbddB"; + auth_gen_string = "CdBBUUUBd"; + ntlmssp_state->unicode = True; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; + } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { + chal_parse_string = "CdAdbddB"; + auth_gen_string = "CdBBAAABd"; + ntlmssp_state->unicode = False; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + } else { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!msrpc_parse(&reply, chal_parse_string, + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(server_domain); + data_blob_free(&struct_blob); + + if (challenge_blob.length != 8) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_state->use_ntlmv2) { + + /* TODO: if the remote server is standalone, then we should replace 'domain' + with the server name as supplied above */ + + if (!SMBNTLMv2encrypt(ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->password, challenge_blob, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&challenge_blob); + return NT_STATUS_NO_MEMORY; + } + } else { + uchar nt_hash[16]; + E_md4hash(ntlmssp_state->password, nt_hash); + + /* non encrypted password supplied. Ignore ntpass. */ + if (lp_client_lanman_auth()) { + lm_response = data_blob(NULL, 24); + SMBencrypt(ntlmssp_state->password,challenge_blob.data, + lm_response.data); + } + + nt_response = data_blob(NULL, 24); + SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, + nt_response.data); + session_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + } + + data_blob_free(&challenge_blob); + + /* this generates the actual auth packet */ + if (!msrpc_gen(next_request, auth_gen_string, + "NTLMSSP", + NTLMSSP_AUTH, + lm_response.data, lm_response.length, + nt_response.data, nt_response.length, + ntlmssp_state->domain, + ntlmssp_state->user, + ntlmssp_state->get_global_myname(), + datagram_sess_key, 0, + ntlmssp_state->neg_flags)) { + + data_blob_free(&lm_response); + data_blob_free(&nt_response); + data_blob_free(&session_key); + return NT_STATUS_NO_MEMORY; + } + + data_blob_free(&lm_response); + data_blob_free(&nt_response); + + ntlmssp_state->session_key = session_key; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP Client context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*ntlmssp_state)->mem_ctx = mem_ctx; + + (*ntlmssp_state)->get_global_myname = lp_netbios_name; + (*ntlmssp_state)->get_domain = lp_workgroup; + + (*ntlmssp_state)->unicode = True; + + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_REQUEST_TARGET; + + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + data_blob_free(&(*ntlmssp_state)->session_key); + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 ntlmssp_command; + *next_request = data_blob(NULL, 0); + + if (!reply.length) { + return ntlmssp_client_initial(ntlmssp_state, reply, next_request); + } + + if (!msrpc_parse(&reply, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command == NTLMSSP_CHALLENGE) { + return ntlmssp_client_challenge(ntlmssp_state, reply, next_request); + } + return NT_STATUS_INVALID_PARAMETER; +} + +NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) +{ + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + if (!ntlmssp_state->user) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) +{ + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) +{ + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} diff --git a/source4/libcli/ntlmssp_parse.c b/source4/libcli/ntlmssp_parse.c new file mode 100644 index 0000000000..ac779a3906 --- /dev/null +++ b/source4/libcli/ntlmssp_parse.c @@ -0,0 +1,303 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 + Copyright (C) Andrew Bartlett 2002-2003 + + 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" + +/* + this is a tiny msrpc packet generator. I am only using this to + avoid tying this code to a particular varient of our rpc code. This + generator is not general enough for all our rpc needs, its just + enough for the spnego/ntlmssp code + + format specifiers are: + + U = unicode string (input is unix string) + a = address (input is BOOL unicode, char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) + B = data blob (pointer + length) + b = data blob in header (pointer + length) + D + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_gen(DATA_BLOB *blob, + const char *format, ...) +{ + int i, n; + va_list ap; + char *s; + uint8 *b; + int head_size=0, data_size=0; + int head_ofs, data_ofs; + BOOL unicode; + + /* first scan the format to work out the header and body size */ + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_charnum(s) * 2; + break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; + case 'a': + unicode = va_arg(ap, BOOL); + n = va_arg(ap, int); + s = va_arg(ap, char *); + if (unicode) { + data_size += (str_charnum(s) * 2) + 4; + } else { + data_size += (str_ascii_charnum(s)) + 4; + } + break; + case 'B': + b = va_arg(ap, uint8 *); + head_size += 8; + data_size += va_arg(ap, int); + break; + case 'b': + b = va_arg(ap, uint8 *); + head_size += va_arg(ap, int); + break; + case 'd': + n = va_arg(ap, int); + head_size += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_size += str_charnum(s) + 1; + break; + } + } + va_end(ap); + + /* allocate the space, then scan the format again to fill in the values */ + *blob = data_blob(NULL, head_size + data_size); + + head_ofs = 0; + data_ofs = head_size; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + data_ofs += n*2; + break; + case 'A': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; + case 'a': + unicode = va_arg(ap, BOOL); + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + if (unicode) { + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + } else { + n = str_ascii_charnum(s); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n, + STR_ASCII|STR_NOALIGN); + } + data_ofs += n; + } + break; + + case 'B': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + memcpy(blob->data+data_ofs, b, n); + data_ofs += n; + break; + case 'd': + n = va_arg(ap, int); + SIVAL(blob->data, head_ofs, n); head_ofs += 4; + break; + case 'b': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + memcpy(blob->data + head_ofs, b, n); + head_ofs += n; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + STR_ASCII|STR_TERMINATE); + break; + } + } + va_end(ap); + + return True; +} + + +/* a helpful macro to avoid running over the end of our blob */ +#define NEED_DATA(amount) \ +if ((head_ofs + amount) > blob->length) { \ + return False; \ +} + +/* + this is a tiny msrpc packet parser. This the the partner of msrpc_gen + + format specifiers are: + + U = unicode string (output is unix string) + A = ascii string + B = data blob + b = data blob in header + d = word (4 bytes) + C = constant ascii string + */ + +BOOL msrpc_parse(const DATA_BLOB *blob, + const char *format, ...) +{ + int i; + va_list ap; + char **ps, *s; + DATA_BLOB *b; + size_t head_ofs = 0; + uint16 len1, len2; + uint32 ptr; + uint32 *v; + pstring p; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + if (len1 & 1) { + /* if odd length and unicode */ + return False; + } + + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = smb_xstrdup(p); + } else { + (*ps) = smb_xstrdup(""); + } + break; + case 'A': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_ASCII|STR_NOALIGN); + (*ps) = smb_xstrdup(p); + } else { + (*ps) = smb_xstrdup(""); + } + break; + case 'B': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + b = (DATA_BLOB *)va_arg(ap, void *); + *b = data_blob(blob->data + ptr, len1); + break; + case 'b': + b = (DATA_BLOB *)va_arg(ap, void *); + len1 = va_arg(ap, unsigned); + /* make sure its in the right format - be strict */ + NEED_DATA(len1); + *b = data_blob(blob->data + head_ofs, len1); + head_ofs += len1; + break; + case 'd': + v = va_arg(ap, uint32 *); + NEED_DATA(4); + *v = IVAL(blob->data, head_ofs); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (strcmp(s, p) != 0) { + return False; + } + break; + } + } + va_end(ap); + + return True; +} + diff --git a/source4/libcli/raw/README b/source4/libcli/raw/README new file mode 100644 index 0000000000..cb3e507e3a --- /dev/null +++ b/source4/libcli/raw/README @@ -0,0 +1,5 @@ +Design notes for client library restructure: + +1 - no references to cli_state should exist in libcli/raw. +2 - all interfaces to functions in this directory should use cli_session or cli_tree as + the primary context structure \ No newline at end of file diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c new file mode 100644 index 0000000000..5edc56daa9 --- /dev/null +++ b/source4/libcli/raw/clikrb5.c @@ -0,0 +1,399 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5 routines for active directory + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002-2003 + + 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" + +#ifdef HAVE_KRB5 + +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + +#ifndef HAVE_KRB5_SET_REAL_TIME +/* + * This function is not in the Heimdal mainline. + */ + krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) +{ + krb5_error_code ret; + int32_t sec, usec; + + ret = krb5_us_timeofday(context, &sec, &usec); + if (ret) + return ret; + + context->kdc_sec_offset = seconds - sec; + context->kdc_usec_offset = microseconds - usec; + + return 0; +} +#endif + +#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_in_tkt_etypes(ctx, enc); +} +#endif + +#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) +/* HEIMDAL */ + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addr_type = KRB5_ADDRESS_INET; + pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) +/* MIT */ + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addrtype = ADDRTYPE_INET; + pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#else + __ERROR__XX__UNKNOWN_ADDRTYPE +#endif + +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + int ret; + krb5_data salt; + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, enctype); + return krb5_string_to_key(context, &eblock, key, password, &salt); +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, enctype, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_permitted_enctypes(context, enctypes); +} +#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_default_in_tkt_etypes(context, enctypes); +} +#else +#error UNKNOWN_GET_ENCTYPES_FUNCTIONS +#endif + + void free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) +{ +#if defined(HAVE_KRB5_FREE_KTYPES) + krb5_free_ktypes(context, enctypes); + return; +#else + SAFE_FREE(enctypes); + return; +#endif +} + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + + void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + if (tkt->enc_part2) + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); +#else + if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); +#endif +} + + krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->client; +#else + return tkt->client; +#endif +} + +#if !defined(HAVE_KRB5_LOCATE_KDC) + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + krb5_krbhst_handle hnd; + krb5_krbhst_info *hinfo; + krb5_error_code rc; + int num_kdcs, i; + struct sockaddr *sa; + + *addr_pp = NULL; + *naddrs = 0; + + rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); + if (rc) { + DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + return rc; + } + + for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) + ; + + krb5_krbhst_reset(ctx, hnd); + + if (!num_kdcs) { + DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + krb5_krbhst_free(ctx, hnd); + return -1; + } + + sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + if (!sa) { + DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + krb5_krbhst_free(ctx, hnd); + naddrs = 0; + return -1; + } + + memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + + for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { + if (hinfo->ai->ai_family == AF_INET) + memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); + } + + krb5_krbhst_free(ctx, hnd); + + *naddrs = num_kdcs; + *addr_pp = sa; + return 0; +} +#endif + +/* + we can't use krb5_mk_req because w2k wants the service to be in a particular format +*/ +static krb5_error_code krb5_mk_req2(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf) +{ + krb5_error_code retval; + krb5_principal server; + krb5_creds * credsp; + krb5_creds creds; + krb5_data in_data; + + retval = krb5_parse_name(context, principal, &server); + if (retval) { + DEBUG(1,("Failed to parse principal %s\n", principal)); + return retval; + } + + /* obtain ticket & session key */ + memset((char *)&creds, 0, sizeof(creds)); + if ((retval = krb5_copy_principal(context, server, &creds.server))) { + DEBUG(1,("krb5_copy_principal failed (%s)\n", + error_message(retval))); + goto cleanup_princ; + } + + if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { + DEBUG(1,("krb5_cc_get_principal failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } + + if ((retval = krb5_get_credentials(context, 0, + ccache, &creds, &credsp))) { + DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + principal, error_message(retval))); + goto cleanup_creds; + } + + /* cope with the ticket being in the future due to clock skew */ + if ((unsigned)credsp->times.starttime > time(NULL)) { + time_t t = time(NULL); + int time_offset = (unsigned)credsp->times.starttime - t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(context, t + time_offset + 1, 0); + } + + in_data.length = 0; + retval = krb5_mk_req_extended(context, auth_context, ap_req_options, + &in_data, credsp, outbuf); + if (retval) { + DEBUG(1,("krb5_mk_req_extended failed (%s)\n", + error_message(retval))); + } + + krb5_free_creds(context, credsp); + +cleanup_creds: + krb5_free_cred_contents(context, &creds); + +cleanup_princ: + krb5_free_principal(context, server); + + return retval; +} + +/* + get a kerberos5 ticket for the given service +*/ +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +{ + krb5_error_code retval; + krb5_data packet; + krb5_ccache ccdef; + krb5_context context; + krb5_auth_context auth_context = NULL; + DATA_BLOB ret; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; + + retval = krb5_init_context(&context); + if (retval) { + DEBUG(1,("krb5_init_context failed (%s)\n", + error_message(retval))); + goto failed; + } + + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + + if ((retval = krb5_cc_default(context, &ccdef))) { + DEBUG(1,("krb5_cc_default failed (%s)\n", + error_message(retval))); + goto failed; + } + + if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { + DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n", + error_message(retval))); + goto failed; + } + + if ((retval = krb5_mk_req2(context, + &auth_context, + 0, + principal, + ccdef, &packet))) { + goto failed; + } + + ret = data_blob(packet.data, packet.length); +/* Hmm, heimdal dooesn't have this - what's the correct call? */ +/* krb5_free_data_contents(context, &packet); */ + krb5_free_context(context); + return ret; + +failed: + if ( context ) + krb5_free_context(context); + + return data_blob(NULL, 0); +} + + BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + { +#ifdef ENCTYPE_ARCFOUR_HMAC + krb5_keyblock *skey; +#endif + BOOL ret = False; + + memset(session_key, 0, 16); + +#ifdef ENCTYPE_ARCFOUR_HMAC + if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (KRB5_KEY_TYPE(skey) == + ENCTYPE_ARCFOUR_HMAC + && KRB5_KEY_LENGTH(skey) == 16) { + memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + ret = True; + } + krb5_free_keyblock(context, skey); + } +#endif /* ENCTYPE_ARCFOUR_HMAC */ + + return ret; + } +#else /* HAVE_KRB5 */ + /* this saves a few linking headaches */ +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) + { + DEBUG(0,("NO KERBEROS SUPPORT\n")); + return data_blob(NULL, 0); + } + +#endif diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c new file mode 100644 index 0000000000..8f69716bda --- /dev/null +++ b/source4/libcli/raw/clioplock.c @@ -0,0 +1,57 @@ +/* + Unix SMB/CIFS implementation. + SMB client oplock functions + Copyright (C) Andrew Tridgell 2001 + + 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" + +/**************************************************************************** +send an ack for an oplock break request +****************************************************************************/ +BOOL cli_oplock_ack(struct cli_tree *tree, uint16 fnum, uint16 ack_level) +{ + BOOL ret; + struct cli_request *req; + + req = cli_request_setup(tree, SMBlockingX, 8, 0); + + SSVAL(req->out.vwv,VWV(0),0xFF); + SSVAL(req->out.vwv,VWV(1),0); + SSVAL(req->out.vwv,VWV(2),fnum); + SSVAL(req->out.vwv,VWV(3),ack_level); + SIVAL(req->out.vwv,VWV(4),0); + SSVAL(req->out.vwv,VWV(6),0); + SSVAL(req->out.vwv,VWV(7),0); + + ret = cli_request_send(req); + cli_request_destroy(req); + + return ret; +} + + +/**************************************************************************** +set the oplock handler for a connection +****************************************************************************/ +void cli_oplock_handler(struct cli_transport *transport, + BOOL (*handler)(struct cli_transport *, uint16, uint16, uint8, void *), + void *private) +{ + transport->oplock.handler = handler; + transport->oplock.private = private; +} diff --git a/source4/libcli/raw/clirewrite.c b/source4/libcli/raw/clirewrite.c new file mode 100644 index 0000000000..2d2e2e3feb --- /dev/null +++ b/source4/libcli/raw/clirewrite.c @@ -0,0 +1,22 @@ +#include "includes.h" + +/* + + this is a set of temporary stub functions used during the libsmb rewrite. + This file will need to go away before the rewrite is complete. +*/ + +void become_root(void) +{} + +void unbecome_root(void) +{} + +BOOL become_user_permanently(uid_t uid, gid_t gid) +{ return True; } + +void set_effective_uid(uid_t uid) +{} + +uid_t sec_initial_uid(void) +{ return 0; } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c new file mode 100644 index 0000000000..406491e432 --- /dev/null +++ b/source4/libcli/raw/clisession.c @@ -0,0 +1,444 @@ +/* + Unix SMB/CIFS implementation. + SMB client session context management functions + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + +#define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ + req = cli_request_setup_session(session, cmd, wct, buflen); \ + if (!req) return NULL; \ +} while (0) + +/**************************************************************************** + Initialize the session context +****************************************************************************/ +struct cli_session *cli_session_init(struct cli_transport *transport) +{ + struct cli_session *session; + TALLOC_CTX *mem_ctx = talloc_init("cli_session"); + if (mem_ctx == NULL) { + return NULL; + } + + session = talloc_zero(mem_ctx, sizeof(*session)); + if (!session) { + talloc_destroy(mem_ctx); + return NULL; + } + + session->mem_ctx = mem_ctx; + session->transport = transport; + session->pid = (uint16)getpid(); + session->vuid = UID_FIELD_INVALID; + session->transport->reference_count++; + + return session; +} + +/**************************************************************************** +reduce reference_count and destroy is <= 0 +****************************************************************************/ +void cli_session_close(struct cli_session *session) +{ + session->reference_count--; + if (session->reference_count <= 0) { + cli_transport_close(session->transport); + talloc_destroy(session->mem_ctx); + } +} + +/**************************************************************************** + Perform a session setup (async send) +****************************************************************************/ +struct cli_request *smb_raw_session_setup_send(struct cli_session *session, union smb_sesssetup *parms) +{ + struct cli_request *req; + + switch (parms->generic.level) { + case RAW_SESSSETUP_GENERIC: + /* handled elsewhere */ + return NULL; + + case RAW_SESSSETUP_OLD: + SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize); + SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max); + SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num); + SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey); + SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length); + cli_req_append_blob(req, &parms->old.in.password); + cli_req_append_string(req, parms->old.in.user, STR_TERMINATE); + cli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER); + cli_req_append_string(req, parms->old.in.os, STR_TERMINATE); + cli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE); + break; + + case RAW_SESSSETUP_NT1: + SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize); + SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max); + SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num); + SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey); + SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length); + SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length); + SIVAL(req->out.vwv, VWV(9), 0); /* reserved */ + SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities); + cli_req_append_blob(req, &parms->nt1.in.password1); + cli_req_append_blob(req, &parms->nt1.in.password2); + cli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE); + cli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER); + cli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE); + cli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE); + break; + + case RAW_SESSSETUP_SPNEGO: + SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize); + SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max); + SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num); + SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey); + SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length); + SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities); + cli_req_append_blob(req, &parms->spnego.in.secblob); + cli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE); + cli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); + break; + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + + +/**************************************************************************** + Perform a session setup (async recv) +****************************************************************************/ +NTSTATUS smb_raw_session_setup_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) +{ + uint16 len; + char *p; + + if (!cli_request_receive(req)) { + return cli_request_destroy(req); + } + + if (!NT_STATUS_IS_OK(req->status) && + !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return cli_request_destroy(req); + } + + switch (parms->generic.level) { + case RAW_SESSSETUP_GENERIC: + /* handled elsewhere */ + return NT_STATUS_INVALID_LEVEL; + + case RAW_SESSSETUP_OLD: + CLI_CHECK_WCT(req, 3); + ZERO_STRUCT(parms->old.out); + parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID); + parms->old.out.action = SVAL(req->in.vwv, VWV(2)); + p = req->in.data; + if (p) { + p += cli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE); + p += cli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE); + p += cli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE); + } + break; + + case RAW_SESSSETUP_NT1: + CLI_CHECK_WCT(req, 3); + ZERO_STRUCT(parms->nt1.out); + parms->nt1.out.vuid = SVAL(req->in.hdr, HDR_UID); + parms->nt1.out.action = SVAL(req->in.vwv, VWV(2)); + p = req->in.data; + if (p) { + p += cli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE); + p += cli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE); + if (p < (req->in.data + req->in.data_size)) { + p += cli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE); + } + } + break; + + case RAW_SESSSETUP_SPNEGO: + CLI_CHECK_WCT(req, 4); + ZERO_STRUCT(parms->spnego.out); + parms->spnego.out.vuid = SVAL(req->in.hdr, HDR_UID); + parms->spnego.out.action = SVAL(req->in.vwv, VWV(2)); + len = SVAL(req->in.vwv, VWV(3)); + p = req->in.data; + if (!p) { + break; + } + + parms->spnego.out.secblob = cli_req_pull_blob(req, mem_ctx, p, len); + p += parms->spnego.out.secblob.length; + p += cli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE); + p += cli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); + p += cli_req_pull_string(req, mem_ctx, &parms->spnego.out.domain, p, -1, STR_TERMINATE); + break; + } + +failed: + return cli_request_destroy(req); +} + +/* + form an encrypted lanman password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB lanman_blob(const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob(NULL, 24); + SMBencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + form an encrypted NT password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob(NULL, 24); + SMBNTencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + setup signing for a NT1 style session setup +*/ +static void setup_nt1_signing(struct cli_transport *transport, const char *password) +{ + uchar nt_hash[16]; + uchar session_key[16]; + DATA_BLOB nt_response; + + E_md4hash(password, nt_hash); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key); + nt_response = nt_blob(password, transport->negotiate.secblob); + + cli_transport_simple_set_signing(transport, session_key, nt_response); +} + +/**************************************************************************** + Perform a session setup (sync interface) using generic interface and the old + style sesssetup call +****************************************************************************/ +static NTSTATUS smb_raw_session_setup_generic_old(struct cli_session *session, + TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) +{ + NTSTATUS status; + union smb_sesssetup s2; + + /* use the old interface */ + s2.generic.level = RAW_SESSSETUP_OLD; + s2.old.in.bufsize = ~0; + s2.old.in.mpx_max = 50; + s2.old.in.vc_num = 1; + s2.old.in.sesskey = parms->generic.in.sesskey; + s2.old.in.domain = parms->generic.in.domain; + s2.old.in.user = parms->generic.in.user; + s2.old.in.os = "Unix"; + s2.old.in.lanman = "Samba"; + + if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + s2.old.in.password = lanman_blob(parms->generic.in.password, + session->transport->negotiate.secblob); + } else { + s2.old.in.password = data_blob(parms->generic.in.password, + strlen(parms->generic.in.password)); + } + + status = smb_raw_session_setup(session, mem_ctx, &s2); + + data_blob_free(&s2.old.in.password); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + parms->generic.out.vuid = s2.old.out.vuid; + parms->generic.out.os = s2.old.out.os; + parms->generic.out.lanman = s2.old.out.lanman; + parms->generic.out.domain = s2.old.out.domain; + + return NT_STATUS_OK; +} + +/**************************************************************************** + Perform a session setup (sync interface) using generic interface and the NT1 + style sesssetup call +****************************************************************************/ +static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, + TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) +{ + NTSTATUS status; + union smb_sesssetup s2; + + s2.generic.level = RAW_SESSSETUP_NT1; + s2.nt1.in.bufsize = ~0; + s2.nt1.in.mpx_max = 50; + s2.nt1.in.vc_num = 1; + s2.nt1.in.sesskey = parms->generic.in.sesskey; + s2.nt1.in.capabilities = parms->generic.in.capabilities; + s2.nt1.in.domain = parms->generic.in.domain; + s2.nt1.in.user = parms->generic.in.user; + s2.nt1.in.os = "Unix"; + s2.nt1.in.lanman = "Samba"; + + if (session->transport->negotiate.sec_mode & + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + s2.nt1.in.password1 = lanman_blob(parms->generic.in.password, + session->transport->negotiate.secblob); + s2.nt1.in.password2 = nt_blob(parms->generic.in.password, + session->transport->negotiate.secblob); + setup_nt1_signing(session->transport, parms->generic.in.password); + } else { + s2.nt1.in.password1 = data_blob(parms->generic.in.password, + strlen(parms->generic.in.password)); + s2.nt1.in.password2 = data_blob(NULL, 0); + } + + status = smb_raw_session_setup(session, mem_ctx, &s2); + + data_blob_free(&s2.nt1.in.password1); + data_blob_free(&s2.nt1.in.password2); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + parms->generic.out.vuid = s2.nt1.out.vuid; + parms->generic.out.os = s2.nt1.out.os; + parms->generic.out.lanman = s2.nt1.out.lanman; + parms->generic.out.domain = s2.nt1.out.domain; + + return NT_STATUS_OK; +} + + +/**************************************************************************** + Perform a session setup (sync interface) using generic interface +****************************************************************************/ +static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, + TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) +{ + if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { + /* no session setup at all in earliest protocols */ + ZERO_STRUCT(parms->generic.out); + return NT_STATUS_OK; + } + + /* see if we need to use the original session setup interface */ + if (session->transport->negotiate.protocol < PROTOCOL_NT1) { + return smb_raw_session_setup_generic_old(session, mem_ctx, parms); + } + + /* see if we should use the NT1 interface */ + if (!(session->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) || + !session->transport->options.use_spnego) { + return smb_raw_session_setup_generic_nt1(session, mem_ctx, parms); + } + + /* default to using SPNEGO/NTLMSSP */ + DEBUG(0,("Need to add client SPNEGO code back in\n")); + return NT_STATUS_UNSUCCESSFUL; +} + + +/**************************************************************************** + Perform a session setup (sync interface) +this interface allows for RAW_SESSSETUP_GENERIC to auto-select session +setup varient based on negotiated protocol options +****************************************************************************/ +NTSTATUS smb_raw_session_setup(struct cli_session *session, TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) +{ + struct cli_request *req; + + if (parms->generic.level == RAW_SESSSETUP_GENERIC) { + return smb_raw_session_setup_generic(session, mem_ctx, parms); + } + + req = smb_raw_session_setup_send(session, parms); + return smb_raw_session_setup_recv(req, mem_ctx, parms); +} + + +/**************************************************************************** + Send a uloggoff (async send) +*****************************************************************************/ +struct cli_request *smb_raw_ulogoff_send(struct cli_session *session) +{ + struct cli_request *req; + + SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0); + + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Send a uloggoff (sync interface) +*****************************************************************************/ +NTSTATUS smb_raw_ulogoff(struct cli_session *session) +{ + struct cli_request *req = smb_raw_ulogoff_send(session); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + Send a SMBexit +****************************************************************************/ +NTSTATUS smb_raw_exit(struct cli_session *session) +{ + struct cli_request *req; + + req = cli_request_setup_session(session, SMBexit, 0, 0); + + if (cli_request_send(req)) { + cli_request_receive(req); + } + return cli_request_destroy(req); +} diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c new file mode 100644 index 0000000000..f0e05085c4 --- /dev/null +++ b/source4/libcli/raw/clisocket.c @@ -0,0 +1,148 @@ +/* + Unix SMB/CIFS implementation. + SMB client socket context management functions + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + + +/* + create a cli_socket context +*/ +struct cli_socket *cli_sock_init(void) +{ + struct cli_socket *sock; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("cli_socket"); + if (!mem_ctx) return NULL; + + sock = talloc_zero(mem_ctx, sizeof(*sock)); + if (!sock) { + talloc_destroy(mem_ctx); + return NULL; + } + + sock->mem_ctx = mem_ctx; + sock->fd = -1; + sock->port = 445; + /* 20 second default timeout */ + sock->timeout = 20000; + + return sock; +} + +/* + connect a cli_socket context to an IP/port pair + if port is 0 then choose 445 then 139 +*/ +BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) +{ + if (getenv("LIBSMB_PROG")) { + sock->fd = sock_exec(getenv("LIBSMB_PROG")); + return sock->fd != -1; + } + + if (port == 0) { + return cli_sock_connect(sock, ip, 445) || + cli_sock_connect(sock, ip, 139); + } + + sock->dest_ip = *ip; + sock->port = port; + sock->fd = open_socket_out(SOCK_STREAM, + &sock->dest_ip, + sock->port, + LONG_CONNECT_TIMEOUT); + return (sock->fd != -1); +} + + +/**************************************************************************** + reduce socket reference count - if it becomes zero then close +****************************************************************************/ +void cli_sock_close(struct cli_socket *sock) +{ + sock->reference_count--; + if (sock->reference_count <= 0 && sock->fd != -1) { + close(sock->fd); + sock->fd = -1; + } +} + +/**************************************************************************** + Set socket options on a open connection. +****************************************************************************/ +void cli_sock_set_options(struct cli_socket *sock, const char *options) +{ + set_socket_options(sock->fd, options); +} + +/**************************************************************************** + Write to socket. Return amount written. +****************************************************************************/ +ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) +{ + return write_data(sock->fd, data, len); +} + + +/**************************************************************************** + Read from socket. return amount read +****************************************************************************/ +ssize_t cli_sock_read(struct cli_socket *sock, char *data, size_t len) +{ + return read_data(sock->fd, data, len); +} + +/**************************************************************************** +resolve a hostname and connect +****************************************************************************/ +BOOL cli_sock_connect_byname(struct cli_socket *sock, const char *host, int port) +{ + int name_type = 0x20; + struct in_addr ip; + TALLOC_CTX *mem_ctx; + char *name, *p; + + if (getenv("LIBSMB_PROG")) { + sock->fd = sock_exec(getenv("LIBSMB_PROG")); + return sock->fd != -1; + } + + mem_ctx = talloc_init("cli_sock_connect_byname"); + if (!mem_ctx) return False; + + name = talloc_strdup(mem_ctx, host); + + /* allow hostnames of the form NAME#xx and do a netbios lookup */ + if ((p = strchr(name, '#'))) { + name_type = strtol(p+1, NULL, 16); + *p = 0; + } + + if (!resolve_name(mem_ctx, name, &ip, name_type)) { + talloc_destroy(mem_ctx); + return False; + } + + talloc_destroy(mem_ctx); + + return cli_sock_connect(sock, &ip, port); +} diff --git a/source4/libcli/raw/clispnego.c b/source4/libcli/raw/clispnego.c new file mode 100644 index 0000000000..53f7eb6e7d --- /dev/null +++ b/source4/libcli/raw/clispnego.c @@ -0,0 +1,533 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 + + 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" + +/* + generate a negTokenInit packet given a GUID, a list of supported + OIDs (the mechanisms) and a principal name string +*/ +DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], + const char *OIDs[], + const char *principal) +{ + int i; + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_write(&data, guid, 16); + asn1_push_tag(&data,ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_GeneralString(&data,principal); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + +/* + Generate a negTokenInit as used by the client side ... It has a mechType + (OID), and a mechToken (a security blob) ... + + Really, we need to break out the NTLMSSP stuff as well, because it could be + raw in the packets! +*/ +DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OID(&data, OID); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + +/* + parse a negTokenInit packet giving a GUID, a list of supported + OIDs (the mechanisms) and a principal name string +*/ +BOOL spnego_parse_negTokenInit(DATA_BLOB blob, + char *OIDs[ASN1_MAX_OIDS], + char **principal) +{ + int i; + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + + asn1_start_tag(&data,ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_GeneralString(&data,principal); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; +} + + +/* + generate a negTokenTarg packet given a list of OIDs and a security blob +*/ +DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) +{ + int i; + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + + +/* + parse a negTokenTarg packet giving a list of OIDs and a security blob +*/ +BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) +{ + int i; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data,secblob); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + return False; + } + + asn1_free(&data); + return True; +} + +/* + generate a krb5 GSS-API wrapper packet given a ticket +*/ +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data, OID_KERBEROS5); + + asn1_write(&data, tok_id, 2); + asn1_write(&data, ticket.data, ticket.length); + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + +/* + parse a krb5 GSS-API wrapper packet giving a ticket +*/ +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) +{ + BOOL ret; + ASN1_DATA data; + int data_remaining; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data, OID_KERBEROS5); + + data_remaining = asn1_tag_remaining(&data); + + if (data_remaining < 3) { + data.has_error = True; + } else { + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob(NULL, data_remaining); + asn1_read(&data, ticket->data, ticket->length); + } + + asn1_end_tag(&data); + + ret = !data.has_error; + + asn1_free(&data); + + return ret; +} + + +/* + generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY + kerberos session setup +*/ +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) +{ + DATA_BLOB tkt, tkt_wrapped, targ; + const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; + + /* get a kerberos ticket for the service */ + tkt = krb5_get_ticket(principal, time_offset); + + /* wrap that up in a nice GSS-API wrapping */ + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); + + /* and wrap that in a shiny SPNEGO wrapper */ + targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + + data_blob_free(&tkt_wrapped); + data_blob_free(&tkt); + + return targ; +} + + +/* + parse a spnego NTLMSSP challenge packet giving two security blobs +*/ +BOOL spnego_parse_challenge(const DATA_BLOB blob, + DATA_BLOB *chal1, DATA_BLOB *chal2) +{ + BOOL ret; + ASN1_DATA data; + + ZERO_STRUCTP(chal1); + ZERO_STRUCTP(chal2); + + asn1_load(&data, blob); + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_check_enumerated(&data,1); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, OID_NTLMSSP); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, chal1); + asn1_end_tag(&data); + + /* the second challenge is optional (XP doesn't send it) */ + if (asn1_tag_remaining(&data)) { + asn1_start_tag(&data,ASN1_CONTEXT(3)); + asn1_read_OctetString(&data, chal2); + asn1_end_tag(&data); + } + + asn1_end_tag(&data); + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; +} + + +/* + generate a SPNEGO auth packet. This will contain the encrypted passwords +*/ +DATA_BLOB spnego_gen_auth(DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_CONTEXT(1)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + ret = data_blob(data.data, data.length); + + asn1_free(&data); + + return ret; +} + +/* + parse a SPNEGO auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) +{ + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data,auth); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); + asn1_free(&data); + return False; + } + + asn1_free(&data); + return True; +} + +/* + generate a minimal SPNEGO response packet. Doesn't contain much. +*/ +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, + const char *mechOID) +{ + ASN1_DATA data; + DATA_BLOB ret; + uint8 negResult; + + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNEGO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNEGO_NEG_RESULT_REJECT; + } + + ZERO_STRUCT(data); + + asn1_push_tag(&data, ASN1_CONTEXT(1)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_enumerated(&data, negResult); + asn1_pop_tag(&data); + + if (reply->data != NULL) { + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, mechOID); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, reply->data, reply->length); + asn1_pop_tag(&data); + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + ret = data_blob(data.data, data.length); + asn1_free(&data); + return ret; +} + +/* + parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, + DATA_BLOB *auth) +{ + ASN1_DATA data; + uint8 negResult; + + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNEGO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNEGO_NEG_RESULT_REJECT; + } + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_check_enumerated(&data, negResult); + asn1_end_tag(&data); + + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, OID_NTLMSSP); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, auth); + asn1_end_tag(&data); + } + + asn1_end_tag(&data); + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data.ofs)); + asn1_free(&data); + data_blob_free(auth); + return False; + } + + asn1_free(&data); + return True; +} + diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c new file mode 100644 index 0000000000..80bb1e301f --- /dev/null +++ b/source4/libcli/raw/clitransport.c @@ -0,0 +1,218 @@ +/* + Unix SMB/CIFS implementation. + SMB client transport context management functions + Copyright (C) Andrew Tridgell 1994-2003 + Copyright (C) James Myers 2003 + + 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" + +/* + create a transport structure based on an established socket +*/ +struct cli_transport *cli_transport_init(struct cli_socket *sock) +{ + TALLOC_CTX *mem_ctx; + struct cli_transport *transport; + + mem_ctx = talloc_init("cli_transport"); + if (!mem_ctx) return NULL; + + transport = talloc_zero(mem_ctx, sizeof(*transport)); + if (!transport) return NULL; + + transport->mem_ctx = mem_ctx; + transport->socket = sock; + transport->negotiate.protocol = PROTOCOL_NT1; + transport->negotiate.max_xmit = ~0; + cli_null_set_signing(transport); + transport->socket->reference_count++; + + return transport; +} + +/* + decrease reference count on a transport, and destroy if it becomes + zero +*/ +void cli_transport_close(struct cli_transport *transport) +{ + transport->reference_count--; + if (transport->reference_count <= 0) { + cli_sock_close(transport->socket); + talloc_destroy(transport->mem_ctx); + } +} + + + +/**************************************************************************** +send a session request (if appropriate) +****************************************************************************/ +BOOL cli_transport_connect(struct cli_transport *transport, + struct nmb_name *calling, + struct nmb_name *called) +{ + char *p; + int len = NBT_HDR_SIZE; + struct cli_request *req; + + /* 445 doesn't have session request */ + if (transport->socket->port == 445) { + return True; + } + + /* allocate output buffer */ + req = cli_request_setup_nonsmb(transport, NBT_HDR_SIZE + 2*nbt_mangled_name_len()); + + /* put in the destination name */ + p = req->out.buffer + NBT_HDR_SIZE; + name_mangle(called->name, p, called->name_type); + len += name_len(p); + + /* and my name */ + p = req->out.buffer+len; + name_mangle(calling->name, p, calling->name_type); + len += name_len(p); + + _smb_setlen(req->out.buffer,len-4); + SCVAL(req->out.buffer,0,0x81); + + if (!cli_request_send(req) || + !cli_request_receive(req)) { + cli_request_destroy(req); + return False; + } + + if (CVAL(req->in.buffer,0) != 0x82) { + transport->error.etype = ETYPE_NBT; + transport->error.e.nbt_error = CVAL(req->in.buffer,4); + cli_request_destroy(req); + return False; + } + + cli_request_destroy(req); + return True; +} + + +/**************************************************************************** +get next mid in sequence +****************************************************************************/ +uint16 cli_transport_next_mid(struct cli_transport *transport) +{ + uint16 mid; + struct cli_request *req; + + mid = transport->next_mid; + +again: + /* now check to see if this mid is being used by one of the + pending requests. This is quite efficient because the list is + usually very short */ + + /* the zero mid is reserved for requests that don't have a mid */ + if (mid == 0) mid = 1; + + for (req=transport->pending_requests; req; req=req->next) { + if (req->mid == mid) { + mid++; + goto again; + } + } + + transport->next_mid = mid+1; + return mid; +} + +/* + setup the idle handler for a transport +*/ +void cli_transport_idle_handler(struct cli_transport *transport, + void (*idle_func)(struct cli_transport *, void *), + uint_t period, + void *private) +{ + transport->idle.func = idle_func; + transport->idle.private = private; + transport->idle.period = period; +} + + +/* + determine if a packet is pending for receive on a transport +*/ +BOOL cli_transport_pending(struct cli_transport *transport) +{ + return socket_pending(transport->socket->fd); +} + + + +/* + wait for data on a transport, periodically calling a wait function + if one has been defined + return True if a packet is received +*/ +BOOL cli_transport_select(struct cli_transport *transport) +{ + fd_set fds; + int selrtn; + int fd; + struct timeval timeout; + + fd = transport->socket->fd; + + if (fd == -1) { + return False; + } + + do { + uint_t period = 1000; + + FD_ZERO(&fds); + FD_SET(fd,&fds); + + if (transport->idle.func) { + period = transport->idle.period; + } + + timeout.tv_sec = period / 1000; + timeout.tv_usec = 1000*(period%1000); + + selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout); + + if (selrtn == 1) { + /* the fd is readable */ + return True; + } + + if (selrtn == -1) { + /* sys_select_intr() already handles EINTR, so this + is an error. The socket is probably dead */ + return False; + } + + /* only other possibility is that we timed out - call the idle function + if there is one */ + if (transport->idle.func) { + transport->idle.func(transport, transport->idle.private); + } + } while (selrtn == 0); + + return True; +} diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c new file mode 100644 index 0000000000..2a41273913 --- /dev/null +++ b/source4/libcli/raw/clitree.c @@ -0,0 +1,290 @@ +/* + Unix SMB/CIFS implementation. + SMB client tree context management functions + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + +#define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ + req = cli_request_setup(tree, cmd, wct, buflen); \ + if (!req) return NULL; \ +} while (0) + + +/**************************************************************************** + Initialize the tree context +****************************************************************************/ +struct cli_tree *cli_tree_init(struct cli_session *session) +{ + struct cli_tree *tree; + TALLOC_CTX *mem_ctx = talloc_init("cli_tree"); + if (mem_ctx == NULL) { + return NULL; + } + + tree = talloc_zero(mem_ctx, sizeof(*tree)); + if (!tree) { + talloc_destroy(mem_ctx); + return NULL; + } + + tree->mem_ctx = mem_ctx; + tree->session = session; + tree->session->reference_count++; + + return tree; +} + +/**************************************************************************** +reduce reference count on a tree and destroy if <= 0 +****************************************************************************/ +void cli_tree_close(struct cli_tree *tree) +{ + if (!tree) return; + tree->reference_count--; + if (tree->reference_count <= 0) { + cli_session_close(tree->session); + talloc_destroy(tree->mem_ctx); + } +} + + +/**************************************************************************** + Send a tconX (async send) +****************************************************************************/ +struct cli_request *smb_tree_connect_send(struct cli_tree *tree, union smb_tcon *parms) +{ + struct cli_request *req; + + switch (parms->tcon.level) { + case RAW_TCON_TCON: + SETUP_REQUEST_TREE(SMBtcon, 0, 0); + cli_req_append_ascii4(req, parms->tcon.in.service, STR_ASCII); + cli_req_append_ascii4(req, parms->tcon.in.password,STR_ASCII); + cli_req_append_ascii4(req, parms->tcon.in.dev, STR_ASCII); + break; + + case RAW_TCON_TCONX: + SETUP_REQUEST_TREE(SMBtconX, 4, 0); + SSVAL(req->out.vwv, VWV(0), 0xFF); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->tconx.in.flags); + SSVAL(req->out.vwv, VWV(3), parms->tconx.in.password.length); + cli_req_append_blob(req, &parms->tconx.in.password); + cli_req_append_string(req, parms->tconx.in.path, STR_TERMINATE | STR_UPPER); + cli_req_append_string(req, parms->tconx.in.device, STR_TERMINATE | STR_ASCII); + break; + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Send a tconX (async recv) +****************************************************************************/ +NTSTATUS smb_tree_connect_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_tcon *parms) +{ + char *p; + + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + goto failed; + } + + switch (parms->tcon.level) { + case RAW_TCON_TCON: + CLI_CHECK_WCT(req, 2); + parms->tcon.out.max_xmit = SVAL(req->in.vwv, VWV(0)); + parms->tcon.out.cnum = SVAL(req->in.vwv, VWV(1)); + break; + + case RAW_TCON_TCONX: + ZERO_STRUCT(parms->tconx.out); + CLI_CHECK_MIN_WCT(req, 0); /* this depends on the protocol level */ + parms->tconx.out.cnum = SVAL(req->in.hdr, HDR_TID); + if (req->in.wct >= 4) { + parms->tconx.out.options = SVAL(req->in.vwv, VWV(3)); + } + + /* output is actual service name */ + p = req->in.data; + if (!p) break; + + p += cli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type, + p, -1, STR_ASCII | STR_TERMINATE); + p += cli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type, + p, -1, STR_TERMINATE); + break; + } + +failed: + return cli_request_destroy(req); +} + +/**************************************************************************** + Send a tconX (sync interface) +****************************************************************************/ +NTSTATUS smb_tree_connect(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_tcon *parms) +{ + struct cli_request *req = smb_tree_connect_send(tree, parms); + return smb_tree_connect_recv(req, mem_ctx, parms); +} + + +/**************************************************************************** + Send a tree disconnect. +****************************************************************************/ +NTSTATUS smb_tree_disconnect(struct cli_tree *tree) +{ + struct cli_request *req; + + if (!tree) return NT_STATUS_OK; + req = cli_request_setup(tree, SMBtdis, 0, 0); + + if (cli_request_send(req)) { + cli_request_receive(req); + } + return cli_request_destroy(req); +} + + +/* + a convenient function to establish a cli_tree from scratch, using reasonable default + parameters +*/ +NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, + const char *my_name, + const char *dest_host, int port, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password) +{ + struct cli_socket *sock; + struct cli_transport *transport; + struct cli_session *session; + struct cli_tree *tree; + NTSTATUS status; + struct nmb_name calling; + struct nmb_name called; + union smb_sesssetup setup; + union smb_tcon tcon; + TALLOC_CTX *mem_ctx; + + *ret_tree = NULL; + + sock = cli_sock_init(); + if (!sock) { + return NT_STATUS_NO_MEMORY; + } + + /* open a TCP socket to the server */ + if (!cli_sock_connect_byname(sock, dest_host, port)) { + DEBUG(2,("Failed to establish socket connection - %s\n", strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + transport = cli_transport_init(sock); + if (!transport) { + cli_sock_close(sock); + return NT_STATUS_NO_MEMORY; + } + + /* send a NBT session request, if applicable */ + make_nmb_name(&calling, my_name, 0x0); + make_nmb_name(&called, dest_host, 0x20); + + if (!cli_transport_connect(transport, &calling, &called)) { + cli_transport_close(transport); + return NT_STATUS_UNSUCCESSFUL; + } + + + /* negotiate protocol options with the server */ + status = smb_raw_negotiate(transport); + if (!NT_STATUS_IS_OK(status)) { + cli_transport_close(transport); + return status; + } + + session = cli_session_init(transport); + if (!session) { + cli_transport_close(transport); + return NT_STATUS_NO_MEMORY; + } + + /* prepare a session setup to establish a security context */ + setup.generic.level = RAW_SESSSETUP_GENERIC; + setup.generic.in.sesskey = transport->negotiate.sesskey; + setup.generic.in.capabilities = CAP_UNICODE | CAP_STATUS32 | + CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | + CAP_W2K_SMBS | CAP_LARGE_READX | CAP_LARGE_WRITEX; + setup.generic.in.password = password; + setup.generic.in.user = user; + setup.generic.in.domain = domain; + + mem_ctx = talloc_init("tcon"); + if (!mem_ctx) { + cli_tree_close(tree); + return NT_STATUS_NO_MEMORY; + } + + status = smb_raw_session_setup(session, mem_ctx, &setup); + if (!NT_STATUS_IS_OK(status)) { + cli_session_close(session); + talloc_destroy(mem_ctx); + return status; + } + + session->vuid = setup.generic.out.vuid; + + tree = cli_tree_init(session); + if (!tree) { + cli_session_close(session); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + /* connect to a share using a tree connect */ + tcon.generic.level = RAW_TCON_TCONX; + tcon.tconx.in.flags = 0; + tcon.tconx.in.password = data_blob(NULL, 0); + tcon.tconx.in.path = service; + tcon.tconx.in.device = service_type; + + status = smb_tree_connect(tree, mem_ctx, &tcon); + if (!NT_STATUS_IS_OK(status)) { + cli_tree_close(tree); + talloc_destroy(mem_ctx); + return status; + } + + tree->tid = tcon.tconx.out.cnum; + tree->device = talloc_strdup(tree->mem_ctx, tcon.tconx.out.dev_type); + tree->fs_type = talloc_strdup(tree->mem_ctx, tcon.tconx.out.fs_type); + + talloc_destroy(mem_ctx); + + *ret_tree = tree; + return NT_STATUS_OK; +} diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c new file mode 100644 index 0000000000..ce0368c304 --- /dev/null +++ b/source4/libcli/raw/raweas.c @@ -0,0 +1,147 @@ +/* + Unix SMB/CIFS implementation. + parsing of EA (extended attribute) lists + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* + work out how many bytes on the wire a ea list will consume. + This assumes the names are strict ascii, which should be a + reasonable assumption +*/ +uint_t ea_list_size(uint_t num_eas, struct ea_struct *eas) +{ + uint_t total = 4; + int i; + for (i=0;ilength < 6) { + return 0; + } + + ea->flags = CVAL(blob->data, 0); + nlen = CVAL(blob->data, 1); + vlen = SVAL(blob->data, 2); + + if (nlen+1+vlen > blob->length-4) { + return 0; + } + + ea->name.s = talloc_strndup(mem_ctx, blob->data+4, nlen); + ea->name.private_length = nlen; + ea->value = data_blob_talloc(mem_ctx, NULL, vlen+1); + if (!ea->value.data) return 0; + if (vlen) { + memcpy(ea->value.data, blob->data+4+nlen+1, vlen); + } + ea->value.data[vlen] = 0; + ea->value.length--; + + return 4 + nlen+1 + vlen; +} + + +/* + pull a ea_list from a buffer +*/ +NTSTATUS ea_pull_list(const DATA_BLOB *blob, + TALLOC_CTX *mem_ctx, + uint_t *num_eas, struct ea_struct **eas) +{ + int n; + uint32 ea_size, ofs; + + if (blob->length < 4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + ea_size = IVAL(blob->data, 0); + if (ea_size > blob->length) { + return NT_STATUS_INVALID_PARAMETER; + } + + ofs = 4; + n = 0; + *num_eas = 0; + *eas = NULL; + + while (ofs < ea_size) { + uint_t len; + DATA_BLOB blob2; + + blob2.data = blob->data + ofs; + blob2.length = ea_size - ofs; + + *eas = talloc_realloc(mem_ctx, *eas, sizeof(**eas) * (n+1)); + if (! *eas) return NT_STATUS_NO_MEMORY; + + len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); + if (len == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + ofs += len; + n++; + } + + *num_eas = n; + + return NT_STATUS_OK; +} + diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c new file mode 100644 index 0000000000..279dfcf0c1 --- /dev/null +++ b/source4/libcli/raw/rawfile.c @@ -0,0 +1,687 @@ +/* + Unix SMB/CIFS implementation. + client file operations + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jeremy Allison 2001-2002 + Copyright (C) James Myers 2003 + + 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" + +#define SETUP_REQUEST(cmd, wct, buflen) do { \ + req = cli_request_setup(tree, cmd, wct, buflen); \ + if (!req) return NULL; \ +} while (0) + + +/**************************************************************************** + Rename a file - async interface +****************************************************************************/ +struct cli_request *smb_raw_rename_send(struct cli_tree *tree, + struct smb_rename *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBmv, 1, 0); + + SSVAL(req->out.vwv, VWV(0), parms->in.attrib); + + cli_req_append_ascii4(req, parms->in.pattern1, STR_TERMINATE); + cli_req_append_ascii4(req, parms->in.pattern2, STR_TERMINATE); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Rename a file - sync interface +****************************************************************************/ +NTSTATUS smb_raw_rename(struct cli_tree *tree, + struct smb_rename *parms) +{ + struct cli_request *req = smb_raw_rename_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + Delete a file - async interface +****************************************************************************/ +struct cli_request *smb_raw_unlink_send(struct cli_tree *tree, + struct smb_unlink *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBunlink, 1, 0); + + SSVAL(req->out.vwv, VWV(0), parms->in.attrib); + cli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + return req; +} + +/* + delete a file - sync interface +*/ +NTSTATUS smb_raw_unlink(struct cli_tree *tree, + struct smb_unlink *parms) +{ + struct cli_request *req = smb_raw_unlink_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + create a directory using TRANSACT2_MKDIR - async interface +****************************************************************************/ +static struct cli_request *smb_raw_t2mkdir_send(struct cli_tree *tree, + union smb_mkdir *parms) +{ + struct smb_trans2 t2; + uint16 setup = TRANSACT2_MKDIR; + TALLOC_CTX *mem_ctx; + struct cli_request *req; + uint16 data_total; + + mem_ctx = talloc_init("t2mkdir"); + + data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); + + t2.in.max_param = 0; + t2.in.max_data = 0; + t2.in.max_setup = 0; + t2.in.flags = 0; + t2.in.timeout = 0; + t2.in.setup_count = 1; + t2.in.setup = &setup; + t2.in.params = data_blob_talloc(mem_ctx, NULL, 4); + t2.in.data = data_blob_talloc(mem_ctx, NULL, data_total); + + SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */ + + cli_blob_append_string(tree->session, mem_ctx, + &t2.in.params, parms->t2mkdir.in.path, 0); + + ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); + + req = smb_raw_trans2_send(tree, &t2); + + talloc_destroy(mem_ctx); + + return req; +} + +/**************************************************************************** + Create a directory - async interface +****************************************************************************/ +struct cli_request *smb_raw_mkdir_send(struct cli_tree *tree, + union smb_mkdir *parms) +{ + struct cli_request *req; + + if (parms->generic.level == RAW_MKDIR_T2MKDIR) { + return smb_raw_t2mkdir_send(tree, parms); + } + + if (parms->generic.level != RAW_MKDIR_MKDIR) { + return NULL; + } + + SETUP_REQUEST(SMBmkdir, 0, 0); + + cli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE); + + if (!cli_request_send(req)) { + return NULL; + } + + return req; +} + +/**************************************************************************** + Create a directory - sync interface +****************************************************************************/ +NTSTATUS smb_raw_mkdir(struct cli_tree *tree, + union smb_mkdir *parms) +{ + struct cli_request *req = smb_raw_mkdir_send(tree, parms); + return cli_request_simple_recv(req); +} + +/**************************************************************************** + Remove a directory - async interface +****************************************************************************/ +struct cli_request *smb_raw_rmdir_send(struct cli_tree *tree, + struct smb_rmdir *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBrmdir, 0, 0); + + cli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Remove a directory - sync interface +****************************************************************************/ +NTSTATUS smb_raw_rmdir(struct cli_tree *tree, + struct smb_rmdir *parms) +{ + struct cli_request *req = smb_raw_rmdir_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + Open a file using TRANSACT2_OPEN - async send +****************************************************************************/ +static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, + union smb_open *parms) +{ + struct smb_trans2 t2; + uint16 setup = TRANSACT2_OPEN; + TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open"); + struct cli_request *req; + uint16 list_size; + + list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas); + + t2.in.max_param = 30; + t2.in.max_data = 0; + t2.in.max_setup = 0; + t2.in.flags = 0; + t2.in.timeout = 0; + t2.in.setup_count = 1; + t2.in.setup = &setup; + t2.in.params = data_blob_talloc(mem_ctx, NULL, 28); + t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size); + + SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags); + SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode); + SSVAL(t2.in.params.data, VWV(2), 0); /* reserved */ + SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs); + put_dos_date(t2.in.params.data, VWV(4), parms->t2open.in.write_time); + SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func); + SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size); + SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout); + SIVAL(t2.in.params.data, VWV(11), 0); + SSVAL(t2.in.params.data, VWV(13), 0); + + cli_blob_append_string(tree->session, mem_ctx, + &t2.in.params, parms->t2open.in.fname, + STR_TERMINATE); + + ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas); + + req = smb_raw_trans2_send(tree, &t2); + + talloc_destroy(mem_ctx); + + return req; +} + + +/**************************************************************************** + Open a file using TRANSACT2_OPEN - async recv +****************************************************************************/ +static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) +{ + struct smb_trans2 t2; + NTSTATUS status; + + status = smb_raw_trans2_recv(req, mem_ctx, &t2); + if (!NT_STATUS_IS_OK(status)) return status; + + if (t2.out.params.length < 30) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + parms->t2open.out.fnum = SVAL(t2.out.params.data, VWV(0)); + parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1)); + parms->t2open.out.write_time = make_unix_date3(t2.out.params.data + VWV(2)); + parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4)); + parms->t2open.out.access = SVAL(t2.out.params.data, VWV(6)); + parms->t2open.out.ftype = SVAL(t2.out.params.data, VWV(7)); + parms->t2open.out.devstate = SVAL(t2.out.params.data, VWV(8)); + parms->t2open.out.action = SVAL(t2.out.params.data, VWV(9)); + parms->t2open.out.unknown = SVAL(t2.out.params.data, VWV(10)); + + return NT_STATUS_OK; +} + +/**************************************************************************** + Open a file - async send +****************************************************************************/ +struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *parms) +{ + int len; + struct cli_request *req = NULL; + + switch (parms->open.level) { + case RAW_OPEN_T2OPEN: + return smb_raw_t2open_send(tree, parms); + + case RAW_OPEN_OPEN: + SETUP_REQUEST(SMBopen, 2, 0); + SSVAL(req->out.vwv, VWV(0), parms->open.in.flags); + SSVAL(req->out.vwv, VWV(1), parms->open.in.search_attrs); + cli_req_append_ascii4(req, parms->open.in.fname, STR_TERMINATE); + break; + + case RAW_OPEN_OPENX: + SETUP_REQUEST(SMBopenX, 15, 0); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags); + SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode); + SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs); + SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs); + put_dos_date3(req->out.vwv, VWV(6), parms->openx.in.write_time); + SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func); + SIVAL(req->out.vwv, VWV(9), parms->openx.in.size); + SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout); + SIVAL(req->out.vwv, VWV(13),0); /* reserved */ + cli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE); + break; + + case RAW_OPEN_MKNEW: + SETUP_REQUEST(SMBmknew, 3, 0); + SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib); + put_dos_date3(req->out.vwv, VWV(1), parms->mknew.in.write_time); + cli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE); + break; + + case RAW_OPEN_CTEMP: + SETUP_REQUEST(SMBctemp, 3, 0); + SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib); + put_dos_date3(req->out.vwv, VWV(1), parms->ctemp.in.write_time); + cli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE); + break; + + case RAW_OPEN_SPLOPEN: + SETUP_REQUEST(SMBsplopen, 2, 0); + SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length); + SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode); + break; + + case RAW_OPEN_NTCREATEX: + SETUP_REQUEST(SMBntcreateX, 24, 0); + SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1),0); + SCVAL(req->out.vwv, VWV(2),0); /* padding */ + SIVAL(req->out.vwv, 7, parms->ntcreatex.in.flags); + SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid); + SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask); + SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size); + SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr); + SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access); + SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition); + SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options); + SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation); + SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags); + + cli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len); + SSVAL(req->out.vwv, 5, len); + break; + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Open a file - async recv +****************************************************************************/ +NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + goto failed; + } + + switch (parms->open.level) { + case RAW_OPEN_T2OPEN: + return smb_raw_t2open_recv(req, mem_ctx, parms); + + case RAW_OPEN_OPEN: + CLI_CHECK_WCT(req, 7); + parms->open.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->open.out.attrib = SVAL(req->in.vwv, VWV(1)); + parms->open.out.write_time = make_unix_date3(req->in.vwv + VWV(2)); + parms->open.out.size = IVAL(req->in.vwv, VWV(4)); + parms->open.out.rmode = SVAL(req->in.vwv, VWV(6)); + break; + + case RAW_OPEN_OPENX: + CLI_CHECK_MIN_WCT(req, 15); + parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2)); + parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3)); + parms->openx.out.write_time = make_unix_date3(req->in.vwv + VWV(4)); + parms->openx.out.size = IVAL(req->in.vwv, VWV(6)); + parms->openx.out.access = SVAL(req->in.vwv, VWV(8)); + parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9)); + parms->openx.out.devstate = SVAL(req->in.vwv, VWV(10)); + parms->openx.out.action = SVAL(req->in.vwv, VWV(11)); + parms->openx.out.unique_fid = IVAL(req->in.vwv, VWV(12)); + if (req->in.wct >= 19) { + parms->openx.out.access_mask = IVAL(req->in.vwv, VWV(15)); + parms->openx.out.unknown = IVAL(req->in.vwv, VWV(17)); + } else { + parms->openx.out.access_mask = 0; + parms->openx.out.unknown = 0; + } + break; + + case RAW_OPEN_MKNEW: + CLI_CHECK_WCT(req, 1); + parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0)); + break; + + case RAW_OPEN_CTEMP: + CLI_CHECK_WCT(req, 1); + parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0)); + cli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); + break; + + case RAW_OPEN_SPLOPEN: + CLI_CHECK_WCT(req, 1); + parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0)); + break; + + case RAW_OPEN_NTCREATEX: + CLI_CHECK_MIN_WCT(req, 34); + parms->ntcreatex.out.oplock_level = CVAL(req->in.vwv, 4); + parms->ntcreatex.out.fnum = SVAL(req->in.vwv, 5); + parms->ntcreatex.out.create_action = IVAL(req->in.vwv, 7); + parms->ntcreatex.out.create_time = cli_pull_nttime(req->in.vwv, 11); + parms->ntcreatex.out.access_time = cli_pull_nttime(req->in.vwv, 19); + parms->ntcreatex.out.write_time = cli_pull_nttime(req->in.vwv, 27); + parms->ntcreatex.out.change_time = cli_pull_nttime(req->in.vwv, 35); + parms->ntcreatex.out.attrib = IVAL(req->in.vwv, 43); + parms->ntcreatex.out.alloc_size = BVAL(req->in.vwv, 47); + parms->ntcreatex.out.size = BVAL(req->in.vwv, 55); + parms->ntcreatex.out.file_type = SVAL(req->in.vwv, 63); + parms->ntcreatex.out.ipc_state = SVAL(req->in.vwv, 65); + parms->ntcreatex.out.is_directory = CVAL(req->in.vwv, 67); + break; + } + +failed: + return cli_request_destroy(req); +} + + +/**************************************************************************** + Open a file - sync interface +****************************************************************************/ +NTSTATUS smb_raw_open(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms) +{ + struct cli_request *req = smb_raw_open_send(tree, parms); + return smb_raw_open_recv(req, mem_ctx, parms); +} + + +/**************************************************************************** + Close a file - async send +****************************************************************************/ +struct cli_request *smb_raw_close_send(struct cli_tree *tree, union smb_close *parms) +{ + struct cli_request *req; + + switch (parms->generic.level) { + case RAW_CLOSE_GENERIC: + return NULL; + + case RAW_CLOSE_CLOSE: + SETUP_REQUEST(SMBclose, 3, 0); + SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum); + put_dos_date3(req->out.vwv, VWV(1), parms->close.in.write_time); + break; + + case RAW_CLOSE_SPLCLOSE: + SETUP_REQUEST(SMBsplclose, 3, 0); + SSVAL(req->out.vwv, VWV(0), parms->splclose.in.fnum); + SIVAL(req->out.vwv, VWV(1), 0); /* reserved */ + break; + } + + if (!req) return NULL; + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + + +/**************************************************************************** + Close a file - sync interface +****************************************************************************/ +NTSTATUS smb_raw_close(struct cli_tree *tree, union smb_close *parms) +{ + struct cli_request *req = smb_raw_close_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + Locking calls - async interface +****************************************************************************/ +struct cli_request *smb_raw_lock_send(struct cli_tree *tree, union smb_lock *parms) +{ + struct cli_request *req; + + switch (parms->generic.level) { + case RAW_LOCK_GENERIC: + return NULL; + + case RAW_LOCK_LOCK: + SETUP_REQUEST(SMBlock, 5, 0); + SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum); + SIVAL(req->out.vwv, VWV(1), parms->lock.in.count); + SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset); + break; + + case RAW_LOCK_UNLOCK: + SETUP_REQUEST(SMBunlock, 5, 0); + SSVAL(req->out.vwv, VWV(0), parms->unlock.in.fnum); + SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count); + SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset); + break; + + case RAW_LOCK_LOCKX: { + struct smb_lock_entry *lockp; + uint_t lck_size = (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES)? 20 : 10; + uint_t lock_count = parms->lockx.in.ulock_cnt + parms->lockx.in.lock_cnt; + int i; + + SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->lockx.in.fnum); + SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode); + SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout); + SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt); + SSVAL(req->out.vwv, VWV(7), parms->lockx.in.lock_cnt); + + /* copy in all the locks */ + lockp = &parms->lockx.in.locks[0]; + for (i = 0; i < lock_count; i++) { + char *p = req->out.data + lck_size * i; + SSVAL(p, 0, lockp[i].pid); + if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) { + SSVAL(p, 2, 0); /* reserved */ + SIVAL(p, 4, lockp[i].offset>>32); + SIVAL(p, 8, lockp[i].offset); + SIVAL(p, 12, lockp[i].count>>32); + SIVAL(p, 16, lockp[i].count); + } else { + SIVAL(p, 2, lockp[i].offset); + SIVAL(p, 6, lockp[i].count); + } + } + } + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Locking calls - sync interface +****************************************************************************/ +NTSTATUS smb_raw_lock(struct cli_tree *tree, union smb_lock *parms) +{ + struct cli_request *req = smb_raw_lock_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + Check for existence of a dir - async send +****************************************************************************/ +struct cli_request *smb_raw_chkpath_send(struct cli_tree *tree, struct smb_chkpath *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBchkpth, 0, 0); + + cli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Check for existence of a dir - sync interface +****************************************************************************/ +NTSTATUS smb_raw_chkpath(struct cli_tree *tree, struct smb_chkpath *parms) +{ + struct cli_request *req = smb_raw_chkpath_send(tree, parms); + return cli_request_simple_recv(req); +} + + + + +/**************************************************************************** + flush a file - async send + a flush to fnum 0xFFFF will flush all files +****************************************************************************/ +struct cli_request *smb_raw_flush_send(struct cli_tree *tree, struct smb_flush *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBflush, 1, 0); + SSVAL(req->out.vwv, VWV(0), parms->in.fnum); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + + +/**************************************************************************** + flush a file - sync interface +****************************************************************************/ +NTSTATUS smb_raw_flush(struct cli_tree *tree, struct smb_flush *parms) +{ + struct cli_request *req = smb_raw_flush_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + seek a file - async send +****************************************************************************/ +struct cli_request *smb_raw_seek_send(struct cli_tree *tree, + struct smb_seek *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBlseek, 4, 0); + + SSVAL(req->out.vwv, VWV(0), parms->in.fnum); + SSVAL(req->out.vwv, VWV(1), parms->in.mode); + SIVALS(req->out.vwv, VWV(2), parms->in.offset); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + return req; +} + +/**************************************************************************** + seek a file - async receive +****************************************************************************/ +NTSTATUS smb_raw_seek_recv(struct cli_request *req, + struct smb_seek *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + CLI_CHECK_WCT(req, 2); + parms->out.offset = IVAL(req->in.vwv, VWV(0)); + +failed: + return cli_request_destroy(req); +} + +/* + seek a file - sync interface +*/ +NTSTATUS smb_raw_seek(struct cli_tree *tree, + struct smb_seek *parms) +{ + struct cli_request *req = smb_raw_seek_send(tree, parms); + return smb_raw_seek_recv(req, parms); +} diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c new file mode 100644 index 0000000000..f685cef9c3 --- /dev/null +++ b/source4/libcli/raw/rawfileinfo.c @@ -0,0 +1,527 @@ +/* + Unix SMB/CIFS implementation. + client trans2 operations + Copyright (C) James Myers 2003 + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* local macros to make the code more readable */ +#define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \ + DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected min of %d\n", \ + blob->length, parms->generic.level, (size))); \ + return NT_STATUS_INFO_LENGTH_MISMATCH; \ +} +#define FINFO_CHECK_SIZE(size) if (blob->length != (size)) { \ + DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected %d\n", \ + blob->length, parms->generic.level, (size))); \ + return NT_STATUS_INFO_LENGTH_MISMATCH; \ +} + +/**************************************************************************** + Handle qfileinfo/qpathinfo trans2 backend. +****************************************************************************/ +static NTSTATUS smb_raw_info_backend(struct cli_session *session, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms, + DATA_BLOB *blob) +{ + uint_t len, ofs; + + switch (parms->generic.level) { + case RAW_FILEINFO_GENERIC: + case RAW_FILEINFO_GETATTR: + case RAW_FILEINFO_GETATTRE: + /* not handled here */ + return NT_STATUS_INVALID_LEVEL; + + case RAW_FILEINFO_STANDARD: + FINFO_CHECK_SIZE(22); + parms->standard.out.create_time = make_unix_date2(blob->data + 0); + parms->standard.out.access_time = make_unix_date2(blob->data + 4); + parms->standard.out.write_time = make_unix_date2(blob->data + 8); + parms->standard.out.size = IVAL(blob->data, 12); + parms->standard.out.alloc_size = IVAL(blob->data, 16); + parms->standard.out.attrib = SVAL(blob->data, 20); + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_SIZE: + FINFO_CHECK_SIZE(26); + parms->ea_size.out.create_time = make_unix_date2(blob->data + 0); + parms->ea_size.out.access_time = make_unix_date2(blob->data + 4); + parms->ea_size.out.write_time = make_unix_date2(blob->data + 8); + parms->ea_size.out.size = IVAL(blob->data, 12); + parms->ea_size.out.alloc_size = IVAL(blob->data, 16); + parms->ea_size.out.attrib = SVAL(blob->data, 20); + parms->ea_size.out.ea_size = IVAL(blob->data, 22); + return NT_STATUS_OK; + + case RAW_FILEINFO_ALL_EAS: + FINFO_CHECK_MIN_SIZE(4); + return ea_pull_list(blob, mem_ctx, + &parms->all_eas.out.num_eas, + &parms->all_eas.out.eas); + + case RAW_FILEINFO_IS_NAME_VALID: + /* no data! */ + FINFO_CHECK_SIZE(0); + return NT_STATUS_OK; + + case RAW_FILEINFO_BASIC_INFO: + case RAW_FILEINFO_BASIC_INFORMATION: + /* some servers return 40 bytes and some 36. w2k3 return 40, so thats + what we should do, but we need to accept 36 */ + if (blob->length != 36) { + FINFO_CHECK_SIZE(40); + } + parms->basic_info.out.create_time = cli_pull_nttime(blob->data, 0); + parms->basic_info.out.access_time = cli_pull_nttime(blob->data, 8); + parms->basic_info.out.write_time = cli_pull_nttime(blob->data, 16); + parms->basic_info.out.change_time = cli_pull_nttime(blob->data, 24); + parms->basic_info.out.attrib = IVAL(blob->data, 32); + return NT_STATUS_OK; + + case RAW_FILEINFO_STANDARD_INFO: + case RAW_FILEINFO_STANDARD_INFORMATION: + FINFO_CHECK_SIZE(24); + parms->standard_info.out.alloc_size = BVAL(blob->data, 0); + parms->standard_info.out.size = BVAL(blob->data, 8); + parms->standard_info.out.nlink = IVAL(blob->data, 16); + parms->standard_info.out.delete_pending = CVAL(blob->data, 20); + parms->standard_info.out.directory = CVAL(blob->data, 21); + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_INFO: + case RAW_FILEINFO_EA_INFORMATION: + FINFO_CHECK_SIZE(4); + parms->ea_info.out.ea_size = IVAL(blob->data, 0); + return NT_STATUS_OK; + + case RAW_FILEINFO_NAME_INFO: + case RAW_FILEINFO_NAME_INFORMATION: + FINFO_CHECK_MIN_SIZE(4); + cli_blob_pull_string(session, mem_ctx, blob, + &parms->name_info.out.fname, 0, 4, STR_UNICODE); + return NT_STATUS_OK; + + case RAW_FILEINFO_ALL_INFO: + case RAW_FILEINFO_ALL_INFORMATION: + FINFO_CHECK_MIN_SIZE(72); + parms->all_info.out.create_time = cli_pull_nttime(blob->data, 0); + parms->all_info.out.access_time = cli_pull_nttime(blob->data, 8); + parms->all_info.out.write_time = cli_pull_nttime(blob->data, 16); + parms->all_info.out.change_time = cli_pull_nttime(blob->data, 24); + parms->all_info.out.attrib = IVAL(blob->data, 32); + parms->all_info.out.alloc_size = BVAL(blob->data, 40); + parms->all_info.out.size = BVAL(blob->data, 48); + parms->all_info.out.nlink = IVAL(blob->data, 56); + parms->all_info.out.delete_pending = CVAL(blob->data, 60); + parms->all_info.out.directory = CVAL(blob->data, 61); + parms->all_info.out.ea_size = IVAL(blob->data, 64); + cli_blob_pull_string(session, mem_ctx, blob, + &parms->all_info.out.fname, 68, 72, STR_UNICODE); + return NT_STATUS_OK; + + case RAW_FILEINFO_ALT_NAME_INFO: + case RAW_FILEINFO_ALT_NAME_INFORMATION: + FINFO_CHECK_MIN_SIZE(4); + cli_blob_pull_string(session, mem_ctx, blob, + &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE); + return NT_STATUS_OK; + + case RAW_FILEINFO_STREAM_INFO: + case RAW_FILEINFO_STREAM_INFORMATION: + FINFO_CHECK_MIN_SIZE(0); + ofs = 0; + parms->stream_info.out.num_streams = 0; + parms->stream_info.out.streams = NULL; + + while (blob->length - ofs >= 24) { + uint_t n = parms->stream_info.out.num_streams; + parms->stream_info.out.streams = + talloc_realloc(mem_ctx,parms->stream_info.out.streams, + (n+1) * sizeof(parms->stream_info.out.streams[0])); + if (!parms->stream_info.out.streams) { + return NT_STATUS_NO_MEMORY; + } + parms->stream_info.out.streams[n].size = BVAL(blob->data, ofs + 8); + parms->stream_info.out.streams[n].alloc_size = BVAL(blob->data, ofs + 16); + cli_blob_pull_string(session, mem_ctx, blob, + &parms->stream_info.out.streams[n].stream_name, + ofs+4, ofs+24, STR_UNICODE); + parms->stream_info.out.num_streams++; + len = IVAL(blob->data, ofs); + if (len > blob->length - ofs) return NT_STATUS_INFO_LENGTH_MISMATCH; + if (len == 0) break; + ofs += len; + } + return NT_STATUS_OK; + + case RAW_FILEINFO_INTERNAL_INFORMATION: + FINFO_CHECK_SIZE(8); + parms->internal_information.out.device = IVAL(blob->data, 0); + parms->internal_information.out.inode = IVAL(blob->data, 4); + return NT_STATUS_OK; + + case RAW_FILEINFO_ACCESS_INFORMATION: + FINFO_CHECK_SIZE(4); + parms->access_information.out.access_flags = IVAL(blob->data, 0); + return NT_STATUS_OK; + + case RAW_FILEINFO_POSITION_INFORMATION: + FINFO_CHECK_SIZE(8); + parms->position_information.out.position = BVAL(blob->data, 0); + return NT_STATUS_OK; + + case RAW_FILEINFO_MODE_INFORMATION: + FINFO_CHECK_SIZE(4); + parms->mode_information.out.mode = IVAL(blob->data, 0); + return NT_STATUS_OK; + + case RAW_FILEINFO_ALIGNMENT_INFORMATION: + FINFO_CHECK_SIZE(4); + parms->alignment_information.out.alignment_requirement + = IVAL(blob->data, 0); + return NT_STATUS_OK; + + case RAW_FILEINFO_COMPRESSION_INFO: + case RAW_FILEINFO_COMPRESSION_INFORMATION: + FINFO_CHECK_SIZE(16); + parms->compression_info.out.compressed_size = BVAL(blob->data, 0); + parms->compression_info.out.format = SVAL(blob->data, 8); + parms->compression_info.out.unit_shift = CVAL(blob->data, 10); + parms->compression_info.out.chunk_shift = CVAL(blob->data, 11); + parms->compression_info.out.cluster_shift = CVAL(blob->data, 12); + /* 3 bytes of padding */ + return NT_STATUS_OK; + + case RAW_FILEINFO_UNIX_BASIC: + FINFO_CHECK_SIZE(100); + parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0); + parms->unix_basic_info.out.num_bytes = BVAL(blob->data, 8); + parms->unix_basic_info.out.status_change_time = cli_pull_nttime(blob->data, 16); + parms->unix_basic_info.out.access_time = cli_pull_nttime(blob->data, 24); + parms->unix_basic_info.out.change_time = cli_pull_nttime(blob->data, 32); + parms->unix_basic_info.out.uid = BVAL(blob->data, 40); + parms->unix_basic_info.out.gid = BVAL(blob->data, 48); + parms->unix_basic_info.out.file_type = IVAL(blob->data, 52); + parms->unix_basic_info.out.dev_major = BVAL(blob->data, 60); + parms->unix_basic_info.out.dev_minor = BVAL(blob->data, 68); + parms->unix_basic_info.out.unique_id = BVAL(blob->data, 76); + parms->unix_basic_info.out.permissions = BVAL(blob->data, 84); + parms->unix_basic_info.out.nlink = BVAL(blob->data, 92); + return NT_STATUS_OK; + + case RAW_FILEINFO_UNIX_LINK: + FINFO_CHECK_MIN_SIZE(0); + cli_blob_pull_string(session, mem_ctx, blob, + &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE); + return NT_STATUS_OK; + + case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: + FINFO_CHECK_SIZE(56); + parms->network_open_information.out.create_time = cli_pull_nttime(blob->data, 0); + parms->network_open_information.out.access_time = cli_pull_nttime(blob->data, 8); + parms->network_open_information.out.write_time = cli_pull_nttime(blob->data, 16); + parms->network_open_information.out.change_time = cli_pull_nttime(blob->data, 24); + parms->network_open_information.out.alloc_size = BVAL(blob->data, 32); + parms->network_open_information.out.size = BVAL(blob->data, 40); + parms->network_open_information.out.attrib = IVAL(blob->data, 48); + return NT_STATUS_OK; + + case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: + FINFO_CHECK_SIZE(8); + parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0); + parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4); + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; +} + +/**************************************************************************** + Very raw query file info - returns param/data blobs - (async send) +****************************************************************************/ +static struct cli_request *smb_raw_fileinfo_blob_send(struct cli_tree *tree, + uint16 fnum, uint16 info_level) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_QFILEINFO; + struct cli_request *req; + TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo"); + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.data = data_blob(NULL, 0); + tp.in.max_param = 2; + tp.in.max_data = 0xFFFF; + tp.in.setup = &setup; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); + if (!tp.in.params.data) { + talloc_destroy(mem_ctx); + return NULL; + } + + SIVAL(tp.in.params.data, 0, fnum); + SSVAL(tp.in.params.data, 2, info_level); + + req = smb_raw_trans2_send(tree, &tp); + + talloc_destroy(mem_ctx); + + return req; +} + + +/**************************************************************************** + Very raw query file info - returns param/data blobs - (async recv) +****************************************************************************/ +static NTSTATUS smb_raw_fileinfo_blob_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob) +{ + struct smb_trans2 tp; + NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp); + if (NT_STATUS_IS_OK(status)) { + *blob = tp.out.data; + } + return status; +} + +/**************************************************************************** + Very raw query path info - returns param/data blobs (async send) +****************************************************************************/ +static struct cli_request *smb_raw_pathinfo_blob_send(struct cli_tree *tree, + const char *fname, + uint16 info_level) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_QPATHINFO; + struct cli_request *req; + TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo"); + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.data = data_blob(NULL, 0); + tp.in.max_param = 2; + tp.in.max_data = 0xFFFF; + tp.in.setup = &setup; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 6); + if (!tp.in.params.data) { + talloc_destroy(mem_ctx); + return NULL; + } + + SSVAL(tp.in.params.data, 0, info_level); + SIVAL(tp.in.params.data, 2, 0); + cli_blob_append_string(tree->session, mem_ctx, &tp.in.params, + fname, STR_TERMINATE); + + req = smb_raw_trans2_send(tree, &tp); + + talloc_destroy(mem_ctx); + + return req; +} + +/**************************************************************************** + send a SMBgetatr (async send) +****************************************************************************/ +static struct cli_request *smb_raw_getattr_send(struct cli_tree *tree, + union smb_fileinfo *parms) +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBgetatr, 0, 0); + if (!req) return NULL; + + cli_req_append_ascii4(req, parms->getattr.in.fname, STR_TERMINATE); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + send a SMBgetatr (async recv) +****************************************************************************/ +static NTSTATUS smb_raw_getattr_recv(struct cli_request *req, + union smb_fileinfo *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + CLI_CHECK_WCT(req, 10); + parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0)); + parms->getattr.out.write_time = make_unix_date3(req->in.vwv + VWV(1)); + parms->getattr.out.size = IVAL(req->in.vwv, VWV(3)); + +failed: + return cli_request_destroy(req); +} + + +/**************************************************************************** + Handle SMBgetattrE (async send) +****************************************************************************/ +static struct cli_request *smb_raw_getattrE_send(struct cli_tree *tree, + union smb_fileinfo *parms) +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBgetattrE, 1, 0); + if (!req) return NULL; + + SSVAL(req->out.vwv, VWV(0), parms->getattre.in.fnum); + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Handle SMBgetattrE (async send) +****************************************************************************/ +static NTSTATUS smb_raw_getattrE_recv(struct cli_request *req, + union smb_fileinfo *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + CLI_CHECK_WCT(req, 11); + parms->getattre.out.create_time = make_unix_date2(req->in.vwv + VWV(0)); + parms->getattre.out.access_time = make_unix_date2(req->in.vwv + VWV(2)); + parms->getattre.out.write_time = make_unix_date2(req->in.vwv + VWV(4)); + parms->getattre.out.size = IVAL(req->in.vwv, VWV(6)); + parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8)); + parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10)); + +failed: + return cli_request_destroy(req); +} + + +/**************************************************************************** + Query file info (async send) +****************************************************************************/ +struct cli_request *smb_raw_fileinfo_send(struct cli_tree *tree, + union smb_fileinfo *parms) +{ + /* pass off the non-trans2 level to specialised functions */ + if (parms->generic.level == RAW_FILEINFO_GETATTRE) { + return smb_raw_getattrE_send(tree, parms); + } + if (parms->generic.level >= RAW_FILEINFO_GENERIC) { + return NULL; + } + + return smb_raw_fileinfo_blob_send(tree, + parms->generic.in.fnum, + parms->generic.level); +} + +/**************************************************************************** + Query file info (async recv) +****************************************************************************/ +NTSTATUS smb_raw_fileinfo_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms) +{ + DATA_BLOB blob; + NTSTATUS status; + struct cli_session *session = req?req->session:NULL; + + if (parms->generic.level == RAW_FILEINFO_GETATTRE) { + return smb_raw_getattrE_recv(req, parms); + } + if (parms->generic.level == RAW_FILEINFO_GETATTR) { + return smb_raw_getattr_recv(req, parms); + } + + status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return smb_raw_info_backend(session, mem_ctx, parms, &blob); +} + +/**************************************************************************** + Query file info (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_fileinfo(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms) +{ + struct cli_request *req = smb_raw_fileinfo_send(tree, parms); + return smb_raw_fileinfo_recv(req, mem_ctx, parms); +} + +/**************************************************************************** + Query path info (async send) +****************************************************************************/ +struct cli_request *smb_raw_pathinfo_send(struct cli_tree *tree, + union smb_fileinfo *parms) +{ + if (parms->generic.level == RAW_FILEINFO_GETATTR) { + return smb_raw_getattr_send(tree, parms); + } + if (parms->generic.level >= RAW_FILEINFO_GENERIC) { + return NULL; + } + + return smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname, + parms->generic.level); +} + +/**************************************************************************** + Query path info (async recv) +****************************************************************************/ +NTSTATUS smb_raw_pathinfo_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms) +{ + /* recv is idential to fileinfo */ + return smb_raw_fileinfo_recv(req, mem_ctx, parms); +} + +/**************************************************************************** + Query path info (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_pathinfo(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms) +{ + struct cli_request *req = smb_raw_pathinfo_send(tree, parms); + return smb_raw_pathinfo_recv(req, mem_ctx, parms); +} diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c new file mode 100644 index 0000000000..362063bfc5 --- /dev/null +++ b/source4/libcli/raw/rawfsinfo.c @@ -0,0 +1,282 @@ +/* + Unix SMB/CIFS implementation. + + RAW_QFS_* operations + + Copyright (C) Andrew Tridgell 2003 + + 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" + +/**************************************************************************** + Query FS Info - SMBdskattr call (async send) +****************************************************************************/ +static struct cli_request *smb_raw_dskattr_send(struct cli_tree *tree, + union smb_fsinfo *fsinfo) +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBdskattr, 0, 0); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Query FS Info - SMBdskattr call (async recv) +****************************************************************************/ +static NTSTATUS smb_raw_dskattr_recv(struct cli_request *req, + union smb_fsinfo *fsinfo) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + goto failed; + } + + CLI_CHECK_WCT(req, 5); + fsinfo->dskattr.out.units_total = SVAL(req->in.vwv, VWV(0)); + fsinfo->dskattr.out.blocks_per_unit = SVAL(req->in.vwv, VWV(1)); + fsinfo->dskattr.out.block_size = SVAL(req->in.vwv, VWV(2)); + fsinfo->dskattr.out.units_free = SVAL(req->in.vwv, VWV(3)); + +failed: + return cli_request_destroy(req); +} + + +/**************************************************************************** + RAW_QFS_ trans2 interface via blobs (async send) +****************************************************************************/ +static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + uint16 info_level) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_QFSINFO; + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.max_param = 0; + tp.in.max_data = 0x1000; /* plenty for all possible QFS levels */ + tp.in.setup = &setup; + tp.in.data = data_blob(NULL, 0); + tp.in.timeout = 0; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 2); + if (!tp.in.params.data) { + return NULL; + } + SSVAL(tp.in.params.data, 0, info_level); + + return smb_raw_trans2_send(tree, &tp); +} + +/**************************************************************************** + RAW_QFS_ trans2 interface via blobs (async recv) +****************************************************************************/ +static NTSTATUS smb_raw_qfsinfo_blob_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob) +{ + struct smb_trans2 tp; + NTSTATUS status; + + status = smb_raw_trans2_recv(req, mem_ctx, &tp); + + if (NT_STATUS_IS_OK(status)) { + (*blob) = tp.out.data; + } + + return status; +} + + +/* local macros to make the code more readable */ +#define QFS_CHECK_MIN_SIZE(size) if (blob.length < (size)) { \ + DEBUG(1,("Unexpected QFS reply size %d for level %u - expected min of %d\n", \ + blob.length, fsinfo->generic.level, (size))); \ + status = NT_STATUS_INFO_LENGTH_MISMATCH; \ + goto failed; \ +} +#define QFS_CHECK_SIZE(size) if (blob.length != (size)) { \ + DEBUG(1,("Unexpected QFS reply size %d for level %u - expected %d\n", \ + blob.length, fsinfo->generic.level, (size))); \ + status = NT_STATUS_INFO_LENGTH_MISMATCH; \ + goto failed; \ +} + + +/**************************************************************************** + Query FSInfo raw interface (async send) +****************************************************************************/ +struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_fsinfo *fsinfo) +{ + uint16 info_level; + + /* handle the only non-trans2 call separately */ + if (fsinfo->generic.level == RAW_QFS_DSKATTR) { + return smb_raw_dskattr_send(tree, fsinfo); + } + if (fsinfo->generic.level >= RAW_QFS_GENERIC) { + return NULL; + } + + /* the headers map the trans2 levels direct to info levels */ + info_level = (uint16)fsinfo->generic.level; + + return smb_raw_qfsinfo_send(tree, mem_ctx, info_level); +} + + +/**************************************************************************** + Query FSInfo raw interface (async recv) +****************************************************************************/ +NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + union smb_fsinfo *fsinfo) +{ + DATA_BLOB blob; + NTSTATUS status; + int i; + struct cli_session *session = req?req->session:NULL; + + if (fsinfo->generic.level == RAW_QFS_DSKATTR) { + return smb_raw_dskattr_recv(req, fsinfo); + } + + status = smb_raw_qfsinfo_blob_recv(req, mem_ctx, &blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* parse the results */ + switch (fsinfo->generic.level) { + case RAW_QFS_GENERIC: + case RAW_QFS_DSKATTR: + /* handled above */ + break; + + case RAW_QFS_ALLOCATION: + QFS_CHECK_SIZE(18); + fsinfo->allocation.out.fs_id = IVAL(blob.data, 0); + fsinfo->allocation.out.sectors_per_unit = IVAL(blob.data, 4); + fsinfo->allocation.out.total_alloc_units = IVAL(blob.data, 8); + fsinfo->allocation.out.avail_alloc_units = IVAL(blob.data, 12); + fsinfo->allocation.out.bytes_per_sector = SVAL(blob.data, 16); + break; + + case RAW_QFS_VOLUME: + QFS_CHECK_MIN_SIZE(5); + fsinfo->volume.out.serial_number = IVAL(blob.data, 0); + cli_blob_pull_string(session, mem_ctx, &blob, + &fsinfo->volume.out.volume_name, + 4, 5, STR_LEN8BIT | STR_NOALIGN); + break; + + case RAW_QFS_VOLUME_INFO: + case RAW_QFS_VOLUME_INFORMATION: + QFS_CHECK_MIN_SIZE(18); + fsinfo->volume_info.out.create_time = cli_pull_nttime(blob.data, 0); + fsinfo->volume_info.out.serial_number = IVAL(blob.data, 8); + cli_blob_pull_string(session, mem_ctx, &blob, + &fsinfo->volume_info.out.volume_name, + 12, 18, STR_UNICODE); + break; + + case RAW_QFS_SIZE_INFO: + case RAW_QFS_SIZE_INFORMATION: + QFS_CHECK_SIZE(24); + fsinfo->size_info.out.total_alloc_units = BVAL(blob.data, 0); + fsinfo->size_info.out.avail_alloc_units = BVAL(blob.data, 8); + fsinfo->size_info.out.sectors_per_unit = IVAL(blob.data, 16); + fsinfo->size_info.out.bytes_per_sector = IVAL(blob.data, 20); + break; + + case RAW_QFS_DEVICE_INFO: + case RAW_QFS_DEVICE_INFORMATION: + QFS_CHECK_SIZE(8); + fsinfo->device_info.out.device_type = IVAL(blob.data, 0); + fsinfo->device_info.out.characteristics = IVAL(blob.data, 4); + break; + + case RAW_QFS_ATTRIBUTE_INFO: + case RAW_QFS_ATTRIBUTE_INFORMATION: + QFS_CHECK_MIN_SIZE(12); + fsinfo->attribute_info.out.fs_attr = IVAL(blob.data, 0); + fsinfo->attribute_info.out.max_file_component_length = IVAL(blob.data, 4); + cli_blob_pull_string(session, mem_ctx, &blob, + &fsinfo->attribute_info.out.fs_type, + 8, 12, STR_UNICODE); + break; + + case RAW_QFS_UNIX_INFO: + QFS_CHECK_SIZE(12); + fsinfo->unix_info.out.major_version = SVAL(blob.data, 0); + fsinfo->unix_info.out.minor_version = SVAL(blob.data, 2); + fsinfo->unix_info.out.capability = SVAL(blob.data, 4); + break; + + case RAW_QFS_QUOTA_INFORMATION: + QFS_CHECK_SIZE(48); + fsinfo->quota_information.out.unknown[0] = BVAL(blob.data, 0); + fsinfo->quota_information.out.unknown[1] = BVAL(blob.data, 8); + fsinfo->quota_information.out.unknown[2] = BVAL(blob.data, 16); + fsinfo->quota_information.out.quota_soft = BVAL(blob.data, 24); + fsinfo->quota_information.out.quota_hard = BVAL(blob.data, 32); + fsinfo->quota_information.out.quota_flags = BVAL(blob.data, 40); + break; + + case RAW_QFS_FULL_SIZE_INFORMATION: + QFS_CHECK_SIZE(32); + fsinfo->full_size_information.out.total_alloc_units = BVAL(blob.data, 0); + fsinfo->full_size_information.out.call_avail_alloc_units = BVAL(blob.data, 8); + fsinfo->full_size_information.out.actual_avail_alloc_units = BVAL(blob.data, 16); + fsinfo->full_size_information.out.sectors_per_unit = IVAL(blob.data, 24); + fsinfo->full_size_information.out.bytes_per_sector = IVAL(blob.data, 28); + break; + + case RAW_QFS_OBJECTID_INFORMATION: + QFS_CHECK_SIZE(64); + memcpy(fsinfo->objectid_information.out.guid.info, blob.data, GUID_SIZE); + for (i=0;i<6;i++) { + fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8); + } + break; + } + +failed: + return status; +} + +/**************************************************************************** + Query FSInfo raw interface (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_fsinfo(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_fsinfo *fsinfo) +{ + struct cli_request *req = smb_raw_fsinfo_send(tree, mem_ctx, fsinfo); + return smb_raw_fsinfo_recv(req, mem_ctx, fsinfo); +} diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c new file mode 100644 index 0000000000..506bddd497 --- /dev/null +++ b/source4/libcli/raw/rawioctl.c @@ -0,0 +1,118 @@ +/* + Unix SMB/CIFS implementation. + client file operations + Copyright (C) Andrew Tridgell 2003 + + 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" + +#define SETUP_REQUEST(cmd, wct, buflen) do { \ + req = cli_request_setup(tree, cmd, wct, buflen); \ + if (!req) return NULL; \ +} while (0) + +/* + send a raw ioctl - async send +*/ +struct cli_request *smb_raw_ioctl_send(struct cli_tree *tree, struct smb_ioctl *parms) +{ + struct cli_request *req; + + SETUP_REQUEST(SMBioctl, 3, 0); + + SSVAL(req->out.vwv, VWV(0), parms->in.fnum); + SIVAL(req->out.vwv, VWV(1), parms->in.request); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/* + send a raw ioctl - async recv +*/ +NTSTATUS smb_raw_ioctl_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, struct smb_ioctl *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + parms->out.blob = cli_req_pull_blob(req, mem_ctx, req->in.data, -1); + return cli_request_destroy(req); +} + +/* + send a raw ioctl - sync interface +*/ +NTSTATUS smb_raw_ioctl(struct cli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_ioctl *parms) +{ + struct cli_request *req = smb_raw_ioctl_send(tree, parms); + return smb_raw_ioctl_recv(req, mem_ctx, parms); +} + + + + +/**************************************************************************** +NT ioctl (async send) +****************************************************************************/ +struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, + struct smb_ntioctl *parms) +{ + struct smb_nttrans nt; + uint16 setup[4]; + + nt.in.max_setup = 0; + nt.in.max_param = 0; + nt.in.max_data = 0; + nt.in.setup_count = 4; + nt.in.setup = setup; + SIVAL(setup, 0, parms->in.function); + SSVAL(setup, 4, parms->in.fnum); + SCVAL(setup, 6, parms->in.fsctl); + SCVAL(setup, 7, parms->in.filter); + nt.in.function = NT_TRANSACT_IOCTL; + nt.in.params = data_blob(NULL, 0); + nt.in.data = data_blob(NULL, 0); + + return smb_raw_nttrans_send(tree, &nt); +} + +/**************************************************************************** +NT ioctl (async recv) +****************************************************************************/ +NTSTATUS smb_raw_ntioctl_recv(struct cli_request *req, + struct smb_ntioctl *parms) +{ + struct smb_nttrans nt; + + return smb_raw_nttrans_recv(req, req->mem_ctx, &nt); +} + +/**************************************************************************** +NT ioctl (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_ntioctl(struct cli_tree *tree, + struct smb_ntioctl *parms) +{ + struct cli_request *req = smb_raw_ntioctl_send(tree, parms); + return smb_raw_ntioctl_recv(req, parms); +} diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c new file mode 100644 index 0000000000..78b2e00706 --- /dev/null +++ b/source4/libcli/raw/rawnegotiate.c @@ -0,0 +1,157 @@ +/* + Unix SMB/CIFS implementation. + SMB client negotiate context management functions + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + +static const struct { + int prot; + const char *name; +} prots[] = { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, +}; + +/**************************************************************************** + Send a negprot command. +****************************************************************************/ +struct cli_request *smb_negprot_send(struct cli_transport *transport, int maxprotocol) +{ + struct cli_request *req; + int i; + + req = cli_request_setup_transport(transport, SMBnegprot, 0, 0); + if (!req) { + return NULL; + } + + /* setup the protocol strings */ + for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) { + cli_req_append_bytes(req, "\2", 1); + cli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII); + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Send a negprot command. +****************************************************************************/ +NTSTATUS smb_raw_negotiate(struct cli_transport *transport) +{ + struct cli_request *req; + int protocol; + + req = smb_negprot_send(transport, PROTOCOL_NT1); + if (!req) { + return NT_STATUS_UNSUCCESSFUL; + } + + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + CLI_CHECK_MIN_WCT(req, 1); + + protocol = SVALS(req->in.vwv, VWV(0)); + + if (protocol >= ARRAY_SIZE(prots) || protocol < 0) { + req->status = NT_STATUS_UNSUCCESSFUL; + return cli_request_destroy(req); + } + + transport->negotiate.protocol = prots[protocol].prot; + + if (transport->negotiate.protocol >= PROTOCOL_NT1) { + NTTIME ntt; + + /* NT protocol */ + CLI_CHECK_WCT(req, 17); + transport->negotiate.sec_mode = CVAL(req->in.vwv,VWV(1)); + transport->negotiate.max_mux = SVAL(req->in.vwv,VWV(1)+1); + transport->negotiate.max_xmit = IVAL(req->in.vwv,VWV(3)+1); + transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(7)+1); + transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60; + + /* this time arrives in real GMT */ + ntt = cli_pull_nttime(req->in.vwv, VWV(11)+1); + transport->negotiate.server_time = nt_time_to_unix(&ntt); + transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); + + transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, req->in.data_size); + if (transport->negotiate.capabilities & CAP_RAW_MODE) { + transport->negotiate.readbraw_supported = True; + transport->negotiate.writebraw_supported = True; + } + + /* work out if they sent us a workgroup */ + if ((transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) && + req->in.data_size > 16) { + cli_req_pull_string(req, transport->mem_ctx, &transport->negotiate.server_domain, + req->in.data+16, + req->in.data_size-16, STR_UNICODE|STR_NOALIGN); + } + } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) { + CLI_CHECK_WCT(req, 13); + transport->negotiate.sec_mode = SVAL(req->in.vwv,VWV(1)); + transport->negotiate.max_xmit = SVAL(req->in.vwv,VWV(2)); + transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(6)); + transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(10)) * 60; + + /* this time is converted to GMT by make_unix_date */ + transport->negotiate.server_time = make_unix_date(req->in.vwv+VWV(8)); + if ((SVAL(req->in.vwv,VWV(5)) & 0x1)) { + transport->negotiate.readbraw_supported = 1; + } + if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) { + transport->negotiate.writebraw_supported = 1; + } + transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, + req->in.data, req->in.data_size); + } else { + /* the old core protocol */ + transport->negotiate.sec_mode = 0; + transport->negotiate.server_time = time(NULL); + transport->negotiate.max_xmit = ~0; + transport->negotiate.server_zone = TimeDiff(time(NULL)); + } + + /* a way to force ascii SMB */ + if (getenv("CLI_FORCE_ASCII")) { + transport->negotiate.capabilities &= ~CAP_UNICODE; + } + +failed: + return cli_request_destroy(req); +} diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c new file mode 100644 index 0000000000..7d635da0dc --- /dev/null +++ b/source4/libcli/raw/rawnotify.c @@ -0,0 +1,116 @@ +/* + Unix SMB/CIFS implementation. + client change notify operations + Copyright (C) Andrew Tridgell 2003 + + 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" + +/**************************************************************************** +change notify (async send) +****************************************************************************/ +struct cli_request *smb_raw_changenotify_send(struct cli_tree *tree, struct smb_notify *parms) +{ + struct smb_nttrans nt; + uint16 setup[4]; + + nt.in.max_setup = 0; + nt.in.max_param = parms->in.buffer_size; + nt.in.max_data = 0; + nt.in.setup_count = 4; + nt.in.setup = setup; + SIVAL(setup, 0, parms->in.completion_filter); + SSVAL(setup, 4, parms->in.fnum); + SSVAL(setup, 6, parms->in.recursive); + nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; + nt.in.params = data_blob(NULL, 0); + nt.in.data = data_blob(NULL, 0); + + return smb_raw_nttrans_send(tree, &nt); +} + +/**************************************************************************** +change notify (async recv) +****************************************************************************/ +NTSTATUS smb_raw_changenotify_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, struct smb_notify *parms) +{ + struct smb_nttrans nt; + NTSTATUS status; + uint32 ofs, i; + struct cli_session *session = req?req->session:NULL; + + status = smb_raw_nttrans_recv(req, mem_ctx, &nt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + parms->out.changes = NULL; + parms->out.num_changes = 0; + + /* count them */ + for (ofs=0; nt.out.params.length - ofs > 12; ) { + uint32 next = IVAL(nt.out.params.data, ofs); + parms->out.num_changes++; + if (next == 0 || + ofs + next >= nt.out.params.length) break; + ofs += next; + } + + /* allocate array */ + parms->out.changes = talloc(mem_ctx, sizeof(parms->out.changes[0]) * + parms->out.num_changes); + if (!parms->out.changes) { + return NT_STATUS_NO_MEMORY; + } + + for (i=ofs=0; iout.num_changes; i++) { + parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); + cli_blob_pull_string(session, mem_ctx, &nt.out.params, + &parms->out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); + ofs += IVAL(nt.out.params.data, ofs); + } + + return NT_STATUS_OK; +} + + +/**************************************************************************** + Send a NT Cancel request - used to hurry along a pending request. Usually + used to cancel a pending change notify request + note that this request does not expect a response! +****************************************************************************/ +NTSTATUS smb_raw_ntcancel(struct cli_request *oldreq) +{ + struct cli_request *req; + + req = cli_request_setup_transport(oldreq->transport, SMBntcancel, 0, 0); + + SSVAL(req->out.hdr, HDR_MID, SVAL(oldreq->out.hdr, HDR_MID)); + SSVAL(req->out.hdr, HDR_PID, SVAL(oldreq->out.hdr, HDR_PID)); + SSVAL(req->out.hdr, HDR_TID, SVAL(oldreq->out.hdr, HDR_TID)); + SSVAL(req->out.hdr, HDR_UID, SVAL(oldreq->out.hdr, HDR_UID)); + + /* this request does not expect a reply, so tell the signing + subsystem not to allocate an id for a reply */ + req->one_way_request = 1; + + cli_request_send(req); + + return cli_request_destroy(req); +} diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c new file mode 100644 index 0000000000..84c7e3c00f --- /dev/null +++ b/source4/libcli/raw/rawreadwrite.c @@ -0,0 +1,321 @@ +/* + Unix SMB/CIFS implementation. + client file read/write routines + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + +#define SETUP_REQUEST(cmd, wct, buflen) do { \ + req = cli_request_setup(tree, cmd, wct, buflen); \ + if (!req) return NULL; \ +} while (0) + + +/**************************************************************************** + low level read operation (async send) +****************************************************************************/ +struct cli_request *smb_raw_read_send(struct cli_tree *tree, union smb_read *parms) +{ + BOOL bigoffset = False; + struct cli_request *req; + + switch (parms->generic.level) { + case RAW_READ_GENERIC: + return NULL; + + case RAW_READ_READBRAW: + if (parms->readbraw.in.offset >= 0x80000000) { + bigoffset = True; + } + SETUP_REQUEST(SMBreadbraw, bigoffset? 10:8, 0); + SSVAL(req->out.vwv, VWV(0), parms->readbraw.in.fnum); + SIVAL(req->out.vwv, VWV(1), parms->readbraw.in.offset); + SSVAL(req->out.vwv, VWV(3), parms->readbraw.in.maxcnt); + SSVAL(req->out.vwv, VWV(4), parms->readbraw.in.mincnt); + SIVAL(req->out.vwv, VWV(5), parms->readbraw.in.timeout); + SSVAL(req->out.vwv, VWV(7), 0); /* reserved */ + if (bigoffset) { + SIVAL(req->out.vwv, VWV(8),parms->readbraw.in.offset>>32); + } + break; + + case RAW_READ_LOCKREAD: + SETUP_REQUEST(SMBlockread, 5, 0); + SSVAL(req->out.vwv, VWV(0), parms->lockread.in.fnum); + SSVAL(req->out.vwv, VWV(1), parms->lockread.in.count); + SIVAL(req->out.vwv, VWV(2), parms->lockread.in.offset); + SSVAL(req->out.vwv, VWV(4), parms->lockread.in.remaining); + break; + + case RAW_READ_READ: + SETUP_REQUEST(SMBread, 5, 0); + SSVAL(req->out.vwv, VWV(0), parms->read.in.fnum); + SSVAL(req->out.vwv, VWV(1), parms->read.in.count); + SIVAL(req->out.vwv, VWV(2), parms->read.in.offset); + SSVAL(req->out.vwv, VWV(4), parms->read.in.remaining); + break; + + case RAW_READ_READX: + if (parms->readx.in.offset >= 0x80000000) { + bigoffset = True; + } + SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); + SSVAL(req->out.vwv, VWV(0), 0xFF); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->readx.in.fnum); + SIVAL(req->out.vwv, VWV(3), parms->readx.in.offset); + SSVAL(req->out.vwv, VWV(5), parms->readx.in.maxcnt); + SSVAL(req->out.vwv, VWV(6), parms->readx.in.mincnt); + SIVAL(req->out.vwv, VWV(7), 0); /* reserved */ + SSVAL(req->out.vwv, VWV(9), parms->readx.in.remaining); + if (bigoffset) { + SIVAL(req->out.vwv, VWV(10),parms->readx.in.offset>>32); + } + break; + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + /* the transport layer needs to know that a readbraw is pending + and handle receives a little differently */ + if (parms->generic.level == RAW_READ_READBRAW) { + tree->session->transport->readbraw_pending = 1; + } + + return req; +} + +/**************************************************************************** + low level read operation (async recv) +****************************************************************************/ +NTSTATUS smb_raw_read_recv(struct cli_request *req, union smb_read *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + goto failed; + } + + switch (parms->generic.level) { + case RAW_READ_GENERIC: + /* handled in _send() */ + break; + + case RAW_READ_READBRAW: + parms->readbraw.out.nread = req->in.size - NBT_HDR_SIZE; + if (parms->readbraw.out.nread > + MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } + memcpy(parms->readbraw.out.data, req->in.buffer + NBT_HDR_SIZE, parms->readbraw.out.nread); + break; + + case RAW_READ_LOCKREAD: + CLI_CHECK_WCT(req, 5); + parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0)); + if (parms->lockread.out.nread > parms->lockread.in.count || + !cli_raw_pull_data(req, req->in.data+3, + parms->lockread.out.nread, parms->lockread.out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + break; + + case RAW_READ_READ: + /* there are 4 reserved words in the reply */ + CLI_CHECK_WCT(req, 5); + parms->read.out.nread = SVAL(req->in.vwv, VWV(0)); + if (parms->read.out.nread > parms->read.in.count || + !cli_raw_pull_data(req, req->in.data+3, + parms->read.out.nread, parms->read.out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + break; + + case RAW_READ_READX: + /* there are 5 reserved words in the reply */ + CLI_CHECK_WCT(req, 12); + parms->readx.out.remaining = SVAL(req->in.vwv, VWV(2)); + parms->readx.out.compaction_mode = SVAL(req->in.vwv, VWV(3)); + parms->readx.out.nread = SVAL(req->in.vwv, VWV(5)); + if (parms->readx.out.nread > MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt) || + !cli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), + parms->readx.out.nread, + parms->readx.out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + break; + } + +failed: + return cli_request_destroy(req); +} + +/**************************************************************************** + low level read operation (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_read(struct cli_tree *tree, union smb_read *parms) +{ + struct cli_request *req = smb_raw_read_send(tree, parms); + return smb_raw_read_recv(req, parms); +} + + +/**************************************************************************** + raw write interface (async send) +****************************************************************************/ +struct cli_request *smb_raw_write_send(struct cli_tree *tree, union smb_write *parms) +{ + BOOL bigoffset = False; + struct cli_request *req; + + switch (parms->generic.level) { + case RAW_WRITE_GENERIC: + return NULL; + + case RAW_WRITE_WRITEUNLOCK: + SETUP_REQUEST(SMBwriteunlock, 5, 3 + parms->writeunlock.in.count); + SSVAL(req->out.vwv, VWV(0), parms->writeunlock.in.fnum); + SSVAL(req->out.vwv, VWV(1), parms->writeunlock.in.count); + SIVAL(req->out.vwv, VWV(2), parms->writeunlock.in.offset); + SSVAL(req->out.vwv, VWV(4), parms->writeunlock.in.remaining); + SCVAL(req->out.data, 0, SMB_DATA_BLOCK); + SSVAL(req->out.data, 1, parms->writeunlock.in.count); + if (parms->writeunlock.in.count > 0) { + memcpy(req->out.data+3, parms->writeunlock.in.data, + parms->writeunlock.in.count); + } + break; + + case RAW_WRITE_WRITE: + SETUP_REQUEST(SMBwrite, 5, 3 + parms->write.in.count); + SSVAL(req->out.vwv, VWV(0), parms->write.in.fnum); + SSVAL(req->out.vwv, VWV(1), parms->write.in.count); + SIVAL(req->out.vwv, VWV(2), parms->write.in.offset); + SSVAL(req->out.vwv, VWV(4), parms->write.in.remaining); + SCVAL(req->out.data, 0, SMB_DATA_BLOCK); + SSVAL(req->out.data, 1, parms->write.in.count); + if (parms->write.in.count > 0) { + memcpy(req->out.data+3, parms->write.in.data, parms->write.in.count); + } + break; + + case RAW_WRITE_WRITECLOSE: + SETUP_REQUEST(SMBwriteclose, 6, 1 + parms->writeclose.in.count); + SSVAL(req->out.vwv, VWV(0), parms->writeclose.in.fnum); + SSVAL(req->out.vwv, VWV(1), parms->writeclose.in.count); + SIVAL(req->out.vwv, VWV(2), parms->writeclose.in.offset); + put_dos_date3(req->out.vwv, VWV(4), parms->writeclose.in.mtime); + SCVAL(req->out.data, 0, 0); + if (parms->writeclose.in.count > 0) { + memcpy(req->out.data+1, parms->writeclose.in.data, + parms->writeclose.in.count); + } + break; + + case RAW_WRITE_WRITEX: + if (parms->writex.in.offset >= 0x80000000) { + bigoffset = True; + } + SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); + SSVAL(req->out.vwv, VWV(0), 0xFF); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->writex.in.fnum); + SIVAL(req->out.vwv, VWV(3), parms->writex.in.offset); + SIVAL(req->out.vwv, VWV(5), 0); /* reserved */ + SSVAL(req->out.vwv, VWV(7), parms->writex.in.wmode); + SSVAL(req->out.vwv, VWV(8), parms->writex.in.remaining); + SSVAL(req->out.vwv, VWV(9), 0); /* reserved */ + SSVAL(req->out.vwv, VWV(10), parms->writex.in.count); + SSVAL(req->out.vwv, VWV(11), PTR_DIFF(req->out.data, req->out.hdr)); + if (bigoffset) { + SIVAL(req->out.vwv,VWV(12),parms->writex.in.offset>>32); + } + if (parms->writex.in.count > 0) { + memcpy(req->out.data, parms->writex.in.data, parms->writex.in.count); + } + break; + + case RAW_WRITE_SPLWRITE: + SETUP_REQUEST(SMBsplwr, 1, parms->splwrite.in.count); + SSVAL(req->out.vwv, VWV(0), parms->splwrite.in.fnum); + if (parms->splwrite.in.count > 0) { + memcpy(req->out.data, parms->splwrite.in.data, parms->splwrite.in.count); + } + break; + } + + if (!cli_request_send(req)) { +cli_request_destroy(req); + return NULL; + } + + return req; +} + + +/**************************************************************************** + raw write interface (async recv) +****************************************************************************/ +NTSTATUS smb_raw_write_recv(struct cli_request *req, union smb_write *parms) +{ + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + goto failed; + } + + switch (parms->generic.level) { + case RAW_WRITE_GENERIC: + break; + case RAW_WRITE_WRITEUNLOCK: + CLI_CHECK_WCT(req, 1); + parms->writeunlock.out.nwritten = SVAL(req->in.vwv, VWV(0)); + break; + case RAW_WRITE_WRITE: + CLI_CHECK_WCT(req, 1); + parms->write.out.nwritten = SVAL(req->in.vwv, VWV(0)); + break; + case RAW_WRITE_WRITECLOSE: + CLI_CHECK_WCT(req, 1); + parms->writeclose.out.nwritten = SVAL(req->in.vwv, VWV(0)); + break; + case RAW_WRITE_WRITEX: + CLI_CHECK_WCT(req, 6); + parms->writex.out.nwritten = SVAL(req->in.vwv, VWV(2)); + parms->writex.out.nwritten += (CVAL(req->in.vwv, VWV(4)) << 16); + parms->writex.out.remaining = SVAL(req->in.vwv, VWV(3)); + break; + case RAW_WRITE_SPLWRITE: + break; + } + +failed: + return cli_request_destroy(req); +} + +/**************************************************************************** + raw write interface (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_write(struct cli_tree *tree, union smb_write *parms) +{ + struct cli_request *req = smb_raw_write_send(tree, parms); + return smb_raw_write_recv(req, parms); +} diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c new file mode 100644 index 0000000000..9c2b2c7367 --- /dev/null +++ b/source4/libcli/raw/rawrequest.c @@ -0,0 +1,1019 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James Myers 2003 + + 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. +*/ + +/* + this file implements functions for manipulating the 'struct cli_request' structure in libsmb +*/ + +#include "includes.h" + +/* we over allocate the data buffer to prevent too many realloc calls */ +#define REQ_OVER_ALLOCATION 256 + +/* assume that a character will not consume more than 3 bytes per char */ +#define MAX_BYTES_PER_CHAR 3 + +/* destroy a request structure and return final status */ +NTSTATUS cli_request_destroy(struct cli_request *req) +{ + NTSTATUS status; + + /* this is the error code we give the application for when a + _send() call fails completely */ + if (!req) return NT_STATUS_UNSUCCESSFUL; + + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_requests, req); + + /* ahh, its so nice to destroy a complex structure in such a + simple way! */ + status = req->status; + talloc_destroy(req->mem_ctx); + return status; +} + + +/* + low-level function to setup a request buffer for a non-SMB packet + at the transport level +*/ +struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, uint_t size) +{ + struct cli_request *req; + TALLOC_CTX *mem_ctx; + + /* each request gets its own talloc context. The request + structure itself is also allocated inside this context, + so we need to allocate it before we construct the request + */ + mem_ctx = talloc_init("cli_request"); + if (!mem_ctx) { + return NULL; + } + + req = talloc(mem_ctx, sizeof(struct cli_request)); + if (!req) { + return NULL; + } + ZERO_STRUCTP(req); + + /* setup the request context */ + req->mem_ctx = mem_ctx; + req->transport = transport; + req->session = NULL; + req->tree = NULL; + req->out.size = size; + + /* over allocate by a small amount */ + req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; + + req->out.buffer = talloc(req->mem_ctx, req->out.allocated); + if (!req->out.buffer) { + return NULL; + } + + SIVAL(req->out.buffer, 0, 0); + + return req; +} + + +/* + setup a SMB packet at transport level +*/ +struct cli_request *cli_request_setup_transport(struct cli_transport *transport, + uint8 command, unsigned wct, unsigned buflen) +{ + struct cli_request *req; + + req = cli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen); + + if (!req) return NULL; + + req->out.hdr = req->out.buffer + NBT_HDR_SIZE; + req->out.vwv = req->out.hdr + HDR_VWV; + req->out.wct = wct; + req->out.data = req->out.vwv + VWV(wct) + 2; + req->out.data_size = buflen; + req->out.ptr = req->out.data; + + SCVAL(req->out.hdr, HDR_WCT, wct); + SSVAL(req->out.vwv, VWV(wct), buflen); + + memcpy(req->out.hdr, "\377SMB", 4); + SCVAL(req->out.hdr,HDR_COM,command); + + SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES); + SSVAL(req->out.hdr,HDR_FLG2, 0); + + /* assign a mid */ + req->mid = cli_transport_next_mid(transport); + + /* copy the pid, uid and mid to the request */ + SSVAL(req->out.hdr, HDR_PID, 0); + SSVAL(req->out.hdr, HDR_UID, 0); + SSVAL(req->out.hdr, HDR_MID, req->mid); + SSVAL(req->out.hdr, HDR_TID,0); + SSVAL(req->out.hdr, HDR_PIDHIGH,0); + SIVAL(req->out.hdr, HDR_RCLS, 0); + memset(req->out.hdr+HDR_SS_FIELD, 0, 10); + + return req; +} + +/* + setup a reply in req->out with the given word count and initial data + buffer size. the caller will then fill in the command words and + data before calling cli_request_send() to send the reply on its + way. This interface is used before a session is setup. +*/ +struct cli_request *cli_request_setup_session(struct cli_session *session, + uint8 command, unsigned wct, unsigned buflen) +{ + struct cli_request *req; + uint16 flags2; + uint32 capabilities; + + req = cli_request_setup_transport(session->transport, command, wct, buflen); + + if (!req) return NULL; + + req->session = session; + + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + capabilities = session->transport->negotiate.capabilities; + + if (capabilities & CAP_UNICODE) { + flags2 |= FLAGS2_UNICODE_STRINGS; + } + if (capabilities & CAP_STATUS32) { + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + } + if (capabilities & CAP_EXTENDED_SECURITY) { + flags2 |= FLAGS2_EXTENDED_SECURITY; + } + if (session->transport->negotiate.sign_info.doing_signing) { + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + } + + SSVAL(req->out.hdr, HDR_FLG2, flags2); + SSVAL(req->out.hdr, HDR_PID, session->pid); + SSVAL(req->out.hdr, HDR_UID, session->vuid); + + return req; +} + +/* + setup a request for tree based commands +*/ +struct cli_request *cli_request_setup(struct cli_tree *tree, + uint8 command, + unsigned wct, unsigned buflen) +{ + struct cli_request *req; + + req = cli_request_setup_session(tree->session, command, wct, buflen); + if (req) { + req->tree = tree; + SSVAL(req->out.hdr,HDR_TID,tree->tid); + } + return req; +} + +/* + grow the allocation of the data buffer portion of a reply + packet. Note that as this can reallocate the packet buffer this + invalidates any local pointers into the packet. + + To cope with this req->out.ptr is supplied. This will be updated to + point at the same offset into the packet as before this call +*/ +static void cli_req_grow_allocation(struct cli_request *req, unsigned new_size) +{ + int delta; + char *buf2; + + delta = new_size - req->out.data_size; + if (delta + req->out.size <= req->out.allocated) { + /* it fits in the preallocation */ + return; + } + + /* we need to realloc */ + req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION; + buf2 = talloc_realloc(req->mem_ctx, req->out.buffer, req->out.allocated); + if (buf2 == NULL) { + smb_panic("out of memory in req_grow_allocation"); + } + + if (buf2 == req->out.buffer) { + /* the malloc library gave us the same pointer */ + return; + } + + /* update the pointers into the packet */ + req->out.data = buf2 + PTR_DIFF(req->out.data, req->out.buffer); + req->out.ptr = buf2 + PTR_DIFF(req->out.ptr, req->out.buffer); + req->out.vwv = buf2 + PTR_DIFF(req->out.vwv, req->out.buffer); + req->out.hdr = buf2 + PTR_DIFF(req->out.hdr, req->out.buffer); + + req->out.buffer = buf2; +} + + +/* + grow the data buffer portion of a reply packet. Note that as this + can reallocate the packet buffer this invalidates any local pointers + into the packet. + + To cope with this req->out.ptr is supplied. This will be updated to + point at the same offset into the packet as before this call +*/ +static void cli_req_grow_data(struct cli_request *req, unsigned new_size) +{ + int delta; + + cli_req_grow_allocation(req, new_size); + + delta = new_size - req->out.data_size; + + req->out.size += delta; + req->out.data_size += delta; + + /* set the BCC to the new data size */ + SSVAL(req->out.vwv, VWV(req->out.wct), new_size); +} + +/* + send a message +*/ +BOOL cli_request_send(struct cli_request *req) +{ + if (IVAL(req->out.buffer, 0) == 0) { + _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); + } + + cli_request_calculate_sign_mac(req); + + if (req->out.size != cli_sock_write(req->transport->socket, req->out.buffer, req->out.size)) { + req->transport->error.etype = ETYPE_SOCKET; + req->transport->error.e.socket_error = SOCKET_WRITE_ERROR; + DEBUG(0,("Error writing %d bytes to server - %s\n", + (int)req->out.size, strerror(errno))); + return False; + } + + /* add it to the list of pending requests */ + DLIST_ADD(req->transport->pending_requests, req); + + return True; +} + + +/* + receive a response to a packet +*/ +BOOL cli_request_receive(struct cli_request *req) +{ + /* req can be NULL when a send has failed. This eliminates lots of NULL + checks in each module */ + if (!req) return False; + + /* keep receiving packets until this one is replied to */ + while (!req->in.buffer) { + if (!cli_transport_select(req->transport)) { + return False; + } + + cli_request_receive_next(req->transport); + } + + return True; +} + + +/* + handle oplock break requests from the server - return True if the request was + an oplock break +*/ +static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char *hdr, const char *vwv) +{ + /* we must be very fussy about what we consider an oplock break to avoid + matching readbraw replies */ + if (len != MIN_SMB_SIZE + VWV(8) || + (CVAL(hdr, HDR_FLG) & FLAG_REPLY) || + CVAL(hdr,HDR_COM) != SMBlockingX || + SVAL(hdr, HDR_MID) != 0xFFFF || + SVAL(vwv,VWV(6)) != 0 || + SVAL(vwv,VWV(7)) != 0) { + return False; + } + + if (transport->oplock.handler) { + uint16 tid = SVAL(hdr, HDR_TID); + uint16 fnum = SVAL(vwv,VWV(2)); + uint8 level = CVAL(vwv,VWV(3)); + transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private); + } + + return True; +} + + +/* + receive an async message from the server + this function assumes that the caller already knows that the socket is readable + and that there is a packet waiting + + The packet is not actually returned by this function, instead any + registered async message handlers are called + + return True if a packet was successfully received and processed + return False if the socket appears to be dead +*/ +BOOL cli_request_receive_next(struct cli_transport *transport) +{ + BOOL ret; + int len; + char header[NBT_HDR_SIZE]; + char *buffer, *hdr, *vwv; + TALLOC_CTX *mem_ctx; + struct cli_request *req; + uint16 wct, mid = 0; + + len = cli_sock_read(transport->socket, header, 4); + if (len != 4) { + return False; + } + + len = smb_len(header); + + mem_ctx = talloc_init("cli_request_receive_next"); + + /* allocate the incoming buffer at the right size */ + buffer = talloc(mem_ctx, len+NBT_HDR_SIZE); + if (!buffer) { + talloc_destroy(mem_ctx); + return False; + } + + /* fill in the already received header */ + memcpy(buffer, header, NBT_HDR_SIZE); + + ret = cli_sock_read(transport->socket, buffer + NBT_HDR_SIZE, len); + /* If the server is not responding, note that now */ + if (ret != len) { + return False; + } + + hdr = buffer+NBT_HDR_SIZE; + vwv = hdr + HDR_VWV; + + /* see if it could be an oplock break request */ + if (handle_oplock_break(transport, len, hdr, vwv)) { + goto done; + } + + /* at this point we need to check for a readbraw reply, as these can be any length */ + if (transport->readbraw_pending) { + transport->readbraw_pending = 0; + + /* it must match the first entry in the pending queue as the client is not allowed + to have outstanding readbraw requests */ + req = transport->pending_requests; + if (!req) goto done; + + req->in.buffer = buffer; + talloc_steal(mem_ctx, req->mem_ctx, buffer); + req->in.size = len + NBT_HDR_SIZE; + req->in.allocated = req->in.size; + goto async; + } + + if (len >= MIN_SMB_SIZE) { + /* extract the mid for matching to pending requests */ + mid = SVAL(hdr, HDR_MID); + wct = CVAL(hdr, HDR_WCT); + } + + /* match the incoming request against the list of pending requests */ + for (req=transport->pending_requests; req; req=req->next) { + if (req->mid == mid) break; + } + + if (!req) { + DEBUG(3,("Discarding unmatched reply with mid %d\n", mid)); + goto done; + } + + /* fill in the 'in' portion of the matching request */ + req->in.buffer = buffer; + talloc_steal(mem_ctx, req->mem_ctx, buffer); + req->in.size = len + NBT_HDR_SIZE; + req->in.allocated = req->in.size; + + /* handle non-SMB replies */ + if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) { + goto done; + } + + if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { + DEBUG(2,("bad reply size for mid %d\n", mid)); + req->status = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + req->in.hdr = hdr; + req->in.vwv = vwv; + req->in.wct = wct; + if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { + req->in.data = req->in.vwv + VWV(wct) + 2; + req->in.data_size = SVAL(req->in.vwv, VWV(wct)); + if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) { + DEBUG(3,("bad data size for mid %d\n", mid)); + /* blergh - w2k3 gives a bogus data size values in some + openX replies */ + req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)); + } + } + req->in.ptr = req->in.data; + req->flags2 = SVAL(req->in.hdr, HDR_FLG2); + + if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) { + transport->error.etype = ETYPE_DOS; + transport->error.e.dos.eclass = CVAL(req->in.hdr,HDR_RCLS); + transport->error.e.dos.ecode = SVAL(req->in.hdr,HDR_ERR); + req->status = dos_to_ntstatus(transport->error.e.dos.eclass, + transport->error.e.dos.ecode); + } else { + transport->error.etype = ETYPE_NT; + transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS)); + req->status = transport->error.e.nt_status; + } + + if (!cli_request_check_sign_mac(req)) { + transport->error.etype = ETYPE_SOCKET; + transport->error.e.socket_error = SOCKET_READ_BAD_SIG; + return False; + }; + +async: + /* if this request has an async handler then call that to + notify that the reply has been received. This might destroy + the request so it must happen last */ + if (req->async.fn) { + req->async.fn(req); + } + +done: + talloc_destroy(mem_ctx); + return True; +} + + +/* + wait for a reply to be received for a packet that just returns an error + code and nothing more +*/ +NTSTATUS cli_request_simple_recv(struct cli_request *req) +{ + cli_request_receive(req); + return cli_request_destroy(req); +} + + +/* Return true if the last packet was in error */ +BOOL cli_request_is_error(struct cli_request *req) +{ + return NT_STATUS_IS_ERR(req->status); +} + +/* + append a string into the data portion of the request packet + + return the number of bytes added to the packet +*/ +size_t cli_req_append_string(struct cli_request *req, const char *str, unsigned flags) +{ + size_t len; + + /* determine string type to use */ + if (!(flags & (STR_ASCII|STR_UNICODE))) { + flags |= (req->transport->negotiate.capabilities & CAP_UNICODE) ? STR_UNICODE : STR_ASCII; + } + + len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; + + cli_req_grow_allocation(req, len + req->out.data_size); + + len = push_string(NULL, req->out.data + req->out.data_size, str, len, flags); + + cli_req_grow_data(req, len + req->out.data_size); + + return len; +} + +/* + this is like cli_req_append_string but it also return the + non-terminated string byte length, which can be less than the number + of bytes consumed in the packet for 2 reasons: + + 1) the string in the packet may be null terminated + 2) the string in the packet may need a 1 byte UCS2 alignment + + this is used in places where the non-terminated string byte length is + placed in the packet as a separate field +*/ +size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsigned flags, int *len) +{ + int diff = 0; + size_t ret; + + /* determine string type to use */ + if (!(flags & (STR_ASCII|STR_UNICODE))) { + flags |= (req->transport->negotiate.capabilities & CAP_UNICODE) ? STR_UNICODE : STR_ASCII; + } + + /* see if an alignment byte will be used */ + if ((flags & STR_UNICODE) && !(flags & STR_NOALIGN)) { + diff = ucs2_align(NULL, req->out.data + req->out.data_size, flags); + } + + /* do the hard work */ + ret = cli_req_append_string(req, str, flags); + + /* see if we need to subtract the termination */ + if (flags & STR_TERMINATE) { + diff += (flags & STR_UNICODE) ? 2 : 1; + } + + if (ret >= diff) { + (*len) = ret - diff; + } else { + (*len) = ret; + } + + return ret; +} + + +/* + push a string into the data portion of the request packet, growing it if necessary + this gets quite tricky - please be very careful to cover all cases when modifying this + + if dest is NULL, then put the string at the end of the data portion of the packet + + if dest_len is -1 then no limit applies +*/ +size_t cli_req_append_ascii4(struct cli_request *req, const char *str, unsigned flags) +{ + size_t size; + cli_req_append_bytes(req, (const uint8 *)"\4", 1); + size = cli_req_append_string(req, str, flags); + return size + 1; +} + + +/* + push a blob into the data portion of the request packet, growing it if necessary + this gets quite tricky - please be very careful to cover all cases when modifying this + + if dest is NULL, then put the blob at the end of the data portion of the packet +*/ +size_t cli_req_append_blob(struct cli_request *req, const DATA_BLOB *blob) +{ + cli_req_grow_allocation(req, req->out.data_size + blob->length); + memcpy(req->out.data + req->out.data_size, blob->data, blob->length); + cli_req_grow_data(req, req->out.data_size + blob->length); + return blob->length; +} + +/* + append raw bytes into the data portion of the request packet + return the number of bytes added +*/ +size_t cli_req_append_bytes(struct cli_request *req, const uint8 *bytes, size_t byte_len) +{ + cli_req_grow_allocation(req, byte_len + req->out.data_size); + memcpy(req->out.data + req->out.data_size, bytes, byte_len); + cli_req_grow_data(req, byte_len + req->out.data_size); + return byte_len; +} + +/* + append variable block (type 5 buffer) into the data portion of the request packet + return the number of bytes added +*/ +size_t cli_req_append_var_block(struct cli_request *req, const uint8 *bytes, uint16 byte_len) +{ + cli_req_grow_allocation(req, byte_len + 3 + req->out.data_size); + SCVAL(req->out.data + req->out.data_size, 0, 5); + SSVAL(req->out.data + req->out.data_size, 1, byte_len); /* add field length */ + if (byte_len > 0) { + memcpy(req->out.data + req->out.data_size + 3, bytes, byte_len); + } + cli_req_grow_data(req, byte_len + 3 + req->out.data_size); + return byte_len + 3; +} + + +/* + pull a UCS2 string from a request packet, returning a talloced unix string + + the string length is limited by the 3 things: + - the data size in the request (end of packet) + - the passed 'byte_len' if it is not -1 + - the end of string (null termination) + + Note that 'byte_len' is the number of bytes in the packet + + on failure zero is returned and *dest is set to NULL, otherwise the number + of bytes consumed in the packet is returned +*/ +static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx, + char **dest, const char *src, int byte_len, unsigned flags) +{ + int src_len, src_len2, alignment=0; + ssize_t ret; + + if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) { + src++; + alignment=1; + if (byte_len != -1) { + byte_len--; + } + } + + src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + if (src_len < 0) { + *dest = NULL; + return 0; + } + if (byte_len != -1 && src_len > byte_len) { + src_len = byte_len; + } + + src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2; + if (src_len2 < src_len - 2) { + /* include the termination if we didn't reach the end of the packet */ + src_len2 += 2; + } + + /* ucs2 strings must be at least 2 bytes long */ + if (src_len2 < 2) { + *dest = NULL; + return 0; + } + + ret = convert_string_talloc(mem_ctx, CH_UCS2, CH_UNIX, src, src_len2, (const void **)dest); + if (ret == -1) { + *dest = NULL; + return 0; + } + + return src_len2 + alignment; +} + +/* + pull a ascii string from a request packet, returning a talloced string + + the string length is limited by the 3 things: + - the data size in the request (end of packet) + - the passed 'byte_len' if it is not -1 + - the end of string (null termination) + + Note that 'byte_len' is the number of bytes in the packet + + on failure zero is returned and *dest is set to NULL, otherwise the number + of bytes consumed in the packet is returned +*/ +size_t cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx, + char **dest, const char *src, int byte_len, unsigned flags) +{ + int src_len, src_len2; + ssize_t ret; + + src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + if (src_len < 0) { + *dest = NULL; + return 0; + } + if (byte_len != -1 && src_len > byte_len) { + src_len = byte_len; + } + src_len2 = strnlen(src, src_len); + if (src_len2 < src_len - 1) { + /* include the termination if we didn't reach the end of the packet */ + src_len2++; + } + + ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (const void **)dest); + + if (ret == -1) { + *dest = NULL; + return 0; + } + + return ret; +} + +/* + pull a string from a request packet, returning a talloced string + + the string length is limited by the 3 things: + - the data size in the request (end of packet) + - the passed 'byte_len' if it is not -1 + - the end of string (null termination) + + Note that 'byte_len' is the number of bytes in the packet + + on failure zero is returned and *dest is set to NULL, otherwise the number + of bytes consumed in the packet is returned +*/ +size_t cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx, + char **dest, const char *src, int byte_len, unsigned flags) +{ + if (!(flags & STR_ASCII) && + ((flags & STR_UNICODE || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { + return cli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags); + } + + return cli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags); +} + + +/* + pull a DATA_BLOB from a reply packet, returning a talloced blob + make sure we don't go past end of packet + + if byte_len is -1 then limit the blob only by packet size +*/ +DATA_BLOB cli_req_pull_blob(struct cli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len) +{ + int src_len; + + src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + + if (src_len < 0) { + return data_blob(NULL, 0); + } + + if (byte_len != -1 && src_len > byte_len) { + src_len = byte_len; + } + + return data_blob_talloc(mem_ctx, src, src_len); +} + +/* check that a lump of data in a request is within the bounds of the data section of + the packet */ +static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32 count) +{ + /* be careful with wraparound! */ + if (ptr < req->in.data || + ptr >= req->in.data + req->in.data_size || + count > req->in.data_size || + ptr + count > req->in.data + req->in.data_size) { + return True; + } + return False; +} + +/* + pull a lump of data from a request packet + + return False if any part is outside the data portion of the packet +*/ +BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char *dest) +{ + if (len == 0) return True; + + if (cli_req_data_oob(req, src, len)) { + return False; + } + + memcpy(dest, src, len); + return True; +} + + +/* + put a NTTIME into a packet +*/ + +void cli_push_nttime(void *base, uint16 offset, NTTIME *t) +{ + SIVAL(base, offset, t->low); + SIVAL(base, offset+4, t->high); +} + +/* + pull a NTTIME from a packet +*/ +NTTIME cli_pull_nttime(void *base, uint16 offset) +{ + NTTIME ret; + ret.low = IVAL(base, offset); + ret.high = IVAL(base, offset+4); + return ret; +} + +/* + pull a UCS2 string from a blob, returning a talloced unix string + + the string length is limited by the 3 things: + - the data size in the blob + - the passed 'byte_len' if it is not -1 + - the end of string (null termination) + + Note that 'byte_len' is the number of bytes in the packet + + on failure zero is returned and *dest is set to NULL, otherwise the number + of bytes consumed in the blob is returned +*/ +static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, + DATA_BLOB *blob, const char **dest, + const char *src, int byte_len, unsigned flags) +{ + int src_len, src_len2, alignment=0; + ssize_t ret; + + if (src < (const char *)blob->data || + src >= (const char *)(blob->data + blob->length)) { + *dest = NULL; + return 0; + } + + src_len = blob->length - PTR_DIFF(src, blob->data); + + if (byte_len != -1 && src_len > byte_len) { + src_len = byte_len; + } + + if (!(flags & STR_NOALIGN) && ucs2_align(blob->data, src, flags)) { + src++; + alignment=1; + src_len--; + } + + if (src_len < 2) { + *dest = NULL; + return 0; + } + + src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2; + + if (src_len2 < src_len - 2) { + /* include the termination if we didn't reach the end of the packet */ + src_len2 += 2; + } + + ret = convert_string_talloc(mem_ctx, CH_UCS2, CH_UNIX, src, src_len2, (const void **)dest); + if (ret == -1) { + *dest = NULL; + return 0; + } + + return src_len2 + alignment; +} + +/* + pull a ascii string from a blob, returning a talloced string + + the string length is limited by the 3 things: + - the data size in the blob + - the passed 'byte_len' if it is not -1 + - the end of string (null termination) + + Note that 'byte_len' is the number of bytes in the blob + + on failure zero is returned and *dest is set to NULL, otherwise the number + of bytes consumed in the blob is returned +*/ +static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, const char **dest, + const char *src, int byte_len, unsigned flags) +{ + int src_len, src_len2; + ssize_t ret; + + src_len = blob->length - PTR_DIFF(src, blob->data); + if (src_len < 0) { + *dest = NULL; + return 0; + } + if (byte_len != -1 && src_len > byte_len) { + src_len = byte_len; + } + src_len2 = strnlen(src, src_len); + + if (src_len2 < src_len - 1) { + /* include the termination if we didn't reach the end of the packet */ + src_len2++; + } + + ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (const void **)dest); + + if (ret == -1) { + *dest = NULL; + return 0; + } + + return ret; +} + +/* + pull a string from a blob, returning a talloced WIRE_STRING + + the string length is limited by the 3 things: + - the data size in the blob + - length field on the wire + - the end of string (null termination) + + if STR_LEN8BIT is set in the flags then assume the length field is + 8 bits, instead of 32 + + on failure zero is returned and dest->s is set to NULL, otherwise the number + of bytes consumed in the blob is returned +*/ +size_t cli_blob_pull_string(struct cli_session *session, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, + WIRE_STRING *dest, + uint16 len_offset, uint16 str_offset, + unsigned flags) +{ + dest->s = NULL; + + if (len_offset > blob->length-4) { + return 0; + } + if (flags & STR_LEN8BIT) { + dest->private_length = CVAL(blob->data, len_offset); + } else { + dest->private_length = IVAL(blob->data, len_offset); + } + dest->s = NULL; + if (!(flags & STR_ASCII) && + ((flags & STR_UNICODE) || + (session->transport->negotiate.capabilities & CAP_UNICODE))) { + if ((str_offset&1) && !(flags & STR_NOALIGN)) { + str_offset++; + } + return cli_blob_pull_ucs2(mem_ctx, blob, &dest->s, + blob->data+str_offset, dest->private_length, flags); + } + + return cli_blob_pull_ascii(mem_ctx, blob, &dest->s, + blob->data+str_offset, dest->private_length, flags); +} + +/* + append a string into a blob +*/ +size_t cli_blob_append_string(struct cli_session *session, + TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + const char *str, unsigned flags) +{ + size_t max_len; + int len; + + if (!str) return 0; + + /* determine string type to use */ + if (!(flags & (STR_ASCII|STR_UNICODE))) { + flags |= (session->transport->negotiate.capabilities & CAP_UNICODE) ? STR_UNICODE : STR_ASCII; + } + + max_len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; + + blob->data = talloc_realloc(mem_ctx, blob->data, blob->length + max_len); + if (!blob->data) { + return 0; + } + + len = push_string(NULL, blob->data + blob->length, str, max_len, flags); + + blob->length += len; + + return len; +} diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c new file mode 100644 index 0000000000..bdc39bb68c --- /dev/null +++ b/source4/libcli/raw/rawsearch.c @@ -0,0 +1,569 @@ +/* + Unix SMB/CIFS implementation. + client directory search routines + Copyright (C) James Myers 2003 + + 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" + +/**************************************************************************** + Old style search backend - process output. +****************************************************************************/ +static void smb_raw_search_backend(struct cli_request *req, + TALLOC_CTX *mem_ctx, + uint16 count, + void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) + +{ + union smb_search_data search_data; + int i; + char *p; + + if (req->in.data_size < 3 + count*43) { + req->status = NT_STATUS_INVALID_PARAMETER; + return; + } + + p = req->in.data + 3; + + for (i=0; i < count; i++) { + search_data.search.search_id = cli_req_pull_blob(req, mem_ctx, p, 21); + search_data.search.attrib = CVAL(p, 21); + search_data.search.write_time = make_unix_date(p + 22); + search_data.search.size = IVAL(p, 26); + cli_req_pull_ascii(req, mem_ctx, &search_data.search.name, p+30, 13, STR_ASCII); + if (!callback(private, &search_data)) { + break; + } + p += 43; + } +} + +/**************************************************************************** + Old style search first. +****************************************************************************/ +static NTSTATUS smb_raw_search_first_old(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_search_first *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) + +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBsearch, 2, 0); + if (!req) { + return NT_STATUS_NO_MEMORY; + } + + SSVAL(req->out.vwv, VWV(0), io->search_first.in.max_count); + SSVAL(req->out.vwv, VWV(1), io->search_first.in.search_attrib); + cli_req_append_ascii4(req, io->search_first.in.pattern, STR_TERMINATE); + cli_req_append_var_block(req, NULL, 0); + + if (!cli_request_send(req) || + !cli_request_receive(req)) { + return cli_request_destroy(req); + } + + if (NT_STATUS_IS_OK(req->status)) { + io->search_first.out.count = SVAL(req->in.vwv, VWV(0)); + smb_raw_search_backend(req, mem_ctx, io->search_first.out.count, private, callback); + } + + return cli_request_destroy(req); +} + +/**************************************************************************** + Old style search next. +****************************************************************************/ +static NTSTATUS smb_raw_search_next_old(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_search_next *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) + +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBsearch, 2, 0); + if (!req) { + return NT_STATUS_NO_MEMORY; + } + + SSVAL(req->out.vwv, VWV(0), io->search_next.in.max_count); + SSVAL(req->out.vwv, VWV(1), io->search_next.in.search_attrib); + cli_req_append_ascii4(req, "", STR_TERMINATE); + cli_req_append_var_block(req, io->search_next.in.search_id.data, 21); + + if (!cli_request_send(req) || + !cli_request_receive(req)) { + return cli_request_destroy(req); + } + + if (NT_STATUS_IS_OK(req->status)) { + io->search_next.out.count = SVAL(req->in.vwv, VWV(0)); + smb_raw_search_backend(req, mem_ctx, io->search_next.out.count, private, callback); + } + + return cli_request_destroy(req); +} + +/**************************************************************************** + Very raw search first - returns param/data blobs. +****************************************************************************/ +static NTSTATUS smb_raw_search_first_blob(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, /* used to allocate output blobs */ + union smb_search_first *io, + uint16 info_level, + DATA_BLOB *out_param_blob, + DATA_BLOB *out_data_blob) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_FINDFIRST; + NTSTATUS status; + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.data = data_blob(NULL, 0); + tp.in.max_param = 1024; + tp.in.max_data = 8192; + tp.in.setup = &setup; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); + if (!tp.in.params.data) { + return NT_STATUS_NO_MEMORY; + } + + SSVAL(tp.in.params.data, 0, io->t2ffirst.in.search_attrib); + SSVAL(tp.in.params.data, 2, io->t2ffirst.in.max_count); + SSVAL(tp.in.params.data, 4, io->t2ffirst.in.flags); + SSVAL(tp.in.params.data, 6, info_level); + SIVAL(tp.in.params.data, 8, io->t2ffirst.in.storage_type); + + cli_blob_append_string(tree->session, mem_ctx, &tp.in.params, + io->t2ffirst.in.pattern, STR_TERMINATE); + + status = smb_raw_trans2(tree, mem_ctx, &tp); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + out_param_blob->length = tp.out.params.length; + out_param_blob->data = tp.out.params.data; + out_data_blob->length = tp.out.data.length; + out_data_blob->data = tp.out.data.data; + + return NT_STATUS_OK; +} + + +/**************************************************************************** + Very raw search first - returns param/data blobs. + Used in CIFS-on-CIFS NTVFS. +****************************************************************************/ +static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_search_next *io, + uint16 info_level, + DATA_BLOB *out_param_blob, + DATA_BLOB *out_data_blob) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_FINDNEXT; + NTSTATUS status; + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.data = data_blob(NULL, 0); + tp.in.max_param = 1024; + tp.in.max_data = 8192; + tp.in.setup = &setup; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); + if (!tp.in.params.data) { + return NT_STATUS_NO_MEMORY; + } + + SSVAL(tp.in.params.data, 0, io->t2fnext.in.handle); + SSVAL(tp.in.params.data, 2, io->t2fnext.in.max_count); + SSVAL(tp.in.params.data, 4, info_level); + SIVAL(tp.in.params.data, 6, io->t2fnext.in.resume_key); + SSVAL(tp.in.params.data, 10, io->t2fnext.in.flags); + + cli_blob_append_string(tree->session, mem_ctx, &tp.in.params, + io->t2fnext.in.last_name, + STR_TERMINATE); + + status = smb_raw_trans2(tree, mem_ctx, &tp); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + out_param_blob->length = tp.out.params.length; + out_param_blob->data = tp.out.params.data; + out_data_blob->length = tp.out.data.length; + out_data_blob->data = tp.out.data.data; + + return NT_STATUS_OK; +} + + +/* + parse a trans2 search response. + Return the number of bytes consumed + return 0 for success with end of list + return -1 for a parse error +*/ +static int parse_trans2_search(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + enum search_level level, + uint16 flags, + DATA_BLOB *blob, + union smb_search_data *data) +{ + uint_t len, ofs; + + switch (level) { + case RAW_SEARCH_GENERIC: + case RAW_SEARCH_SEARCH: + /* handled elsewhere */ + return -1; + + case RAW_SEARCH_STANDARD: + if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { + if (blob->length < 4) return -1; + data->standard.resume_key = IVAL(blob->data, 0); + blob->data += 4; + blob->length -= 4; + } + if (blob->length < 24) return -1; + data->standard.create_time = make_unix_date2(blob->data + 0); + data->standard.access_time = make_unix_date2(blob->data + 4); + data->standard.write_time = make_unix_date2(blob->data + 8); + data->standard.size = IVAL(blob->data, 12); + data->standard.alloc_size = IVAL(blob->data, 16); + data->standard.attrib = SVAL(blob->data, 20); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->standard.name, + 22, 23, STR_LEN8BIT); + return (len + 23 + 3) & ~3; + + case RAW_SEARCH_EA_SIZE: + if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { + if (blob->length < 4) return -1; + data->ea_size.resume_key = IVAL(blob->data, 0); + blob->data += 4; + blob->length -= 4; + } + if (blob->length < 28) return -1; + data->ea_size.create_time = make_unix_date2(blob->data + 0); + data->ea_size.access_time = make_unix_date2(blob->data + 4); + data->ea_size.write_time = make_unix_date2(blob->data + 8); + data->ea_size.size = IVAL(blob->data, 12); + data->ea_size.alloc_size = IVAL(blob->data, 16); + data->ea_size.attrib = SVAL(blob->data, 20); + data->ea_size.ea_size = IVAL(blob->data, 22); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->ea_size.name, + 26, 27, STR_LEN8BIT | STR_NOALIGN); + return len + 27; + + case RAW_SEARCH_DIRECTORY_INFO: + if (blob->length < 65) return -1; + ofs = IVAL(blob->data, 0); + data->directory_info.file_index = IVAL(blob->data, 4); + data->directory_info.create_time = cli_pull_nttime(blob->data, 8); + data->directory_info.access_time = cli_pull_nttime(blob->data, 16); + data->directory_info.write_time = cli_pull_nttime(blob->data, 24); + data->directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->directory_info.size = BVAL(blob->data, 40); + data->directory_info.alloc_size = BVAL(blob->data, 48); + data->directory_info.attrib = IVAL(blob->data, 56); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->directory_info.name, + 60, 64, 0); + if (ofs != 0 && ofs < 64+len) { + return -1; + } + return ofs; + + case RAW_SEARCH_FULL_DIRECTORY_INFO: + if (blob->length < 69) return -1; + ofs = IVAL(blob->data, 0); + data->full_directory_info.file_index = IVAL(blob->data, 4); + data->full_directory_info.create_time = cli_pull_nttime(blob->data, 8); + data->full_directory_info.access_time = cli_pull_nttime(blob->data, 16); + data->full_directory_info.write_time = cli_pull_nttime(blob->data, 24); + data->full_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->full_directory_info.size = BVAL(blob->data, 40); + data->full_directory_info.alloc_size = BVAL(blob->data, 48); + data->full_directory_info.attrib = IVAL(blob->data, 56); + data->full_directory_info.ea_size = IVAL(blob->data, 64); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->full_directory_info.name, + 60, 68, 0); + if (ofs != 0 && ofs < 68+len) { + return -1; + } + return ofs; + + case RAW_SEARCH_NAME_INFO: + if (blob->length < 13) return -1; + ofs = IVAL(blob->data, 0); + data->name_info.file_index = IVAL(blob->data, 4); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->name_info.name, + 8, 12, 0); + if (ofs != 0 && ofs < 12+len) { + return -1; + } + return ofs; + + + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + if (blob->length < 95) return -1; + ofs = IVAL(blob->data, 0); + data->both_directory_info.file_index = IVAL(blob->data, 4); + data->both_directory_info.create_time = cli_pull_nttime(blob->data, 8); + data->both_directory_info.access_time = cli_pull_nttime(blob->data, 16); + data->both_directory_info.write_time = cli_pull_nttime(blob->data, 24); + data->both_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->both_directory_info.size = BVAL(blob->data, 40); + data->both_directory_info.alloc_size = BVAL(blob->data, 48); + data->both_directory_info.attrib = IVAL(blob->data, 56); + data->both_directory_info.ea_size = IVAL(blob->data, 64); + cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->both_directory_info.short_name, + 68, 70, STR_LEN8BIT | STR_UNICODE); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->both_directory_info.name, + 60, 94, 0); + if (ofs != 0 && ofs < 94+len) { + return -1; + } + return ofs; + + + case RAW_SEARCH_261: + if (blob->length < 81) return -1; + ofs = IVAL(blob->data, 0); + data->level_261.file_index = IVAL(blob->data, 4); + data->level_261.create_time = cli_pull_nttime(blob->data, 8); + data->level_261.access_time = cli_pull_nttime(blob->data, 16); + data->level_261.write_time = cli_pull_nttime(blob->data, 24); + data->level_261.change_time = cli_pull_nttime(blob->data, 32); + data->level_261.size = BVAL(blob->data, 40); + data->level_261.alloc_size = BVAL(blob->data, 48); + data->level_261.attrib = IVAL(blob->data, 56); + data->level_261.ea_size = IVAL(blob->data, 64); + data->level_261.unknown[0] = IVAL(blob->data, 68); + data->level_261.unknown[1] = IVAL(blob->data, 72); + data->level_261.unknown[2] = IVAL(blob->data, 76); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->level_261.name, + 60, 80, 0); + if (ofs != 0 && ofs < 80+len) { + return -1; + } + return ofs; + + case RAW_SEARCH_262: + if (blob->length < 105) return -1; + ofs = IVAL(blob->data, 0); + data->level_262.file_index = IVAL(blob->data, 4); + data->level_262.create_time = cli_pull_nttime(blob->data, 8); + data->level_262.access_time = cli_pull_nttime(blob->data, 16); + data->level_262.write_time = cli_pull_nttime(blob->data, 24); + data->level_262.change_time = cli_pull_nttime(blob->data, 32); + data->level_262.size = BVAL(blob->data, 40); + data->level_262.alloc_size = BVAL(blob->data, 48); + data->level_262.attrib = SVAL(blob->data, 56); + data->level_262.ea_size = IVAL(blob->data, 64); + cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->level_262.short_name, + 68, 70, STR_LEN8BIT | STR_UNICODE); + data->level_262.unknown[0] = IVAL(blob->data, 94); + data->level_262.unknown[1] = IVAL(blob->data, 98); + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->level_262.name, + 60, 104, 0); + if (ofs != 0 && ofs < 104+len) { + return -1; + } + return ofs; + } + + /* invalid level */ + return -1; +} + +/**************************************************************************** + Trans2 search backend - process output. +****************************************************************************/ +static NTSTATUS smb_raw_t2search_backend(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + enum search_level level, + uint16 flags, + int16 count, + DATA_BLOB *blob, + void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) + +{ + int i; + DATA_BLOB blob2; + + blob2.data = blob->data; + blob2.length = blob->length; + + for (i=0; i < count; i++) { + union smb_search_data search_data; + uint_t len; + + len = parse_trans2_search(tree, mem_ctx, level, flags, &blob2, &search_data); + if (len == -1) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* the callback function can tell us that no more will + fit - in that case we stop, but it isn't an error */ + if (!callback(private, &search_data)) { + break; + } + + if (len == 0) break; + + blob2.data += len; + blob2.length -= len; + } + + return NT_STATUS_OK; +} + + +/* Implements trans2findfirst2 and old search + */ +NTSTATUS smb_raw_search_first(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_search_first *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) +{ + uint16 info_level = 0; + DATA_BLOB p_blob, d_blob; + NTSTATUS status; + + if (io->generic.level == RAW_SEARCH_SEARCH) { + return smb_raw_search_first_old(tree, mem_ctx, io, private, callback); + } + if (io->generic.level >= RAW_SEARCH_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + info_level = (uint16)io->generic.level; + + status = smb_raw_search_first_blob(tree, mem_ctx, + io, info_level, &p_blob, &d_blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (p_blob.length != 10) { + DEBUG(1,("smb_raw_search_first: parms wrong size %d != expected_param_size\n", + p_blob.length)); + return NT_STATUS_INVALID_PARAMETER; + } + + /* process output data */ + io->t2ffirst.out.handle = SVAL(p_blob.data, 0); + io->t2ffirst.out.count = SVAL(p_blob.data, 2); + io->t2ffirst.out.end_of_search = SVAL(p_blob.data, 4); + + status = smb_raw_t2search_backend(tree, mem_ctx, + io->generic.level, + io->t2ffirst.in.flags, io->t2ffirst.out.count, + &d_blob, private, callback); + + return status; +} + +/* Implements trans2findnext2 and old smbsearch + */ +NTSTATUS smb_raw_search_next(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_search_next *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) +{ + uint16 info_level = 0; + DATA_BLOB p_blob, d_blob; + NTSTATUS status; + + if (io->generic.level == RAW_SEARCH_SEARCH) { + return smb_raw_search_next_old(tree, mem_ctx, io, private, callback); + } + if (io->generic.level >= RAW_SEARCH_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + info_level = (uint16)io->generic.level; + + status = smb_raw_search_next_blob(tree, mem_ctx, + io, info_level, &p_blob, &d_blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (p_blob.length != 8) { + DEBUG(1,("smb_raw_search_next: parms wrong size %d != expected_param_size\n", + p_blob.length)); + return NT_STATUS_INVALID_PARAMETER; + } + + /* process output data */ + io->t2fnext.out.count = SVAL(p_blob.data, 0); + io->t2fnext.out.end_of_search = SVAL(p_blob.data, 2); + + status = smb_raw_t2search_backend(tree, mem_ctx, + io->generic.level, + io->t2fnext.in.flags, io->t2fnext.out.count, + &d_blob, private, callback); + + return status; +} + +/* + Implements trans2findclose2 + */ +NTSTATUS smb_raw_search_close(struct cli_tree *tree, + union smb_search_close *io) +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBfindclose, 1, 0); + if (!req) { + return NT_STATUS_NO_MEMORY; + } + + SSVAL(req->out.vwv, VWV(0), io->findclose.in.handle); + + if (cli_request_send(req)) { + cli_request_receive(req); + } + + return cli_request_destroy(req); +} diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c new file mode 100644 index 0000000000..4044686c64 --- /dev/null +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -0,0 +1,335 @@ +/* + Unix SMB/CIFS implementation. + RAW_SFILEINFO_* calls + Copyright (C) James Myers 2003 + Copyright (C) Andrew Tridgell 2003 + + 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" + +/**************************************************************************** + Handle qfileinfo/qpathinfo trans2 backend. +****************************************************************************/ +static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_setfileinfo *parms, + DATA_BLOB *blob) +{ + uint_t len; + +#define NEED_BLOB(n) do { \ + *blob = data_blob_talloc(mem_ctx, NULL, n); \ + if (blob->data == NULL) return False; \ + } while (0) + + switch (parms->generic.level) { + case RAW_SFILEINFO_GENERIC: + case RAW_SFILEINFO_SETATTR: + case RAW_SFILEINFO_SETATTRE: + /* not handled here */ + return False; + + case RAW_SFILEINFO_STANDARD: + NEED_BLOB(12); + put_dos_date2(blob->data, 0, parms->standard.in.create_time); + put_dos_date2(blob->data, 4, parms->standard.in.access_time); + put_dos_date2(blob->data, 8, parms->standard.in.write_time); + return True; + + case RAW_SFILEINFO_EA_SET: + NEED_BLOB(ea_list_size(1, &parms->ea_set.in.ea)); + ea_put_list(blob->data, 1, &parms->ea_set.in.ea); + return True; + + case RAW_SFILEINFO_BASIC_INFO: + case RAW_SFILEINFO_BASIC_INFORMATION: + NEED_BLOB(40); + cli_push_nttime(blob->data, 0, &parms->basic_info.in.create_time); + cli_push_nttime(blob->data, 8, &parms->basic_info.in.access_time); + cli_push_nttime(blob->data, 16, &parms->basic_info.in.write_time); + cli_push_nttime(blob->data, 24, &parms->basic_info.in.change_time); + SIVAL(blob->data, 32, parms->basic_info.in.attrib); + SIVAL(blob->data, 36, 0); /* padding */ + return True; + + case RAW_SFILEINFO_UNIX_BASIC: + NEED_BLOB(92); + SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file); + SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes); + cli_push_nttime(blob->data, 16, &parms->unix_basic.in.status_change_time); + cli_push_nttime(blob->data, 24, &parms->unix_basic.in.access_time); + cli_push_nttime(blob->data, 32, &parms->unix_basic.in.change_time); + SBVAL(blob->data, 40, parms->unix_basic.in.uid); + SBVAL(blob->data, 48, parms->unix_basic.in.gid); + SIVAL(blob->data, 56, parms->unix_basic.in.file_type); + SBVAL(blob->data, 60, parms->unix_basic.in.dev_major); + SBVAL(blob->data, 68, parms->unix_basic.in.dev_minor); + SBVAL(blob->data, 76, parms->unix_basic.in.unique_id); + SBVAL(blob->data, 84, parms->unix_basic.in.nlink); + return True; + + case RAW_SFILEINFO_DISPOSITION_INFO: + case RAW_SFILEINFO_DISPOSITION_INFORMATION: + NEED_BLOB(4); + SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close); + return True; + + case RAW_SFILEINFO_ALLOCATION_INFO: + case RAW_SFILEINFO_ALLOCATION_INFORMATION: + NEED_BLOB(8); + SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size); + return True; + + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + NEED_BLOB(8); + SBVAL(blob->data, 0, parms->end_of_file_info.in.size); + return True; + + case RAW_SFILEINFO_RENAME_INFORMATION: + NEED_BLOB(12); + SIVAL(blob->data, 0, parms->rename_information.in.overwrite); + SIVAL(blob->data, 4, parms->rename_information.in.root_fid); + len = cli_blob_append_string(tree->session, mem_ctx, blob, + parms->rename_information.in.new_name, + STR_UNICODE|STR_TERMINATE); + SIVAL(blob->data, 8, len - 2); + return True; + + case RAW_SFILEINFO_POSITION_INFORMATION: + NEED_BLOB(8); + SBVAL(blob->data, 0, parms->position_information.in.position); + return True; + + case RAW_SFILEINFO_MODE_INFORMATION: + NEED_BLOB(4); + SIVAL(blob->data, 0, parms->mode_information.in.mode); + return True; + } + + return False; +} + +/**************************************************************************** + Very raw set file info - takes data blob (async send) +****************************************************************************/ +static struct cli_request *smb_raw_setfileinfo_blob_send(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + uint16 fnum, + uint16 info_level, + DATA_BLOB *blob) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_SETFILEINFO; + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.max_param = 2; + tp.in.max_data = 0; + tp.in.setup = &setup; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 6); + if (!tp.in.params.data) { + return NULL; + } + SSVAL(tp.in.params.data, 0, fnum); + SSVAL(tp.in.params.data, 2, info_level); + SSVAL(tp.in.params.data, 4, 0); /* reserved */ + + tp.in.data = *blob; + + return smb_raw_trans2_send(tree, &tp); +} + +/**************************************************************************** + Very raw set path info - takes data blob +****************************************************************************/ +static struct cli_request *smb_raw_setpathinfo_blob_send(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + const char *fname, + uint16 info_level, + DATA_BLOB *blob) +{ + struct smb_trans2 tp; + uint16 setup = TRANSACT2_SETPATHINFO; + + tp.in.max_setup = 0; + tp.in.flags = 0; + tp.in.timeout = 0; + tp.in.setup_count = 1; + tp.in.max_param = 2; + tp.in.max_data = 0; + tp.in.setup = &setup; + + tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); + if (!tp.in.params.data) { + return NULL; + } + SSVAL(tp.in.params.data, 0, info_level); + SSVAL(tp.in.params.data, 2, 0); + cli_blob_append_string(tree->session, mem_ctx, + &tp.in.params, + fname, STR_TERMINATE); + + tp.in.data = *blob; + + return smb_raw_trans2_send(tree, &tp); +} + +/**************************************************************************** + Handle setattr (async send) +****************************************************************************/ +static struct cli_request *smb_raw_setattr_send(struct cli_tree *tree, + union smb_setfileinfo *parms) +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBsetatr, 8, 0); + if (!req) return NULL; + + SSVAL(req->out.vwv, VWV(0), parms->setattr.in.attrib); + put_dos_date3(req->out.vwv, VWV(1), parms->setattr.in.write_time); + memset(req->out.vwv + VWV(3), 0, 10); /* reserved */ + cli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE); + cli_req_append_ascii4(req, "", STR_TERMINATE); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Handle setattrE. (async send) +****************************************************************************/ +static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree, + union smb_setfileinfo *parms) +{ + struct cli_request *req; + + req = cli_request_setup(tree, SMBsetattrE, 7, 0); + if (!req) return NULL; + + SSVAL(req->out.vwv, VWV(0), parms->setattre.file.fnum); + put_dos_date2(req->out.vwv, VWV(1), parms->setattre.in.create_time); + put_dos_date2(req->out.vwv, VWV(3), parms->setattre.in.access_time); + put_dos_date2(req->out.vwv, VWV(5), parms->setattre.in.write_time); + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + Set file info (async send) +****************************************************************************/ +struct cli_request *smb_raw_setfileinfo_send(struct cli_tree *tree, + union smb_setfileinfo *parms) +{ + DATA_BLOB blob; + TALLOC_CTX *mem_ctx; + struct cli_request *req; + + if (parms->generic.level == RAW_SFILEINFO_SETATTRE) { + return smb_raw_setattrE_send(tree, parms); + } + if (parms->generic.level >= RAW_SFILEINFO_GENERIC) { + return NULL; + } + + mem_ctx = talloc_init("setpathinfo"); + if (!mem_ctx) return NULL; + + if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) { + talloc_destroy(mem_ctx); + return NULL; + } + + /* send request and process the output */ + req = smb_raw_setfileinfo_blob_send(tree, + mem_ctx, + parms->generic.file.fnum, + parms->generic.level, + &blob); + + talloc_destroy(mem_ctx); + return req; +} + +/**************************************************************************** + Set file info (async send) +****************************************************************************/ +NTSTATUS smb_raw_setfileinfo(struct cli_tree *tree, + union smb_setfileinfo *parms) +{ + struct cli_request *req = smb_raw_setfileinfo_send(tree, parms); + return cli_request_simple_recv(req); +} + + +/**************************************************************************** + Set path info (async send) +****************************************************************************/ +struct cli_request *smb_raw_setpathinfo_send(struct cli_tree *tree, + union smb_setfileinfo *parms) +{ + DATA_BLOB blob; + TALLOC_CTX *mem_ctx; + struct cli_request *req; + + if (parms->generic.level == RAW_SFILEINFO_SETATTR) { + return smb_raw_setattr_send(tree, parms); + } + if (parms->generic.level >= RAW_SFILEINFO_GENERIC) { + return NULL; + } + + mem_ctx = talloc_init("setpathinfo"); + if (!mem_ctx) return NULL; + + if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) { + talloc_destroy(mem_ctx); + return NULL; + } + + /* send request and process the output */ + req = smb_raw_setpathinfo_blob_send(tree, + mem_ctx, + parms->generic.file.fname, + parms->generic.level, + &blob); + + talloc_destroy(mem_ctx); + return req; +} + +/**************************************************************************** + Set path info (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_setpathinfo(struct cli_tree *tree, + union smb_setfileinfo *parms) +{ + struct cli_request *req = smb_raw_setpathinfo_send(tree, parms); + return cli_request_simple_recv(req); +} diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c new file mode 100644 index 0000000000..508f920268 --- /dev/null +++ b/source4/libcli/raw/rawtrans.c @@ -0,0 +1,489 @@ +/* + Unix SMB/CIFS implementation. + raw trans/trans2/nttrans operations + + Copyright (C) James Myers 2003 + + 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" + + +/* + check out of bounds for incoming data +*/ +static BOOL raw_trans_oob(struct cli_request *req, + uint_t offset, uint_t count) +{ + char *ptr; + + if (count == 0) { + return False; + } + + ptr = req->in.hdr + offset; + + /* be careful with wraparound! */ + if (ptr < req->in.data || + ptr >= req->in.data + req->in.data_size || + count > req->in.data_size || + ptr + count > req->in.data + req->in.data_size) { + return True; + } + return False; +} + +/**************************************************************************** + receive a SMB trans or trans2 response allocating the necessary memory + ****************************************************************************/ +NTSTATUS smb_raw_trans2_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + struct smb_trans2 *parms) +{ + int total_data=0; + int total_param=0; + char *tdata; + char *tparam; + + parms->out.data.length = 0; + parms->out.data.data = NULL; + parms->out.params.length = 0; + parms->out.params.data = NULL; + + if (!cli_request_receive(req)) { + req->status = NT_STATUS_UNSUCCESSFUL; + return cli_request_destroy(req); + } + + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + if (NT_STATUS_IS_ERR(req->status)) { + return cli_request_destroy(req); + } + + CLI_CHECK_MIN_WCT(req, 10); + + /* parse out the lengths */ + total_data = SVAL(req->in.vwv, VWV(1)); + total_param = SVAL(req->in.vwv, VWV(0)); + + /* allocate it */ + if (total_data != 0) { + tdata = talloc_realloc(mem_ctx, parms->out.data.data,total_data); + if (!tdata) { + DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); + req->status = NT_STATUS_NO_MEMORY; + return cli_request_destroy(req); + } + parms->out.data.data = tdata; + } + + if (total_param != 0) { + tparam = talloc_realloc(mem_ctx, parms->out.params.data,total_param); + if (!tparam) { + DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); + req->status = NT_STATUS_NO_MEMORY; + return cli_request_destroy(req); + } + parms->out.params.data = tparam; + } + + parms->out.setup_count = SVAL(req->in.vwv, VWV(9)); + CLI_CHECK_WCT(req, 10 + parms->out.setup_count); + + if (parms->out.setup_count > 0) { + int i; + parms->out.setup = talloc(mem_ctx, 2 * parms->out.setup_count); + if (!parms->out.setup) { + req->status = NT_STATUS_NO_MEMORY; + return cli_request_destroy(req); + } + for (i=0;iout.setup_count;i++) { + parms->out.setup[i] = SVAL(req->in.vwv, VWV(10+i)); + } + } + + while (1) { + uint16 param_count, param_ofs, param_disp; + uint16 data_count, data_ofs, data_disp; + uint16 total_data2, total_param2; + + /* parse out the total lengths again - they can shrink! */ + total_data2 = SVAL(req->in.vwv, VWV(1)); + total_param2 = SVAL(req->in.vwv, VWV(0)); + + if (total_data2 > total_data || + total_param2 > total_param) { + /* they must *only* shrink */ + DEBUG(1,("smb_raw_receive_trans: data/params expanded!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + return cli_request_destroy(req); + } + + total_data = total_data2; + total_param = total_param2; + + /* parse params for this lump */ + param_count = SVAL(req->in.vwv, VWV(3)); + param_ofs = SVAL(req->in.vwv, VWV(4)); + param_disp = SVAL(req->in.vwv, VWV(5)); + + data_count = SVAL(req->in.vwv, VWV(6)); + data_ofs = SVAL(req->in.vwv, VWV(7)); + data_disp = SVAL(req->in.vwv, VWV(8)); + + if (data_count + data_disp > total_data || + param_count + param_disp > total_param) { + DEBUG(1,("smb_raw_receive_trans: Buffer overflow\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + return cli_request_destroy(req); + } + + /* check the server isn't being nasty */ + if (raw_trans_oob(req, param_ofs, param_count) || + raw_trans_oob(req, data_ofs, data_count)) { + DEBUG(1,("smb_raw_receive_trans: out of bounds parameters!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + return cli_request_destroy(req); + } + + if (data_count) { + memcpy(parms->out.data.data + data_disp, + req->in.hdr + data_ofs, + data_count); + } + + if (param_count) { + memcpy(parms->out.params.data + param_disp, + req->in.hdr + param_ofs, + param_count); + } + + parms->out.data.length += data_count; + parms->out.params.length += param_count; + + if (total_data <= parms->out.data.length && total_param <= parms->out.params.length) + break; + + /* to receive more requests we need to mark this request as not received */ + req->in.buffer = NULL; + + if (!cli_request_receive(req)) { + req->status = NT_STATUS_UNSUCCESSFUL; + return cli_request_destroy(req); + } + } + +failed: + return cli_request_destroy(req); +} + + +/**************************************************************************** + trans2 raw async interface - only BLOBs used in this interface. +note that this doesn't yet support multi-part requests +****************************************************************************/ +struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, + struct smb_trans2 *parms) +{ + uint8 command = SMBtrans2; + int wct = 14 + parms->in.setup_count; + struct cli_request *req; + char *outdata,*outparam; + int data_sent, param_sent; + int i; + const int padding = 3; + + req = cli_request_setup(tree, command, wct, padding); + if (!req) { + return NULL; + } + + /* fill in SMB parameters */ + data_sent = parms->in.data.length; + param_sent = parms->in.params.length; + outparam = req->out.data + padding; + outdata = outparam + param_sent; + + /* make sure we don't leak data via the padding */ + memset(req->out.data, 0, padding); + + /* primary request */ + SSVAL(req->out.vwv,VWV(0),parms->in.params.length); + SSVAL(req->out.vwv,VWV(1),parms->in.data.length); + SSVAL(req->out.vwv,VWV(2),parms->in.max_param); + SSVAL(req->out.vwv,VWV(3),parms->in.max_data); + SSVAL(req->out.vwv,VWV(4),parms->in.max_setup); + SSVAL(req->out.vwv,VWV(5),parms->in.flags); + SIVAL(req->out.vwv,VWV(6),parms->in.timeout); + SSVAL(req->out.vwv,VWV(8),0); /* reserved */ + SSVAL(req->out.vwv,VWV(9),parms->in.params.length); + SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)); + SSVAL(req->out.vwv,VWV(11),parms->in.data.length); + SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)); + SSVAL(req->out.vwv,VWV(13),parms->in.setup_count); + for (i=0;iin.setup_count;i++) { + SSVAL(req->out.vwv,VWV(14)+i*2,parms->in.setup[i]); + } + if (parms->in.params.data) { + cli_req_append_blob(req, &parms->in.params); + } + if (parms->in.data.data) { + cli_req_append_blob(req, &parms->in.data); + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + +/* + trans2 synchronous blob interface +*/ +NTSTATUS smb_raw_trans2(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_trans2 *parms) +{ + struct cli_request *req; + req = smb_raw_trans2_send(tree, parms); + if (!req) return NT_STATUS_UNSUCCESSFUL; + return smb_raw_trans2_recv(req, mem_ctx, parms); +} + + +/**************************************************************************** + receive a SMB nttrans response allocating the necessary memory + ****************************************************************************/ +NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + struct smb_nttrans *parms) +{ + uint32 total_data, recvd_data=0; + uint32 total_param, recvd_param=0; + + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + /* sanity check */ + if (CVAL(req->in.hdr, HDR_COM) != SMBnttrans) { + DEBUG(0,("smb_raw_receive_nttrans: Expected %s response, got command 0x%02x\n", + "SMBnttrans", + CVAL(req->in.hdr,HDR_COM))); + req->status = NT_STATUS_UNSUCCESSFUL; + return cli_request_destroy(req); + } + + CLI_CHECK_MIN_WCT(req, 18); + + /* parse out the lengths */ + total_param = IVAL(req->in.vwv, 3); + total_data = IVAL(req->in.vwv, 7); + + parms->out.data = data_blob_talloc(mem_ctx, NULL, total_data); + parms->out.params = data_blob_talloc(mem_ctx, NULL, total_param); + + if (parms->out.data.length != total_data || + parms->out.params.length != total_param) { + req->status = NT_STATUS_NO_MEMORY; + return cli_request_destroy(req); + } + + parms->out.setup_count = CVAL(req->in.vwv, 35); + CLI_CHECK_WCT(req, 18 + parms->out.setup_count); + + if (parms->out.setup_count > 0) { + int i; + parms->out.setup = talloc(mem_ctx, 2 * parms->out.setup_count); + if (!parms->out.setup) { + req->status = NT_STATUS_NO_MEMORY; + return cli_request_destroy(req); + } + for (i=0;iout.setup_count;i++) { + parms->out.setup[i] = SVAL(req->in.vwv, VWV(18+i)); + } + } + + while (recvd_data < total_data || + recvd_param < total_param) { + uint32 param_count, param_ofs, param_disp; + uint32 data_count, data_ofs, data_disp; + uint32 total_data2, total_param2; + + /* parse out the total lengths again - they can shrink! */ + total_param2 = IVAL(req->in.vwv, 3); + total_data2 = IVAL(req->in.vwv, 7); + + if (total_data2 > total_data || + total_param2 > total_param) { + /* they must *only* shrink */ + DEBUG(1,("smb_raw_receive_nttrans: data/params expanded!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + return cli_request_destroy(req); + } + + total_data = total_data2; + total_param = total_param2; + parms->out.data.length = total_data; + parms->out.params.length = total_param; + + /* parse params for this lump */ + param_count = IVAL(req->in.vwv, 11); + param_ofs = IVAL(req->in.vwv, 15); + param_disp = IVAL(req->in.vwv, 19); + + data_count = IVAL(req->in.vwv, 23); + data_ofs = IVAL(req->in.vwv, 27); + data_disp = IVAL(req->in.vwv, 31); + + if (data_count + data_disp > total_data || + param_count + param_disp > total_param) { + DEBUG(1,("smb_raw_receive_nttrans: Buffer overflow\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + return cli_request_destroy(req); + } + + /* check the server isn't being nasty */ + if (raw_trans_oob(req, param_ofs, param_count) || + raw_trans_oob(req, data_ofs, data_count)) { + DEBUG(1,("smb_raw_receive_nttrans: out of bounds parameters!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + return cli_request_destroy(req); + } + + if (data_count) { + memcpy(parms->out.data.data + data_disp, + req->in.hdr + data_ofs, + data_count); + } + + if (param_count) { + memcpy(parms->out.params.data + param_disp, + req->in.hdr + param_ofs, + param_count); + } + + recvd_param += param_count; + recvd_data += data_count; + + if (recvd_data >= total_data && + recvd_param >= total_param) { + break; + } + + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } + + /* sanity check */ + if (CVAL(req->in.hdr, HDR_COM) != SMBnttrans) { + DEBUG(0,("smb_raw_receive_nttrans: Expected nttranss, got command 0x%02x\n", + CVAL(req->in.hdr, HDR_COM))); + req->status = NT_STATUS_UNSUCCESSFUL; + return cli_request_destroy(req); + } + } + +failed: + return cli_request_destroy(req); +} + + +/**************************************************************************** + nttrans raw - only BLOBs used in this interface. + at the moment we only handle a single primary request +****************************************************************************/ +struct cli_request *smb_raw_nttrans_send(struct cli_tree *tree, + struct smb_nttrans *parms) +{ + struct cli_request *req; + char *outdata, *outparam; + int i; + int align = 0; + + /* only align if there are parameters or data */ + if (parms->in.params.length || parms->in.data.length) { + align = 3; + } + + req = cli_request_setup(tree, SMBnttrans, + 19 + parms->in.setup_count, + align + + parms->in.params.length + + parms->in.data.length); + if (!req) { + return NULL; + } + + /* fill in SMB parameters */ + outparam = req->out.data + align; + outdata = outparam + parms->in.params.length; + + SCVAL(req->out.vwv, 0, parms->in.max_setup); + SSVAL(req->out.vwv, 1, 0); /* reserved */ + SIVAL(req->out.vwv, 3, parms->in.params.length); + SIVAL(req->out.vwv, 7, parms->in.data.length); + SIVAL(req->out.vwv, 11, parms->in.max_param); + SIVAL(req->out.vwv, 15, parms->in.max_data); + SIVAL(req->out.vwv, 19, parms->in.params.length); + SIVAL(req->out.vwv, 23, PTR_DIFF(outparam,req->out.hdr)); + SIVAL(req->out.vwv, 27, parms->in.data.length); + SIVAL(req->out.vwv, 31, PTR_DIFF(outdata,req->out.hdr)); + SCVAL(req->out.vwv, 35, parms->in.setup_count); + SSVAL(req->out.vwv, 36, parms->in.function); + for (i=0;iin.setup_count;i++) { + SSVAL(req->out.vwv,VWV(19+i),parms->in.setup[i]); + } + if (parms->in.params.length) { + memcpy(outparam, parms->in.params.data, parms->in.params.length); + } + if (parms->in.data.length) { + memcpy(outparam, parms->in.data.data, parms->in.data.length); + } + + if (!cli_request_send(req)) { + cli_request_destroy(req); + return NULL; + } + + return req; +} + + +/**************************************************************************** + receive a SMB nttrans response allocating the necessary memory + ****************************************************************************/ +NTSTATUS smb_raw_nttrans(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_nttrans *parms) +{ + struct cli_request *req; + + req = smb_raw_nttrans_send(tree, parms); + if (!req) { + return NT_STATUS_UNSUCCESSFUL; + } + + return smb_raw_nttrans_recv(req, mem_ctx, parms); +} diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c new file mode 100644 index 0000000000..2ab61aa001 --- /dev/null +++ b/source4/libcli/raw/smb_signing.c @@ -0,0 +1,341 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2002. + Copyright (C) Andrew Bartlett 2002-2003 + Copyright (C) James J Myers 2003 + + 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" + +struct smb_basic_signing_context { + DATA_BLOB mac_key; + uint32 next_seq_num; +}; + +/*********************************************************** + SMB signing - Common code before we set a new signing implementation +************************************************************/ +static BOOL set_smb_signing_common(struct cli_transport *transport) +{ + if (!(transport->negotiate.sec_mode & + (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) { + return False; + } + + if (transport->negotiate.sign_info.doing_signing) { + return False; + } + + if (transport->negotiate.sign_info.free_signing_context) + transport->negotiate.sign_info.free_signing_context(transport); + + /* These calls are INCOMPATIBLE with SMB signing */ + transport->negotiate.readbraw_supported = False; + transport->negotiate.writebraw_supported = False; + + return True; +} + +/*********************************************************** + SMB signing - Common code for 'real' implementations +************************************************************/ +static BOOL set_smb_signing_real_common(struct cli_transport *transport) +{ + if (transport->negotiate.sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { + DEBUG(5, ("Mandatory SMB signing enabled!\n")); + transport->negotiate.sign_info.doing_signing = True; + } + + DEBUG(5, ("SMB signing enabled!\n")); + + return True; +} + +static void mark_packet_signed(struct cli_request *req) +{ + uint16 flags2; + flags2 = SVAL(req->out.hdr, HDR_FLG2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(req->out.hdr, HDR_FLG2, flags2); +} + +static BOOL signing_good(struct cli_request *req, BOOL good) +{ + if (good && !req->transport->negotiate.sign_info.doing_signing) { + req->transport->negotiate.sign_info.doing_signing = True; + } + + if (!good) { + if (req->transport->negotiate.sign_info.doing_signing) { + DEBUG(1, ("SMB signature check failed!\n")); + return False; + } else { + DEBUG(3, ("Server did not sign reply correctly\n")); + cli_transport_free_signing_context(req->transport); + return False; + } + } + return True; +} + +/*********************************************************** + SMB signing - Simple implementation - calculate a MAC to send. +************************************************************/ +static void cli_request_simple_sign_outgoing_message(struct cli_request *req) +{ + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; + +#if 0 + /* enable this when packet signing is preventing you working out why valgrind + says that data is uninitialised */ + file_save("pkt.dat", req->out.buffer, req->out.size); +#endif + + req->seq_num = data->next_seq_num; + + /* some requests (eg. NTcancel) are one way, and the sequence number + should be increased by 1 not 2 */ + if (req->one_way_request) { + data->next_seq_num += 1; + } else { + data->next_seq_num += 2; + } + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(req->out.hdr, HDR_SS_FIELD, req->seq_num); + SIVAL(req->out.hdr, HDR_SS_FIELD + 4, 0); + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(req); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, + req->out.buffer + NBT_HDR_SIZE, + req->out.size - NBT_HDR_SIZE); + MD5Final(calc_md5_mac, &md5_ctx); + + memcpy(&req->out.hdr[HDR_SS_FIELD], calc_md5_mac, 8); + +/* req->out.hdr[HDR_SS_FIELD+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ +} + + +/*********************************************************** + SMB signing - Simple implementation - check a MAC sent by server. +************************************************************/ +static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) +{ + BOOL good; + unsigned char calc_md5_mac[16]; + unsigned char server_sent_mac[8]; + unsigned char sequence_buf[8]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; + const size_t offset_end_of_sig = (HDR_SS_FIELD + 8); + int i; + const int sign_range = 0; + + /* its quite bogus to be guessing sequence numbers, but very useful + when debugging signing implementations */ + for (i = 1-sign_range; i <= 1+sign_range; i++) { + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(sequence_buf, 0, req->seq_num+i); + SIVAL(sequence_buf, 4, 0); + + /* get a copy of the server-sent mac */ + memcpy(server_sent_mac, &req->in.hdr[HDR_SS_FIELD], sizeof(server_sent_mac)); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, req->in.hdr, HDR_SS_FIELD); + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + MD5Update(&md5_ctx, req->in.hdr + offset_end_of_sig, + req->in.size - NBT_HDR_SIZE - (offset_end_of_sig)); + MD5Final(calc_md5_mac, &md5_ctx); + + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (good) break; + } + + if (good && i != 1) { + DEBUG(0,("SIGNING OFFSET %d\n", i)); + } + + if (!good) { + DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } + return signing_good(req, good); +} + + +/*********************************************************** + SMB signing - Simple implementation - free signing context +************************************************************/ +static void cli_transport_simple_free_signing_context(struct cli_transport *transport) +{ + struct smb_basic_signing_context *data = transport->negotiate.sign_info.signing_context; + + data_blob_free(&data->mac_key); + SAFE_FREE(transport->negotiate.sign_info.signing_context); + + return; +} + + +/*********************************************************** + SMB signing - Simple implementation - setup the MAC key. +************************************************************/ +BOOL cli_transport_simple_set_signing(struct cli_transport *transport, + const uchar user_transport_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!set_smb_signing_common(transport)) { + return False; + } + + if (!set_smb_signing_real_common(transport)) { + return False; + } + + data = smb_xmalloc(sizeof(*data)); + transport->negotiate.sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + + memcpy(&data->mac_key.data[0], user_transport_key, 16); + memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + + /* Initialise the sequence number */ + data->next_seq_num = 0; + + transport->negotiate.sign_info.sign_outgoing_message = cli_request_simple_sign_outgoing_message; + transport->negotiate.sign_info.check_incoming_message = cli_request_simple_check_incoming_message; + transport->negotiate.sign_info.free_signing_context = cli_transport_simple_free_signing_context; + + return True; +} + + +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ +static void cli_request_null_sign_outgoing_message(struct cli_request *req) +{ + /* we can't zero out the sig, as we might be trying to send a + transport request - which is NBT-level, not SMB level and doesn't + have the field */ +} + + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ +static BOOL cli_request_null_check_incoming_message(struct cli_request *req) +{ + return True; +} + + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ +static void cli_null_free_signing_context(struct cli_transport *transport) +{ +} + +/** + SMB signing - NULL implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ +BOOL cli_null_set_signing(struct cli_transport *transport) +{ + transport->negotiate.sign_info.signing_context = NULL; + + transport->negotiate.sign_info.sign_outgoing_message = cli_request_null_sign_outgoing_message; + transport->negotiate.sign_info.check_incoming_message = cli_request_null_check_incoming_message; + transport->negotiate.sign_info.free_signing_context = cli_null_free_signing_context; + + return True; +} + + +/** + * Free the signing context + */ +void cli_transport_free_signing_context(struct cli_transport *transport) +{ + if (transport->negotiate.sign_info.free_signing_context) { + transport->negotiate.sign_info.free_signing_context(transport); + } + + cli_null_set_signing(transport); +} + + +/** + * Sign a packet with the current mechanism + */ +void cli_request_calculate_sign_mac(struct cli_request *req) +{ + req->transport->negotiate.sign_info.sign_outgoing_message(req); +} + + +/** + * Check a packet with the current mechanism + * @return False if we had an established signing connection + * which had a back checksum, True otherwise + */ +BOOL cli_request_check_sign_mac(struct cli_request *req) +{ + BOOL good; + + if (req->in.size < (HDR_SS_FIELD + 8)) { + good = False; + } else { + good = req->transport->negotiate.sign_info.check_incoming_message(req); + } + + if (!good && req->transport->negotiate.sign_info.doing_signing) { + return False; + } + + return True; +} diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c new file mode 100644 index 0000000000..c80dfa0465 --- /dev/null +++ b/source4/libcli/unexpected.c @@ -0,0 +1,172 @@ +/* + Unix SMB/CIFS implementation. + handle unexpected packets + Copyright (C) Andrew Tridgell 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" + +static TDB_CONTEXT *tdbd = NULL; + +/* the key type used in the unexpeceted packet database */ +struct unexpected_key { + enum packet_type packet_type; + time_t timestamp; + int count; +}; + + + +/**************************************************************************** + all unexpected packets are passed in here, to be stored in a unexpected + packet database. This allows nmblookup and other tools to receive packets + erroneoously sent to the wrong port by broken MS systems + **************************************************************************/ +void unexpected_packet(struct packet_struct *p) +{ + static int count; + TDB_DATA kbuf, dbuf; + struct unexpected_key key; + char buf[1024]; + int len=0; + TALLOC_CTX *mem_ctx; + + if (!tdbd) { + mem_ctx = talloc_init("receive_unexpected"); + if (!mem_ctx) return; + tdbd = tdb_open_log(lock_path(mem_ctx, "unexpected.tdb"), 0, + TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644); + talloc_destroy(mem_ctx); + if (!tdbd) { + DEBUG(0,("Failed to open unexpected.tdb\n")); + return; + } + } + + memset(buf,'\0',sizeof(buf)); + + len = build_packet(buf, p); + + key.packet_type = p->packet_type; + key.timestamp = p->timestamp; + key.count = count++; + + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + dbuf.dptr = buf; + dbuf.dsize = len; + + tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE); +} + + +static time_t lastt; + +/**************************************************************************** +delete the record if it is too old + **************************************************************************/ +static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct unexpected_key key; + + memcpy(&key, kbuf.dptr, sizeof(key)); + + if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) { + tdb_delete(ttdb, kbuf); + } + + return 0; +} + + +/**************************************************************************** +delete all old unexpected packets + **************************************************************************/ +void clear_unexpected(time_t t) +{ + if (!tdbd) return; + + if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT)) + return; + + lastt = t; + + tdb_traverse(tdbd, traverse_fn, NULL); +} + + +static struct packet_struct *matched_packet; +static int match_id; +static enum packet_type match_type; +static const char *match_name; + +/**************************************************************************** +tdb traversal fn to find a matching 137 packet + **************************************************************************/ +static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct unexpected_key key; + struct packet_struct *p; + + memcpy(&key, kbuf.dptr, sizeof(key)); + + if (key.packet_type != match_type) return 0; + + p = parse_packet(dbuf.dptr, dbuf.dsize, match_type); + + if ((match_type == NMB_PACKET && + p->packet.nmb.header.name_trn_id == match_id) || + (match_type == DGRAM_PACKET && + match_mailslot_name(p, match_name))) { + matched_packet = p; + return -1; + } + + free_packet(p); + + return 0; +} + + +/**************************************************************************** +check for a particular packet in the unexpected packet queue + **************************************************************************/ +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + const char *mailslot_name) +{ + TDB_CONTEXT *tdb2; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("receive_unexpected"); + if (!mem_ctx) return NULL; + tdb2 = tdb_open_log(lock_path(mem_ctx, "unexpected.tdb"), 0, 0, O_RDONLY, 0); + talloc_destroy(mem_ctx); + if (!tdb2) return NULL; + + matched_packet = NULL; + match_id = id; + match_type = packet_type; + match_name = mailslot_name; + + tdb_traverse(tdb2, traverse_match, NULL); + + tdb_close(tdb2); + + return matched_packet; +} diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c new file mode 100644 index 0000000000..09d4fbb6c9 --- /dev/null +++ b/source4/libcli/util/asn1.c @@ -0,0 +1,428 @@ +/* + Unix SMB/CIFS implementation. + simple SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + + 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" + +/* free an asn1 structure */ +void asn1_free(ASN1_DATA *data) +{ + SAFE_FREE(data->data); +} + +/* write to the ASN1 buffer, advancing the buffer pointer */ +BOOL asn1_write(ASN1_DATA *data, const void *p, int len) +{ + if (data->has_error) return False; + if (data->length < data->ofs+len) { + uint8 *newp; + newp = Realloc(data->data, data->ofs+len); + if (!newp) { + SAFE_FREE(data->data); + data->has_error = True; + return False; + } + data->data = newp; + data->length = data->ofs+len; + } + memcpy(data->data + data->ofs, p, len); + data->ofs += len; + return True; +} + +/* useful fn for writing a uint8 */ +BOOL asn1_write_uint8(ASN1_DATA *data, uint8 v) +{ + return asn1_write(data, &v, 1); +} + +/* push a tag onto the asn1 data buffer. Used for nested structures */ +BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) +{ + struct nesting *nesting; + + asn1_write_uint8(data, tag); + nesting = (struct nesting *)malloc(sizeof(struct nesting)); + if (!nesting) { + data->has_error = True; + return False; + } + + nesting->start = data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + return asn1_write_uint8(data, 0xff); +} + +/* pop a tag */ +BOOL asn1_pop_tag(ASN1_DATA *data) +{ + struct nesting *nesting; + size_t len; + + nesting = data->nesting; + + if (!nesting) { + data->has_error = True; + return False; + } + len = data->ofs - (nesting->start+1); + /* yes, this is ugly. We don't know in advance how many bytes the length + of a tag will take, so we assumed 1 byte. If we were wrong then we + need to correct our mistake */ + if (len > 255) { + data->data[nesting->start] = 0x82; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); + data->data[nesting->start+1] = len>>8; + data->data[nesting->start+2] = len&0xff; + } else if (len > 127) { + data->data[nesting->start] = 0x81; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); + data->data[nesting->start+1] = len; + } else { + data->data[nesting->start] = len; + } + + data->nesting = nesting->next; + free(nesting); + return True; +} + + +/* write an integer */ +BOOL asn1_write_Integer(ASN1_DATA *data, int i) +{ + if (!asn1_push_tag(data, ASN1_INTEGER)) return False; + do { + asn1_write_uint8(data, i); + i = i >> 8; + } while (i); + return asn1_pop_tag(data); +} + +/* write an object ID to a ASN1 buffer */ +BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) +{ + unsigned v, v2; + const char *p = (const char *)OID; + char *newp; + + if (!asn1_push_tag(data, ASN1_OID)) + return False; + v = strtol(p, &newp, 10); + p = newp; + v2 = strtol(p, &newp, 10); + p = newp; + if (!asn1_write_uint8(data, 40*v + v2)) + return False; + + while (*p) { + v = strtol(p, &newp, 10); + p = newp; + if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff)); + if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); + if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); + if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); + if (!asn1_write_uint8(data, v&0x7f)) + return False; + } + return asn1_pop_tag(data); +} + +/* write an octet string */ +BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) +{ + asn1_push_tag(data, ASN1_OCTET_STRING); + asn1_write(data, p, length); + asn1_pop_tag(data); + return !data->has_error; +} + +/* write a general string */ +BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) +{ + asn1_push_tag(data, ASN1_GENERAL_STRING); + asn1_write(data, s, strlen(s)); + asn1_pop_tag(data); + return !data->has_error; +} + +/* write a BOOLEAN */ +BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) +{ + asn1_write_uint8(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + return !data->has_error; +} + +/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the + above boolean is bogus. Need to check */ +BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) +{ + asn1_push_tag(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} + +/* check a BOOLEAN */ +BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) +{ + uint8 b = 0; + + asn1_read_uint8(data, &b); + if (b != ASN1_BOOLEAN) { + data->has_error = True; + return False; + } + asn1_read_uint8(data, &b); + if (b != v) { + data->has_error = True; + return False; + } + return !data->has_error; +} + + +/* load a ASN1_DATA structure with a lump of data, ready to be parsed */ +BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) +{ + ZERO_STRUCTP(data); + data->data = memdup(blob.data, blob.length); + if (!data->data) { + data->has_error = True; + return False; + } + data->length = blob.length; + return True; +} + +/* read from a ASN1 buffer, advancing the buffer pointer */ +BOOL asn1_read(ASN1_DATA *data, void *p, int len) +{ + if (data->ofs + len > data->length) { + data->has_error = True; + return False; + } + memcpy(p, data->data + data->ofs, len); + data->ofs += len; + return True; +} + +/* read a uint8 from a ASN1 buffer */ +BOOL asn1_read_uint8(ASN1_DATA *data, uint8 *v) +{ + return asn1_read(data, v, 1); +} + +/* start reading a nested asn1 structure */ +BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) +{ + uint8 b; + struct nesting *nesting; + + if (!asn1_read_uint8(data, &b)) + return False; + + if (b != tag) { + data->has_error = True; + return False; + } + nesting = (struct nesting *)malloc(sizeof(struct nesting)); + if (!nesting) { + data->has_error = True; + return False; + } + + if (!asn1_read_uint8(data, &b)) { + return False; + } + + if (b & 0x80) { + int n = b & 0x7f; + if (!asn1_read_uint8(data, &b)) + return False; + nesting->taglen = b; + while (n > 1) { + if (!asn1_read_uint8(data, &b)) + return False; + nesting->taglen = (nesting->taglen << 8) | b; + n--; + } + } else { + nesting->taglen = b; + } + nesting->start = data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + return !data->has_error; +} + + +/* stop reading a tag */ +BOOL asn1_end_tag(ASN1_DATA *data) +{ + struct nesting *nesting; + + /* make sure we read it all */ + if (asn1_tag_remaining(data) != 0) { + data->has_error = True; + return False; + } + + nesting = data->nesting; + + if (!nesting) { + data->has_error = True; + return False; + } + + data->nesting = nesting->next; + free(nesting); + return True; +} + +/* work out how many bytes are left in this nested tag */ +int asn1_tag_remaining(ASN1_DATA *data) +{ + if (!data->nesting) { + data->has_error = True; + return -1; + } + return data->nesting->taglen - (data->ofs - data->nesting->start); +} + +/* read an object ID from a ASN1 buffer */ +BOOL asn1_read_OID(ASN1_DATA *data, char **OID) +{ + uint8 b; + pstring oid; + fstring el; + + if (!asn1_start_tag(data, ASN1_OID)) return False; + asn1_read_uint8(data, &b); + + oid[0] = 0; + snprintf(el, sizeof(el), "%u", b/40); + pstrcat(oid, el); + snprintf(el, sizeof(el), " %u", b%40); + pstrcat(oid, el); + + while (asn1_tag_remaining(data) > 0) { + unsigned v = 0; + do { + asn1_read_uint8(data, &b); + v = (v<<7) | (b&0x7f); + } while (!data->has_error && b & 0x80); + snprintf(el, sizeof(el), " %u", v); + pstrcat(oid, el); + } + + asn1_end_tag(data); + + *OID = strdup(oid); + + return !data->has_error; +} + +/* check that the next object ID is correct */ +BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) +{ + char *id; + + if (!asn1_read_OID(data, &id)) return False; + + if (strcmp(id, OID) != 0) { + data->has_error = True; + return False; + } + free(id); + return True; +} + +/* read a GeneralString from a ASN1 buffer */ +BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) +{ + int len; + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; + len = asn1_tag_remaining(data); + *s = malloc(len+1); + if (! *s) { + data->has_error = True; + return False; + } + asn1_read(data, *s, len); + (*s)[len] = 0; + asn1_end_tag(data); + return !data->has_error; +} + +/* read a octet string blob */ +BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) +{ + int len; + ZERO_STRUCTP(blob); + if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; + len = asn1_tag_remaining(data); + *blob = data_blob(NULL, len); + asn1_read(data, blob->data, len); + asn1_end_tag(data); + return !data->has_error; +} + +/* read an interger */ +BOOL asn1_read_Integer(ASN1_DATA *data, int *i) +{ + uint8 b; + *i = 0; + + if (!asn1_start_tag(data, ASN1_INTEGER)) return False; + while (asn1_tag_remaining(data)>0) { + asn1_read_uint8(data, &b); + *i = (*i << 8) + b; + } + return asn1_end_tag(data); + +} + +/* check a enumarted value is correct */ +BOOL asn1_check_enumerated(ASN1_DATA *data, int v) +{ + uint8 b; + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; + asn1_read_uint8(data, &b); + asn1_end_tag(data); + + if (v != b) + data->has_error = False; + + return !data->has_error; +} + +/* write an enumarted value to the stream */ +BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v) +{ + if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c new file mode 100644 index 0000000000..4fa1daa3be --- /dev/null +++ b/source4/libcli/util/clierror.c @@ -0,0 +1,99 @@ +/* + Unix SMB/CIFS implementation. + client error handling routines + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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" + + +/*************************************************************************** + Return an error message from the last response +****************************************************************************/ +const char *cli_errstr(struct cli_state *cli) +{ + switch (cli->transport->error.etype) { + case ETYPE_DOS: + return dos_errstr(cli->transport->error.e.dos.eclass, + cli->transport->error.e.dos.ecode); + case ETYPE_NT: + return nt_errstr(cli->transport->error.e.nt_status); + + case ETYPE_SOCKET: + return "socket_error"; + + case ETYPE_NBT: + return "nbt_error"; + + case ETYPE_NONE: + return "no_error"; + } + return NULL; +} + + +/* Return the 32-bit NT status code from the last packet */ +NTSTATUS cli_nt_error(struct cli_state *cli) +{ + switch (cli->transport->error.etype) { + case ETYPE_NT: + return cli->transport->error.e.nt_status; + + case ETYPE_DOS: + return dos_to_ntstatus(cli->transport->error.e.dos.eclass, + cli->transport->error.e.dos.ecode); + case ETYPE_SOCKET: + return NT_STATUS_UNSUCCESSFUL; + + case ETYPE_NBT: + return NT_STATUS_UNSUCCESSFUL; + + case ETYPE_NONE: + return NT_STATUS_OK; + } + + return NT_STATUS_UNSUCCESSFUL; +} + + +/* Return the DOS error from the last packet - an error class and an error + code. */ +void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) +{ + if (cli->transport->error.etype == ETYPE_DOS) { + ntstatus_to_dos(cli->transport->error.e.nt_status, + eclass, ecode); + return; + } + + if (eclass) *eclass = cli->transport->error.e.dos.eclass; + if (ecode) *ecode = cli->transport->error.e.dos.ecode; +} + + +/* Return true if the last packet was an error */ +BOOL cli_is_error(struct cli_state *cli) +{ + return NT_STATUS_IS_ERR(cli_nt_error(cli)); +} + +/* Return true if the last error was a DOS error */ +BOOL cli_is_dos_error(struct cli_state *cli) +{ + return cli->transport->error.etype == ETYPE_DOS; +} diff --git a/source4/libcli/util/cliutil.c b/source4/libcli/util/cliutil.c new file mode 100644 index 0000000000..47f94992a4 --- /dev/null +++ b/source4/libcli/util/cliutil.c @@ -0,0 +1,110 @@ +/* + Unix SMB/CIFS implementation. + client utility routines + Copyright (C) Andrew Tridgell 2001 + Copyright (C) James Myers 2003 + + 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" +/******************************************************************* + Functions nicked from lib/util.c needed by client. +*******************************************************************/ + +/* a default finfo structure to ensure all fields are sensible */ +file_info def_finfo = {-1,0,0,0,0,0,0,"",""}; + +/******************************************************************* + A wrapper that handles case sensitivity and the special handling + of the ".." name. +*******************************************************************/ + +BOOL mask_match(struct cli_state *cli, const char *string, char *pattern, BOOL is_case_sensitive) +{ + fstring p2, s2; + + if (strcmp(string,"..") == 0) + string = "."; + if (strcmp(pattern,".") == 0) + return False; + + if (is_case_sensitive) + return ms_fnmatch(pattern, string, + cli->transport->negotiate.protocol) == 0; + + fstrcpy(p2, pattern); + fstrcpy(s2, string); + strlower(p2); + strlower(s2); + return ms_fnmatch(p2, s2, cli->transport->negotiate.protocol) == 0; +} + +/**************************************************************************** + Put up a yes/no prompt. +****************************************************************************/ + +BOOL yesno(char *p) +{ + pstring ans; + printf("%s",p); + + if (!fgets(ans,sizeof(ans)-1,stdin)) + return(False); + + if (*ans == 'y' || *ans == 'Y') + return(True); + + return(False); +} + +/******************************************************************* + A readdir wrapper which just returns the file name. + ********************************************************************/ + +const char *readdirname(DIR *p) +{ + SMB_STRUCT_DIRENT *ptr; + char *dname; + + if (!p) + return(NULL); + + ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p); + if (!ptr) + return(NULL); + + dname = ptr->d_name; + +#ifdef NEXT2 + if (telldir(p) < 0) + return(NULL); +#endif + +#ifdef HAVE_BROKEN_READDIR + /* using /usr/ucb/cc is BAD */ + dname = dname - 2; +#endif + + { + static pstring buf; + int len = NAMLEN(ptr); + memcpy(buf, dname, len); + buf[len] = 0; + dname = buf; + } + + return(dname); +} diff --git a/source4/libcli/util/credentials.c b/source4/libcli/util/credentials.c new file mode 100644 index 0000000000..0d521bae8a --- /dev/null +++ b/source4/libcli/util/credentials.c @@ -0,0 +1,215 @@ +/* + Unix SMB/CIFS implementation. + code to manipulate domain credentials + Copyright (C) Andrew Tridgell 1997-1998 + + 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" + +/**************************************************************************** +represent a credential as a string +****************************************************************************/ +char *credstr(const uchar *cred) +{ + static fstring buf; + slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", + cred[0], cred[1], cred[2], cred[3], + cred[4], cred[5], cred[6], cred[7]); + return buf; +} + + +/**************************************************************************** + setup the session key. +Input: 8 byte challenge block + 8 byte server challenge block + 16 byte md4 encrypted password +Output: + 8 byte session key +****************************************************************************/ +void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass, + uchar session_key[8]) +{ + uint32 sum[2]; + unsigned char sum2[8]; + + sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); + sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); + + SIVAL(sum2,0,sum[0]); + SIVAL(sum2,4,sum[1]); + + cred_hash1(session_key, sum2, pass); + + /* debug output */ + DEBUG(4,("cred_session_key\n")); + + DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data))); + DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data))); + DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); + DEBUG(5,(" sess_key : %s\n", credstr(session_key))); +} + + +/**************************************************************************** +create a credential + +Input: + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + 8 byte credential +****************************************************************************/ +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, + DOM_CHAL *cred) +{ + DOM_CHAL time_cred; + + SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time); + SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); + + cred_hash2(cred->data, time_cred.data, session_key); + + /* debug output*/ + DEBUG(4,("cred_create\n")); + + DEBUG(5,(" sess_key : %s\n", credstr(session_key))); + DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); + DEBUG(5,(" timestamp: %x\n" , timestamp.time)); + DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); + DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); +} + + +/**************************************************************************** + check a supplied credential + +Input: + 8 byte received credential + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + returns 1 if computed credential matches received credential + returns 0 otherwise +****************************************************************************/ +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, + UTIME timestamp) +{ + DOM_CHAL cred2; + + cred_create(session_key, stored_cred, timestamp, &cred2); + + /* debug output*/ + DEBUG(4,("cred_assert\n")); + + DEBUG(5,(" challenge : %s\n", credstr(cred->data))); + DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); + + if (memcmp(cred->data, cred2.data, 8) == 0) + { + DEBUG(5, ("credentials check ok\n")); + return True; + } + else + { + DEBUG(5, ("credentials check wrong\n")); + return False; + } +} + + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL clnt_deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); + + /* increment client time by one second */ + new_clnt_time.time = sto_clnt_cred->timestamp.time + 1; + + /* check that the received server credentials are valid */ + if (!cred_assert(&rcv_srv_cred->challenge, sess_key, + &sto_clnt_cred->challenge, new_clnt_time)) + { + return False; + } + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->challenge.data, 0); + new_cred += new_clnt_time.time; + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); + + DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data))); + return True; +} + + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* check that the received client credentials are valid */ + if (!cred_assert(&rcv_clnt_cred->challenge, sess_key, + &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp)) + { + return False; + } + + /* increment client time by one second */ + new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->challenge.data, 0); + new_cred += new_clnt_time.time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); + + /* doesn't matter that server time is 0 */ + rtn_srv_cred->timestamp.time = 0; + + DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time)); + + /* create return credentials for inclusion in the reply */ + cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time, + &rtn_srv_cred->challenge); + + DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); + + return True; +} diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c new file mode 100644 index 0000000000..28bad6109d --- /dev/null +++ b/source4/libcli/util/doserr.c @@ -0,0 +1,91 @@ +/* + * Unix SMB/CIFS implementation. + * DOS error routines + * Copyright (C) Tim Potter 2002. + * + * 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. + */ + +/* DOS error codes. please read doserr.h */ + +#include "includes.h" + +typedef const struct +{ + const char *dos_errstr; + WERROR werror; +} werror_code_struct; + +werror_code_struct dos_errs[] = +{ + { "WERR_OK", WERR_OK }, + { "WERR_BADFILE", WERR_BADFILE }, + { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED }, + { "WERR_BADFID", WERR_BADFID }, + { "WERR_BADFUNC", WERR_BADFUNC }, + { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, + { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, + { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, + { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, + { "WERR_NOT_SUPPORTED", WERR_NOT_SUPPORTED }, + { "WERR_BAD_PASSWORD", WERR_BAD_PASSWORD }, + { "WERR_NOMEM", WERR_NOMEM }, + { "WERR_INVALID_NAME", WERR_INVALID_NAME }, + { "WERR_UNKNOWN_LEVEL", WERR_UNKNOWN_LEVEL }, + { "WERR_OBJECT_PATH_INVALID", WERR_OBJECT_PATH_INVALID }, + { "WERR_NO_MORE_ITEMS", WERR_NO_MORE_ITEMS }, + { "WERR_MORE_DATA", WERR_MORE_DATA }, + { "WERR_UNKNOWN_PRINTER_DRIVER", WERR_UNKNOWN_PRINTER_DRIVER }, + { "WERR_INVALID_PRINTER_NAME", WERR_INVALID_PRINTER_NAME }, + { "WERR_PRINTER_ALREADY_EXISTS", WERR_PRINTER_ALREADY_EXISTS }, + { "WERR_INVALID_DATATYPE", WERR_INVALID_DATATYPE }, + { "WERR_INVALID_ENVIRONMENT", WERR_INVALID_ENVIRONMENT }, + { "WERR_INVALID_FORM_NAME", WERR_INVALID_FORM_NAME }, + { "WERR_INVALID_FORM_SIZE", WERR_INVALID_FORM_SIZE }, + { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, + { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, + { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, + { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, + { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, + { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, + { "WERR_DFS_NO_SUCH_SHARE", WERR_DFS_NO_SUCH_SHARE }, + { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, + { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, + { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, + { NULL, W_ERROR(0) } +}; + +/***************************************************************************** + returns a windows error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +const char *win_errstr(WERROR werror) +{ + static pstring msg; + int idx = 0; + + slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror)); + + while (dos_errs[idx].dos_errstr != NULL) { + if (W_ERROR_V(dos_errs[idx].werror) == + W_ERROR_V(werror)) + return dos_errs[idx].dos_errstr; + idx++; + } + + return msg; +} diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c new file mode 100644 index 0000000000..a257c2d0ea --- /dev/null +++ b/source4/libcli/util/errormap.c @@ -0,0 +1,1546 @@ +/* + * Unix SMB/CIFS implementation. + * error mapping functions + * Copyright (C) Andrew Tridgell 2001 + * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Tim Potter 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" + +/* This map was extracted by the ERRMAPEXTRACT smbtorture command. + The setup was a Samba HEAD (2002-01-03) PDC and an Win2k member + workstation. The PDC was modified (by using the 'name_to_nt_status' + authentication module) to convert the username (in hex) into the + corresponding NTSTATUS error return. + + By opening two nbt sessions to the Win2k workstation, one negotiating + DOS and one negotiating NT errors it was possible to extract the + error mapping. (Because the server only supplies NT errors, the + NT4 workstation had to use its own error tables to convert these + to dos errors). + + Some errors show up as 'squashed' because the NT error connection + got back a different error to the one it sent, so a mapping could + not be determined (a guess has been made in this case, to map the + error as squashed). This is done mainly to prevent users from getting + NT_STATUS_WRONG_PASSWORD and NT_STATUS_NO_SUCH_USER errors (they get + NT_STATUS_LOGON_FAILURE instead. + + -- abartlet (2002-01-03) +*/ + +/* NT status -> dos error map */ +static const struct { + uint8 dos_class; + uint32 dos_code; + NTSTATUS ntstatus; +} ntstatus_to_dos_map[] = { + {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, + {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, + {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, + {ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, + {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, + {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, + {ERRDOS, 87, NT_STATUS_INVALID_CID}, + {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, + {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, + {ERRDOS, 38, NT_STATUS_END_OF_FILE}, + {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, + {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, + {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, + {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, +/** Session setup succeeded. This shouldn't happen...*/ +/** Session setup succeeded. This shouldn't happen...*/ +/** NT error on DOS connection! (NT_STATUS_OK) */ +/* { This NT error code was 'sqashed' + from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK + during the session setup } +*/ +#if 0 + {SUCCESS, 0, NT_STATUS_OK}, +#endif + {ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, + {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, + {ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, + {ERRDOS, 87, NT_STATUS_UNABLE_TO_FREE_VM}, + {ERRDOS, 87, NT_STATUS_UNABLE_TO_DELETE_SECTION}, + {ERRDOS, 2142, NT_STATUS_INVALID_SYSTEM_SERVICE}, + {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, + {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, + {ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, + {ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, +/* { This NT error code was 'sqashed' + from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, + {ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, + {ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, + {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, + {ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, + {ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, + {ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, + {ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, + {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, + {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, + {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, + {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, + {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, + {ERRDOS, 23, NT_STATUS_DATA_ERROR}, + {ERRDOS, 23, NT_STATUS_CRC_ERROR}, + {ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, + {ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, + {ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, + {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, + {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, + {ERRDOS, 87, NT_STATUS_INVALID_PAGE_PROTECTION}, + {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, + {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {ERRDOS, 87, NT_STATUS_PORT_ALREADY_SET}, + {ERRDOS, 87, NT_STATUS_SECTION_NOT_IMAGE}, + {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, + {ERRDOS, 87, NT_STATUS_BAD_WORKING_SET_LIMIT}, + {ERRDOS, 87, NT_STATUS_INCOMPATIBLE_FILE_MAP}, + {ERRDOS, 87, NT_STATUS_SECTION_PROTECTION}, + {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, + {ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, + {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, + {ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, + {ERRDOS, ERRnoaccess, NT_STATUS_DELETE_PENDING}, + {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, + {ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, + {ERRDOS, 2215, NT_STATUS_NO_LOGON_SERVERS}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, + {ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, + {ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, +/* { This NT error code was 'sqashed' + from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, + {ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, +/* { This NT error code was 'sqashed' + from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE + during the session setup } +*/ + {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, + {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, + {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, + {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, + {ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, + {ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, + {ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, + {ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, + {ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, + {ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, + {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, + {ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, + {ERRDOS, 112, NT_STATUS_DISK_FULL}, + {ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, + {ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, + {ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, + {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, + {ERRDOS, ERRres, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, + {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, + {ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, + {ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, + {ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, +/* { This NT error code was 'sqashed' + from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES + during the session setup } +*/ + {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, + {ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, + {ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, + {ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, + {ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, + {ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, + {ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, + {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, + {ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, + {ERRDOS, 87, NT_STATUS_BAD_MASTER_BOOT_RECORD}, + {ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, + {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, + {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, + {ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, + {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, + {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, + {ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, + {ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, + {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, + {ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, + {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, + {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, + {ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, + {ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, + {ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, + {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, + {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, + {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, + {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, + {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, + {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, + {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, + {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, + {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, + {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, + {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, + {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, + {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, + {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, + {ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, + {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, + {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, + {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, + {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, + {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_1}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_2}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_3}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_4}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_5}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_6}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_7}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_8}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_9}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_10}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_11}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_12}, + {ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, + {ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, + {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, + {ERRDOS, 203, NT_STATUS(0xc0000100)}, + {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, + {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, + {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, + {ERRDOS, 2401, NT_STATUS_FILES_OPEN}, + {ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, + {ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, + {ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, + {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, + {ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_PRESENT}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_NOT_EXIST}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_ALREADY_OWNED}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_LID_OWNER}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_COMMAND}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_LID}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_SELECTOR}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, + {ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, + {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, + {ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, + {ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, + {ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, + {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, + {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, + {ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, + {ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, + {ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, + {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, + {ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, + {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, + {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, + {ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, + {ERRDOS, 64, NT_STATUS_LOCAL_DISCONNECT}, + {ERRDOS, 64, NT_STATUS_REMOTE_DISCONNECT}, + {ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, + {ERRDOS, 59, NT_STATUS_LINK_FAILED}, + {ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, + {ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, + {ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, + {ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, + {ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, + {ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, + {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, + {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, + {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, + {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, + {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, + {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, + {ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, + {ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, + {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, + {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, + {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, + {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, + {ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, + {ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, + {ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000016e)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000016f)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc0000170)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc0000171)}, + {ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, + {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc0000179)}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, + {ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, + {ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRDOS, 87, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, + {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, + {ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, + {ERRDOS, 19, NT_STATUS_TOO_LATE}, + {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, +/* { This NT error code was 'sqashed' + from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, + {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, + {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, + {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, + {ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, + {ERRDOS, ERRinvgroup, NT_STATUS_NETLOGON_NOT_STARTED}, + {ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, + {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, + {ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, + {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, + {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, + {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, + {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, +/* { This NT error code was 'sqashed' + from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, + {ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, + {ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, + {ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, + {ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, + {ERRDOS, 64, NT_STATUS_ADDRESS_CLOSED}, + {ERRDOS, 64, NT_STATUS_CONNECTION_DISCONNECTED}, + {ERRDOS, 64, NT_STATUS_CONNECTION_RESET}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_RELEASE}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_MATCH}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_RESPONDED}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_ID}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, + {ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, + {ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, + {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, + {ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, + {ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, + {ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, + {ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, + {ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, + {ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, + {ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, + {ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, + {ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, + {ERRHRD, ERRgeneral, NT_STATUS_RETRY}, + {ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, + {ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, + {ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, + {ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, + {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, + {ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, + {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, + {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, + {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, + {ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, + {ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024a)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024b)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024c)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024d)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024e)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024f)}, + {ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, + {ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, + {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, + {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, + {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, + {ERRSRV, ERRbadtype, NT_STATUS_PATH_NOT_COVERED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, + {ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, + {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, + {ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000025d)}, + {ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, + {ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, + {ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, + {ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, + {ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LINKS}, + {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, + {ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, + {ERRDOS, 21, NT_STATUS(0xc000026e)}, + {ERRDOS, 161, NT_STATUS(0xc0000281)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028a)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028b)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000028c)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028d)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028e)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028f)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc0000290)}, + {ERRDOS, ERRbadfunc, NT_STATUS(0xc000029c)}, +}; + + +/* dos -> nt status error map */ +static const struct { + uint8 dos_class; + uint32 dos_code; + NTSTATUS ntstatus; +} dos_to_ntstatus_map[] = { + {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, + {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, + {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, + {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, + {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, + {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRbaddata, NT_STATUS_DATA_ERROR}, + {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, + {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, + {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, + {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, + {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, + {ERRDOS, 23, NT_STATUS_DATA_ERROR}, + {ERRDOS, 24, NT_STATUS_DATA_ERROR}, + {ERRDOS, 26, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, + {ERRDOS, 28, NT_STATUS(0x8000000e)}, + {ERRDOS, 31, NT_STATUS_UNSUCCESSFUL}, + {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, + {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, + {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, + {ERRDOS, 38, NT_STATUS_END_OF_FILE}, + {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, + {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, + {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, + {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, + {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, + {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, + {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, + {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, + {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, + {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, + {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, + {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD}, + {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, + {ERRDOS, 111, STATUS_MORE_ENTRIES}, + {ERRDOS, 112, NT_STATUS_DISK_FULL}, + {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, + {ERRDOS, 122, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, + {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, + {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, + {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, + {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRDOS, 170, NT_STATUS(0x80000011)}, + {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, + {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, + {ERRDOS, 203, NT_STATUS(0xc0000100)}, + {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, + {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, + {ERRDOS, ERRmoredata, NT_STATUS_MORE_PROCESSING_REQUIRED}, + {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {ERRDOS, 254, NT_STATUS(0x80000013)}, + {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, + {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, + {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRDOS, 275, NT_STATUS_EA_TOO_LARGE}, + {ERRDOS, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, + {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {ERRDOS, 299, NT_STATUS(0x8000000d)}, + {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, + {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, + {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, + {ERRDOS, 535, NT_STATUS_PIPE_CONNECTED}, + {ERRDOS, 536, NT_STATUS_PIPE_LISTENING}, + {ERRDOS, 995, NT_STATUS_CANCELLED}, + {ERRDOS, 997, NT_STATUS(0x00000103)}, + {ERRDOS, 998, NT_STATUS_ACCESS_VIOLATION}, + {ERRDOS, 999, NT_STATUS_IN_PAGE_ERROR}, + {ERRDOS, 1001, NT_STATUS_BAD_INITIAL_STACK}, + {ERRDOS, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRDOS, 1006, NT_STATUS_FILE_INVALID}, + {ERRDOS, 1007, NT_STATUS_FULLSCREEN_MODE}, + {ERRDOS, 1008, NT_STATUS_NO_TOKEN}, + {ERRDOS, 1009, NT_STATUS_REGISTRY_CORRUPT}, + {ERRDOS, 1016, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRDOS, 1017, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRDOS, 1018, NT_STATUS_KEY_DELETED}, + {ERRDOS, 1019, NT_STATUS_NO_LOG_SPACE}, + {ERRDOS, 1020, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRDOS, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRDOS, 1022, NT_STATUS(0x0000010c)}, + {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, + {ERRSRV, ERRbadtype, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRSRV, ERRaccess, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRSRV, ERRinvnid, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRSRV, ERRinvnetname, NT_STATUS_BAD_NETWORK_NAME}, + {ERRSRV, ERRinvdevice, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRSRV, ERRqfull, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRSRV, ERRqtoobig, NT_STATUS_NO_SPOOL_SPACE}, + {ERRSRV, ERRinvpfid, NT_STATUS_PRINT_CANCELLED}, + {ERRSRV, ERRsmbcmd, NT_STATUS_NOT_IMPLEMENTED}, + {ERRSRV, ERRbadpermits, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRSRV, ERRpaused, NT_STATUS_SHARING_PAUSED}, + {ERRSRV, ERRmsgoff, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRSRV, ERRnoroom, NT_STATUS_DISK_FULL}, + {ERRSRV, ERRnoresource, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRSRV, ERRtoomanyuids, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRSRV, 123, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRSRV, 206, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRHRD, 1, NT_STATUS_NOT_IMPLEMENTED}, + {ERRHRD, 2, NT_STATUS_NO_SUCH_DEVICE}, + {ERRHRD, 3, NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {ERRHRD, 4, NT_STATUS_TOO_MANY_OPENED_FILES}, + {ERRHRD, 5, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRHRD, 6, NT_STATUS_INVALID_HANDLE}, + {ERRHRD, 8, NT_STATUS_INSUFFICIENT_RESOURCES}, + {ERRHRD, 12, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRHRD, 13, NT_STATUS_DATA_ERROR}, + {ERRHRD, 14, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRHRD, 16, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRHRD, 17, NT_STATUS_NOT_SAME_DEVICE}, + {ERRHRD, 18, NT_STATUS(0x80000006)}, + {ERRHRD, ERRnowrite, NT_STATUS_MEDIA_WRITE_PROTECTED}, + {ERRHRD, ERRnotready, NT_STATUS_NO_MEDIA_IN_DEVICE}, + {ERRHRD, ERRbadcmd, NT_STATUS_INVALID_DEVICE_STATE}, + {ERRHRD, ERRdata, NT_STATUS_DATA_ERROR}, + {ERRHRD, ERRbadreq, NT_STATUS_DATA_ERROR}, + {ERRHRD, ERRbadmedia, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRHRD, ERRbadsector, NT_STATUS_NONEXISTENT_SECTOR}, + {ERRHRD, ERRnopaper, NT_STATUS(0x8000000e)}, + {ERRHRD, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, + {ERRHRD, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, + {ERRHRD, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, + {ERRHRD, ERRwrongdisk, NT_STATUS_WRONG_VOLUME}, + {ERRHRD, 38, NT_STATUS_END_OF_FILE}, + {ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL}, + {ERRHRD, 50, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {ERRHRD, 51, NT_STATUS_REMOTE_NOT_LISTENING}, + {ERRHRD, 52, NT_STATUS_DUPLICATE_NAME}, + {ERRHRD, 53, NT_STATUS_BAD_NETWORK_PATH}, + {ERRHRD, 54, NT_STATUS_NETWORK_BUSY}, + {ERRHRD, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {ERRHRD, 56, NT_STATUS_TOO_MANY_COMMANDS}, + {ERRHRD, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {ERRHRD, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, + {ERRHRD, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {ERRHRD, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, + {ERRHRD, 61, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRHRD, 62, NT_STATUS_NO_SPOOL_SPACE}, + {ERRHRD, 63, NT_STATUS_PRINT_CANCELLED}, + {ERRHRD, 64, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRHRD, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRHRD, 66, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRHRD, 67, NT_STATUS_BAD_NETWORK_NAME}, + {ERRHRD, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {ERRHRD, 69, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRHRD, 70, NT_STATUS_SHARING_PAUSED}, + {ERRHRD, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRHRD, 72, NT_STATUS_REDIRECTOR_PAUSED}, + {ERRHRD, 80, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRHRD, 86, NT_STATUS_WRONG_PASSWORD}, + {ERRHRD, 87, NT_STATUS_INVALID_INFO_CLASS}, + {ERRHRD, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRHRD, 109, NT_STATUS_PIPE_BROKEN}, + {ERRHRD, 111, STATUS_MORE_ENTRIES}, + {ERRHRD, 112, NT_STATUS_DISK_FULL}, + {ERRHRD, 121, NT_STATUS_IO_TIMEOUT}, + {ERRHRD, 122, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRHRD, 123, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRHRD, 124, NT_STATUS_INVALID_LEVEL}, + {ERRHRD, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRHRD, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, + {ERRHRD, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRHRD, 154, NT_STATUS_INVALID_VOLUME_LABEL}, + {ERRHRD, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {ERRHRD, 158, NT_STATUS_NOT_LOCKED}, + {ERRHRD, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRHRD, 170, NT_STATUS(0x80000011)}, + {ERRHRD, 182, NT_STATUS_ORDINAL_NOT_FOUND}, + {ERRHRD, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRHRD, 193, NT_STATUS_BAD_INITIAL_PC}, + {ERRHRD, 203, NT_STATUS(0xc0000100)}, + {ERRHRD, 206, NT_STATUS_NAME_TOO_LONG}, + {ERRHRD, 230, NT_STATUS_INVALID_INFO_CLASS}, + {ERRHRD, 231, NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {ERRHRD, 232, NT_STATUS_PIPE_CLOSING}, + {ERRHRD, 233, NT_STATUS_PIPE_DISCONNECTED}, + {ERRHRD, 234, STATUS_MORE_ENTRIES}, + {ERRHRD, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {ERRHRD, 254, NT_STATUS(0x80000013)}, + {ERRHRD, 255, NT_STATUS_EA_TOO_LARGE}, + {ERRHRD, 259, NT_STATUS_GUIDS_EXHAUSTED}, + {ERRHRD, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRHRD, 275, NT_STATUS_EA_TOO_LARGE}, + {ERRHRD, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRHRD, 288, NT_STATUS_MUTANT_NOT_OWNED}, + {ERRHRD, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {ERRHRD, 299, NT_STATUS(0x8000000d)}, + {ERRHRD, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, + {ERRHRD, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {ERRHRD, 487, NT_STATUS_CONFLICTING_ADDRESSES}, + {ERRHRD, 534, NT_STATUS_INTEGER_OVERFLOW}, + {ERRHRD, 535, NT_STATUS_PIPE_CONNECTED}, + {ERRHRD, 536, NT_STATUS_PIPE_LISTENING}, + {ERRHRD, 995, NT_STATUS_CANCELLED}, + {ERRHRD, 997, NT_STATUS(0x00000103)}, + {ERRHRD, 998, NT_STATUS_ACCESS_VIOLATION}, + {ERRHRD, 999, NT_STATUS_IN_PAGE_ERROR}, + {ERRHRD, 1001, NT_STATUS_BAD_INITIAL_STACK}, + {ERRHRD, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRHRD, 1006, NT_STATUS_FILE_INVALID}, + {ERRHRD, 1007, NT_STATUS_FULLSCREEN_MODE}, + {ERRHRD, 1008, NT_STATUS_NO_TOKEN}, + {ERRHRD, 1009, NT_STATUS_REGISTRY_CORRUPT}, + {ERRHRD, 1016, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRHRD, 1017, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRHRD, 1018, NT_STATUS_KEY_DELETED}, + {ERRHRD, 1019, NT_STATUS_NO_LOG_SPACE}, + {ERRHRD, 1020, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRHRD, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRHRD, 1022, NT_STATUS(0x0000010c)}, +}; + +/* errmap NTSTATUS->Win32 */ +static const struct { + NTSTATUS ntstatus; + WERROR werror; +} ntstatus_to_werror_map[] = { + {NT_STATUS(0x103), W_ERROR(0x3e5)}, + {NT_STATUS(0x105), W_ERROR(0xea)}, + {NT_STATUS(0x106), W_ERROR(0x514)}, + {NT_STATUS(0x107), W_ERROR(0x515)}, + {NT_STATUS(0x10c), W_ERROR(0x3fe)}, + {NT_STATUS(0x10d), W_ERROR(0x516)}, + {NT_STATUS(0x121), W_ERROR(0x2009)}, + {NT_STATUS(0xc0000001), W_ERROR(0x1f)}, + {NT_STATUS(0xc0000002), W_ERROR(0x1)}, + {NT_STATUS(0xc0000003), W_ERROR(0x57)}, + {NT_STATUS(0xc0000004), W_ERROR(0x18)}, + {NT_STATUS(0xc0000005), W_ERROR(0x3e6)}, + {NT_STATUS(0xc0000006), W_ERROR(0x3e7)}, + {NT_STATUS(0xc0000007), W_ERROR(0x5ae)}, + {NT_STATUS(0xc0000008), W_ERROR(0x6)}, + {NT_STATUS(0xc0000009), W_ERROR(0x3e9)}, + {NT_STATUS(0xc000000a), W_ERROR(0xc1)}, + {NT_STATUS(0xc000000b), W_ERROR(0x57)}, + {NT_STATUS(0xc000000d), W_ERROR(0x57)}, + {NT_STATUS(0xc000000e), W_ERROR(0x2)}, + {NT_STATUS(0xc000000f), W_ERROR(0x2)}, + {NT_STATUS(0xc0000010), W_ERROR(0x1)}, + {NT_STATUS(0xc0000011), W_ERROR(0x26)}, + {NT_STATUS(0xc0000012), W_ERROR(0x22)}, + {NT_STATUS(0xc0000013), W_ERROR(0x15)}, + {NT_STATUS(0xc0000014), W_ERROR(0x6f9)}, + {NT_STATUS(0xc0000015), W_ERROR(0x1b)}, + {NT_STATUS(0xc0000016), W_ERROR(0xea)}, + {NT_STATUS(0xc0000017), W_ERROR(0x8)}, + {NT_STATUS(0xc0000018), W_ERROR(0x1e7)}, + {NT_STATUS(0xc0000019), W_ERROR(0x1e7)}, + {NT_STATUS(0xc000001a), W_ERROR(0x57)}, + {NT_STATUS(0xc000001b), W_ERROR(0x57)}, + {NT_STATUS(0xc000001c), W_ERROR(0x1)}, + {NT_STATUS(0xc000001d), W_ERROR(0xc000001d)}, + {NT_STATUS(0xc000001e), W_ERROR(0x5)}, + {NT_STATUS(0xc000001f), W_ERROR(0x5)}, + {NT_STATUS(0xc0000020), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000021), W_ERROR(0x5)}, + {NT_STATUS(0xc0000022), W_ERROR(0x5)}, + {NT_STATUS(0xc0000023), W_ERROR(0x7a)}, + {NT_STATUS(0xc0000024), W_ERROR(0x6)}, + {NT_STATUS(0xc0000025), W_ERROR(0xc0000025)}, + {NT_STATUS(0xc0000026), W_ERROR(0xc0000026)}, + {NT_STATUS(0xc000002a), W_ERROR(0x9e)}, + {NT_STATUS(0xc000002b), W_ERROR(0xc000002b)}, + {NT_STATUS(0xc000002c), W_ERROR(0x1e7)}, + {NT_STATUS(0xc000002d), W_ERROR(0x1e7)}, + {NT_STATUS(0xc0000030), W_ERROR(0x57)}, + {NT_STATUS(0xc0000032), W_ERROR(0x571)}, + {NT_STATUS(0xc0000033), W_ERROR(0x7b)}, + {NT_STATUS(0xc0000034), W_ERROR(0x2)}, + {NT_STATUS(0xc0000035), W_ERROR(0xb7)}, + {NT_STATUS(0xc0000037), W_ERROR(0x6)}, + {NT_STATUS(0xc0000039), W_ERROR(0xa1)}, + {NT_STATUS(0xc000003a), W_ERROR(0x3)}, + {NT_STATUS(0xc000003b), W_ERROR(0xa1)}, + {NT_STATUS(0xc000003c), W_ERROR(0x45d)}, + {NT_STATUS(0xc000003d), W_ERROR(0x45d)}, + {NT_STATUS(0xc000003e), W_ERROR(0x17)}, + {NT_STATUS(0xc000003f), W_ERROR(0x17)}, + {NT_STATUS(0xc0000040), W_ERROR(0x8)}, + {NT_STATUS(0xc0000041), W_ERROR(0x5)}, + {NT_STATUS(0xc0000042), W_ERROR(0x6)}, + {NT_STATUS(0xc0000043), W_ERROR(0x20)}, + {NT_STATUS(0xc0000044), W_ERROR(0x718)}, + {NT_STATUS(0xc0000045), W_ERROR(0x57)}, + {NT_STATUS(0xc0000046), W_ERROR(0x120)}, + {NT_STATUS(0xc0000047), W_ERROR(0x12a)}, + {NT_STATUS(0xc0000048), W_ERROR(0x57)}, + {NT_STATUS(0xc0000049), W_ERROR(0x57)}, + {NT_STATUS(0xc000004a), W_ERROR(0x9c)}, + {NT_STATUS(0xc000004b), W_ERROR(0x5)}, + {NT_STATUS(0xc000004c), W_ERROR(0x57)}, + {NT_STATUS(0xc000004d), W_ERROR(0x57)}, + {NT_STATUS(0xc000004e), W_ERROR(0x57)}, + {NT_STATUS(0xc000004f), W_ERROR(0x11a)}, + {NT_STATUS(0xc0000050), W_ERROR(0xff)}, + {NT_STATUS(0xc0000051), W_ERROR(0x570)}, + {NT_STATUS(0xc0000052), W_ERROR(0x570)}, + {NT_STATUS(0xc0000053), W_ERROR(0x570)}, + {NT_STATUS(0xc0000054), W_ERROR(0x21)}, + {NT_STATUS(0xc0000055), W_ERROR(0x21)}, + {NT_STATUS(0xc0000056), W_ERROR(0x5)}, + {NT_STATUS(0xc0000057), W_ERROR(0x32)}, + {NT_STATUS(0xc0000058), W_ERROR(0x519)}, + {NT_STATUS(0xc0000059), W_ERROR(0x51a)}, + {NT_STATUS(0xc000005a), W_ERROR(0x51b)}, + {NT_STATUS(0xc000005b), W_ERROR(0x51c)}, + {NT_STATUS(0xc000005c), W_ERROR(0x51d)}, + {NT_STATUS(0xc000005d), W_ERROR(0x51e)}, + {NT_STATUS(0xc000005e), W_ERROR(0x51f)}, + {NT_STATUS(0xc000005f), W_ERROR(0x520)}, + {NT_STATUS(0xc0000060), W_ERROR(0x521)}, + {NT_STATUS(0xc0000061), W_ERROR(0x522)}, + {NT_STATUS(0xc0000062), W_ERROR(0x523)}, + {NT_STATUS(0xc0000063), W_ERROR(0x524)}, + {NT_STATUS(0xc0000064), W_ERROR(0x525)}, + {NT_STATUS(0xc0000065), W_ERROR(0x526)}, + {NT_STATUS(0xc0000066), W_ERROR(0x527)}, + {NT_STATUS(0xc0000067), W_ERROR(0x528)}, + {NT_STATUS(0xc0000068), W_ERROR(0x529)}, + {NT_STATUS(0xc0000069), W_ERROR(0x52a)}, + {NT_STATUS(0xc000006a), W_ERROR(0x56)}, + {NT_STATUS(0xc000006b), W_ERROR(0x52c)}, + {NT_STATUS(0xc000006c), W_ERROR(0x52d)}, + {NT_STATUS(0xc000006d), W_ERROR(0x52e)}, + {NT_STATUS(0xc000006e), W_ERROR(0x52f)}, + {NT_STATUS(0xc000006f), W_ERROR(0x530)}, + {NT_STATUS(0xc0000070), W_ERROR(0x531)}, + {NT_STATUS(0xc0000071), W_ERROR(0x532)}, + {NT_STATUS(0xc0000072), W_ERROR(0x533)}, + {NT_STATUS(0xc0000073), W_ERROR(0x534)}, + {NT_STATUS(0xc0000074), W_ERROR(0x535)}, + {NT_STATUS(0xc0000075), W_ERROR(0x536)}, + {NT_STATUS(0xc0000076), W_ERROR(0x537)}, + {NT_STATUS(0xc0000077), W_ERROR(0x538)}, + {NT_STATUS(0xc0000078), W_ERROR(0x539)}, + {NT_STATUS(0xc0000079), W_ERROR(0x53a)}, + {NT_STATUS(0xc000007a), W_ERROR(0x7f)}, + {NT_STATUS(0xc000007b), W_ERROR(0xc1)}, + {NT_STATUS(0xc000007c), W_ERROR(0x3f0)}, + {NT_STATUS(0xc000007d), W_ERROR(0x53c)}, + {NT_STATUS(0xc000007e), W_ERROR(0x9e)}, + {NT_STATUS(0xc000007f), W_ERROR(0x70)}, + {NT_STATUS(0xc0000080), W_ERROR(0x53d)}, + {NT_STATUS(0xc0000081), W_ERROR(0x53e)}, + {NT_STATUS(0xc0000082), W_ERROR(0x44)}, + {NT_STATUS(0xc0000083), W_ERROR(0x103)}, + {NT_STATUS(0xc0000084), W_ERROR(0x53f)}, + {NT_STATUS(0xc0000085), W_ERROR(0x103)}, + {NT_STATUS(0xc0000086), W_ERROR(0x9a)}, + {NT_STATUS(0xc0000087), W_ERROR(0xe)}, + {NT_STATUS(0xc0000088), W_ERROR(0x1e7)}, + {NT_STATUS(0xc0000089), W_ERROR(0x714)}, + {NT_STATUS(0xc000008a), W_ERROR(0x715)}, + {NT_STATUS(0xc000008b), W_ERROR(0x716)}, + {NT_STATUS(0xc000008c), W_ERROR(0xc000008c)}, + {NT_STATUS(0xc000008d), W_ERROR(0xc000008d)}, + {NT_STATUS(0xc000008e), W_ERROR(0xc000008e)}, + {NT_STATUS(0xc000008f), W_ERROR(0xc000008f)}, + {NT_STATUS(0xc0000090), W_ERROR(0xc0000090)}, + {NT_STATUS(0xc0000091), W_ERROR(0xc0000091)}, + {NT_STATUS(0xc0000092), W_ERROR(0xc0000092)}, + {NT_STATUS(0xc0000093), W_ERROR(0xc0000093)}, + {NT_STATUS(0xc0000094), W_ERROR(0xc0000094)}, + {NT_STATUS(0xc0000095), W_ERROR(0x216)}, + {NT_STATUS(0xc0000096), W_ERROR(0xc0000096)}, + {NT_STATUS(0xc0000097), W_ERROR(0x8)}, + {NT_STATUS(0xc0000098), W_ERROR(0x3ee)}, + {NT_STATUS(0xc0000099), W_ERROR(0x540)}, + {NT_STATUS(0xc000009a), W_ERROR(0x5aa)}, + {NT_STATUS(0xc000009b), W_ERROR(0x3)}, + {NT_STATUS(0xc000009c), W_ERROR(0x17)}, + {NT_STATUS(0xc000009d), W_ERROR(0x48f)}, + {NT_STATUS(0xc000009e), W_ERROR(0x15)}, + {NT_STATUS(0xc000009f), W_ERROR(0x1e7)}, + {NT_STATUS(0xc00000a0), W_ERROR(0x1e7)}, + {NT_STATUS(0xc00000a1), W_ERROR(0x5ad)}, + {NT_STATUS(0xc00000a2), W_ERROR(0x13)}, + {NT_STATUS(0xc00000a3), W_ERROR(0x15)}, + {NT_STATUS(0xc00000a4), W_ERROR(0x541)}, + {NT_STATUS(0xc00000a5), W_ERROR(0x542)}, + {NT_STATUS(0xc00000a6), W_ERROR(0x543)}, + {NT_STATUS(0xc00000a7), W_ERROR(0x544)}, + {NT_STATUS(0xc00000a8), W_ERROR(0x545)}, + {NT_STATUS(0xc00000a9), W_ERROR(0x57)}, + {NT_STATUS(0xc00000ab), W_ERROR(0xe7)}, + {NT_STATUS(0xc00000ac), W_ERROR(0xe7)}, + {NT_STATUS(0xc00000ad), W_ERROR(0xe6)}, + {NT_STATUS(0xc00000ae), W_ERROR(0xe7)}, + {NT_STATUS(0xc00000af), W_ERROR(0x1)}, + {NT_STATUS(0xc00000b0), W_ERROR(0xe9)}, + {NT_STATUS(0xc00000b1), W_ERROR(0xe8)}, + {NT_STATUS(0xc00000b2), W_ERROR(0x217)}, + {NT_STATUS(0xc00000b3), W_ERROR(0x218)}, + {NT_STATUS(0xc00000b4), W_ERROR(0xe6)}, + {NT_STATUS(0xc00000b5), W_ERROR(0x79)}, + {NT_STATUS(0xc00000b6), W_ERROR(0x26)}, + {NT_STATUS(0xc00000ba), W_ERROR(0x5)}, + {NT_STATUS(0xc00000bb), W_ERROR(0x32)}, + {NT_STATUS(0xc00000bc), W_ERROR(0x33)}, + {NT_STATUS(0xc00000bd), W_ERROR(0x34)}, + {NT_STATUS(0xc00000be), W_ERROR(0x35)}, + {NT_STATUS(0xc00000bf), W_ERROR(0x36)}, + {NT_STATUS(0xc00000c0), W_ERROR(0x37)}, + {NT_STATUS(0xc00000c1), W_ERROR(0x38)}, + {NT_STATUS(0xc00000c2), W_ERROR(0x39)}, + {NT_STATUS(0xc00000c3), W_ERROR(0x3a)}, + {NT_STATUS(0xc00000c4), W_ERROR(0x3b)}, + {NT_STATUS(0xc00000c5), W_ERROR(0x3c)}, + {NT_STATUS(0xc00000c6), W_ERROR(0x3d)}, + {NT_STATUS(0xc00000c7), W_ERROR(0x3e)}, + {NT_STATUS(0xc00000c8), W_ERROR(0x3f)}, + {NT_STATUS(0xc00000c9), W_ERROR(0x40)}, + {NT_STATUS(0xc00000ca), W_ERROR(0x41)}, + {NT_STATUS(0xc00000cb), W_ERROR(0x42)}, + {NT_STATUS(0xc00000cc), W_ERROR(0x43)}, + {NT_STATUS(0xc00000cd), W_ERROR(0x44)}, + {NT_STATUS(0xc00000ce), W_ERROR(0x45)}, + {NT_STATUS(0xc00000cf), W_ERROR(0x46)}, + {NT_STATUS(0xc00000d0), W_ERROR(0x47)}, + {NT_STATUS(0xc00000d1), W_ERROR(0x48)}, + {NT_STATUS(0xc00000d2), W_ERROR(0x58)}, + {NT_STATUS(0xc00000d4), W_ERROR(0x11)}, + {NT_STATUS(0xc00000d5), W_ERROR(0x5)}, + {NT_STATUS(0xc00000d6), W_ERROR(0xf0)}, + {NT_STATUS(0xc00000d7), W_ERROR(0x546)}, + {NT_STATUS(0xc00000d9), W_ERROR(0xe8)}, + {NT_STATUS(0xc00000da), W_ERROR(0x547)}, + {NT_STATUS(0xc00000dc), W_ERROR(0x548)}, + {NT_STATUS(0xc00000dd), W_ERROR(0x549)}, + {NT_STATUS(0xc00000de), W_ERROR(0x54a)}, + {NT_STATUS(0xc00000df), W_ERROR(0x54b)}, + {NT_STATUS(0xc00000e0), W_ERROR(0x54c)}, + {NT_STATUS(0xc00000e1), W_ERROR(0x54d)}, + {NT_STATUS(0xc00000e2), W_ERROR(0x12c)}, + {NT_STATUS(0xc00000e3), W_ERROR(0x12d)}, + {NT_STATUS(0xc00000e4), W_ERROR(0x54e)}, + {NT_STATUS(0xc00000e5), W_ERROR(0x54f)}, + {NT_STATUS(0xc00000e6), W_ERROR(0x550)}, + {NT_STATUS(0xc00000e7), W_ERROR(0x551)}, + {NT_STATUS(0xc00000e8), W_ERROR(0x6f8)}, + {NT_STATUS(0xc00000ed), W_ERROR(0x552)}, + {NT_STATUS(0xc00000ee), W_ERROR(0x553)}, + {NT_STATUS(0xc00000ef), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f0), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f1), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f2), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f3), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f4), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f5), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f6), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f7), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f8), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f9), W_ERROR(0x57)}, + {NT_STATUS(0xc00000fa), W_ERROR(0x57)}, + {NT_STATUS(0xc00000fb), W_ERROR(0x3)}, + {NT_STATUS(0xc00000fd), W_ERROR(0x3e9)}, + {NT_STATUS(0xc00000fe), W_ERROR(0x554)}, + {NT_STATUS(0xc0000100), W_ERROR(0xcb)}, + {NT_STATUS(0xc0000101), W_ERROR(0x91)}, + {NT_STATUS(0xc0000102), W_ERROR(0x570)}, + {NT_STATUS(0xc0000103), W_ERROR(0x10b)}, + {NT_STATUS(0xc0000104), W_ERROR(0x555)}, + {NT_STATUS(0xc0000105), W_ERROR(0x556)}, + {NT_STATUS(0xc0000106), W_ERROR(0xce)}, + {NT_STATUS(0xc0000107), W_ERROR(0x961)}, + {NT_STATUS(0xc0000108), W_ERROR(0x964)}, + {NT_STATUS(0xc000010a), W_ERROR(0x5)}, + {NT_STATUS(0xc000010b), W_ERROR(0x557)}, + {NT_STATUS(0xc000010d), W_ERROR(0x558)}, + {NT_STATUS(0xc000010e), W_ERROR(0x420)}, + {NT_STATUS(0xc0000117), W_ERROR(0x5a4)}, + {NT_STATUS(0xc000011b), W_ERROR(0xc1)}, + {NT_STATUS(0xc000011c), W_ERROR(0x559)}, + {NT_STATUS(0xc000011d), W_ERROR(0x55a)}, + {NT_STATUS(0xc000011e), W_ERROR(0x3ee)}, + {NT_STATUS(0xc000011f), W_ERROR(0x4)}, + {NT_STATUS(0xc0000120), W_ERROR(0x3e3)}, + {NT_STATUS(0xc0000121), W_ERROR(0x5)}, + {NT_STATUS(0xc0000122), W_ERROR(0x4ba)}, + {NT_STATUS(0xc0000123), W_ERROR(0x5)}, + {NT_STATUS(0xc0000124), W_ERROR(0x55b)}, + {NT_STATUS(0xc0000125), W_ERROR(0x55c)}, + {NT_STATUS(0xc0000126), W_ERROR(0x55d)}, + {NT_STATUS(0xc0000127), W_ERROR(0x55e)}, + {NT_STATUS(0xc0000128), W_ERROR(0x6)}, + {NT_STATUS(0xc000012b), W_ERROR(0x55f)}, + {NT_STATUS(0xc000012d), W_ERROR(0x5af)}, + {NT_STATUS(0xc000012e), W_ERROR(0xc1)}, + {NT_STATUS(0xc000012f), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000130), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000131), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000133), W_ERROR(0x576)}, + {NT_STATUS(0xc0000135), W_ERROR(0x7e)}, + {NT_STATUS(0xc0000138), W_ERROR(0xb6)}, + {NT_STATUS(0xc0000139), W_ERROR(0x7f)}, + {NT_STATUS(0xc000013b), W_ERROR(0x40)}, + {NT_STATUS(0xc000013c), W_ERROR(0x40)}, + {NT_STATUS(0xc000013d), W_ERROR(0x33)}, + {NT_STATUS(0xc000013e), W_ERROR(0x3b)}, + {NT_STATUS(0xc000013f), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000140), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000141), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000142), W_ERROR(0x45a)}, + {NT_STATUS(0xc0000148), W_ERROR(0x7c)}, + {NT_STATUS(0xc0000149), W_ERROR(0x56)}, + {NT_STATUS(0xc000014b), W_ERROR(0x6d)}, + {NT_STATUS(0xc000014c), W_ERROR(0x3f1)}, + {NT_STATUS(0xc000014d), W_ERROR(0x3f8)}, + {NT_STATUS(0xc000014f), W_ERROR(0x3ed)}, + {NT_STATUS(0xc0000150), W_ERROR(0x45e)}, + {NT_STATUS(0xc0000151), W_ERROR(0x560)}, + {NT_STATUS(0xc0000152), W_ERROR(0x561)}, + {NT_STATUS(0xc0000153), W_ERROR(0x562)}, + {NT_STATUS(0xc0000154), W_ERROR(0x563)}, + {NT_STATUS(0xc0000155), W_ERROR(0x564)}, + {NT_STATUS(0xc0000156), W_ERROR(0x565)}, + {NT_STATUS(0xc0000157), W_ERROR(0x566)}, + {NT_STATUS(0xc0000158), W_ERROR(0x567)}, + {NT_STATUS(0xc0000159), W_ERROR(0x3ef)}, + {NT_STATUS(0xc000015a), W_ERROR(0x568)}, + {NT_STATUS(0xc000015b), W_ERROR(0x569)}, + {NT_STATUS(0xc000015c), W_ERROR(0x3f9)}, + {NT_STATUS(0xc000015d), W_ERROR(0x56a)}, + {NT_STATUS(0xc000015f), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000162), W_ERROR(0x459)}, + {NT_STATUS(0xc0000165), W_ERROR(0x462)}, + {NT_STATUS(0xc0000166), W_ERROR(0x463)}, + {NT_STATUS(0xc0000167), W_ERROR(0x464)}, + {NT_STATUS(0xc0000168), W_ERROR(0x465)}, + {NT_STATUS(0xc0000169), W_ERROR(0x466)}, + {NT_STATUS(0xc000016a), W_ERROR(0x467)}, + {NT_STATUS(0xc000016b), W_ERROR(0x468)}, + {NT_STATUS(0xc000016c), W_ERROR(0x45f)}, + {NT_STATUS(0xc000016d), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000172), W_ERROR(0x451)}, + {NT_STATUS(0xc0000173), W_ERROR(0x452)}, + {NT_STATUS(0xc0000174), W_ERROR(0x453)}, + {NT_STATUS(0xc0000175), W_ERROR(0x454)}, + {NT_STATUS(0xc0000176), W_ERROR(0x455)}, + {NT_STATUS(0xc0000177), W_ERROR(0x469)}, + {NT_STATUS(0xc0000178), W_ERROR(0x458)}, + {NT_STATUS(0xc000017a), W_ERROR(0x56b)}, + {NT_STATUS(0xc000017b), W_ERROR(0x56c)}, + {NT_STATUS(0xc000017c), W_ERROR(0x3fa)}, + {NT_STATUS(0xc000017d), W_ERROR(0x3fb)}, + {NT_STATUS(0xc000017e), W_ERROR(0x56d)}, + {NT_STATUS(0xc000017f), W_ERROR(0x56e)}, + {NT_STATUS(0xc0000180), W_ERROR(0x3fc)}, + {NT_STATUS(0xc0000181), W_ERROR(0x3fd)}, + {NT_STATUS(0xc0000182), W_ERROR(0x57)}, + {NT_STATUS(0xc0000183), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000184), W_ERROR(0x16)}, + {NT_STATUS(0xc0000185), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000186), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000188), W_ERROR(0x5de)}, + {NT_STATUS(0xc0000189), W_ERROR(0x13)}, + {NT_STATUS(0xc000018a), W_ERROR(0x6fa)}, + {NT_STATUS(0xc000018b), W_ERROR(0x6fb)}, + {NT_STATUS(0xc000018c), W_ERROR(0x6fc)}, + {NT_STATUS(0xc000018d), W_ERROR(0x6fd)}, + {NT_STATUS(0xc000018e), W_ERROR(0x5dc)}, + {NT_STATUS(0xc000018f), W_ERROR(0x5dd)}, + {NT_STATUS(0xc0000190), W_ERROR(0x6fe)}, + {NT_STATUS(0xc0000192), W_ERROR(0x700)}, + {NT_STATUS(0xc0000193), W_ERROR(0x701)}, + {NT_STATUS(0xc0000194), W_ERROR(0x46b)}, + {NT_STATUS(0xc0000195), W_ERROR(0x4c3)}, + {NT_STATUS(0xc0000196), W_ERROR(0x4c4)}, + {NT_STATUS(0xc0000197), W_ERROR(0x5df)}, + {NT_STATUS(0xc0000198), W_ERROR(0x70f)}, + {NT_STATUS(0xc0000199), W_ERROR(0x710)}, + {NT_STATUS(0xc000019a), W_ERROR(0x711)}, + {NT_STATUS(0xc000019b), W_ERROR(0x712)}, + {NT_STATUS(0xc0000202), W_ERROR(0x572)}, + {NT_STATUS(0xc0000203), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000204), W_ERROR(0x717)}, + {NT_STATUS(0xc0000205), W_ERROR(0x46a)}, + {NT_STATUS(0xc0000206), W_ERROR(0x6f8)}, + {NT_STATUS(0xc0000207), W_ERROR(0x4be)}, + {NT_STATUS(0xc0000208), W_ERROR(0x4be)}, + {NT_STATUS(0xc0000209), W_ERROR(0x44)}, + {NT_STATUS(0xc000020a), W_ERROR(0x34)}, + {NT_STATUS(0xc000020b), W_ERROR(0x40)}, + {NT_STATUS(0xc000020c), W_ERROR(0x40)}, + {NT_STATUS(0xc000020d), W_ERROR(0x40)}, + {NT_STATUS(0xc000020e), W_ERROR(0x44)}, + {NT_STATUS(0xc000020f), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000210), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000211), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000212), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000213), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000214), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000215), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000216), W_ERROR(0x32)}, + {NT_STATUS(0xc0000217), W_ERROR(0x32)}, + {NT_STATUS(0xc000021c), W_ERROR(0x17e6)}, + {NT_STATUS(0xc0000220), W_ERROR(0x46c)}, + {NT_STATUS(0xc0000221), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000224), W_ERROR(0x773)}, + {NT_STATUS(0xc0000225), W_ERROR(0x490)}, + {NT_STATUS(0xc000022a), W_ERROR(0xc000022a)}, + {NT_STATUS(0xc000022b), W_ERROR(0xc000022b)}, + {NT_STATUS(0xc000022d), W_ERROR(0x4d5)}, + {NT_STATUS(0xc0000230), W_ERROR(0x492)}, + {NT_STATUS(0xc0000233), W_ERROR(0x774)}, + {NT_STATUS(0xc0000234), W_ERROR(0x775)}, + {NT_STATUS(0xc0000235), W_ERROR(0x6)}, + {NT_STATUS(0xc0000236), W_ERROR(0x4c9)}, + {NT_STATUS(0xc0000237), W_ERROR(0x4ca)}, + {NT_STATUS(0xc0000238), W_ERROR(0x4cb)}, + {NT_STATUS(0xc0000239), W_ERROR(0x4cc)}, + {NT_STATUS(0xc000023a), W_ERROR(0x4cd)}, + {NT_STATUS(0xc000023b), W_ERROR(0x4ce)}, + {NT_STATUS(0xc000023c), W_ERROR(0x4cf)}, + {NT_STATUS(0xc000023d), W_ERROR(0x4d0)}, + {NT_STATUS(0xc000023e), W_ERROR(0x4d1)}, + {NT_STATUS(0xc000023f), W_ERROR(0x4d2)}, + {NT_STATUS(0xc0000240), W_ERROR(0x4d3)}, + {NT_STATUS(0xc0000241), W_ERROR(0x4d4)}, + {NT_STATUS(0xc0000243), W_ERROR(0x4c8)}, + {NT_STATUS(0xc0000246), W_ERROR(0x4d6)}, + {NT_STATUS(0xc0000247), W_ERROR(0x4d7)}, + {NT_STATUS(0xc0000248), W_ERROR(0x4d8)}, + {NT_STATUS(0xc0000249), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000253), W_ERROR(0x54f)}, + {NT_STATUS(0xc0000257), W_ERROR(0x4d0)}, + {NT_STATUS(0xc0000259), W_ERROR(0x573)}, + {NT_STATUS(0xc000025e), W_ERROR(0x422)}, + {NT_STATUS(0xc0000262), W_ERROR(0xb6)}, + {NT_STATUS(0xc0000263), W_ERROR(0x7f)}, + {NT_STATUS(0xc0000264), W_ERROR(0x120)}, + {NT_STATUS(0xc0000265), W_ERROR(0x476)}, + {NT_STATUS(0xc0000267), W_ERROR(0x10fe)}, + {NT_STATUS(0xc000026c), W_ERROR(0x7d1)}, + {NT_STATUS(0xc000026d), W_ERROR(0x4b1)}, + {NT_STATUS(0xc000026e), W_ERROR(0x15)}, + {NT_STATUS(0xc0000272), W_ERROR(0x491)}, + {NT_STATUS(0xc0000275), W_ERROR(0x1126)}, + {NT_STATUS(0xc0000276), W_ERROR(0x1129)}, + {NT_STATUS(0xc0000277), W_ERROR(0x112a)}, + {NT_STATUS(0xc0000278), W_ERROR(0x1128)}, + {NT_STATUS(0xc0000279), W_ERROR(0x780)}, + {NT_STATUS(0xc0000280), W_ERROR(0x781)}, + {NT_STATUS(0xc0000281), W_ERROR(0xa1)}, + {NT_STATUS(0xc0000283), W_ERROR(0x488)}, + {NT_STATUS(0xc0000284), W_ERROR(0x489)}, + {NT_STATUS(0xc0000285), W_ERROR(0x48a)}, + {NT_STATUS(0xc0000286), W_ERROR(0x48b)}, + {NT_STATUS(0xc0000287), W_ERROR(0x48c)}, + {NT_STATUS(0xc000028a), W_ERROR(0x5)}, + {NT_STATUS(0xc000028b), W_ERROR(0x5)}, + {NT_STATUS(0xc000028d), W_ERROR(0x5)}, + {NT_STATUS(0xc000028e), W_ERROR(0x5)}, + {NT_STATUS(0xc000028f), W_ERROR(0x5)}, + {NT_STATUS(0xc0000290), W_ERROR(0x5)}, + {NT_STATUS(0xc0000291), W_ERROR(0x1777)}, + {NT_STATUS(0xc0000292), W_ERROR(0x1778)}, + {NT_STATUS(0xc0000293), W_ERROR(0x1772)}, + {NT_STATUS(0xc0000295), W_ERROR(0x1068)}, + {NT_STATUS(0xc0000296), W_ERROR(0x1069)}, + {NT_STATUS(0xc0000297), W_ERROR(0x106a)}, + {NT_STATUS(0xc0000298), W_ERROR(0x106b)}, + {NT_STATUS(0xc0000299), W_ERROR(0x201a)}, + {NT_STATUS(0xc000029a), W_ERROR(0x201b)}, + {NT_STATUS(0xc000029b), W_ERROR(0x201c)}, + {NT_STATUS(0xc000029c), W_ERROR(0x1)}, + {NT_STATUS(0xc000029d), W_ERROR(0x10ff)}, + {NT_STATUS(0xc000029e), W_ERROR(0x1100)}, + {NT_STATUS(0xc000029f), W_ERROR(0x494)}, + {NT_STATUS(0xc00002a1), W_ERROR(0x200a)}, + {NT_STATUS(0xc00002a2), W_ERROR(0x200b)}, + {NT_STATUS(0xc00002a3), W_ERROR(0x200c)}, + {NT_STATUS(0xc00002a4), W_ERROR(0x200d)}, + {NT_STATUS(0xc00002a5), W_ERROR(0x200e)}, + {NT_STATUS(0xc00002a6), W_ERROR(0x200f)}, + {NT_STATUS(0xc00002a7), W_ERROR(0x2010)}, + {NT_STATUS(0xc00002a8), W_ERROR(0x2011)}, + {NT_STATUS(0xc00002a9), W_ERROR(0x2012)}, + {NT_STATUS(0xc00002aa), W_ERROR(0x2013)}, + {NT_STATUS(0xc00002ab), W_ERROR(0x2014)}, + {NT_STATUS(0xc00002ac), W_ERROR(0x2015)}, + {NT_STATUS(0xc00002ad), W_ERROR(0x2016)}, + {NT_STATUS(0xc00002ae), W_ERROR(0x2017)}, + {NT_STATUS(0xc00002af), W_ERROR(0x2018)}, + {NT_STATUS(0xc00002b0), W_ERROR(0x2019)}, + {NT_STATUS(0xc00002b1), W_ERROR(0x211e)}, + {NT_STATUS(0xc00002b2), W_ERROR(0x1127)}, + {NT_STATUS(0xc00002b6), W_ERROR(0x651)}, + {NT_STATUS(0xc00002b7), W_ERROR(0x49a)}, + {NT_STATUS(0xc00002b8), W_ERROR(0x49b)}, + {NT_STATUS(0xc00002c1), W_ERROR(0x2024)}, + {NT_STATUS(0xc00002c3), W_ERROR(0x575)}, + {NT_STATUS(0xc00002c5), W_ERROR(0x3e6)}, + {NT_STATUS(0xc00002c6), W_ERROR(0x1075)}, + {NT_STATUS(0xc00002c7), W_ERROR(0x1076)}, + {NT_STATUS(0xc00002ca), W_ERROR(0x10e8)}, + {NT_STATUS(0xc00002cb), W_ERROR(0x2138)}, + {NT_STATUS(0xc00002cc), W_ERROR(0x4e3)}, + {NT_STATUS(0xc00002cd), W_ERROR(0x2139)}, + {NT_STATUS(0xc00002cf), W_ERROR(0x49d)}, + {NT_STATUS(0xc00002d0), W_ERROR(0x213a)}, + {NT_STATUS(0xc00002d4), W_ERROR(0x2141)}, + {NT_STATUS(0xc00002d5), W_ERROR(0x2142)}, + {NT_STATUS(0xc00002d6), W_ERROR(0x2143)}, + {NT_STATUS(0xc00002d7), W_ERROR(0x2144)}, + {NT_STATUS(0xc00002d8), W_ERROR(0x2145)}, + {NT_STATUS(0xc00002d9), W_ERROR(0x2146)}, + {NT_STATUS(0xc00002da), W_ERROR(0x2147)}, + {NT_STATUS(0xc00002db), W_ERROR(0x2148)}, + {NT_STATUS(0xc00002dc), W_ERROR(0x2149)}, + {NT_STATUS(0xc00002dd), W_ERROR(0x32)}, + {NT_STATUS(0xc00002df), W_ERROR(0x2151)}, + {NT_STATUS(0xc00002e0), W_ERROR(0x2152)}, + {NT_STATUS(0xc00002e1), W_ERROR(0x2153)}, + {NT_STATUS(0xc00002e2), W_ERROR(0x2154)}, + {NT_STATUS(0xc00002e3), W_ERROR(0x215d)}, + {NT_STATUS(0xc00002e4), W_ERROR(0x2163)}, + {NT_STATUS(0xc00002e5), W_ERROR(0x2164)}, + {NT_STATUS(0xc00002e6), W_ERROR(0x2165)}, + {NT_STATUS(0xc00002e7), W_ERROR(0x216d)}, + {NT_STATUS(0xc00002fe), W_ERROR(0x45b)}, + {NT_STATUS(0xc00002ff), W_ERROR(0x4e7)}, + {NT_STATUS(0xc0000300), W_ERROR(0x4e6)}, + {NT_STATUS(0x80000001), W_ERROR(0x80000001)}, + {NT_STATUS(0x80000002), W_ERROR(0x3e6)}, + {NT_STATUS(0x80000003), W_ERROR(0x80000003)}, + {NT_STATUS(0x80000004), W_ERROR(0x80000004)}, + {NT_STATUS(0x80000005), W_ERROR(0xea)}, + {NT_STATUS(0x80000006), W_ERROR(0x12)}, + {NT_STATUS(0x8000000b), W_ERROR(0x56f)}, + {NT_STATUS(0x8000000d), W_ERROR(0x12b)}, + {NT_STATUS(0x8000000e), W_ERROR(0x1c)}, + {NT_STATUS(0x8000000f), W_ERROR(0x15)}, + {NT_STATUS(0x80000010), W_ERROR(0x15)}, + {NT_STATUS(0x80000011), W_ERROR(0xaa)}, + {NT_STATUS(0x80000012), W_ERROR(0x103)}, + {NT_STATUS(0x80000013), W_ERROR(0xfe)}, + {NT_STATUS(0x80000014), W_ERROR(0xff)}, + {NT_STATUS(0x80000015), W_ERROR(0xff)}, + {NT_STATUS(0x80000016), W_ERROR(0x456)}, + {NT_STATUS(0x8000001a), W_ERROR(0x103)}, + {NT_STATUS(0x8000001b), W_ERROR(0x44d)}, + {NT_STATUS(0x8000001c), W_ERROR(0x456)}, + {NT_STATUS(0x8000001d), W_ERROR(0x457)}, + {NT_STATUS(0x8000001e), W_ERROR(0x44c)}, + {NT_STATUS(0x8000001f), W_ERROR(0x44e)}, + {NT_STATUS(0x80000021), W_ERROR(0x44f)}, + {NT_STATUS(0x80000022), W_ERROR(0x450)}, + {NT_STATUS(0x80000025), W_ERROR(0x962)}, + {NT_STATUS(0x80000288), W_ERROR(0x48d)}, + {NT_STATUS(0x80000289), W_ERROR(0x48e)}, + {NT_STATUS_OK, WERR_OK}}; + + +/***************************************************************************** +convert a dos eclas/ecode to a NT status32 code + *****************************************************************************/ +NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode) +{ + int i; + if (eclass == 0 && ecode == 0) return NT_STATUS_OK; + for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) { + if (eclass == dos_to_ntstatus_map[i].dos_class && + ecode == dos_to_ntstatus_map[i].dos_code) { + return dos_to_ntstatus_map[i].ntstatus; + } + } + return NT_STATUS_UNSUCCESSFUL; +} + + +/***************************************************************************** +convert a NT status code to a dos class/code + *****************************************************************************/ +void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) +{ + int i; + if (NT_STATUS_IS_OK(ntstatus)) { + *eclass = 0; + *ecode = 0; + return; + } + for (i=0; NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus); i++) { + if (NT_STATUS_V(ntstatus) == + NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus)) { + *eclass = ntstatus_to_dos_map[i].dos_class; + *ecode = ntstatus_to_dos_map[i].dos_code; + return; + } + } + *eclass = ERRHRD; + *ecode = ERRgeneral; +} + + +/***************************************************************************** +convert a WERROR to a NT status32 code + *****************************************************************************/ +NTSTATUS werror_to_ntstatus(WERROR error) +{ + int i; + if (W_ERROR_IS_OK(error)) return NT_STATUS_OK; + for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { + if (W_ERROR_V(error) == + W_ERROR_V(ntstatus_to_werror_map[i].werror)) { + return ntstatus_to_werror_map[i].ntstatus; + } + } + + /* just guess ... */ + return NT_STATUS(W_ERROR_V(error) | 0xc0000000); +} + +/***************************************************************************** +convert a NTSTATUS to a WERROR + *****************************************************************************/ +WERROR ntstatus_to_werror(NTSTATUS error) +{ + int i; + if (NT_STATUS_IS_OK(error)) return WERR_OK; + for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { + if (NT_STATUS_V(error) == + NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus)) { + return ntstatus_to_werror_map[i].werror; + } + } + + /* a lame guess */ + return W_ERROR(NT_STATUS_V(error) & 0xffff); +} + +/* Mapping between Unix, DOS and NT error numbers */ + +const struct unix_error_map unix_dos_nt_errmap[] = { + { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, + { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, + { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, + { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, + { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, + { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, + { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, + { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { EISDIR, ERRDOS, ERRbadpath, NT_STATUS_FILE_IS_A_DIRECTORY }, +#ifdef EDQUOT + { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#endif +#ifdef ENOTEMPTY + { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, +#endif +#ifdef EXDEV + { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, +#endif +#ifdef EROFS + { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, +#endif +#ifdef ENAMETOOLONG + { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, +#endif +#ifdef EFBIG + { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#endif +#ifdef EFBIG + { EBUSY, ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION }, +#endif + { 0, 0, 0, NT_STATUS_OK } +}; + +/********************************************************************* + Map an NT error code from a Unix error code. +*********************************************************************/ + +NTSTATUS map_nt_error_from_unix(int unix_error) +{ + int i = 0; + + if (unix_error == 0) + return NT_STATUS_OK; + + /* Look through list */ + while(unix_dos_nt_errmap[i].unix_error != 0) { + if (unix_dos_nt_errmap[i].unix_error == unix_error) + return unix_dos_nt_errmap[i].nt_error; + i++; + } + + /* Default return */ + return NT_STATUS_ACCESS_DENIED; +} diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c new file mode 100644 index 0000000000..6c4b7c8417 --- /dev/null +++ b/source4/libcli/util/nterr.c @@ -0,0 +1,715 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. + * + * 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. + */ + +/* NT error codes. please read nterr.h */ + +#include "includes.h" + +typedef struct +{ + const char *nt_errstr; + NTSTATUS nt_errcode; +} nt_err_code_struct; + +static const nt_err_code_struct nt_errs[] = +{ + { "NT_STATUS_OK", NT_STATUS_OK }, + { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, + { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, + { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, + { "NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH }, + { "NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION }, + { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW }, + { "NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR }, + { "NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA }, + { "NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE }, + { "NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK }, + { "NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC }, + { "NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID }, + { "NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED }, + { "NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER }, + { "NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE }, + { "NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE }, + { "NT_STATUS_INVALID_DEVICE_REQUEST", NT_STATUS_INVALID_DEVICE_REQUEST }, + { "NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE }, + { "NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME }, + { "NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE }, + { "NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA }, + { "NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR }, + { "NT_STATUS_MORE_PROCESSING_REQUIRED", NT_STATUS_MORE_PROCESSING_REQUIRED }, + { "NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY }, + { "NT_STATUS_CONFLICTING_ADDRESSES", NT_STATUS_CONFLICTING_ADDRESSES }, + { "NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW }, + { "NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM }, + { "NT_STATUS_UNABLE_TO_DELETE_SECTION", NT_STATUS_UNABLE_TO_DELETE_SECTION }, + { "NT_STATUS_INVALID_SYSTEM_SERVICE", NT_STATUS_INVALID_SYSTEM_SERVICE }, + { "NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION }, + { "NT_STATUS_INVALID_LOCK_SEQUENCE", NT_STATUS_INVALID_LOCK_SEQUENCE }, + { "NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE }, + { "NT_STATUS_INVALID_FILE_FOR_SECTION", NT_STATUS_INVALID_FILE_FOR_SECTION }, + { "NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED }, + { "NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED }, + { "NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL }, + { "NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH }, + { "NT_STATUS_NONCONTINUABLE_EXCEPTION", NT_STATUS_NONCONTINUABLE_EXCEPTION }, + { "NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION }, + { "NT_STATUS_UNWIND", NT_STATUS_UNWIND }, + { "NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK }, + { "NT_STATUS_INVALID_UNWIND_TARGET", NT_STATUS_INVALID_UNWIND_TARGET }, + { "NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED }, + { "NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR }, + { "NT_STATUS_UNABLE_TO_DECOMMIT_VM", NT_STATUS_UNABLE_TO_DECOMMIT_VM }, + { "NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED }, + { "NT_STATUS_INVALID_PORT_ATTRIBUTES", NT_STATUS_INVALID_PORT_ATTRIBUTES }, + { "NT_STATUS_PORT_MESSAGE_TOO_LONG", NT_STATUS_PORT_MESSAGE_TOO_LONG }, + { "NT_STATUS_INVALID_PARAMETER_MIX", NT_STATUS_INVALID_PARAMETER_MIX }, + { "NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER }, + { "NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR }, + { "NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID }, + { "NT_STATUS_OBJECT_NAME_NOT_FOUND", NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { "NT_STATUS_OBJECT_NAME_COLLISION", NT_STATUS_OBJECT_NAME_COLLISION }, + { "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE }, + { "NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED }, + { "NT_STATUS_DEVICE_ALREADY_ATTACHED", NT_STATUS_DEVICE_ALREADY_ATTACHED }, + { "NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID }, + { "NT_STATUS_OBJECT_PATH_NOT_FOUND", NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { "NT_STATUS_OBJECT_PATH_SYNTAX_BAD", NT_STATUS_OBJECT_PATH_SYNTAX_BAD }, + { "NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN }, + { "NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR }, + { "NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR }, + { "NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR }, + { "NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG }, + { "NT_STATUS_PORT_CONNECTION_REFUSED", NT_STATUS_PORT_CONNECTION_REFUSED }, + { "NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE }, + { "NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION }, + { "NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED }, + { "NT_STATUS_INVALID_PAGE_PROTECTION", NT_STATUS_INVALID_PAGE_PROTECTION }, + { "NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED }, + { "NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED }, + { "NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET }, + { "NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE }, + { "NT_STATUS_SUSPEND_COUNT_EXCEEDED", NT_STATUS_SUSPEND_COUNT_EXCEEDED }, + { "NT_STATUS_THREAD_IS_TERMINATING", NT_STATUS_THREAD_IS_TERMINATING }, + { "NT_STATUS_BAD_WORKING_SET_LIMIT", NT_STATUS_BAD_WORKING_SET_LIMIT }, + { "NT_STATUS_INCOMPATIBLE_FILE_MAP", NT_STATUS_INCOMPATIBLE_FILE_MAP }, + { "NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION }, + { "NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED }, + { "NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE }, + { "NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY }, + { "NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE }, + { "NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR }, + { "NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT }, + { "NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED }, + { "NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING }, + { "NT_STATUS_CTL_FILE_NOT_SUPPORTED", NT_STATUS_CTL_FILE_NOT_SUPPORTED }, + { "NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION }, + { "NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH }, + { "NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER }, + { "NT_STATUS_INVALID_PRIMARY_GROUP", NT_STATUS_INVALID_PRIMARY_GROUP }, + { "NT_STATUS_NO_IMPERSONATION_TOKEN", NT_STATUS_NO_IMPERSONATION_TOKEN }, + { "NT_STATUS_CANT_DISABLE_MANDATORY", NT_STATUS_CANT_DISABLE_MANDATORY }, + { "NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS }, + { "NT_STATUS_NO_SUCH_LOGON_SESSION", NT_STATUS_NO_SUCH_LOGON_SESSION }, + { "NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE }, + { "NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD }, + { "NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS }, + { "NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER }, + { "NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS }, + { "NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP }, + { "NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP }, + { "NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN }, + { "NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD }, + { "NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD }, + { "NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION }, + { "NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE }, + { "NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION }, + { "NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS }, + { "NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION }, + { "NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED }, + { "NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED }, + { "NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED }, + { "NT_STATUS_TOO_MANY_LUIDS_REQUESTED", NT_STATUS_TOO_MANY_LUIDS_REQUESTED }, + { "NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED }, + { "NT_STATUS_INVALID_SUB_AUTHORITY", NT_STATUS_INVALID_SUB_AUTHORITY }, + { "NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL }, + { "NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID }, + { "NT_STATUS_INVALID_SECURITY_DESCR", NT_STATUS_INVALID_SECURITY_DESCR }, + { "NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND }, + { "NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT }, + { "NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN }, + { "NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL }, + { "NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED }, + { "NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL }, + { "NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED }, + { "NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED }, + { "NT_STATUS_TOO_MANY_GUIDS_REQUESTED", NT_STATUS_TOO_MANY_GUIDS_REQUESTED }, + { "NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED }, + { "NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY }, + { "NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED }, + { "NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL }, + { "NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED }, + { "NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA }, + { "NT_STATUS_RESOURCE_DATA_NOT_FOUND", NT_STATUS_RESOURCE_DATA_NOT_FOUND }, + { "NT_STATUS_RESOURCE_TYPE_NOT_FOUND", NT_STATUS_RESOURCE_TYPE_NOT_FOUND }, + { "NT_STATUS_RESOURCE_NAME_NOT_FOUND", NT_STATUS_RESOURCE_NAME_NOT_FOUND }, + { "NT_STATUS_ARRAY_BOUNDS_EXCEEDED", NT_STATUS_ARRAY_BOUNDS_EXCEEDED }, + { "NT_STATUS_FLOAT_DENORMAL_OPERAND", NT_STATUS_FLOAT_DENORMAL_OPERAND }, + { "NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO }, + { "NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT }, + { "NT_STATUS_FLOAT_INVALID_OPERATION", NT_STATUS_FLOAT_INVALID_OPERATION }, + { "NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW }, + { "NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK }, + { "NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW }, + { "NT_STATUS_INTEGER_DIVIDE_BY_ZERO", NT_STATUS_INTEGER_DIVIDE_BY_ZERO }, + { "NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW }, + { "NT_STATUS_PRIVILEGED_INSTRUCTION", NT_STATUS_PRIVILEGED_INSTRUCTION }, + { "NT_STATUS_TOO_MANY_PAGING_FILES", NT_STATUS_TOO_MANY_PAGING_FILES }, + { "NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID }, + { "NT_STATUS_ALLOTTED_SPACE_EXCEEDED", NT_STATUS_ALLOTTED_SPACE_EXCEEDED }, + { "NT_STATUS_INSUFFICIENT_RESOURCES", NT_STATUS_INSUFFICIENT_RESOURCES }, + { "NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND }, + { "NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR }, + { "NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED }, + { "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE }, + { "NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE }, + { "NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED }, + { "NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA }, + { "NT_STATUS_MEDIA_WRITE_PROTECTED", NT_STATUS_MEDIA_WRITE_PROTECTED }, + { "NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY }, + { "NT_STATUS_INVALID_GROUP_ATTRIBUTES", NT_STATUS_INVALID_GROUP_ATTRIBUTES }, + { "NT_STATUS_BAD_IMPERSONATION_LEVEL", NT_STATUS_BAD_IMPERSONATION_LEVEL }, + { "NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS }, + { "NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS }, + { "NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE }, + { "NT_STATUS_BAD_MASTER_BOOT_RECORD", NT_STATUS_BAD_MASTER_BOOT_RECORD }, + { "NT_STATUS_INSTRUCTION_MISALIGNMENT", NT_STATUS_INSTRUCTION_MISALIGNMENT }, + { "NT_STATUS_INSTANCE_NOT_AVAILABLE", NT_STATUS_INSTANCE_NOT_AVAILABLE }, + { "NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE }, + { "NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY }, + { "NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION }, + { "NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED }, + { "NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING }, + { "NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED }, + { "NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING }, + { "NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE }, + { "NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT }, + { "NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED }, + { "NT_STATUS_PROFILING_NOT_STARTED", NT_STATUS_PROFILING_NOT_STARTED }, + { "NT_STATUS_PROFILING_NOT_STOPPED", NT_STATUS_PROFILING_NOT_STOPPED }, + { "NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET }, + { "NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY }, + { "NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED }, + { "NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING }, + { "NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME }, + { "NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH }, + { "NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY }, + { "NT_STATUS_DEVICE_DOES_NOT_EXIST", NT_STATUS_DEVICE_DOES_NOT_EXIST }, + { "NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS }, + { "NT_STATUS_ADAPTER_HARDWARE_ERROR", NT_STATUS_ADAPTER_HARDWARE_ERROR }, + { "NT_STATUS_INVALID_NETWORK_RESPONSE", NT_STATUS_INVALID_NETWORK_RESPONSE }, + { "NT_STATUS_UNEXPECTED_NETWORK_ERROR", NT_STATUS_UNEXPECTED_NETWORK_ERROR }, + { "NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER }, + { "NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL }, + { "NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE }, + { "NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED }, + { "NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED }, + { "NT_STATUS_NETWORK_ACCESS_DENIED", NT_STATUS_NETWORK_ACCESS_DENIED }, + { "NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE }, + { "NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME }, + { "NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES }, + { "NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS }, + { "NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED }, + { "NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED }, + { "NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED }, + { "NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT }, + { "NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT }, + { "NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE }, + { "NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED }, + { "NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", NT_STATUS_VIRTUAL_CIRCUIT_CLOSED }, + { "NT_STATUS_NO_SECURITY_ON_OBJECT", NT_STATUS_NO_SECURITY_ON_OBJECT }, + { "NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT }, + { "NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY }, + { "NT_STATUS_CANT_ACCESS_DOMAIN_INFO", NT_STATUS_CANT_ACCESS_DOMAIN_INFO }, + { "NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF }, + { "NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE }, + { "NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE }, + { "NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE }, + { "NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN }, + { "NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS }, + { "NT_STATUS_DOMAIN_LIMIT_EXCEEDED", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, + { "NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED }, + { "NT_STATUS_INVALID_OPLOCK_PROTOCOL", NT_STATUS_INVALID_OPLOCK_PROTOCOL }, + { "NT_STATUS_INTERNAL_DB_CORRUPTION", NT_STATUS_INTERNAL_DB_CORRUPTION }, + { "NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR }, + { "NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED }, + { "NT_STATUS_BAD_DESCRIPTOR_FORMAT", NT_STATUS_BAD_DESCRIPTOR_FORMAT }, + { "NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER }, + { "NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR }, + { "NT_STATUS_UNEXPECTED_MM_CREATE_ERR", NT_STATUS_UNEXPECTED_MM_CREATE_ERR }, + { "NT_STATUS_UNEXPECTED_MM_MAP_ERROR", NT_STATUS_UNEXPECTED_MM_MAP_ERROR }, + { "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", NT_STATUS_UNEXPECTED_MM_EXTEND_ERR }, + { "NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS }, + { "NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS }, + { "NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1 }, + { "NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2 }, + { "NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3 }, + { "NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4 }, + { "NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5 }, + { "NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6 }, + { "NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7 }, + { "NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8 }, + { "NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9 }, + { "NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10 }, + { "NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11 }, + { "NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12 }, + { "NT_STATUS_REDIRECTOR_NOT_STARTED", NT_STATUS_REDIRECTOR_NOT_STARTED }, + { "NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED }, + { "NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW }, + { "NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE }, + { "NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE }, + { "NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY }, + { "NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR }, + { "NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY }, + { "NT_STATUS_BAD_LOGON_SESSION_STATE", NT_STATUS_BAD_LOGON_SESSION_STATE }, + { "NT_STATUS_LOGON_SESSION_COLLISION", NT_STATUS_LOGON_SESSION_COLLISION }, + { "NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG }, + { "NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN }, + { "NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE }, + { "NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND }, + { "NT_STATUS_PROCESS_IS_TERMINATING", NT_STATUS_PROCESS_IS_TERMINATING }, + { "NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE }, + { "NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION }, + { "NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE }, + { "NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED }, + { "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT }, + { "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST }, + { "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED }, + { "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER }, + { "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND }, + { "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID }, + { "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE }, + { "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR }, + { "NT_STATUS_NO_LDT", NT_STATUS_NO_LDT }, + { "NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE }, + { "NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET }, + { "NT_STATUS_INVALID_LDT_DESCRIPTOR", NT_STATUS_INVALID_LDT_DESCRIPTOR }, + { "NT_STATUS_INVALID_IMAGE_NE_FORMAT", NT_STATUS_INVALID_IMAGE_NE_FORMAT }, + { "NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE }, + { "NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE }, + { "NT_STATUS_MAPPED_FILE_SIZE_ZERO", NT_STATUS_MAPPED_FILE_SIZE_ZERO }, + { "NT_STATUS_TOO_MANY_OPENED_FILES", NT_STATUS_TOO_MANY_OPENED_FILES }, + { "NT_STATUS_CANCELLED", NT_STATUS_CANCELLED }, + { "NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE }, + { "NT_STATUS_INVALID_COMPUTER_NAME", NT_STATUS_INVALID_COMPUTER_NAME }, + { "NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED }, + { "NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT }, + { "NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP }, + { "NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER }, + { "NT_STATUS_MEMBERS_PRIMARY_GROUP", NT_STATUS_MEMBERS_PRIMARY_GROUP }, + { "NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED }, + { "NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS }, + { "NT_STATUS_THREAD_NOT_IN_PROCESS", NT_STATUS_THREAD_NOT_IN_PROCESS }, + { "NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE }, + { "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", NT_STATUS_PAGEFILE_QUOTA_EXCEEDED }, + { "NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT }, + { "NT_STATUS_INVALID_IMAGE_LE_FORMAT", NT_STATUS_INVALID_IMAGE_LE_FORMAT }, + { "NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ }, + { "NT_STATUS_INVALID_IMAGE_PROTECT", NT_STATUS_INVALID_IMAGE_PROTECT }, + { "NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16 }, + { "NT_STATUS_LOGON_SERVER_CONFLICT", NT_STATUS_LOGON_SERVER_CONFLICT }, + { "NT_STATUS_TIME_DIFFERENCE_AT_DC", NT_STATUS_TIME_DIFFERENCE_AT_DC }, + { "NT_STATUS_SYNCHRONIZATION_REQUIRED", NT_STATUS_SYNCHRONIZATION_REQUIRED }, + { "NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND }, + { "NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED }, + { "NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED }, + { "NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND }, + { "NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND }, + { "NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT }, + { "NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT }, + { "NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT }, + { "NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES }, + { "NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED }, + { "NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT }, + { "NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION }, + { "NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS }, + { "NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED }, + { "NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE }, + { "NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION }, + { "NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE }, + { "NT_STATUS_PAGEFILE_CREATE_FAILED", NT_STATUS_PAGEFILE_CREATE_FAILED }, + { "NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE }, + { "NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL }, + { "NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE }, + { "NT_STATUS_ILLEGAL_FLOAT_CONTEXT", NT_STATUS_ILLEGAL_FLOAT_CONTEXT }, + { "NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN }, + { "NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT }, + { "NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED }, + { "NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR }, + { "NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME }, + { "NT_STATUS_SERIAL_NO_DEVICE_INITED", NT_STATUS_SERIAL_NO_DEVICE_INITED }, + { "NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS }, + { "NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS }, + { "NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS }, + { "NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS }, + { "NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED }, + { "NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS }, + { "NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG }, + { "NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR }, + { "NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE }, + { "NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS }, + { "NT_STATUS_LOGON_TYPE_NOT_GRANTED", NT_STATUS_LOGON_TYPE_NOT_GRANTED }, + { "NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE }, + { "NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED }, + { "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR }, + { "NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER }, + { "NT_STATUS_ILL_FORMED_SERVICE_ENTRY", NT_STATUS_ILL_FORMED_SERVICE_ENTRY }, + { "NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER }, + { "NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER }, + { "NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER }, + { "NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME }, + { "NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND }, + { "NT_STATUS_FLOPPY_WRONG_CYLINDER", NT_STATUS_FLOPPY_WRONG_CYLINDER }, + { "NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR }, + { "NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS }, + { "NT_STATUS_DISK_RECALIBRATE_FAILED", NT_STATUS_DISK_RECALIBRATE_FAILED }, + { "NT_STATUS_DISK_OPERATION_FAILED", NT_STATUS_DISK_OPERATION_FAILED }, + { "NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED }, + { "NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY }, + { "NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING }, + { "NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE }, + { "NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH }, + { "NT_STATUS_DEVICE_NOT_PARTITIONED", NT_STATUS_DEVICE_NOT_PARTITIONED }, + { "NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA }, + { "NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", NT_STATUS_UNABLE_TO_UNLOAD_MEDIA }, + { "NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW }, + { "NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA }, + { "NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER }, + { "NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER }, + { "NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED }, + { "NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE }, + { "NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS }, + { "NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, + { "NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN }, + { "NT_STATUS_CHILD_MUST_BE_VOLATILE", NT_STATUS_CHILD_MUST_BE_VOLATILE }, + { "NT_STATUS_DEVICE_CONFIGURATION_ERROR", NT_STATUS_DEVICE_CONFIGURATION_ERROR }, + { "NT_STATUS_DRIVER_INTERNAL_ERROR", NT_STATUS_DRIVER_INTERNAL_ERROR }, + { "NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE }, + { "NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR }, + { "NT_STATUS_DEVICE_PROTOCOL_ERROR", NT_STATUS_DEVICE_PROTOCOL_ERROR }, + { "NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER }, + { "NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL }, + { "NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE }, + { "NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET }, + { "NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, + { "NT_STATUS_TRUSTED_DOMAIN_FAILURE", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, + { "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, + { "NT_STATUS_EVENTLOG_FILE_CORRUPT", NT_STATUS_EVENTLOG_FILE_CORRUPT }, + { "NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START }, + { "NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE }, + { "NT_STATUS_MUTANT_LIMIT_EXCEEDED", NT_STATUS_MUTANT_LIMIT_EXCEEDED }, + { "NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED }, + { "NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED }, + { "NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK }, + { "NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, + { "NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT }, + { "NT_STATUS_EVENTLOG_FILE_CHANGED", NT_STATUS_EVENTLOG_FILE_CHANGED }, + { "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, + { "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, + { "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, + { "NT_STATUS_DOMAIN_TRUST_INCONSISTENT", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, + { "NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED }, + { "NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY }, + { "NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED }, + { "NT_STATUS_RESOURCE_LANG_NOT_FOUND", NT_STATUS_RESOURCE_LANG_NOT_FOUND }, + { "NT_STATUS_INSUFF_SERVER_RESOURCES", NT_STATUS_INSUFF_SERVER_RESOURCES }, + { "NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE }, + { "NT_STATUS_INVALID_ADDRESS_COMPONENT", NT_STATUS_INVALID_ADDRESS_COMPONENT }, + { "NT_STATUS_INVALID_ADDRESS_WILDCARD", NT_STATUS_INVALID_ADDRESS_WILDCARD }, + { "NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES }, + { "NT_STATUS_ADDRESS_ALREADY_EXISTS", NT_STATUS_ADDRESS_ALREADY_EXISTS }, + { "NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED }, + { "NT_STATUS_CONNECTION_DISCONNECTED", NT_STATUS_CONNECTION_DISCONNECTED }, + { "NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET }, + { "NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES }, + { "NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED }, + { "NT_STATUS_TRANSACTION_TIMED_OUT", NT_STATUS_TRANSACTION_TIMED_OUT }, + { "NT_STATUS_TRANSACTION_NO_RELEASE", NT_STATUS_TRANSACTION_NO_RELEASE }, + { "NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH }, + { "NT_STATUS_TRANSACTION_RESPONDED", NT_STATUS_TRANSACTION_RESPONDED }, + { "NT_STATUS_TRANSACTION_INVALID_ID", NT_STATUS_TRANSACTION_INVALID_ID }, + { "NT_STATUS_TRANSACTION_INVALID_TYPE", NT_STATUS_TRANSACTION_INVALID_TYPE }, + { "NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION }, + { "NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION }, + { "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", NT_STATUS_CANNOT_LOAD_REGISTRY_FILE }, + { "NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED }, + { "NT_STATUS_SYSTEM_PROCESS_TERMINATED", NT_STATUS_SYSTEM_PROCESS_TERMINATED }, + { "NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED }, + { "NT_STATUS_NO_BROWSER_SERVERS_FOUND", NT_STATUS_NO_BROWSER_SERVERS_FOUND }, + { "NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR }, + { "NT_STATUS_DRIVER_CANCEL_TIMEOUT", NT_STATUS_DRIVER_CANCEL_TIMEOUT }, + { "NT_STATUS_REPLY_MESSAGE_MISMATCH", NT_STATUS_REPLY_MESSAGE_MISMATCH }, + { "NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT }, + { "NT_STATUS_IMAGE_CHECKSUM_MISMATCH", NT_STATUS_IMAGE_CHECKSUM_MISMATCH }, + { "NT_STATUS_LOST_WRITEBEHIND_DATA", NT_STATUS_LOST_WRITEBEHIND_DATA }, + { "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID }, + { "NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE }, + { "NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND }, + { "NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM }, + { "NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE }, + { "NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ }, + { "NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK }, + { "NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID }, + { "NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS }, + { "NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE }, + { "NT_STATUS_RETRY", NT_STATUS_RETRY }, + { "NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE }, + { "NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET }, + { "NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND }, + { "NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW }, + { "NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT }, + { "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, + { "NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE }, + { "NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED }, + { "NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT }, + { "NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, + { "NT_STATUS_ADDRESS_NOT_ASSOCIATED", NT_STATUS_ADDRESS_NOT_ASSOCIATED }, + { "NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID }, + { "NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE }, + { "NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE }, + { "NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE }, + { "NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE }, + { "NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE }, + { "NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED }, + { "NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED }, + { "NT_STATUS_BAD_COMPRESSION_BUFFER", NT_STATUS_BAD_COMPRESSION_BUFFER }, + { "NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE }, + { "NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED }, + { "NT_STATUS_TIMER_RESOLUTION_NOT_SET", NT_STATUS_TIMER_RESOLUTION_NOT_SET }, + { "NT_STATUS_CONNECTION_COUNT_LIMIT", NT_STATUS_CONNECTION_COUNT_LIMIT }, + { "NT_STATUS_LOGIN_TIME_RESTRICTION", NT_STATUS_LOGIN_TIME_RESTRICTION }, + { "NT_STATUS_LOGIN_WKSTA_RESTRICTION", NT_STATUS_LOGIN_WKSTA_RESTRICTION }, + { "NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH }, + { "NT_STATUS_INSUFFICIENT_LOGON_INFO", NT_STATUS_INSUFFICIENT_LOGON_INFO }, + { "NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT }, + { "NT_STATUS_BAD_SERVICE_ENTRYPOINT", NT_STATUS_BAD_SERVICE_ENTRYPOINT }, + { "NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST }, + { "NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1 }, + { "NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2 }, + { "NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT }, + { "NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED }, + { "NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE }, + { "NT_STATUS_LICENSE_QUOTA_EXCEEDED", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, + { "NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT }, + { "NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT }, + { "NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE }, + { "NT_STATUS_UNSUPPORTED_COMPRESSION", NT_STATUS_UNSUPPORTED_COMPRESSION }, + { "NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE }, + { "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH }, + { "NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", NT_STATUS_DRIVER_ORDINAL_NOT_FOUND }, + { "NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND }, + { "NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED }, + { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, + { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, + { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, + { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, + { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, + { NULL, NT_STATUS(0) } +}; + +static const nt_err_code_struct nt_err_desc[] = +{ + { "Success", NT_STATUS_OK }, + { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, + { "Access denied", NT_STATUS_ACCESS_DENIED }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Must change password", NT_STATUS_PASSWORD_MUST_CHANGE }, + { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, + { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, + { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "Improperly formed account name", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "User exists", NT_STATUS_USER_EXISTS }, + { "No such user", NT_STATUS_NO_SUCH_USER }, + { "Group exists", NT_STATUS_GROUP_EXISTS }, + { "No such group", NT_STATUS_NO_SUCH_GROUP }, + { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, + { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, + { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, + { "Logon failure", NT_STATUS_LOGON_FAILURE }, + { "Account restriction", NT_STATUS_ACCOUNT_RESTRICTION }, + { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, + { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, + { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, + { "Account disabled", NT_STATUS_ACCOUNT_DISABLED }, + { "Unexpected information received", NT_STATUS_INVALID_PARAMETER }, + { "Memory allocation error", NT_STATUS_NO_MEMORY }, + { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "Not implemented", NT_STATUS_NOT_IMPLEMENTED }, + { "Invalid information class", NT_STATUS_INVALID_INFO_CLASS }, + { "Information length mismatch", NT_STATUS_INFO_LENGTH_MISMATCH }, + { "Access violation", NT_STATUS_ACCESS_VIOLATION }, + { "Invalid handle", NT_STATUS_INVALID_HANDLE }, + { "Invalid parameter", NT_STATUS_INVALID_PARAMETER }, + { "No memory", NT_STATUS_NO_MEMORY }, + { "Buffer too small", NT_STATUS_BUFFER_TOO_SMALL }, + { "Revision mismatch", NT_STATUS_REVISION_MISMATCH }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "No such logon session", NT_STATUS_NO_SUCH_LOGON_SESSION }, + { "No such privilege", NT_STATUS_NO_SUCH_PRIVILEGE }, + { "Procedure not found", NT_STATUS_PROCEDURE_NOT_FOUND }, + { "Server disabled", NT_STATUS_SERVER_DISABLED }, + { "Invalid pipe state", NT_STATUS_INVALID_PIPE_STATE }, + { "Named pipe busy", NT_STATUS_PIPE_BUSY }, + { "Illegal function", NT_STATUS_ILLEGAL_FUNCTION }, + { "Named pipe dicconnected", NT_STATUS_PIPE_DISCONNECTED }, + { "Named pipe closing", NT_STATUS_PIPE_CLOSING }, + { "Remote host not listening", NT_STATUS_REMOTE_NOT_LISTENING }, + { "Duplicate name on network", NT_STATUS_DUPLICATE_NAME }, + { "Print queue is full", NT_STATUS_PRINT_QUEUE_FULL }, + { "No print spool space available", NT_STATUS_NO_SPOOL_SPACE }, + { "Too many names", NT_STATUS_TOO_MANY_NAMES }, + { "Too many sessions", NT_STATUS_TOO_MANY_SESSIONS }, + { "Invalid server state", NT_STATUS_INVALID_SERVER_STATE }, + { "Invalid domain state", NT_STATUS_INVALID_DOMAIN_STATE }, + { "Invalid domain role", NT_STATUS_INVALID_DOMAIN_ROLE }, + { "No such domain", NT_STATUS_NO_SUCH_DOMAIN }, + { "Domain exists", NT_STATUS_DOMAIN_EXISTS }, + { "Domain limit exceeded", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, + { "Bad logon session state", NT_STATUS_BAD_LOGON_SESSION_STATE }, + { "Logon session collision", NT_STATUS_LOGON_SESSION_COLLISION }, + { "Invalid logon type", NT_STATUS_INVALID_LOGON_TYPE }, + { "Cancelled", NT_STATUS_CANCELLED }, + { "Invalid computer name", NT_STATUS_INVALID_COMPUTER_NAME }, + { "Logon server conflict", NT_STATUS_LOGON_SERVER_CONFLICT }, + { "Time difference at domain controller", NT_STATUS_TIME_DIFFERENCE_AT_DC }, + { "Pipe broken", NT_STATUS_PIPE_BROKEN }, + { "Registry corrupt", NT_STATUS_REGISTRY_CORRUPT }, + { "Too many secrets", NT_STATUS_TOO_MANY_SECRETS }, + { "Too many SIDs", NT_STATUS_TOO_MANY_SIDS }, + { "Lanmanager cross encryption required", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, + { "Log file full", NT_STATUS_LOG_FILE_FULL }, + { "No trusted LSA secret", NT_STATUS_NO_TRUST_LSA_SECRET }, + { "No trusted SAM account", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, + { "Trusted domain failure", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, + { "Trust relationship failure", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, + { "Trust failure", NT_STATUS_TRUST_FAILURE }, + { "Netlogon service not started", NT_STATUS_NETLOGON_NOT_STARTED }, + { "Account expired", NT_STATUS_ACCOUNT_EXPIRED }, + { "Network credential conflict", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, + { "Remote session limit", NT_STATUS_REMOTE_SESSION_LIMIT }, + { "No logon interdomain trust account", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, + { "No logon workstation trust account", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, + { "No logon server trust account", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, + { "Domain trust inconsistent", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, + { "No user session key available", NT_STATUS_NO_USER_SESSION_KEY }, + { "User session deleted", NT_STATUS_USER_SESSION_DELETED }, + { "Insufficient server resources", NT_STATUS_INSUFF_SERVER_RESOURCES }, + { "Insufficient logon information", NT_STATUS_INSUFFICIENT_LOGON_INFO }, + + { "License quota exceeded", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, + + { NULL, NT_STATUS(0) } +}; + + +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +const char *nt_errstr(NTSTATUS nt_code) +{ + static pstring msg; + int idx = 0; + + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); + + while (nt_errs[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == + NT_STATUS_V(nt_code)) { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + return msg; +} + +/************************************************************************ + Print friendler version fo NT error code + ***********************************************************************/ +const char *get_friendly_nt_error_msg(NTSTATUS nt_code) +{ + int idx = 0; + + while (nt_err_desc[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { + return nt_err_desc[idx].nt_errstr; + } + idx++; + } + + /* fall back to NT_STATUS_XXX string */ + return nt_errstr(nt_code); +} + +/***************************************************************************** + returns an NT_STATUS constant as a string for inclusion in autogen C code + *****************************************************************************/ +const char *get_nt_error_c_code(NTSTATUS nt_code) +{ + static pstring out; + int idx = 0; + + while (nt_errs[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == + NT_STATUS_V(nt_code)) { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); + + return out; +} + +/***************************************************************************** + returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) + *****************************************************************************/ +NTSTATUS nt_status_string_to_code(char *nt_status_str) +{ + int idx = 0; + + while (nt_errs[idx].nt_errstr != NULL) { + if (strcmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { + return nt_errs[idx].nt_errcode; + } + idx++; + } + return NT_STATUS_UNSUCCESSFUL; +} diff --git a/source4/libcli/util/ntlmssp_sign.c b/source4/libcli/util/ntlmssp_sign.c new file mode 100644 index 0000000000..bd6d64d842 --- /dev/null +++ b/source4/libcli/util/ntlmssp_sign.c @@ -0,0 +1,226 @@ +/* + * Unix SMB/CIFS implementation. + * Version 3.0 + * NTLMSSP Signing routines + * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 + * Copyright (C) Andrew Bartlett 2003 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "includes.h" + +#define CLI_SIGN "session key to client-to-server signing key magic constant" +#define CLI_SEAL "session key to client-to-server sealing key magic constant" +#define SRV_SIGN "session key to server-to-client signing key magic constant" +#define SRV_SEAL "session key to server-to-client sealing key magic constant" + +static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; + + for (ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +static void calc_hash(unsigned char *hash, const char *k2, int k2l) +{ + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (unsigned char)ind; + } + + for (ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (hash[ind] + k2[ind%k2l]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], + const char encrypted_response[16], + const char *constant) +{ + struct MD5Context ctx3; + + MD5Init(&ctx3); + MD5Update(&ctx3, encrypted_response, 5); + MD5Update(&ctx3, constant, strlen(constant)); + MD5Final(digest, &ctx3); + + calc_hash(hash, digest, 16); +} + +enum ntlmssp_direction { + NTLMSSP_SEND, + NTLMSSP_RECEIVE +}; + +static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + enum ntlmssp_direction direction, + DATA_BLOB *sig) +{ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; + char seq_num[4]; + uchar digest[16]; + SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); + + hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); + hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_update(data, length, &ctx); + hmac_md5_final(digest, &ctx); + + if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data, sig->length); + break; + } + } else { + uint32 crc; + crc = crc32_buffer(data, length); + if (!msrpc_gen(sig, "ddd", 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data, sig->length); + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + ntlmssp_state->ntlmssp_seq_num++; + return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); +} + +/** + * Check the signature of an incoming packet + * @note caller *must* check that the signature is the size it expects + * + */ + +NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + const DATA_BLOB *sig) +{ + DATA_BLOB local_sig; + NTSTATUS nt_status; + + if (sig->length < 8) { + DEBUG(0, ("NTLMSSP packet check failed due to short signiture (%u bytes)!\n", + sig->length)); + } + + nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, + length, NTLMSSP_RECEIVE, &local_sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); + return nt_status; + } + + if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(5, ("BAD SIG: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); + + DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); + return NT_STATUS_ACCESS_DENIED; + } +} + +/** + Initialise the state for NTLMSSP signing. +*/ +NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) +{ + unsigned char p24[24]; + unsigned char lm_hash[16]; + + if (!ntlmssp_state->lm_resp.data) { + /* can't sign or check signitures yet */ + return NT_STATUS_UNSUCCESSFUL; + } + + E_deshash(ntlmssp_state->password, lm_hash); + + NTLMSSPOWFencrypt(lm_hash, ntlmssp_state->lm_resp.data, p24); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + { + calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, ntlmssp_state->cli_sign_const, p24, CLI_SIGN); + calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, ntlmssp_state->cli_seal_const, p24, CLI_SEAL); + calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, ntlmssp_state->srv_sign_const, p24, SRV_SIGN); + calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, ntlmssp_state->srv_seal_const, p24, SRV_SEAL); + } + else + { + char k2[8]; + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + calc_hash(ntlmssp_state->ntlmssp_hash, k2, 8); + } + + ntlmssp_state->ntlmssp_seq_num = 0; + + ZERO_STRUCT(lm_hash); + return NT_STATUS_OK; +} diff --git a/source4/libcli/util/pwd_cache.c b/source4/libcli/util/pwd_cache.c new file mode 100644 index 0000000000..0d84f04ee3 --- /dev/null +++ b/source4/libcli/util/pwd_cache.c @@ -0,0 +1,72 @@ +/* + Unix SMB/CIFS implementation. + Password cacheing. obfuscation is planned + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + + 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" + +/**************************************************************************** + Initialises a password structure. +****************************************************************************/ + +static void pwd_init(struct pwd_info *pwd) +{ + memset((char *)pwd->password , '\0', sizeof(pwd->password )); + memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); + memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd)); + memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf)); + memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf)); + + pwd->null_pwd = True; /* safest option... */ + pwd->cleartext = False; + pwd->crypted = False; +} + +/**************************************************************************** + Makes lm and nt hashed passwords. +****************************************************************************/ + +static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) +{ + pstring dos_passwd; + + pwd_init(pwd); + + push_ascii_pstring(dos_passwd, clr); + + nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; +} + +/**************************************************************************** + Stores a cleartext password. +****************************************************************************/ + +void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) +{ + pwd_init(pwd); + push_ascii_fstring(pwd->password, clr); + pwd->cleartext = True; + pwd->null_pwd = False; + pwd->crypted = False; + pwd_make_lm_nt_16(pwd, clr); +} + + diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c new file mode 100644 index 0000000000..cde77f94a3 --- /dev/null +++ b/source4/libcli/util/smbdes.c @@ -0,0 +1,415 @@ +/* + Unix SMB/CIFS implementation. + + a partial implementation of DES designed for use in the + SMB authentication protocol + + Copyright (C) Andrew Tridgell 1998 + + 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" + +/* NOTES: + + This code makes no attempt to be fast! In fact, it is a very + slow implementation + + This code is NOT a complete DES implementation. It implements only + the minimum necessary for SMB authentication, as used by all SMB + products (including every copy of Microsoft Windows95 ever sold) + + In particular, it can only do a unchained forward DES pass. This + means it is not possible to use this code for encryption/decryption + of data, instead it is only useful as a "hash" algorithm. + + There is no entry point into this code that allows normal DES operation. + + I believe this means that this code does not come under ITAR + regulations but this is NOT a legal opinion. If you are concerned + about the applicability of ITAR regulations to this code then you + should confirm it for yourself (and maybe let me know if you come + up with a different answer to the one above) +*/ + + +#define uchar unsigned char + +static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4}; + +static const uchar perm2[48] = {14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32}; + +static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7}; + +static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1}; + +static const uchar perm5[32] = { 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25}; + + +static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25}; + + +static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + +static const uchar sbox[8][4][16] = { + {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; + +static void permute(char *out, const char *in, const uchar *p, int n) +{ + int i; + for (i=0;i>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } +} + + +static void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) +{ + int i; + char outb[64]; + char inb[64]; + char keyb[64]; + unsigned char key2[8]; + + str_to_key(key, key2); + + for (i=0;i<64;i++) { + inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + outb[i] = 0; + } + + dohash(outb, inb, keyb, forw); + + for (i=0;i<8;i++) { + out[i] = 0; + } + + for (i=0;i<64;i++) { + if (outb[i]) + out[i/8] |= (1<<(7-(i%8))); + } +} + +void E_P16(const unsigned char *p14,unsigned char *p16) +{ + unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + smbhash(p16, sp8, p14, 1); + smbhash(p16+8, sp8, p14+7, 1); +} + +void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24) +{ + smbhash(p24, c8, p21, 1); + smbhash(p24+8, c8, p21+7, 1); + smbhash(p24+16, c8, p21+14, 1); +} + +void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out) +{ + smbhash(out, in, p14, 0); + smbhash(out+8, in+8, p14+7, 0); +} + +void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out) +{ + smbhash(out, in, p14, 1); + smbhash(out+8, in+8, p14+7, 1); +} + +void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key) +{ + unsigned char buf[8]; + + smbhash(buf, in, key, 1); + smbhash(out, buf, key+9, 1); +} + +void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) +{ + unsigned char buf[8]; + static unsigned char key2[8]; + + smbhash(buf, in, key, 1); + key2[0] = key[7]; + smbhash(out, buf, key2, 1); +} + +void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) +{ + static unsigned char key2[8]; + + smbhash(out, in, key, forw); + key2[0] = key[7]; + smbhash(out + 8, in + 8, key2, forw); +} + +void SamOEMhash( unsigned char *data, const unsigned char *key, int val) +{ + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (s_box[ind] + key[ind%16]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + for( ind = 0; ind < val; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } +} + +/* Decode a sam password hash into a password. The password hash is the + same method used to store passwords in the NT registry. The DES key + used is based on the RID of the user. */ + +void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw) +{ + uchar s[14]; + + s[0] = s[4] = s[8] = s[12] = (uchar)(rid & 0xFF); + s[1] = s[5] = s[9] = s[13] = (uchar)((rid >> 8) & 0xFF); + s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF); + s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF); + + smbhash(out, in, s, forw); + smbhash(out+8, in+8, s+7, forw); +} diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c new file mode 100644 index 0000000000..00c2b58146 --- /dev/null +++ b/source4/libcli/util/smbencrypt.c @@ -0,0 +1,418 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-1998 + Modified by Jeremy Allison 1995. + Copyright (C) Jeremy Allison 1995-2000. + Copyright (C) Luke Kennethc Casson Leighton 1996-2000. + Copyright (C) Andrew Bartlett 2002-2003 + + 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 "byteorder.h" + +/* + This implements the X/Open SMB password encryption + It takes a password ('unix' string), a 8 byte "crypt key" + and puts 24 bytes of encrypted password into p24 */ +void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); + E_deshash(passwd, p21); + + SMBOWFencrypt(p21, c8, p24); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + dump_data(100, (char *)p21, 16); + dump_data(100, (const char *)c8, 8); + dump_data(100, (char *)p24, 24); +#endif +} + +/** + * Creates the MD4 Hash of the users password in NT UNICODE. + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with md4, caller allocated 16 byte buffer + */ + +void E_md4hash(const char *passwd, uchar p16[16]) +{ + int len; + smb_ucs2_t wpwd[129]; + + /* Password must be converted to NT unicode - null terminated. */ + push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); + /* Calculate length in bytes */ + len = strlen_w(wpwd) * sizeof(int16); + + mdfour(p16, (unsigned char *)wpwd, len); + ZERO_STRUCT(wpwd); +} + +/** + * Creates the DES forward-only Hash of the users password in DOS ASCII charset + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with DES, caller allocated 16 byte buffer + */ + +void E_deshash(const char *passwd, uchar p16[16]) +{ + fstring dospwd; + ZERO_STRUCT(dospwd); + ZERO_STRUCTP(p16); + + /* Password must be converted to DOS charset - null terminated, uppercase. */ + push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + E_P16(dospwd, p16); + + ZERO_STRUCT(dospwd); +} + +/** + * Creates the MD4 and DES (LM) Hash of the users password. + * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password. + * @param passwd password in 'unix' charset. + * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer + * @param p16 return password hashed with des, caller allocated 16 byte buffer + */ + +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +{ + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash(pwd, nt_p16); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); + dump_data(120, pwd, strlen(pwd)); + dump_data(100, (char *)nt_p16, 16); +#endif + + E_deshash(pwd, (uchar *)p16); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); + dump_data(120, pwd, strlen(pwd)); + dump_data(100, (char *)p16, 16); +#endif +} + +/* Does both the NTLMv2 owfs of a user's password */ +BOOL ntv2_owf_gen(const uchar owf[16], + const char *user_in, const char *domain_in, uchar kr_buf[16]) +{ + smb_ucs2_t *user; + smb_ucs2_t *domain; + + size_t user_byte_len; + size_t domain_byte_len; + + HMACMD5Context ctx; + + user_byte_len = push_ucs2_allocate(&user, user_in); + if (user_byte_len == (size_t)-1) { + DEBUG(0, ("push_uss2_allocate() for user returned -1 (probably malloc() failure)\n")); + return False; + } + + domain_byte_len = push_ucs2_allocate(&domain, domain_in); + if (domain_byte_len == (size_t)-1) { + DEBUG(0, ("push_uss2_allocate() for domain returned -1 (probably malloc() failure)\n")); + return False; + } + + strupper_w(user); + strupper_w(domain); + + SMB_ASSERT(user_byte_len >= 2); + SMB_ASSERT(domain_byte_len >= 2); + + /* We don't want null termination */ + user_byte_len = user_byte_len - 2; + domain_byte_len = domain_byte_len - 2; + + hmac_md5_init_limK_to_64(owf, 16, &ctx); + hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); + hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); + hmac_md5_final(kr_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); + dump_data(100, (const char *)user, user_byte_len); + dump_data(100, (const char *)domain, domain_byte_len); + dump_data(100, owf, 16); + dump_data(100, kr_buf, 16); +#endif + + SAFE_FREE(user); + SAFE_FREE(domain); + return True; +} + +/* Does the des encryption from the NT or LM MD4 hash. */ +void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) +{ + uchar p21[21]; + + ZERO_STRUCT(p21); + + memcpy(p21, passwd, 16); + E_P24(p21, c8, p24); +} + +/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ +void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); + memcpy(p21, passwd, 8); + memset(p21 + 8, 0xbd, 8); + + E_P24(p21, ntlmchalresp, p24); +#ifdef DEBUG_PASSWORD + DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); + dump_data(100, (char *)p21, 21); + dump_data(100, (const char *)ntlmchalresp, 8); + dump_data(100, (char *)p24, 24); +#endif +} + + +/* Does the NT MD4 hash then des encryption. */ + +void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) +{ + uchar p21[21]; + + memset(p21,'\0',21); + + E_md4hash(passwd, p21); + SMBOWFencrypt(p21, c8, p24); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); + dump_data(100, (char *)p21, 16); + dump_data(100, (char *)c8, 8); + dump_data(100, (char *)p24, 24); +#endif +} + +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) +{ + int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); + + if (new_pw_len > 512) + { + DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); + return False; + } + + /* + * Now setup the data area. + * We need to generate a random fill + * for this area to make it harder to + * decrypt. JRA. + */ + generate_random_buffer((unsigned char *)data, 516, False); + push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len, + STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII)); + SIVAL(data, 512, new_pw_len); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, data, 516); +#endif + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); + + return True; +} + +/* Does the md5 encryption from the NT hash for NTLMv2. */ +void SMBOWFencrypt_ntv2(const uchar kr[16], + const DATA_BLOB srv_chal, + const DATA_BLOB cli_chal, + uchar resp_buf[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); + hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); + hmac_md5_final(resp_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); + dump_data(100, srv_chal.data, srv_chal.length); + dump_data(100, cli_chal.data, cli_chal.length); + dump_data(100, resp_buf, 16); +#endif +} + +void SMBsesskeygen_ntv2(const uchar kr[16], + const uchar * nt_resp, uint8 sess_key[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(nt_resp, 16, &ctx); + hmac_md5_final((unsigned char *)sess_key, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv2:\n")); + dump_data(100, sess_key, 16); +#endif +} + +void SMBsesskeygen_ntv1(const uchar kr[16], + const uchar * nt_resp, uint8 sess_key[16]) +{ + mdfour((unsigned char *)sess_key, kr, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv1:\n")); + dump_data(100, sess_key, 16); +#endif +} + +DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], + DATA_BLOB server_chal, size_t client_chal_length) +{ + uchar ntlmv2_response[16]; + DATA_BLOB ntlmv2_client_data; + DATA_BLOB final_response; + + /* NTLMv2 */ + + /* We also get to specify some random data */ + ntlmv2_client_data = data_blob(NULL, client_chal_length); + generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + + /* put it into nt_response, for the code below to put into the packet */ + final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); + /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ + memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); + + return final_response; +} + +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB server_chal, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *session_key) +{ + uchar nt_hash[16]; + uchar ntlm_v2_hash[16]; + E_md4hash(password, nt_hash); + + /* We don't use the NT# directly. Instead we use it mashed up with + the username and domain. + This prevents username swapping during the auth exchange + */ + if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) { + return False; + } + + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + + /* LMv2 */ + + *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); + + *session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data); + + return True; +} + +/*********************************************************** + encode a password buffer. The caller gets to figure out + what to put in it. +************************************************************/ +BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length) +{ + generate_random_buffer((unsigned char *)buffer, 516, True); + + memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length); + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + SIVAL(buffer, 512, new_pw_length); + + return True; +} + +/*********************************************************** + decode a password buffer + *new_pw_len is the length in bytes of the possibly mulitbyte + returned password including termination. +************************************************************/ +BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len) +{ + int byte_len=0; + + /* + Warning !!! : This function is called from some rpc call. + The password IN the buffer is a UNICODE string. + The password IN new_pwrd is an ASCII string + If you reuse that code somewhere else check first. + */ + + /* The length of the new password is in the last 4 bytes of the data buffer. */ + + byte_len = IVAL(in_buffer, 512); + +#ifdef DEBUG_PASSWORD + dump_data(100, in_buffer, 516); +#endif + + /* Password cannot be longer than 128 characters */ + if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); + DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); + return False; + } + + /* decode into the return buffer. Buffer must be a pstring */ + *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("decode_pw_buffer: new_pwrd: ")); + dump_data(100, (char *)new_pwrd, *new_pw_len); + DEBUG(100,("multibyte len:%d\n", *new_pw_len)); + DEBUG(100,("original char len:%d\n", byte_len/2)); +#endif + + return True; +} diff --git a/source4/libcli/util/smberr.c b/source4/libcli/util/smberr.c new file mode 100644 index 0000000000..d6eabcfbce --- /dev/null +++ b/source4/libcli/util/smberr.c @@ -0,0 +1,181 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Andrew Tridgell 1998-2003 + + 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" + +/* + error code stuff - put together by Merik Karman + merik@blackadder.dsh.oz.au +*/ + +struct err_code_struct { + const char *name; + int code; + const char *message; +}; + +/* Dos Error Messages */ +static const struct err_code_struct dos_msgs[] = { + {"ERRbadfunc",ERRbadfunc,"Invalid function."}, + {"ERRbadfile",ERRbadfile,"File not found."}, + {"ERRbadpath",ERRbadpath,"Directory invalid."}, + {"ERRnofids",ERRnofids,"No file descriptors available"}, + {"ERRnoaccess",ERRnoaccess,"Access denied."}, + {"ERRbadfid",ERRbadfid,"Invalid file handle."}, + {"ERRbadmcb",ERRbadmcb,"Memory control blocks destroyed."}, + {"ERRnomem",ERRnomem,"Insufficient server memory to perform the requested function."}, + {"ERRbadmem",ERRbadmem,"Invalid memory block address."}, + {"ERRbadenv",ERRbadenv,"Invalid environment."}, + {"ERRbadformat",11,"Invalid format."}, + {"ERRbadaccess",ERRbadaccess,"Invalid open mode."}, + {"ERRbaddata",ERRbaddata,"Invalid data."}, + {"ERRres",ERRres,"reserved."}, + {"ERRbaddrive",ERRbaddrive,"Invalid drive specified."}, + {"ERRremcd",ERRremcd,"A Delete Directory request attempted to remove the server's current directory."}, + {"ERRdiffdevice",ERRdiffdevice,"Not same device."}, + {"ERRnofiles",ERRnofiles,"A File Search command can find no more files matching the specified criteria."}, + {"ERRbadshare",ERRbadshare,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, + {"ERRlock",ERRlock,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRunsup", ERRunsup, "The operation is unsupported"}, + {"ERRnosuchshare", ERRnosuchshare, "You specified an invalid share name"}, + {"ERRfilexists",ERRfilexists,"The file named in a Create Directory, Make New File or Link request already exists."}, + {"ERRinvalidname",ERRinvalidname, "Invalid name"}, + {"ERRbadpipe",ERRbadpipe,"Pipe invalid."}, + {"ERRpipebusy",ERRpipebusy,"All instances of the requested pipe are busy."}, + {"ERRpipeclosing",ERRpipeclosing,"Pipe close in progress."}, + {"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."}, + {"ERRmoredata",ERRmoredata,"There is more data to be returned."}, + {"ERRinvgroup",ERRinvgroup,"Invalid workgroup (try the -W option)"}, + {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, + {"ERRdiskfull",ERRdiskfull,"Disk full"}, + {"ERRgeneral",ERRgeneral, "General failure"}, + {"ERRunknownlevel",ERRunknownlevel, "Unknown info level"}, + {NULL,-1,NULL}}; + +/* Server Error Messages */ +static const struct err_code_struct server_msgs[] = { + {"ERRerror",1,"Non-specific error code."}, + {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, + {"ERRbadtype",3,"reserved."}, + {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, + {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, + {"ERRinvnetname",6,"Invalid network name in tree connect."}, + {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, + {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, + {"ERRqtoobig",50,"Print queue full -- no space."}, + {"ERRqeof",51,"EOF on print queue dump."}, + {"ERRinvpfid",52,"Invalid print file FID."}, + {"ERRsmbcmd",64,"The server did not recognize the command received."}, + {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, + {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, + {"ERRreserved",68,"reserved."}, + {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, + {"ERRreserved",70,"reserved."}, + {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, + {"ERRpaused",81,"Server is paused."}, + {"ERRmsgoff",82,"Not receiving messages."}, + {"ERRnoroom",83,"No room to buffer message."}, + {"ERRrmuns",87,"Too many remote user names."}, + {"ERRtimeout",88,"Operation timed out."}, + {"ERRnoresource",89,"No resources currently available for request."}, + {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, + {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, + {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, + {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, + {"ERRcontmpx",252,"Continue in MPX mode."}, + {"ERRreserved",253,"reserved."}, + {"ERRreserved",254,"reserved."}, + {"ERRnosupport",0xFFFF,"Function not supported."}, + {NULL,-1,NULL}}; + +/* Hard Error Messages */ +static const struct err_code_struct hard_msgs[] = { + {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, + {"ERRbadunit",20,"Unknown unit."}, + {"ERRnotready",21,"Drive not ready."}, + {"ERRbadcmd",22,"Unknown command."}, + {"ERRdata",23,"Data error (CRC)."}, + {"ERRbadreq",24,"Bad request structure length."}, + {"ERRseek",25 ,"Seek error."}, + {"ERRbadmedia",26,"Unknown media type."}, + {"ERRbadsector",27,"Sector not found."}, + {"ERRnopaper",28,"Printer out of paper."}, + {"ERRwrite",29,"Write fault."}, + {"ERRread",30,"Read fault."}, + {"ERRgeneral",31,"General failure."}, + {"ERRbadshare",32,"An open conflicts with an existing open."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, + {"ERRFCBUnavail",35,"No FCBs are available to process request."}, + {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, + {NULL,-1,NULL}}; + + +static const struct { + uint8 class; + const char *class_name; + const struct err_code_struct *err_msgs; +} err_classes[] = { + {0,"SUCCESS",NULL}, + {0x01,"ERRDOS",dos_msgs}, + {0x02,"ERRSRV",server_msgs}, + {0x03,"ERRHRD",hard_msgs}, + {0x04,"ERRXOS",NULL}, + {0xE1,"ERRRMX1",NULL}, + {0xE2,"ERRRMX2",NULL}, + {0xE3,"ERRRMX3",NULL}, + {0xFF,"ERRCMD",NULL}, + {-1,NULL,NULL}}; + + +/* return a dos error string given a error class and error code */ +const char *dos_errstr(uint8 class, uint16 code) +{ + static char *msg; + int i, j; + const struct err_code_struct *err_msgs; + + if (msg) { + free(msg); + msg = NULL; + } + + for (i=0;err_classes[i].class_name;i++) { + if (class == err_classes[i].class) break; + } + if (!err_classes[i].class_name) { + asprintf(&msg, "Unknown DOS error %d:%d\n", class, code); + return msg; + } + + err_msgs = err_classes[i].err_msgs; + + for (j=0;err_msgs && err_msgs[j].name;j++) { + if (err_msgs[j].code == code) { + asprintf(&msg, "%s:%s (%s)\n", + err_classes[i].class_name, + err_msgs[j].name, + err_msgs[j].message); + return msg; + } + } + + asprintf(&msg, "Unknown DOS error %s:%d\n", err_classes[i].class_name, code); + return msg; +} -- cgit From e063ea70ad05d9a8cc927ddbcf61aa3b4ea04ade Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 02:01:01 +0000 Subject: use the \\server\share form of tconx to work with servers that don't cope with the simpler form (This used to be commit 295cc63fb8d99d403c863a7b30cb30382070a6f9) --- source4/libcli/raw/clitree.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 2a41273913..60e8610bd8 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -269,10 +269,13 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, tcon.generic.level = RAW_TCON_TCONX; tcon.tconx.in.flags = 0; tcon.tconx.in.password = data_blob(NULL, 0); - tcon.tconx.in.path = service; + asprintf(&tcon.tconx.in.path, "\\\\%s\\%s", dest_host, service); tcon.tconx.in.device = service_type; status = smb_tree_connect(tree, mem_ctx, &tcon); + + free(tcon.tconx.in.path); + if (!NT_STATUS_IS_OK(status)) { cli_tree_close(tree); talloc_destroy(mem_ctx); -- cgit From b05a2aad5434b188b624db97fb53dc67534a24c6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 02:02:17 +0000 Subject: add support for 32 bit pid using the PIDHIGH field. This allows the test suite to see if it is supported. w2k3 doesn't seem to support it. (This used to be commit c946be06a49e9a187045f2372ef7c1b987eaf6e5) --- source4/libcli/raw/rawrequest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 9c2b2c7367..52349d415c 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -176,7 +176,8 @@ struct cli_request *cli_request_setup_session(struct cli_session *session, } SSVAL(req->out.hdr, HDR_FLG2, flags2); - SSVAL(req->out.hdr, HDR_PID, session->pid); + SSVAL(req->out.hdr, HDR_PID, session->pid & 0xFFFF); + SSVAL(req->out.hdr, HDR_PIDHIGH, session->pid >> 16); SSVAL(req->out.hdr, HDR_UID, session->vuid); return req; -- cgit From 75c0125fb71b0562e7bdd85c391764796b5f12f6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 16:04:21 +0000 Subject: - added SMBntrename test suite - allow username of form DOMAIN\username or DOMAIN/username - added ntrename to gentest (This used to be commit 2b464472c17b791eb5b117f89d5aaea2bf60f6ad) --- source4/libcli/cliconnect.c | 15 ++++++++++++++- source4/libcli/clifile.c | 9 +++++---- source4/libcli/namequery.c | 2 +- source4/libcli/raw/rawfile.c | 27 +++++++++++++++++++-------- 4 files changed, 39 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index da8a842dae..03112176d4 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -146,13 +146,24 @@ NTSTATUS cli_full_connection(struct cli_state **ret_cli, { struct cli_tree *tree; NTSTATUS status; + char *p; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("cli_full_connection"); *ret_cli = NULL; + /* if the username is of the form DOMAIN\username then split out the domain */ + p = strpbrk(username, "\\/"); + if (p) { + domain = talloc_strndup(mem_ctx, username, PTR_DIFF(p, username)); + username = talloc_strdup(mem_ctx, p+1); + } + status = cli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, username, domain, password); if (!NT_STATUS_IS_OK(status)) { - return status; + goto done; } (*ret_cli) = cli_state_init(); @@ -162,6 +173,8 @@ NTSTATUS cli_full_connection(struct cli_state **ret_cli, (*ret_cli)->transport = tree->session->transport; tree->reference_count++; +done: + talloc_destroy(mem_ctx); return status; } diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index c203e4633d..cd01d51017 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -137,11 +137,12 @@ BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t g ****************************************************************************/ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) { - struct smb_rename parms; + union smb_rename parms; - parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; - parms.in.pattern1 = fname_src; - parms.in.pattern2 = fname_dst; + parms.generic.level = RAW_RENAME_RENAME; + parms.rename.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; + parms.rename.in.pattern1 = fname_src; + parms.rename.in.pattern2 = fname_dst; return NT_STATUS_IS_OK(smb_raw_rename(cli->tree, &parms)); } diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 2f6343dcaf..a04e883138 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -801,7 +801,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam } } else if(strequal( tok, "lmhosts")) { /* REWRITE: add back in? */ - DEBUG(0,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok)); + DEBUG(2,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok)); } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ if (name_type != 0x1D && diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 279dfcf0c1..57b6ded66f 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -32,16 +32,27 @@ Rename a file - async interface ****************************************************************************/ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, - struct smb_rename *parms) + union smb_rename *parms) { struct cli_request *req; - SETUP_REQUEST(SMBmv, 1, 0); - - SSVAL(req->out.vwv, VWV(0), parms->in.attrib); - - cli_req_append_ascii4(req, parms->in.pattern1, STR_TERMINATE); - cli_req_append_ascii4(req, parms->in.pattern2, STR_TERMINATE); + switch (parms->generic.level) { + case RAW_RENAME_RENAME: + SETUP_REQUEST(SMBmv, 1, 0); + SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib); + cli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE); + cli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE); + break; + + case RAW_RENAME_NTRENAME: + SETUP_REQUEST(SMBntrename, 4, 0); + SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib); + SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags); + SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.root_fid); + cli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); + cli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); + break; + } if (!cli_request_send(req)) { cli_request_destroy(req); @@ -55,7 +66,7 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, Rename a file - sync interface ****************************************************************************/ NTSTATUS smb_raw_rename(struct cli_tree *tree, - struct smb_rename *parms) + union smb_rename *parms) { struct cli_request *req = smb_raw_rename_send(tree, parms); return cli_request_simple_recv(req); -- cgit From 4b3d329ca21e731729af0a305386bee5d748ae92 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 22:23:18 +0000 Subject: - added a raw smb scanner - its not a root_fid in ntrename (This used to be commit 74be55efdc77d4ba7e70d0554cbd72472522abff) --- source4/libcli/raw/rawfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 57b6ded66f..97ec7c1f00 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -48,7 +48,7 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, SETUP_REQUEST(SMBntrename, 4, 0); SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib); SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags); - SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.root_fid); + SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.unknown); cli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); cli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); break; -- cgit From 89f55d36f31ae51e365fc0e4020be0728091bd53 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Aug 2003 01:31:31 +0000 Subject: added the ancient SMBcreate operation to the testsuite and client lib (This used to be commit 3eef35e581b5e1802711b9b5297f61800a7e242e) --- source4/libcli/raw/rawfile.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 97ec7c1f00..e9d3a8305d 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -330,6 +330,13 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par put_dos_date3(req->out.vwv, VWV(1), parms->mknew.in.write_time); cli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE); break; + + case RAW_OPEN_CREATE: + SETUP_REQUEST(SMBcreate, 3, 0); + SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib); + put_dos_date3(req->out.vwv, VWV(1), parms->create.in.write_time); + cli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE); + break; case RAW_OPEN_CTEMP: SETUP_REQUEST(SMBctemp, 3, 0); @@ -421,6 +428,11 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0)); break; + case RAW_OPEN_CREATE: + CLI_CHECK_WCT(req, 1); + parms->create.out.fnum = SVAL(req->in.vwv, VWV(0)); + break; + case RAW_OPEN_CTEMP: CLI_CHECK_WCT(req, 1); parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0)); -- cgit From 2efe201fa4082f0aad7360b9f6f21c7683a29e96 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 14 Aug 2003 21:56:26 +0000 Subject: client/client.c - cannot initialize struct with non-const values include/byteorder.h - fix for IRIX compiler - cannot cast an LVALUE include/smb_interfaces.h - remove empty structure source/lib/debug.c - void functions cannot return value libcli/clifile.c - cannot assign *struct to struct (This used to be commit 9a724762012f55d21d44ea87add7daf21f7414d1) --- source4/libcli/clifile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index cd01d51017..d37a68c1e1 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -505,11 +505,11 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, } if (a_time) { - *a_time = &parms.getattre.out.access_time; + *a_time = parms.getattre.out.access_time; } if (m_time) { - *m_time = &parms.getattre.out.write_time; + *m_time = parms.getattre.out.write_time; } return True; -- cgit From 9e96467d36e9c4bf51ba74390cde0b84f08eeac7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 15:13:24 +0000 Subject: nicer formatting in getattre (This used to be commit 52657c369b26710ed4d3a8cce81dd518547c583e) --- source4/libcli/raw/rawfileinfo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index f685cef9c3..70121025d0 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -419,12 +419,12 @@ static NTSTATUS smb_raw_getattrE_recv(struct cli_request *req, } CLI_CHECK_WCT(req, 11); - parms->getattre.out.create_time = make_unix_date2(req->in.vwv + VWV(0)); - parms->getattre.out.access_time = make_unix_date2(req->in.vwv + VWV(2)); - parms->getattre.out.write_time = make_unix_date2(req->in.vwv + VWV(4)); - parms->getattre.out.size = IVAL(req->in.vwv, VWV(6)); - parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8)); - parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10)); + parms->getattre.out.create_time = make_unix_date2(req->in.vwv + VWV(0)); + parms->getattre.out.access_time = make_unix_date2(req->in.vwv + VWV(2)); + parms->getattre.out.write_time = make_unix_date2(req->in.vwv + VWV(4)); + parms->getattre.out.size = IVAL(req->in.vwv, VWV(6)); + parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8)); + parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10)); failed: return cli_request_destroy(req); -- cgit From 0efd81efec653f97e6d24e9b19cc6bd6f72185fe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 15:13:43 +0000 Subject: fixed a comment typo (This used to be commit 4cc8fef8ca278b19eb4601e7660fc1976594412e) --- source4/libcli/raw/rawsetfileinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 4044686c64..b82c20176b 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -22,7 +22,7 @@ #include "includes.h" /**************************************************************************** - Handle qfileinfo/qpathinfo trans2 backend. + Handle setfileinfo/setpathinfo trans2 backend. ****************************************************************************/ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, TALLOC_CTX *mem_ctx, @@ -232,7 +232,7 @@ static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree, put_dos_date2(req->out.vwv, VWV(1), parms->setattre.in.create_time); put_dos_date2(req->out.vwv, VWV(3), parms->setattre.in.access_time); put_dos_date2(req->out.vwv, VWV(5), parms->setattre.in.write_time); - + if (!cli_request_send(req)) { cli_request_destroy(req); return NULL; -- cgit From d3bc355533af429be645bb1c965350fa532d03d4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 15:14:14 +0000 Subject: some servers don't return a fs_type and dev_type (This used to be commit eaec1bdaadd744c63fb270b3807bc284dfadb37d) --- source4/libcli/raw/clitree.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 60e8610bd8..a088ae7023 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -283,8 +283,12 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, } tree->tid = tcon.tconx.out.cnum; - tree->device = talloc_strdup(tree->mem_ctx, tcon.tconx.out.dev_type); - tree->fs_type = talloc_strdup(tree->mem_ctx, tcon.tconx.out.fs_type); + if (tcon.tconx.out.dev_type) { + tree->device = talloc_strdup(tree->mem_ctx, tcon.tconx.out.dev_type); + } + if (tcon.tconx.out.fs_type) { + tree->fs_type = talloc_strdup(tree->mem_ctx, tcon.tconx.out.fs_type); + } talloc_destroy(mem_ctx); -- cgit From 03ecf9b2aa1cc011c94a79dfda010f1f14f617fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 15:14:49 +0000 Subject: try to cope with servers that return a blank alt_name field (This used to be commit 0a1cda392ad29c95c8886a26c34fcea0b19ecebf) --- source4/libcli/clitrans2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 6fd5c2ce28..0ceac925f7 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -213,7 +213,11 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, return cli_nt_error(cli); } - *alt_name = strdup(parms.alt_name_info.out.fname.s); + if (!parms.alt_name_info.out.fname.s) { + *alt_name = strdup(""); + } else { + *alt_name = strdup(parms.alt_name_info.out.fname.s); + } talloc_destroy(mem_ctx); -- cgit From cc38992e3f6c6ca04ae7170cb03028d3d1c06ae3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 16:19:48 +0000 Subject: fixed some places where we don't brace (flags & STR_UNICODE) this fixes the samba4 server with ascii clients (This used to be commit c770603ac6c3331a4ac79a650cbbbeb21c778137) --- source4/libcli/raw/rawrequest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 52349d415c..fa3b3ab627 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -754,7 +754,7 @@ size_t cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx, char **dest, const char *src, int byte_len, unsigned flags) { if (!(flags & STR_ASCII) && - ((flags & STR_UNICODE || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { + (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { return cli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags); } -- cgit From efacfb37fc0d7310c72c40bfed4b52ecaf365b11 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 17:50:16 +0000 Subject: wrong typecast (This used to be commit de7674ebefe3a8b0f953afe983ce058e11f827c2) --- source4/libcli/raw/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c index 5edc56daa9..24da1455de 100644 --- a/source4/libcli/raw/clikrb5.c +++ b/source4/libcli/raw/clikrb5.c @@ -74,7 +74,7 @@ { pkaddr->addrtype = ADDRTYPE_INET; pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else __ERROR__XX__UNKNOWN_ADDRTYPE -- cgit From 8e4ab747b02207671203d40cd2a78692da78faef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 18:33:43 +0000 Subject: more fixes from the IRIX compiler (thanks herb!) (This used to be commit 4cf3839b727c77a727abb558bd9473119a092913) --- source4/libcli/clifile.c | 4 ++-- source4/libcli/clilist.c | 2 +- source4/libcli/raw/clitree.c | 2 -- source4/libcli/raw/rawfileinfo.c | 2 -- source4/libcli/raw/rawnegotiate.c | 2 +- 5 files changed, 4 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index d37a68c1e1..27ead40740 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -34,11 +34,11 @@ static BOOL cli_link_internal(struct cli_state *cli, NTSTATUS status; if (hard_link) { - parms.generic.level = SMB_SFILEINFO_UNIX_HLINK; + parms.generic.level = RAW_SFILEINFO_UNIX_HLINK; parms.unix_hlink.file.fname = fname_src; parms.unix_hlink.in.link_dest = fname_dst; } else { - parms.generic.level = SMB_SFILEINFO_UNIX_LINK; + parms.generic.level = RAW_SFILEINFO_UNIX_LINK; parms.unix_link.file.fname = fname_src; parms.unix_link.in.link_dest = fname_dst; } diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 620e4382f4..425a6002cc 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -94,7 +94,7 @@ int cli_list_new(struct cli_state *cli, const char *Mask, uint16 attribute, char *mask; int ff_eos = 0, i, ff_searchcount; int ff_dir_handle=0; - int level; + enum search_level level; /* initialize state for search */ state.dirlist = NULL; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index a088ae7023..1e9104308e 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -121,7 +121,6 @@ NTSTATUS smb_tree_connect_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, uni case RAW_TCON_TCONX: ZERO_STRUCT(parms->tconx.out); - CLI_CHECK_MIN_WCT(req, 0); /* this depends on the protocol level */ parms->tconx.out.cnum = SVAL(req->in.hdr, HDR_TID); if (req->in.wct >= 4) { parms->tconx.out.options = SVAL(req->in.vwv, VWV(3)); @@ -245,7 +244,6 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, mem_ctx = talloc_init("tcon"); if (!mem_ctx) { - cli_tree_close(tree); return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 70121025d0..41fe1225cc 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -146,7 +146,6 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, case RAW_FILEINFO_STREAM_INFO: case RAW_FILEINFO_STREAM_INFORMATION: - FINFO_CHECK_MIN_SIZE(0); ofs = 0; parms->stream_info.out.num_streams = 0; parms->stream_info.out.streams = NULL; @@ -228,7 +227,6 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, return NT_STATUS_OK; case RAW_FILEINFO_UNIX_LINK: - FINFO_CHECK_MIN_SIZE(0); cli_blob_pull_string(session, mem_ctx, blob, &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE); return NT_STATUS_OK; diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 78b2e00706..04941f6118 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -22,7 +22,7 @@ #include "includes.h" static const struct { - int prot; + enum protocol_types prot; const char *name; } prots[] = { {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, -- cgit From de10237719db8101cd9487b257761d4721f857ab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Aug 2003 18:54:44 +0000 Subject: more fixes from the IRIX compiler (thanks herb!) (This used to be commit 02d068ba7d81d6db25122144981c63f74ad44025) --- source4/libcli/raw/rawtrans.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 508f920268..f8076f7133 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -206,7 +206,6 @@ struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, int wct = 14 + parms->in.setup_count; struct cli_request *req; char *outdata,*outparam; - int data_sent, param_sent; int i; const int padding = 3; @@ -216,10 +215,8 @@ struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, } /* fill in SMB parameters */ - data_sent = parms->in.data.length; - param_sent = parms->in.params.length; outparam = req->out.data + padding; - outdata = outparam + param_sent; + outdata = outparam + parms->in.params.length; /* make sure we don't leak data via the padding */ memset(req->out.data, 0, padding); -- cgit From a59229614ebeb17f3e4db2edcb70b71f7bf31982 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 21:37:42 +0000 Subject: don't dereference null pointer (This used to be commit ba5d1cde98f9146ffc889ac89ec79331e2bfae18) --- source4/libcli/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 03112176d4..ea5f4e8a5d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -211,7 +211,7 @@ struct cli_state *cli_state_init(void) ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - if (!cli) return; + if (!cli || !cli->tree) return; cli->tree->reference_count++; cli_tree_close(cli->tree); if (cli->mem_ctx) { -- cgit From 4809559c6450d0768a6b03681098286e3d5294da Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 23:57:05 +0000 Subject: don't leak memory if cli->tree is NULL (This used to be commit b034c4b86e2faddf0928810a3e56c03d6aaef9f5) --- source4/libcli/cliconnect.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index ea5f4e8a5d..4fdffa6287 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -211,9 +211,11 @@ struct cli_state *cli_state_init(void) ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - if (!cli || !cli->tree) return; - cli->tree->reference_count++; - cli_tree_close(cli->tree); + if (!cli) return; + if (cli->tree) { + cli->tree->reference_count++; + cli_tree_close(cli->tree); + } if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); } -- cgit From 11c5869a450d5f78a9395889ec03f77732cc8be5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 31 Aug 2003 03:16:52 +0000 Subject: I think I've finally got the ascii/unicode issues right in trans2 find first Also expanded the rename test a little (This used to be commit 723af7f097a8c7f23dac23039e479811559ac3cb) --- source4/libcli/raw/rawfile.c | 2 +- source4/libcli/raw/rawrequest.c | 23 +++++++++++++++++------ source4/libcli/raw/rawsearch.c | 8 ++++---- 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index e9d3a8305d..0dc2a15c11 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -48,7 +48,7 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, SETUP_REQUEST(SMBntrename, 4, 0); SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib); SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags); - SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.unknown); + SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size); cli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); cli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); break; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index fa3b3ab627..139f031178 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -963,8 +963,9 @@ size_t cli_blob_pull_string(struct cli_session *session, uint16 len_offset, uint16 str_offset, unsigned flags) { + int extra; dest->s = NULL; - + if (len_offset > blob->length-4) { return 0; } @@ -973,19 +974,29 @@ size_t cli_blob_pull_string(struct cli_session *session, } else { dest->private_length = IVAL(blob->data, len_offset); } + extra = 0; dest->s = NULL; if (!(flags & STR_ASCII) && ((flags & STR_UNICODE) || (session->transport->negotiate.capabilities & CAP_UNICODE))) { + int align = 0; if ((str_offset&1) && !(flags & STR_NOALIGN)) { - str_offset++; + align = 1; + } + if (flags & STR_LEN_NOTERM) { + extra = 2; } - return cli_blob_pull_ucs2(mem_ctx, blob, &dest->s, - blob->data+str_offset, dest->private_length, flags); + return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, &dest->s, + blob->data+str_offset+align, + dest->private_length, flags); + } + + if (flags & STR_LEN_NOTERM) { + extra = 1; } - return cli_blob_pull_ascii(mem_ctx, blob, &dest->s, - blob->data+str_offset, dest->private_length, flags); + return extra + cli_blob_pull_ascii(mem_ctx, blob, &dest->s, + blob->data+str_offset, dest->private_length, flags); } /* diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index bdc39bb68c..222bf53623 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -263,8 +263,8 @@ static int parse_trans2_search(struct cli_tree *tree, data->standard.attrib = SVAL(blob->data, 20); len = cli_blob_pull_string(tree->session, mem_ctx, blob, &data->standard.name, - 22, 23, STR_LEN8BIT); - return (len + 23 + 3) & ~3; + 22, 23, STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM); + return len + 23; case RAW_SEARCH_EA_SIZE: if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { @@ -283,8 +283,8 @@ static int parse_trans2_search(struct cli_tree *tree, data->ea_size.ea_size = IVAL(blob->data, 22); len = cli_blob_pull_string(tree->session, mem_ctx, blob, &data->ea_size.name, - 26, 27, STR_LEN8BIT | STR_NOALIGN); - return len + 27; + 26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN); + return len + 27 + 1; case RAW_SEARCH_DIRECTORY_INFO: if (blob->length < 65) return -1; -- cgit From 0becf4d68329ca599f3e34ee97ca3f72d0e9425f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Sep 2003 04:37:33 +0000 Subject: thanks to ntfsd and some google searches I worked out what the unknown fields in level 261 and level 262 of directory search are, plus the names of the levels the unknown fields are a 64bit unique file id, and match the 64 bit number from the internal_information qfileinfo level (This used to be commit b69f54eb028a24144a2e813f059b08644118ab09) --- source4/libcli/raw/rawfileinfo.c | 3 +-- source4/libcli/raw/rawsearch.c | 53 +++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 30 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 41fe1225cc..fd66080057 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -173,8 +173,7 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, case RAW_FILEINFO_INTERNAL_INFORMATION: FINFO_CHECK_SIZE(8); - parms->internal_information.out.device = IVAL(blob->data, 0); - parms->internal_information.out.inode = IVAL(blob->data, 4); + parms->internal_information.out.file_id = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_FILEINFO_ACCESS_INFORMATION: diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 222bf53623..430cf925a6 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -362,48 +362,45 @@ static int parse_trans2_search(struct cli_tree *tree, return ofs; - case RAW_SEARCH_261: + case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: if (blob->length < 81) return -1; ofs = IVAL(blob->data, 0); - data->level_261.file_index = IVAL(blob->data, 4); - data->level_261.create_time = cli_pull_nttime(blob->data, 8); - data->level_261.access_time = cli_pull_nttime(blob->data, 16); - data->level_261.write_time = cli_pull_nttime(blob->data, 24); - data->level_261.change_time = cli_pull_nttime(blob->data, 32); - data->level_261.size = BVAL(blob->data, 40); - data->level_261.alloc_size = BVAL(blob->data, 48); - data->level_261.attrib = IVAL(blob->data, 56); - data->level_261.ea_size = IVAL(blob->data, 64); - data->level_261.unknown[0] = IVAL(blob->data, 68); - data->level_261.unknown[1] = IVAL(blob->data, 72); - data->level_261.unknown[2] = IVAL(blob->data, 76); + data->id_full_directory_info.file_index = IVAL(blob->data, 4); + data->id_full_directory_info.create_time = cli_pull_nttime(blob->data, 8); + data->id_full_directory_info.access_time = cli_pull_nttime(blob->data, 16); + data->id_full_directory_info.write_time = cli_pull_nttime(blob->data, 24); + data->id_full_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->id_full_directory_info.size = BVAL(blob->data, 40); + data->id_full_directory_info.alloc_size = BVAL(blob->data, 48); + data->id_full_directory_info.attrib = IVAL(blob->data, 56); + data->id_full_directory_info.ea_size = IVAL(blob->data, 64); + data->id_full_directory_info.file_id = BVAL(blob->data, 72); len = cli_blob_pull_string(tree->session, mem_ctx, blob, - &data->level_261.name, + &data->id_full_directory_info.name, 60, 80, 0); if (ofs != 0 && ofs < 80+len) { return -1; } return ofs; - case RAW_SEARCH_262: + case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: if (blob->length < 105) return -1; ofs = IVAL(blob->data, 0); - data->level_262.file_index = IVAL(blob->data, 4); - data->level_262.create_time = cli_pull_nttime(blob->data, 8); - data->level_262.access_time = cli_pull_nttime(blob->data, 16); - data->level_262.write_time = cli_pull_nttime(blob->data, 24); - data->level_262.change_time = cli_pull_nttime(blob->data, 32); - data->level_262.size = BVAL(blob->data, 40); - data->level_262.alloc_size = BVAL(blob->data, 48); - data->level_262.attrib = SVAL(blob->data, 56); - data->level_262.ea_size = IVAL(blob->data, 64); + data->id_both_directory_info.file_index = IVAL(blob->data, 4); + data->id_both_directory_info.create_time = cli_pull_nttime(blob->data, 8); + data->id_both_directory_info.access_time = cli_pull_nttime(blob->data, 16); + data->id_both_directory_info.write_time = cli_pull_nttime(blob->data, 24); + data->id_both_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->id_both_directory_info.size = BVAL(blob->data, 40); + data->id_both_directory_info.alloc_size = BVAL(blob->data, 48); + data->id_both_directory_info.attrib = SVAL(blob->data, 56); + data->id_both_directory_info.ea_size = IVAL(blob->data, 64); cli_blob_pull_string(tree->session, mem_ctx, blob, - &data->level_262.short_name, + &data->id_both_directory_info.short_name, 68, 70, STR_LEN8BIT | STR_UNICODE); - data->level_262.unknown[0] = IVAL(blob->data, 94); - data->level_262.unknown[1] = IVAL(blob->data, 98); + data->id_both_directory_info.file_id = BVAL(blob->data, 96); len = cli_blob_pull_string(tree->session, mem_ctx, blob, - &data->level_262.name, + &data->id_both_directory_info.name, 60, 104, 0); if (ofs != 0 && ofs < 104+len) { return -1; -- cgit From 4e73a3c0feb47c761fdcded9e6c2ac6d32534d9b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 10 Oct 2003 05:40:32 +0000 Subject: fixed snprintf.c for systems that have only some of the *printf() family of functions cope with servers that return bogus (too large) values in max_xmit cope with a couple more error conditions in RAW-SFILEINFO better startup time heuristics in NBENCH (This used to be commit 89f7261ba589e5760b3cf9c3594eab9d7198dd7e) --- source4/libcli/clireadwrite.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index e1d154b283..1e6c0fc064 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -42,6 +42,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ * rounded down to a multiple of 1024. */ readsize = (cli->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; + if (readsize > 0xFFFF) readsize = 0xFFFF; while (total < size) { NTSTATUS status; @@ -91,6 +92,9 @@ ssize_t cli_write(struct cli_state *cli, return 0; } + if (block > 0xFFFF) block = 0xFFFF; + + parms.writex.level = RAW_WRITE_WRITEX; parms.writex.in.fnum = fnum; parms.writex.in.wmode = write_mode; @@ -133,6 +137,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, do { size_t size = MIN(size1, cli->transport->negotiate.max_xmit - 48); + if (size > 0xFFFF) size = 0xFFFF; parms.write.in.fnum = fnum; parms.write.in.offset = offset; -- cgit From 931dc553909c4ee345f7c16ca79f56f84ae39ff6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 Oct 2003 10:17:05 +0000 Subject: Implement raw SMBtrans by backending the SMBtrans2 send code. Receive is the same for trans and trans2. (This used to be commit 7d21af3fdf6cf5144a41021425179ca2bba553b3) --- source4/libcli/raw/rawtrans.c | 61 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index f8076f7133..f31b1eaf7e 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -194,20 +194,32 @@ failed: return cli_request_destroy(req); } +NTSTATUS smb_raw_trans_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + struct smb_trans2 *parms) +{ + return smb_raw_trans2_recv(req, mem_ctx, parms); +} /**************************************************************************** - trans2 raw async interface - only BLOBs used in this interface. -note that this doesn't yet support multi-part requests + trans/trans2 raw async interface - only BLOBs used in this interface. + note that this doesn't yet support multi-part requests ****************************************************************************/ -struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, - struct smb_trans2 *parms) +struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, + struct smb_trans2 *parms, + uint8 command) { - uint8 command = SMBtrans2; int wct = 14 + parms->in.setup_count; struct cli_request *req; char *outdata,*outparam; int i; - const int padding = 3; + int padding; + size_t namelen = 0; + + if (command == SMBtrans) + padding = 1; + else + padding = 3; req = cli_request_setup(tree, command, wct, padding); if (!req) { @@ -231,9 +243,12 @@ struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, SIVAL(req->out.vwv,VWV(6),parms->in.timeout); SSVAL(req->out.vwv,VWV(8),0); /* reserved */ SSVAL(req->out.vwv,VWV(9),parms->in.params.length); - SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)); + if (command == SMBtrans && parms->in.trans_name) + namelen = cli_req_append_string(req, parms->in.trans_name, + STR_TERMINATE); + SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)+namelen); SSVAL(req->out.vwv,VWV(11),parms->in.data.length); - SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)); + SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)+namelen); SSVAL(req->out.vwv,VWV(13),parms->in.setup_count); for (i=0;iin.setup_count;i++) { SSVAL(req->out.vwv,VWV(14)+i*2,parms->in.setup[i]); @@ -253,6 +268,23 @@ struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, return req; } +/**************************************************************************** + trans/trans2 raw async interface - only BLOBs used in this interface. +note that this doesn't yet support multi-part requests +****************************************************************************/ + +struct cli_request *smb_raw_trans_send(struct cli_tree *tree, + struct smb_trans2 *parms) +{ + return smb_raw_trans_send_backend(tree, parms, SMBtrans); +} + +struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, + struct smb_trans2 *parms) +{ + return smb_raw_trans_send_backend(tree, parms, SMBtrans2); +} + /* trans2 synchronous blob interface */ @@ -267,6 +299,19 @@ NTSTATUS smb_raw_trans2(struct cli_tree *tree, } +/* + trans synchronous blob interface +*/ +NTSTATUS smb_raw_trans(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_trans2 *parms) +{ + struct cli_request *req; + req = smb_raw_trans_send(tree, parms); + if (!req) return NT_STATUS_UNSUCCESSFUL; + return smb_raw_trans_recv(req, mem_ctx, parms); +} + /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ -- cgit From 476adf5725cd06bcd04623a2c61701158076a3b9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 Oct 2003 10:24:13 +0000 Subject: Initial version of raw dcerpc client support. (This used to be commit 34a2cc10992953897268ca864f2851f4c2d99e1e) --- source4/libcli/raw/rawdcerpc.c | 222 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 source4/libcli/raw/rawdcerpc.c (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c new file mode 100644 index 0000000000..11bd0057ce --- /dev/null +++ b/source4/libcli/raw/rawdcerpc.c @@ -0,0 +1,222 @@ +/* + Unix SMB/CIFS implementation. + raw dcerpc operations + + Copyright (C) Tim Potter, 2003 + + 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" + +static int put_uuid(char *data, int offset, struct dcerpc_uuid *uuid) +{ + int i; + + SIVAL(data, offset, uuid->time_low); offset += 4; + SSVAL(data, offset, uuid->time_mid); offset += 2; + SSVAL(data, offset, uuid->time_hi_and_version); offset += 2; + for (i = 0; i < 8; i++) + SCVAL(data, offset + i, uuid->remaining[i]); + offset += 8; + + return offset; +} + +DATA_BLOB dcerpc_raw_bind_setup(struct dcerpc_bind *parms) +{ + int i, offset, size; + char *data; + + /* Allocate storage for bind request */ + + size = 28; + for (i = 0; i < parms->in.num_contexts; i++) { + size += 24; /* as header + uuid */ + size += 20 * parms->in.ctx_list[i].num_ts; /* xfer syntaxes */ + } + size += parms->in.auth_verifier.length; + + data = smb_xmalloc(size); + memset(data, 0, size); + + parms->in.hdr.frag_len = size; + + /* Create bind request */ + + SCVAL(data, 0, parms->in.hdr.rpc_vers); + SCVAL(data, 1, parms->in.hdr.rpc_vers_minor); + SCVAL(data, 2, parms->in.hdr.ptype); + SCVAL(data, 3, parms->in.hdr.pfc_flags); + for (i = 0; i < 4; i++) + SCVAL(data, 4 + i, parms->in.hdr.drep[i]); + SSVAL(data, 8, parms->in.hdr.frag_len); + SSVAL(data, 10, parms->in.auth_verifier.length); + SIVAL(data, 12, parms->in.hdr.call_id); + + SSVAL(data, 16, parms->in.max_xmit_frag); + SSVAL(data, 18, parms->in.max_recv_frag); + SIVAL(data, 20, parms->in.assoc_group_id); + SIVAL(data, 24, parms->in.num_contexts); + + offset = 28; + for (i = 0; i < parms->in.num_contexts; i++) { + struct p_ctx_list *ctx = &parms->in.ctx_list[i]; + int j; + + SSVAL(data, offset, ctx->cont_id); offset += 2; + SSVAL(data, offset, ctx->num_ts); offset += 2; + offset = put_uuid(data, offset, &ctx->as->if_uuid); + SIVAL(data, offset, ctx->as->if_version); offset += 4; + for (j = 0; j < ctx->num_ts; j++) { + offset = put_uuid(data, offset, &ctx->ts[i]->if_uuid); + SIVAL(data, offset, ctx->ts[i]->if_version); + offset += 4; + } + } + + if (parms->in.auth_verifier.length) + memcpy(&data[offset], parms->in.auth_verifier.data, + parms->in.auth_verifier.length); + + return data_blob(data, size); +} + +NTSTATUS dcerpc_raw_bind_send(struct cli_dcerpc_pipe *p, + struct dcerpc_bind *parms) +{ + struct smb_trans2 trans; + DATA_BLOB blob; + NTSTATUS result; + uint16 setup[2]; + + blob = dcerpc_raw_bind_setup(parms); + + ZERO_STRUCT(trans); + + trans.in.max_data = blob.length; + trans.in.setup_count = 2; + trans.in.setup = setup; + trans.in.trans_name = "\\PIPE\\"; + + setup[0] = TRANSACT_DCERPCCMD; + setup[1] = p->fnum; + + trans.in.data = blob; + + result = smb_raw_trans(p->tree, p->mem_ctx, &trans); + + data_blob_free(&blob); + + return result; +} + +NTSTATUS dcerpc_raw_bind_recv(struct cli_dcerpc_pipe *p, + struct dcerpc_bind *parms) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS dcerpc_raw_bind(struct cli_dcerpc_pipe *p, struct dcerpc_bind *parms) +{ + NTSTATUS result; + + result = dcerpc_raw_bind_send(p, parms); + if (NT_STATUS_IS_ERR(result)) + return result; + return dcerpc_raw_bind_recv(p, parms); +} + +DATA_BLOB dcerpc_raw_request_setup(struct dcerpc_request *parms) +{ + int size, i; + char *data; + + /* Allocate storage for request */ + + size = 24 + parms->in.stub_data.length; + + data = smb_xmalloc(size); + memset(data, 0, size); + + parms->in.hdr.frag_len = size; + parms->in.alloc_hint = parms->in.stub_data.length; + + SCVAL(data, 0, parms->in.hdr.rpc_vers); + SCVAL(data, 1, parms->in.hdr.rpc_vers_minor); + SCVAL(data, 2, parms->in.hdr.ptype); + SCVAL(data, 3, parms->in.hdr.pfc_flags); + for (i = 0; i < 4; i++) + SCVAL(data, 4 + i, parms->in.hdr.drep[i]); + SSVAL(data, 8, parms->in.hdr.frag_len); + SSVAL(data, 10, parms->in.auth_verifier.length); + SIVAL(data, 12, parms->in.hdr.call_id); + + SIVAL(data, 16, parms->in.alloc_hint); + SSVAL(data, 20, parms->in.cont_id); + SSVAL(data, 22, parms->in.opnum); + + if (parms->in.stub_data.length) + memcpy(&data[24], parms->in.stub_data.data, + parms->in.stub_data.length); + + return data_blob(data, size); +} + +NTSTATUS dcerpc_raw_request_send(struct cli_dcerpc_pipe *p, + struct dcerpc_request *parms) +{ + struct smb_trans2 trans; + DATA_BLOB blob; + NTSTATUS result; + uint16 setup[2]; + + blob = dcerpc_raw_request_setup(parms); + + ZERO_STRUCT(trans); + + trans.in.max_data = blob.length; + trans.in.setup_count = 2; + trans.in.setup = setup; + trans.in.trans_name = "\\PIPE\\"; + + setup[0] = TRANSACT_DCERPCCMD; + setup[1] = p->fnum; + + trans.in.data = blob; + + result = smb_raw_trans(p->tree, p->mem_ctx, &trans); + + data_blob_free(&blob); + + return result; +} + +NTSTATUS dcerpc_raw_request_recv(struct cli_dcerpc_pipe *p, + struct dcerpc_request *parms) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS dcerpc_raw_request(struct cli_dcerpc_pipe *p, + struct dcerpc_request *parms) +{ + NTSTATUS result; + + result = dcerpc_raw_request_send(p, parms); + if (NT_STATUS_IS_ERR(result)) + return result; + return dcerpc_raw_request_recv(p, parms); +} -- cgit From 8d87d7ede5a17a244ff3d47faf038e6c40eaba44 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 Oct 2003 10:25:12 +0000 Subject: Cli level code for initial dcerpc client support. (This used to be commit 94686a3f941086510415273f71503cd5f18179b8) --- source4/libcli/clidcerpc.c | 254 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 source4/libcli/clidcerpc.c (limited to 'source4/libcli') diff --git a/source4/libcli/clidcerpc.c b/source4/libcli/clidcerpc.c new file mode 100644 index 0000000000..fffd4e0941 --- /dev/null +++ b/source4/libcli/clidcerpc.c @@ -0,0 +1,254 @@ +/* + Unix SMB/CIFS implementation. + raw dcerpc operations + + Copyright (C) Tim Potter, 2003 + + 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" + +struct cli_dcerpc_pipe *cli_dcerpc_pipe_init(struct cli_tree *tree) +{ + struct cli_dcerpc_pipe *p; + + TALLOC_CTX *mem_ctx = talloc_init("cli_dcerpc_tree"); + if (mem_ctx == NULL) + return NULL; + + p = talloc_zero(mem_ctx, sizeof(*p)); + if (!p) { + talloc_destroy(mem_ctx); + return NULL; + } + + p->mem_ctx = mem_ctx; + p->tree = tree; + p->tree->reference_count++; + + return p; +} + +void cli_dcerpc_pipe_close(struct cli_dcerpc_pipe *p) +{ + if (!p) return; + p->reference_count--; + if (p->reference_count <= 0) { + cli_tree_close(p->tree); + talloc_destroy(p->mem_ctx); + } +} + +static void init_dcerpc_hdr(struct dcerpc_hdr *hdr, uint8 ptype, + uint8 pfc_flags, uint32 call_id) +{ + hdr->rpc_vers = 5; + hdr->rpc_vers_minor = 0; + hdr->ptype = ptype; + hdr->pfc_flags = pfc_flags; + hdr->drep[0] = 0x10; /* Little endian */ + hdr->call_id = call_id; +} + +struct syntax_id trans_synt_v2 = +{ + { + 0x8a885d04, 0x1ceb, 0x11c9, + { 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60 } + }, 0x02 +}; + +struct syntax_id synt_netlogon_v2 = +{ + { + 0x8a885d04, 0x1ceb, 0x11c9, + { 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60 } + }, 0x02 +}; + +struct syntax_id synt_wkssvc_v1 = +{ + { + 0x6bffd098, 0xa112, 0x3610, + { 0x98, 0x33, 0x46, 0xc3, + 0xf8, 0x7e, 0x34, 0x5a } + }, 0x01 +}; + +struct syntax_id synt_srvsvc_v3 = +{ + { + 0x4b324fc8, 0x1670, 0x01d3, + { 0x12, 0x78, 0x5a, 0x47, + 0xbf, 0x6e, 0xe1, 0x88 } + }, 0x03 +}; + +struct syntax_id synt_lsarpc_v0 = +{ + { + 0x12345778, 0x1234, 0xabcd, + { 0xef, 0x00, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xab } + }, 0x00 +}; + +struct syntax_id synt_lsarpc_v0_ds = +{ + { + 0x3919286a, 0xb10c, 0x11d0, + { 0x9b, 0xa8, 0x00, 0xc0, + 0x4f, 0xd9, 0x2e, 0xf5 } + }, 0x00 +}; + +struct syntax_id synt_samr_v1 = +{ + { + 0x12345778, 0x1234, 0xabcd, + { 0xef, 0x00, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xac } + }, 0x01 +}; + +struct syntax_id synt_netlogon_v1 = +{ + { + 0x12345678, 0x1234, 0xabcd, + { 0xef, 0x00, 0x01, 0x23, + 0x45, 0x67, 0xcf, 0xfb } + }, 0x01 +}; + +struct syntax_id synt_winreg_v1 = +{ + { + 0x338cd001, 0x2244, 0x31f1, + { 0xaa, 0xaa, 0x90, 0x00, + 0x38, 0x00, 0x10, 0x03 } + }, 0x01 +}; + +struct syntax_id synt_spoolss_v1 = +{ + { + 0x12345678, 0x1234, 0xabcd, + { 0xef, 0x00, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xab } + }, 0x01 +}; + +struct syntax_id synt_netdfs_v3 = +{ + { + 0x4fc742e0, 0x4a10, 0x11cf, + { 0x82, 0x73, 0x00, 0xaa, + 0x00, 0x4a, 0xe6, 0x73 } + }, 0x03 +}; + +struct known_pipes { + const char *client_pipe; + struct p_ctx_list ctx_list; +}; + +const struct known_pipes known_pipes[] = +{ + { PIPE_LSARPC , { 0, 1, &synt_lsarpc_v0, &trans_synt_v2 }}, + { PIPE_SAMR , { 0, 1, &synt_samr_v1, &trans_synt_v2 }}, + { PIPE_NETLOGON, { 0, 1, &synt_netlogon_v1, &trans_synt_v2 }}, + { PIPE_SRVSVC , { 0, 1, &synt_srvsvc_v3 , &trans_synt_v2 }}, + { PIPE_WKSSVC , { 0, 1, &synt_wkssvc_v1 , &trans_synt_v2 }}, + { PIPE_WINREG , { 0, 1, &synt_winreg_v1 , &trans_synt_v2 }}, + { PIPE_SPOOLSS , { 0, 1, &synt_spoolss_v1, &trans_synt_v2 }}, + { PIPE_NETDFS , { 0, 1, &synt_netdfs_v3 , &trans_synt_v2 }}, + { NULL , { 0, 0, NULL, NULL }} +}; + +/* Perform a bind using the given syntaxes */ + +NTSTATUS cli_dcerpc_bind(struct cli_dcerpc_pipe *p, int num_contexts, + struct p_ctx_list *ctx_list) +{ + TALLOC_CTX *mem_ctx; + struct dcerpc_bind parms; + NTSTATUS status; + + mem_ctx = talloc_init("cli_dcerpc_bind"); + + ZERO_STRUCT(parms); + + init_dcerpc_hdr(&parms.in.hdr, RPC_BIND, RPC_FLG_FIRST|RPC_FLG_LAST, + p->call_id++); + + parms.in.max_xmit_frag = 5680; + parms.in.max_recv_frag = 5680; + parms.in.num_contexts = num_contexts; + parms.in.ctx_list = ctx_list; + + status = dcerpc_raw_bind(p, &parms); + + talloc_destroy(mem_ctx); + + return status; +} + +/* Perform a bind using the given well-known pipe name */ + +NTSTATUS cli_dcerpc_bind_byname(struct cli_dcerpc_pipe *p, + const char *pipe_name) +{ + const struct known_pipes *pi; + + for (pi = known_pipes; pi->client_pipe; pi++) { + if (strequal(&pi->client_pipe[5], pipe_name)) + break; + } + + if (pi->client_pipe == NULL) + return NT_STATUS_UNSUCCESSFUL; + + + return cli_dcerpc_bind(p, 1, &pi->ctx_list); +} + +NTSTATUS cli_dcerpc_request(struct cli_dcerpc_pipe *p, uint16 opnum, + DATA_BLOB stub_data) +{ + TALLOC_CTX *mem_ctx; + struct dcerpc_request parms; + NTSTATUS status; + + mem_ctx = talloc_init("cli_dcerpc_request"); + + ZERO_STRUCT(parms); + + init_dcerpc_hdr(&parms.in.hdr, RPC_REQUEST, + RPC_FLG_FIRST|RPC_FLG_LAST, p->call_id++); + + parms.in.alloc_hint = 0; + parms.in.cont_id = 0; + parms.in.opnum = opnum; + parms.in.stub_data = stub_data; + + status = dcerpc_raw_request(p, &parms); + + talloc_destroy(mem_ctx); + + return status; +} -- cgit From 4cac564d71f7387497fa23f2b6bcc0461a1978bc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 Oct 2003 10:59:19 +0000 Subject: A fix for making transfer syntax a pointer instead of an array of pointers in struct p_ctx_list. (This used to be commit e99e28aa36f31e862e89cef246b50a34b5115af9) --- source4/libcli/raw/rawdcerpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index 11bd0057ce..1cc034de78 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -81,8 +81,8 @@ DATA_BLOB dcerpc_raw_bind_setup(struct dcerpc_bind *parms) offset = put_uuid(data, offset, &ctx->as->if_uuid); SIVAL(data, offset, ctx->as->if_version); offset += 4; for (j = 0; j < ctx->num_ts; j++) { - offset = put_uuid(data, offset, &ctx->ts[i]->if_uuid); - SIVAL(data, offset, ctx->ts[i]->if_version); + offset = put_uuid(data, offset, &ctx->ts[i].if_uuid); + SIVAL(data, offset, ctx->ts[i].if_version); offset += 4; } } -- cgit From 7fd381376f88ae99a4bf022d89f21ae497b48c1a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Oct 2003 08:32:26 +0000 Subject: - a few portability fixes from Jim Myers - added SMBD_LISTEN_BACKLOG in local.h - added the beginnings of a ndr/rpc parsing framework for Samba4. It currently correctly parses security descriptors for the nttrans QUERY_SECDESC call, but I hope it will become a reasonable framework that an idl based generator can work to (This used to be commit 9bf904fc34f88e0581f93656e73d3c01ca96f761) --- source4/libcli/raw/rawacl.c | 97 ++++++++++++++++++++++ source4/libcli/rpc/librpc.h | 71 ++++++++++++++++ source4/libcli/rpc/rpc_basic.c | 97 ++++++++++++++++++++++ source4/libcli/rpc/rpc_sec.c | 179 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/rpc/rpc_sec.h | 81 +++++++++++++++++++ source4/libcli/rpc/rpcparse.c | 105 ++++++++++++++++++++++++ 6 files changed, 630 insertions(+) create mode 100644 source4/libcli/raw/rawacl.c create mode 100644 source4/libcli/rpc/librpc.h create mode 100644 source4/libcli/rpc/rpc_basic.c create mode 100644 source4/libcli/rpc/rpc_sec.c create mode 100644 source4/libcli/rpc/rpc_sec.h create mode 100644 source4/libcli/rpc/rpcparse.c (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c new file mode 100644 index 0000000000..4cd3338ec5 --- /dev/null +++ b/source4/libcli/raw/rawacl.c @@ -0,0 +1,97 @@ +/* + Unix SMB/CIFS implementation. + ACL get/set operations + Copyright (C) Andrew Tridgell 2003 + + 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" + +/**************************************************************************** +fetch file ACL (async send) +****************************************************************************/ +struct cli_request *smb_raw_query_secdesc_send(struct cli_tree *tree, + struct smb_query_secdesc *query) +{ + struct smb_nttrans nt; + uint8 params[8]; + + nt.in.max_setup = 0; + nt.in.max_param = 4; + nt.in.max_data = 0x10000; + nt.in.setup_count = 0; + nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; + nt.in.setup = NULL; + + SSVAL(params, 0, query->in.fnum); + SSVAL(params, 2, 0); /* padding */ + SIVAL(params, 4, query->in.secinfo_flags); + + nt.in.params.data = params; + nt.in.params.length = 8; + + nt.in.data = data_blob(NULL, 0); + + return smb_raw_nttrans_send(tree, &nt); +} + + +/**************************************************************************** +fetch file ACL (async recv) +****************************************************************************/ +NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + struct smb_query_secdesc *query) +{ + NTSTATUS status; + struct smb_nttrans nt; + struct ndr_parse *rpc; + + status = smb_raw_nttrans_recv(req, mem_ctx, &nt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* check that the basics are valid */ + if (nt.out.params.length != 4 || + IVAL(nt.out.params.data, 0) > nt.out.data.length) { + return NT_STATUS_INVALID_PARAMETER; + } + + nt.out.data.length = IVAL(nt.out.params.data, 0); + + rpc = ndr_parse_init_blob(&nt.out.data, mem_ctx); + if (!rpc) { + return NT_STATUS_INVALID_PARAMETER; + } + + status = ndr_parse_security_descriptor(rpc, &query->out.sd); + + return NT_STATUS_OK; +} + + +/**************************************************************************** +fetch file ACL (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_query_secdesc(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_query_secdesc *query) +{ + struct cli_request *req = smb_raw_query_secdesc_send(tree, query); + return smb_raw_query_secdesc_recv(req, mem_ctx, query); +} + diff --git a/source4/libcli/rpc/librpc.h b/source4/libcli/rpc/librpc.h new file mode 100644 index 0000000000..f4f7101c90 --- /dev/null +++ b/source4/libcli/rpc/librpc.h @@ -0,0 +1,71 @@ +/* + Unix SMB/CIFS implementation. + rpc interface definitions + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* + this provides definitions for the libcli/rpc/ MSRPC library +*/ + + +/* this is the base structure passed to routines that + parse MSRPC formatted data + + note that in Samba4 we use separate routines and structures for + MSRPC marshalling and unmarshalling. Also note that these routines + are being kept deliberately very simple, and are not tied to a + particular transport +*/ +struct ndr_parse { + uint32 flags; /* LIBNDR_FLAG_* */ + char *data; + uint32 data_size; + uint32 offset; + TALLOC_CTX *mem_ctx; +}; + +struct ndr_parse_save { + uint32 data_size; + uint32 offset; +}; + +#define LIBNDR_FLAG_BIGENDIAN 1 + + +/* these are used to make the error checking on each element in libndr + less tedious, hopefully making the code more readable */ +#define NDR_CHECK(call) do { NTSTATUS _status; \ + _status = call; \ + if (!NT_STATUS_IS_OK(_status)) \ + return _status; \ + } while (0) + + +#define NDR_ALLOC(ndr, s) do { \ + (s) = talloc(ndr->mem_ctx, sizeof(*(s))); \ + if (!(s)) return NT_STATUS_NO_MEMORY; \ + } while (0) + +#define NDR_ALLOC_N(ndr, s, n) do { \ + if ((n) == 0) { \ + (s) = NULL; \ + } else { \ + (s) = talloc(ndr->mem_ctx, (n) * sizeof(*(s))); \ + if (!(s)) return NT_STATUS_NO_MEMORY; \ + } \ + } while (0) diff --git a/source4/libcli/rpc/rpc_basic.c b/source4/libcli/rpc/rpc_basic.c new file mode 100644 index 0000000000..5ff17f9d99 --- /dev/null +++ b/source4/libcli/rpc/rpc_basic.c @@ -0,0 +1,97 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling basic types + + Copyright (C) Andrew Tridgell 2003 + + 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" + +#define NDR_NEED_BYTES(ndr, n) do { \ + if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \ + return NT_STATUS_BUFFER_TOO_SMALL; \ + } \ +} while(0) + +#define NDR_ALIGN(ndr, n) do { \ + ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ + if (ndr->offset >= ndr->data_size) { \ + return NT_STATUS_BUFFER_TOO_SMALL; \ + } \ +} while(0) + +/* + parse a GUID +*/ +NTSTATUS ndr_parse_guid(struct ndr_parse *ndr, GUID *guid) +{ + int i; + NDR_NEED_BYTES(ndr, GUID_SIZE); + for (i=0;iinfo[i] = CVAL(ndr->data, ndr->offset + i); + } + ndr->offset += i; + return NT_STATUS_OK; +} + + +/* + parse a u8 +*/ +NTSTATUS ndr_parse_u8(struct ndr_parse *ndr, uint8 *v) +{ + NDR_NEED_BYTES(ndr, 1); + *v = CVAL(ndr->data, ndr->offset); + ndr->offset += 1; + return NT_STATUS_OK; +} + + +/* + parse a u16 +*/ +NTSTATUS ndr_parse_u16(struct ndr_parse *ndr, uint16 *v) +{ + NDR_ALIGN(ndr, 2); + NDR_NEED_BYTES(ndr, 2); + if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { + *v = RSVAL(ndr->data, ndr->offset); + } else { + *v = SVAL(ndr->data, ndr->offset); + } + ndr->offset += 2; + return NT_STATUS_OK; +} + + +/* + parse a u32 +*/ +NTSTATUS ndr_parse_u32(struct ndr_parse *ndr, uint32 *v) +{ + NDR_ALIGN(ndr, 4); + NDR_NEED_BYTES(ndr, 4); + if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { + *v = RIVAL(ndr->data, ndr->offset); + } else { + *v = IVAL(ndr->data, ndr->offset); + } + ndr->offset += 2; + return NT_STATUS_OK; +} + diff --git a/source4/libcli/rpc/rpc_sec.c b/source4/libcli/rpc/rpc_sec.c new file mode 100644 index 0000000000..49b50c758c --- /dev/null +++ b/source4/libcli/rpc/rpc_sec.c @@ -0,0 +1,179 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling security descriptors + and related structures + + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* + parse a security_ace +*/ +NTSTATUS ndr_parse_security_ace(struct ndr_parse *ndr, struct security_ace *ace) +{ + uint16 size; + struct ndr_parse_save save; + + ndr_parse_save(ndr, &save); + + NDR_CHECK(ndr_parse_u8(ndr, &ace->type)); + NDR_CHECK(ndr_parse_u8(ndr, &ace->flags)); + NDR_CHECK(ndr_parse_u16(ndr, &size)); + NDR_CHECK(ndr_parse_limit_size(ndr, size, 4)); + + NDR_CHECK(ndr_parse_u32(ndr, &ace->access_mask)); + + if (sec_ace_object(ace->type)) { + NDR_ALLOC(ndr, ace->obj); + NDR_CHECK(ndr_parse_u32(ndr, &ace->obj->flags)); + if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) { + NDR_CHECK(ndr_parse_guid(ndr, &ace->obj->object_guid)); + } + if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { + NDR_CHECK(ndr_parse_guid(ndr, &ace->obj->inherit_guid)); + } + } + + + NDR_CHECK(ndr_parse_dom_sid(ndr, &ace->trustee)); + + ndr_parse_restore(ndr, &save); + NDR_CHECK(ndr_parse_advance(ndr, size)); + + return NT_STATUS_OK; +} + +/* + parse a security_acl +*/ +NTSTATUS ndr_parse_security_acl(struct ndr_parse *ndr, struct security_acl *acl) +{ + int i; + uint16 size; + struct ndr_parse_save save; + + ndr_parse_save(ndr, &save); + + NDR_CHECK(ndr_parse_u16(ndr, &acl->revision)); + NDR_CHECK(ndr_parse_u16(ndr, &size)); + NDR_CHECK(ndr_parse_limit_size(ndr, size, 4)); + NDR_CHECK(ndr_parse_u32(ndr, &acl->num_aces)); + + NDR_ALLOC_N(ndr, acl->aces, acl->num_aces); + + for (i=0;inum_aces;i++) { + NDR_CHECK(ndr_parse_security_ace(ndr, &acl->aces[i])); + } + + ndr_parse_restore(ndr, &save); + NDR_CHECK(ndr_parse_advance(ndr, size)); + + return NT_STATUS_OK; +} + +/* + parse a security_acl offset and structure +*/ +NTSTATUS ndr_parse_security_acl_ofs(struct ndr_parse *ndr, struct security_acl **acl) +{ + uint32 ofs; + struct ndr_parse_save save; + + NDR_CHECK(ndr_parse_u32(ndr, &ofs)); + if (ofs == 0) { + /* it is valid for an acl ptr to be NULL */ + *acl = NULL; + return NT_STATUS_OK; + } + + ndr_parse_save(ndr, &save); + NDR_CHECK(ndr_parse_set_offset(ndr, ofs)); + NDR_ALLOC(ndr, *acl); + NDR_CHECK(ndr_parse_security_acl(ndr, *acl)); + ndr_parse_restore(ndr, &save); + + return NT_STATUS_OK; +} + + +/* + parse a dom_sid +*/ +NTSTATUS ndr_parse_dom_sid(struct ndr_parse *ndr, struct dom_sid *sid) +{ + int i; + + NDR_CHECK(ndr_parse_u8(ndr, &sid->sid_rev_num)); + NDR_CHECK(ndr_parse_u8(ndr, &sid->num_auths)); + for (i=0;i<6;i++) { + NDR_CHECK(ndr_parse_u8(ndr, &sid->id_auth[i])); + } + + NDR_ALLOC_N(ndr, sid->sub_auths, sid->num_auths); + + for (i=0;inum_auths;i++) { + NDR_CHECK(ndr_parse_u32(ndr, &sid->sub_auths[i])); + } + + return NT_STATUS_OK; +} + +/* + parse a dom_sid offset and structure +*/ +NTSTATUS ndr_parse_dom_sid_ofs(struct ndr_parse *ndr, struct dom_sid **sid) +{ + uint32 ofs; + struct ndr_parse_save save; + + NDR_CHECK(ndr_parse_u32(ndr, &ofs)); + if (ofs == 0) { + /* it is valid for a dom_sid ptr to be NULL */ + *sid = NULL; + return NT_STATUS_OK; + } + + ndr_parse_save(ndr, &save); + NDR_CHECK(ndr_parse_set_offset(ndr, ofs)); + NDR_ALLOC(ndr, *sid); + NDR_CHECK(ndr_parse_dom_sid(ndr, *sid)); + ndr_parse_restore(ndr, &save); + + return NT_STATUS_OK; +} + +/* + parse a security descriptor +*/ +NTSTATUS ndr_parse_security_descriptor(struct ndr_parse *ndr, + struct security_descriptor **sd) +{ + NDR_ALLOC(ndr, *sd); + + NDR_CHECK(ndr_parse_u8(ndr, &(*sd)->revision)); + NDR_CHECK(ndr_parse_u16(ndr, &(*sd)->type)); + NDR_CHECK(ndr_parse_dom_sid_ofs(ndr, &(*sd)->owner_sid)); + NDR_CHECK(ndr_parse_dom_sid_ofs(ndr, &(*sd)->group_sid)); + NDR_CHECK(ndr_parse_security_acl_ofs(ndr, &(*sd)->sacl)); + NDR_CHECK(ndr_parse_security_acl_ofs(ndr, &(*sd)->dacl)); + + return NT_STATUS_OK; +} diff --git a/source4/libcli/rpc/rpc_sec.h b/source4/libcli/rpc/rpc_sec.h new file mode 100644 index 0000000000..3cda400eb2 --- /dev/null +++ b/source4/libcli/rpc/rpc_sec.h @@ -0,0 +1,81 @@ +/* + Unix SMB/CIFS implementation. + + definitions for marshalling/unmarshalling security descriptors + and related structures + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + + +/* a domain SID. Note that unlike Samba3 this contains a pointer, + so you can't copy them using assignment */ +struct dom_sid { + uint8 sid_rev_num; /**< SID revision number */ + uint8 num_auths; /**< Number of sub-authorities */ + uint8 id_auth[6]; /**< Identifier Authority */ + uint32 *sub_auths; +}; + +/* an access control element */ +struct security_ace { + uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */ + uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */ + + uint32 access_mask; + + /* the 'obj' part is present when type is XXXX_TYPE_XXXX_OBJECT */ + struct { + uint32 flags; + GUID object_guid; + GUID inherit_guid; + } *obj; + + struct dom_sid trustee; +}; + + +/* a security ACL */ +struct security_acl { + uint16 revision; + uint32 num_aces; + + struct security_ace *aces; +}; + + +/* a security descriptor */ +struct security_descriptor { + uint8 revision; + uint16 type; /* SEC_DESC_xxxx flags */ + + struct dom_sid *owner_sid; + struct dom_sid *group_sid; + struct security_acl *sacl; /* system ACL */ + struct security_acl *dacl; /* user (discretionary) ACL */ +}; + +/* query security descriptor */ +struct smb_query_secdesc { + struct { + uint16 fnum; + uint32 secinfo_flags; + } in; + struct { + struct security_descriptor *sd; + } out; +}; diff --git a/source4/libcli/rpc/rpcparse.c b/source4/libcli/rpc/rpcparse.c new file mode 100644 index 0000000000..41e6919b72 --- /dev/null +++ b/source4/libcli/rpc/rpcparse.c @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + libndr interface + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* + this provides the core routines for MSNDR parsing functions +*/ + +#include "includes.h" + +/* + initialise a ndr parse structure from a data blob +*/ +struct ndr_parse *ndr_parse_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx) +{ + struct ndr_parse *ndr; + + ndr = talloc(mem_ctx, sizeof(*ndr)); + if (!ndr) return NULL; + + ndr->data = blob->data; + ndr->data_size = blob->length; + ndr->offset = 0; + ndr->mem_ctx = mem_ctx; + + return ndr; +} + + +/* limit the remaining size of the current ndr parse structure to the + given size, starting at the given offset + + this is used when a ndr packet has an explicit size on the wire, and we + need to make sure that we don't use more data than is indicated + + the 'ofs' parameter indicates how many bytes back from the current + offset in the buffer the 'size' number of bytes starts +*/ +NTSTATUS ndr_parse_limit_size(struct ndr_parse *ndr, uint32 size, uint32 ofs) +{ + uint32 new_size; + new_size = ndr->offset + size - ofs; + + if (new_size > ndr->data_size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ndr->data_size = new_size; + + return NT_STATUS_OK; +} + + +/* + advance by 'size' bytes +*/ +NTSTATUS ndr_parse_advance(struct ndr_parse *ndr, uint32 size) +{ + ndr->offset += size; + if (ndr->offset > ndr->data_size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + return NT_STATUS_OK; +} + +/* + set the parse offset to 'ofs' +*/ +NTSTATUS ndr_parse_set_offset(struct ndr_parse *ndr, uint32 ofs) +{ + ndr->offset = ofs; + if (ndr->offset > ndr->data_size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + return NT_STATUS_OK; +} + +/* save the offset/size of the current ndr state */ +void ndr_parse_save(struct ndr_parse *ndr, struct ndr_parse_save *save) +{ + save->offset = ndr->offset; + save->data_size = ndr->data_size; +} + +/* restore the size/offset of a ndr structure */ +void ndr_parse_restore(struct ndr_parse *ndr, struct ndr_parse_save *save) +{ + ndr->offset = save->offset; + ndr->data_size = save->data_size; +} -- cgit From c5cf47443985c34ad32c44c322901e0fc3a065d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 06:22:45 +0000 Subject: a major revamp of the low level dcerpc code in samba4, We can now do a successful LSA OpenPolicy using smbtorture (This used to be commit e925c315f55905060fcca1b188ae1f7e40baf514) --- source4/libcli/clidcerpc.c | 254 ---------------- source4/libcli/ndr/libndr.h | 85 ++++++ source4/libcli/ndr/ndr.c | 184 ++++++++++++ source4/libcli/ndr/ndr_basic.c | 140 +++++++++ source4/libcli/ndr/ndr_sec.c | 201 +++++++++++++ source4/libcli/ndr/ndr_sec.h | 90 ++++++ source4/libcli/raw/clisession.c | 4 +- source4/libcli/raw/rawacl.c | 52 +++- source4/libcli/raw/rawdcerpc.c | 215 +++----------- source4/libcli/raw/rawsearch.c | 8 +- source4/libcli/rpc/dcerpc.c | 644 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/rpc/dcerpc.h | 124 ++++++++ source4/libcli/rpc/librpc.h | 71 ----- source4/libcli/rpc/rpc_basic.c | 97 ------ source4/libcli/rpc/rpc_sec.c | 179 ----------- source4/libcli/rpc/rpc_sec.h | 81 ----- source4/libcli/rpc/rpcparse.c | 105 ------- 17 files changed, 1560 insertions(+), 974 deletions(-) delete mode 100644 source4/libcli/clidcerpc.c create mode 100644 source4/libcli/ndr/libndr.h create mode 100644 source4/libcli/ndr/ndr.c create mode 100644 source4/libcli/ndr/ndr_basic.c create mode 100644 source4/libcli/ndr/ndr_sec.c create mode 100644 source4/libcli/ndr/ndr_sec.h create mode 100644 source4/libcli/rpc/dcerpc.c create mode 100644 source4/libcli/rpc/dcerpc.h delete mode 100644 source4/libcli/rpc/librpc.h delete mode 100644 source4/libcli/rpc/rpc_basic.c delete mode 100644 source4/libcli/rpc/rpc_sec.c delete mode 100644 source4/libcli/rpc/rpc_sec.h delete mode 100644 source4/libcli/rpc/rpcparse.c (limited to 'source4/libcli') diff --git a/source4/libcli/clidcerpc.c b/source4/libcli/clidcerpc.c deleted file mode 100644 index fffd4e0941..0000000000 --- a/source4/libcli/clidcerpc.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - Unix SMB/CIFS implementation. - raw dcerpc operations - - Copyright (C) Tim Potter, 2003 - - 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" - -struct cli_dcerpc_pipe *cli_dcerpc_pipe_init(struct cli_tree *tree) -{ - struct cli_dcerpc_pipe *p; - - TALLOC_CTX *mem_ctx = talloc_init("cli_dcerpc_tree"); - if (mem_ctx == NULL) - return NULL; - - p = talloc_zero(mem_ctx, sizeof(*p)); - if (!p) { - talloc_destroy(mem_ctx); - return NULL; - } - - p->mem_ctx = mem_ctx; - p->tree = tree; - p->tree->reference_count++; - - return p; -} - -void cli_dcerpc_pipe_close(struct cli_dcerpc_pipe *p) -{ - if (!p) return; - p->reference_count--; - if (p->reference_count <= 0) { - cli_tree_close(p->tree); - talloc_destroy(p->mem_ctx); - } -} - -static void init_dcerpc_hdr(struct dcerpc_hdr *hdr, uint8 ptype, - uint8 pfc_flags, uint32 call_id) -{ - hdr->rpc_vers = 5; - hdr->rpc_vers_minor = 0; - hdr->ptype = ptype; - hdr->pfc_flags = pfc_flags; - hdr->drep[0] = 0x10; /* Little endian */ - hdr->call_id = call_id; -} - -struct syntax_id trans_synt_v2 = -{ - { - 0x8a885d04, 0x1ceb, 0x11c9, - { 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60 } - }, 0x02 -}; - -struct syntax_id synt_netlogon_v2 = -{ - { - 0x8a885d04, 0x1ceb, 0x11c9, - { 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60 } - }, 0x02 -}; - -struct syntax_id synt_wkssvc_v1 = -{ - { - 0x6bffd098, 0xa112, 0x3610, - { 0x98, 0x33, 0x46, 0xc3, - 0xf8, 0x7e, 0x34, 0x5a } - }, 0x01 -}; - -struct syntax_id synt_srvsvc_v3 = -{ - { - 0x4b324fc8, 0x1670, 0x01d3, - { 0x12, 0x78, 0x5a, 0x47, - 0xbf, 0x6e, 0xe1, 0x88 } - }, 0x03 -}; - -struct syntax_id synt_lsarpc_v0 = -{ - { - 0x12345778, 0x1234, 0xabcd, - { 0xef, 0x00, 0x01, 0x23, - 0x45, 0x67, 0x89, 0xab } - }, 0x00 -}; - -struct syntax_id synt_lsarpc_v0_ds = -{ - { - 0x3919286a, 0xb10c, 0x11d0, - { 0x9b, 0xa8, 0x00, 0xc0, - 0x4f, 0xd9, 0x2e, 0xf5 } - }, 0x00 -}; - -struct syntax_id synt_samr_v1 = -{ - { - 0x12345778, 0x1234, 0xabcd, - { 0xef, 0x00, 0x01, 0x23, - 0x45, 0x67, 0x89, 0xac } - }, 0x01 -}; - -struct syntax_id synt_netlogon_v1 = -{ - { - 0x12345678, 0x1234, 0xabcd, - { 0xef, 0x00, 0x01, 0x23, - 0x45, 0x67, 0xcf, 0xfb } - }, 0x01 -}; - -struct syntax_id synt_winreg_v1 = -{ - { - 0x338cd001, 0x2244, 0x31f1, - { 0xaa, 0xaa, 0x90, 0x00, - 0x38, 0x00, 0x10, 0x03 } - }, 0x01 -}; - -struct syntax_id synt_spoolss_v1 = -{ - { - 0x12345678, 0x1234, 0xabcd, - { 0xef, 0x00, 0x01, 0x23, - 0x45, 0x67, 0x89, 0xab } - }, 0x01 -}; - -struct syntax_id synt_netdfs_v3 = -{ - { - 0x4fc742e0, 0x4a10, 0x11cf, - { 0x82, 0x73, 0x00, 0xaa, - 0x00, 0x4a, 0xe6, 0x73 } - }, 0x03 -}; - -struct known_pipes { - const char *client_pipe; - struct p_ctx_list ctx_list; -}; - -const struct known_pipes known_pipes[] = -{ - { PIPE_LSARPC , { 0, 1, &synt_lsarpc_v0, &trans_synt_v2 }}, - { PIPE_SAMR , { 0, 1, &synt_samr_v1, &trans_synt_v2 }}, - { PIPE_NETLOGON, { 0, 1, &synt_netlogon_v1, &trans_synt_v2 }}, - { PIPE_SRVSVC , { 0, 1, &synt_srvsvc_v3 , &trans_synt_v2 }}, - { PIPE_WKSSVC , { 0, 1, &synt_wkssvc_v1 , &trans_synt_v2 }}, - { PIPE_WINREG , { 0, 1, &synt_winreg_v1 , &trans_synt_v2 }}, - { PIPE_SPOOLSS , { 0, 1, &synt_spoolss_v1, &trans_synt_v2 }}, - { PIPE_NETDFS , { 0, 1, &synt_netdfs_v3 , &trans_synt_v2 }}, - { NULL , { 0, 0, NULL, NULL }} -}; - -/* Perform a bind using the given syntaxes */ - -NTSTATUS cli_dcerpc_bind(struct cli_dcerpc_pipe *p, int num_contexts, - struct p_ctx_list *ctx_list) -{ - TALLOC_CTX *mem_ctx; - struct dcerpc_bind parms; - NTSTATUS status; - - mem_ctx = talloc_init("cli_dcerpc_bind"); - - ZERO_STRUCT(parms); - - init_dcerpc_hdr(&parms.in.hdr, RPC_BIND, RPC_FLG_FIRST|RPC_FLG_LAST, - p->call_id++); - - parms.in.max_xmit_frag = 5680; - parms.in.max_recv_frag = 5680; - parms.in.num_contexts = num_contexts; - parms.in.ctx_list = ctx_list; - - status = dcerpc_raw_bind(p, &parms); - - talloc_destroy(mem_ctx); - - return status; -} - -/* Perform a bind using the given well-known pipe name */ - -NTSTATUS cli_dcerpc_bind_byname(struct cli_dcerpc_pipe *p, - const char *pipe_name) -{ - const struct known_pipes *pi; - - for (pi = known_pipes; pi->client_pipe; pi++) { - if (strequal(&pi->client_pipe[5], pipe_name)) - break; - } - - if (pi->client_pipe == NULL) - return NT_STATUS_UNSUCCESSFUL; - - - return cli_dcerpc_bind(p, 1, &pi->ctx_list); -} - -NTSTATUS cli_dcerpc_request(struct cli_dcerpc_pipe *p, uint16 opnum, - DATA_BLOB stub_data) -{ - TALLOC_CTX *mem_ctx; - struct dcerpc_request parms; - NTSTATUS status; - - mem_ctx = talloc_init("cli_dcerpc_request"); - - ZERO_STRUCT(parms); - - init_dcerpc_hdr(&parms.in.hdr, RPC_REQUEST, - RPC_FLG_FIRST|RPC_FLG_LAST, p->call_id++); - - parms.in.alloc_hint = 0; - parms.in.cont_id = 0; - parms.in.opnum = opnum; - parms.in.stub_data = stub_data; - - status = dcerpc_raw_request(p, &parms); - - talloc_destroy(mem_ctx); - - return status; -} diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h new file mode 100644 index 0000000000..4369ebeb30 --- /dev/null +++ b/source4/libcli/ndr/libndr.h @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + rpc interface definitions + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* + this provides definitions for the libcli/rpc/ MSRPC library +*/ + + +/* this is the base structure passed to routines that + parse MSRPC formatted data + + note that in Samba4 we use separate routines and structures for + MSRPC marshalling and unmarshalling. Also note that these routines + are being kept deliberately very simple, and are not tied to a + particular transport +*/ +struct ndr_pull { + uint32 flags; /* LIBNDR_FLAG_* */ + char *data; + uint32 data_size; + uint32 offset; + TALLOC_CTX *mem_ctx; +}; + +struct ndr_pull_save { + uint32 data_size; + uint32 offset; +}; + + +/* structure passed to functions that generate NDR formatted data */ +struct ndr_push { + uint32 flags; /* LIBNDR_FLAG_* */ + char *data; + uint32 alloc_size; + uint32 offset; + TALLOC_CTX *mem_ctx; +}; + +#define NDR_BASE_MARSHALL_SIZE 1024 + + + +#define LIBNDR_FLAG_BIGENDIAN 1 + + +/* these are used to make the error checking on each element in libndr + less tedious, hopefully making the code more readable */ +#define NDR_CHECK(call) do { NTSTATUS _status; \ + _status = call; \ + if (!NT_STATUS_IS_OK(_status)) \ + return _status; \ + } while (0) + + +#define NDR_ALLOC(ndr, s) do { \ + (s) = talloc(ndr->mem_ctx, sizeof(*(s))); \ + if (!(s)) return NT_STATUS_NO_MEMORY; \ + } while (0) + +#define NDR_ALLOC_N(ndr, s, n) do { \ + if ((n) == 0) { \ + (s) = NULL; \ + } else { \ + (s) = talloc(ndr->mem_ctx, (n) * sizeof(*(s))); \ + if (!(s)) return NT_STATUS_NO_MEMORY; \ + } \ + } while (0) diff --git a/source4/libcli/ndr/ndr.c b/source4/libcli/ndr/ndr.c new file mode 100644 index 0000000000..d9a5ff7735 --- /dev/null +++ b/source4/libcli/ndr/ndr.c @@ -0,0 +1,184 @@ +/* + Unix SMB/CIFS implementation. + + libndr interface + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* + this provides the core routines for NDR parsing functions + + see http://www.opengroup.org/onlinepubs/9629399/chap14.htm for details + of NDR encoding rules +*/ + +#include "includes.h" + +/* + initialise a ndr parse structure from a data blob +*/ +struct ndr_pull *ndr_pull_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx) +{ + struct ndr_pull *ndr; + + ndr = talloc(mem_ctx, sizeof(*ndr)); + if (!ndr) return NULL; + + ndr->data = blob->data; + ndr->data_size = blob->length; + ndr->offset = 0; + ndr->mem_ctx = mem_ctx; + + return ndr; +} + + +/* limit the remaining size of the current ndr parse structure to the + given size, starting at the given offset + + this is used when a ndr packet has an explicit size on the wire, and we + need to make sure that we don't use more data than is indicated + + the 'ofs' parameter indicates how many bytes back from the current + offset in the buffer the 'size' number of bytes starts +*/ +NTSTATUS ndr_pull_limit_size(struct ndr_pull *ndr, uint32 size, uint32 ofs) +{ + uint32 new_size; + new_size = ndr->offset + size - ofs; + + if (new_size > ndr->data_size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ndr->data_size = new_size; + + return NT_STATUS_OK; +} + + +/* + advance by 'size' bytes +*/ +NTSTATUS ndr_pull_advance(struct ndr_pull *ndr, uint32 size) +{ + ndr->offset += size; + if (ndr->offset > ndr->data_size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + return NT_STATUS_OK; +} + +/* + set the parse offset to 'ofs' +*/ +NTSTATUS ndr_pull_set_offset(struct ndr_pull *ndr, uint32 ofs) +{ + ndr->offset = ofs; + if (ndr->offset > ndr->data_size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + return NT_STATUS_OK; +} + +/* save the offset/size of the current ndr state */ +void ndr_pull_save(struct ndr_pull *ndr, struct ndr_pull_save *save) +{ + save->offset = ndr->offset; + save->data_size = ndr->data_size; +} + +/* restore the size/offset of a ndr structure */ +void ndr_pull_restore(struct ndr_pull *ndr, struct ndr_pull_save *save) +{ + ndr->offset = save->offset; + ndr->data_size = save->data_size; +} + + + + +/* create a ndr_push structure, ready for some marshalling */ +struct ndr_push *ndr_push_init(void) +{ + struct ndr_push *ndr; + TALLOC_CTX *mem_ctx = talloc_init("ndr_push_init"); + if (!mem_ctx) return NULL; + + ndr = talloc(mem_ctx, sizeof(*ndr)); + if (!ndr) { + talloc_destroy(mem_ctx); + return NULL; + } + + ndr->mem_ctx = mem_ctx; + ndr->flags = 0; + ndr->alloc_size = NDR_BASE_MARSHALL_SIZE; + ndr->data = talloc(ndr->mem_ctx, ndr->alloc_size); + if (!ndr->data) { + ndr_push_free(ndr); + return NULL; + } + ndr->offset = 0; + + return ndr; +} + +/* free a ndr_push structure */ +void ndr_push_free(struct ndr_push *ndr) +{ + talloc_destroy(ndr->mem_ctx); +} + + +/* return a DATA_BLOB structure for the current ndr_push marshalled data */ +DATA_BLOB ndr_push_blob(struct ndr_push *ndr) +{ + DATA_BLOB blob; + blob.data = ndr->data; + blob.length = ndr->offset; + return blob; +} + + +/* + expand the available space in the buffer to 'size' +*/ +NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32 size) +{ + if (ndr->alloc_size >= size) { + return NT_STATUS_OK; + } + + ndr->alloc_size = size; + ndr->data = realloc(ndr->data, ndr->alloc_size); + if (!ndr->data) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/* + set the push offset to 'ofs' +*/ +NTSTATUS ndr_push_set_offset(struct ndr_push *ndr, uint32 ofs) +{ + NDR_CHECK(ndr_push_expand(ndr, ofs)); + ndr->offset = ofs; + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c new file mode 100644 index 0000000000..736ad0b762 --- /dev/null +++ b/source4/libcli/ndr/ndr_basic.c @@ -0,0 +1,140 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling basic types + + Copyright (C) Andrew Tridgell 2003 + + 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" + +#define NDR_PULL_NEED_BYTES(ndr, n) do { \ + if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \ + return NT_STATUS_BUFFER_TOO_SMALL; \ + } \ +} while(0) + +#define NDR_PULL_ALIGN(ndr, n) do { \ + ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ + if (ndr->offset >= ndr->data_size) { \ + return NT_STATUS_BUFFER_TOO_SMALL; \ + } \ +} while(0) + +/* + parse a GUID +*/ +NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid) +{ + int i; + NDR_PULL_NEED_BYTES(ndr, GUID_SIZE); + for (i=0;iinfo[i] = CVAL(ndr->data, ndr->offset + i); + } + ndr->offset += i; + return NT_STATUS_OK; +} + + +/* + parse a u8 +*/ +NTSTATUS ndr_pull_u8(struct ndr_pull *ndr, uint8 *v) +{ + NDR_PULL_NEED_BYTES(ndr, 1); + *v = CVAL(ndr->data, ndr->offset); + ndr->offset += 1; + return NT_STATUS_OK; +} + + +/* + parse a u16 +*/ +NTSTATUS ndr_pull_u16(struct ndr_pull *ndr, uint16 *v) +{ + NDR_PULL_ALIGN(ndr, 2); + NDR_PULL_NEED_BYTES(ndr, 2); + if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { + *v = RSVAL(ndr->data, ndr->offset); + } else { + *v = SVAL(ndr->data, ndr->offset); + } + ndr->offset += 2; + return NT_STATUS_OK; +} + + +/* + parse a u32 +*/ +NTSTATUS ndr_pull_u32(struct ndr_pull *ndr, uint32 *v) +{ + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 4); + if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { + *v = RIVAL(ndr->data, ndr->offset); + } else { + *v = IVAL(ndr->data, ndr->offset); + } + ndr->offset += 2; + return NT_STATUS_OK; +} + + + +#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n))) + +#define NDR_PUSH_ALIGN(ndr, n) do { \ + ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ + NDR_CHECK(ndr_push_expand(ndr, ndr->offset)); \ +} while(0) + +/* + push a u8 +*/ +NTSTATUS ndr_push_u8(struct ndr_push *ndr, uint8 v) +{ + NDR_PUSH_NEED_BYTES(ndr, 1); + SCVAL(ndr->data, ndr->offset, v); + ndr->offset += 1; + return NT_STATUS_OK; +} + +/* + push a u16 +*/ +NTSTATUS ndr_push_u16(struct ndr_push *ndr, uint16 v) +{ + NDR_PUSH_ALIGN(ndr, 2); + NDR_PUSH_NEED_BYTES(ndr, 2); + SSVAL(ndr->data, ndr->offset, v); + ndr->offset += 2; + return NT_STATUS_OK; +} + +/* + push a u32 +*/ +NTSTATUS ndr_push_u32(struct ndr_push *ndr, uint32 v) +{ + NDR_PUSH_ALIGN(ndr, 4); + NDR_PUSH_NEED_BYTES(ndr, 4); + SIVAL(ndr->data, ndr->offset, v); + ndr->offset += 4; + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_sec.c b/source4/libcli/ndr/ndr_sec.c new file mode 100644 index 0000000000..6b83a09d7a --- /dev/null +++ b/source4/libcli/ndr/ndr_sec.c @@ -0,0 +1,201 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling security descriptors + and related structures + + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* + parse a security_ace +*/ +NTSTATUS ndr_pull_security_ace(struct ndr_pull *ndr, struct security_ace *ace) +{ + uint16 size; + struct ndr_pull_save save; + + ndr_pull_save(ndr, &save); + + NDR_CHECK(ndr_pull_u8(ndr, &ace->type)); + NDR_CHECK(ndr_pull_u8(ndr, &ace->flags)); + NDR_CHECK(ndr_pull_u16(ndr, &size)); + NDR_CHECK(ndr_pull_limit_size(ndr, size, 4)); + + NDR_CHECK(ndr_pull_u32(ndr, &ace->access_mask)); + + if (sec_ace_object(ace->type)) { + NDR_ALLOC(ndr, ace->obj); + NDR_CHECK(ndr_pull_u32(ndr, &ace->obj->flags)); + if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) { + NDR_CHECK(ndr_pull_guid(ndr, &ace->obj->object_guid)); + } + if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { + NDR_CHECK(ndr_pull_guid(ndr, &ace->obj->inherit_guid)); + } + } + + + NDR_CHECK(ndr_pull_dom_sid(ndr, &ace->trustee)); + + ndr_pull_restore(ndr, &save); + NDR_CHECK(ndr_pull_advance(ndr, size)); + + return NT_STATUS_OK; +} + +/* + parse a security_acl +*/ +NTSTATUS ndr_pull_security_acl(struct ndr_pull *ndr, struct security_acl *acl) +{ + int i; + uint16 size; + struct ndr_pull_save save; + + ndr_pull_save(ndr, &save); + + NDR_CHECK(ndr_pull_u16(ndr, &acl->revision)); + NDR_CHECK(ndr_pull_u16(ndr, &size)); + NDR_CHECK(ndr_pull_limit_size(ndr, size, 4)); + NDR_CHECK(ndr_pull_u32(ndr, &acl->num_aces)); + + NDR_ALLOC_N(ndr, acl->aces, acl->num_aces); + + for (i=0;inum_aces;i++) { + NDR_CHECK(ndr_pull_security_ace(ndr, &acl->aces[i])); + } + + ndr_pull_restore(ndr, &save); + NDR_CHECK(ndr_pull_advance(ndr, size)); + + return NT_STATUS_OK; +} + +/* + parse a security_acl offset and structure +*/ +NTSTATUS ndr_pull_security_acl_ofs(struct ndr_pull *ndr, struct security_acl **acl) +{ + uint32 ofs; + struct ndr_pull_save save; + + NDR_CHECK(ndr_pull_u32(ndr, &ofs)); + if (ofs == 0) { + /* it is valid for an acl ptr to be NULL */ + *acl = NULL; + return NT_STATUS_OK; + } + + ndr_pull_save(ndr, &save); + NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); + NDR_ALLOC(ndr, *acl); + NDR_CHECK(ndr_pull_security_acl(ndr, *acl)); + ndr_pull_restore(ndr, &save); + + return NT_STATUS_OK; +} + + +/* + parse a dom_sid +*/ +NTSTATUS ndr_pull_dom_sid(struct ndr_pull *ndr, struct dom_sid *sid) +{ + int i; + + NDR_CHECK(ndr_pull_u8(ndr, &sid->sid_rev_num)); + NDR_CHECK(ndr_pull_u8(ndr, &sid->num_auths)); + for (i=0;i<6;i++) { + NDR_CHECK(ndr_pull_u8(ndr, &sid->id_auth[i])); + } + + NDR_ALLOC_N(ndr, sid->sub_auths, sid->num_auths); + + for (i=0;inum_auths;i++) { + NDR_CHECK(ndr_pull_u32(ndr, &sid->sub_auths[i])); + } + + return NT_STATUS_OK; +} + +/* + parse a dom_sid offset and structure +*/ +NTSTATUS ndr_pull_dom_sid_ofs(struct ndr_pull *ndr, struct dom_sid **sid) +{ + uint32 ofs; + struct ndr_pull_save save; + + NDR_CHECK(ndr_pull_u32(ndr, &ofs)); + if (ofs == 0) { + /* it is valid for a dom_sid ptr to be NULL */ + *sid = NULL; + return NT_STATUS_OK; + } + + ndr_pull_save(ndr, &save); + NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); + NDR_ALLOC(ndr, *sid); + NDR_CHECK(ndr_pull_dom_sid(ndr, *sid)); + ndr_pull_restore(ndr, &save); + + return NT_STATUS_OK; +} + +/* + parse a security descriptor +*/ +NTSTATUS ndr_pull_security_descriptor(struct ndr_pull *ndr, + struct security_descriptor **sd) +{ + NDR_ALLOC(ndr, *sd); + + NDR_CHECK(ndr_pull_u8(ndr, &(*sd)->revision)); + NDR_CHECK(ndr_pull_u16(ndr, &(*sd)->type)); + NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &(*sd)->owner_sid)); + NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &(*sd)->group_sid)); + NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &(*sd)->sacl)); + NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &(*sd)->dacl)); + + return NT_STATUS_OK; +} + +/* + generate a ndr security descriptor +*/ +NTSTATUS ndr_push_security_descriptor(struct ndr_push *ndr, + struct security_descriptor *sd) +{ + uint32 var_offset; + + var_offset = 20; + + NDR_CHECK(ndr_push_u8(ndr, sd->revision)); + NDR_CHECK(ndr_push_u16(ndr, sd->type)); +/* + NDR_CHECK(ndr_push_dom_sid_ofs(ndr, sd->owner_sid, &var_offset)); + NDR_CHECK(ndr_push_dom_sid_ofs(ndr, sd->group_sid, &var_offset)); + NDR_CHECK(ndr_push_security_acl_ofs(ndr, sd->sacl, &var_offset)); + NDR_CHECK(ndr_push_security_acl_ofs(ndr, sd->dacl, &var_offset)); +*/ + return NT_STATUS_OK; +} + diff --git a/source4/libcli/ndr/ndr_sec.h b/source4/libcli/ndr/ndr_sec.h new file mode 100644 index 0000000000..0c9d542006 --- /dev/null +++ b/source4/libcli/ndr/ndr_sec.h @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + definitions for marshalling/unmarshalling security descriptors + and related structures + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + + +/* a domain SID. Note that unlike Samba3 this contains a pointer, + so you can't copy them using assignment */ +struct dom_sid { + uint8 sid_rev_num; /**< SID revision number */ + uint8 num_auths; /**< Number of sub-authorities */ + uint8 id_auth[6]; /**< Identifier Authority */ + uint32 *sub_auths; +}; + +/* an access control element */ +struct security_ace { + uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */ + uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */ + + uint32 access_mask; + + /* the 'obj' part is present when type is XXXX_TYPE_XXXX_OBJECT */ + struct { + uint32 flags; + GUID object_guid; + GUID inherit_guid; + } *obj; + + struct dom_sid trustee; +}; + + +/* a security ACL */ +struct security_acl { + uint16 revision; + uint32 num_aces; + + struct security_ace *aces; +}; + + +/* a security descriptor */ +struct security_descriptor { + uint8 revision; + uint16 type; /* SEC_DESC_xxxx flags */ + + struct dom_sid *owner_sid; + struct dom_sid *group_sid; + struct security_acl *sacl; /* system ACL */ + struct security_acl *dacl; /* user (discretionary) ACL */ +}; + +/* query security descriptor */ +struct smb_query_secdesc { + struct { + uint16 fnum; + uint32 secinfo_flags; + } in; + struct { + struct security_descriptor *sd; + } out; +}; + +/* set security descriptor */ +struct smb_set_secdesc { + struct { + uint16 fnum; + uint32 secinfo_flags; + struct security_descriptor *sd; + } in; +}; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 406491e432..9d154e10cd 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -318,8 +318,8 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, s2.nt1.in.os = "Unix"; s2.nt1.in.lanman = "Samba"; - if (session->transport->negotiate.sec_mode & - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + if (s2.nt1.in.user[0] && + (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) { s2.nt1.in.password1 = lanman_blob(parms->generic.in.password, session->transport->negotiate.secblob); s2.nt1.in.password2 = nt_blob(parms->generic.in.password, diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 4cd3338ec5..c45152381d 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -58,7 +58,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, { NTSTATUS status; struct smb_nttrans nt; - struct ndr_parse *rpc; + struct ndr_pull *ndr; status = smb_raw_nttrans_recv(req, mem_ctx, &nt); if (!NT_STATUS_IS_OK(status)) { @@ -73,12 +73,12 @@ NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, nt.out.data.length = IVAL(nt.out.params.data, 0); - rpc = ndr_parse_init_blob(&nt.out.data, mem_ctx); - if (!rpc) { + ndr = ndr_pull_init_blob(&nt.out.data, mem_ctx); + if (!ndr) { return NT_STATUS_INVALID_PARAMETER; } - status = ndr_parse_security_descriptor(rpc, &query->out.sd); + status = ndr_pull_security_descriptor(ndr, &query->out.sd); return NT_STATUS_OK; } @@ -95,3 +95,47 @@ NTSTATUS smb_raw_query_secdesc(struct cli_tree *tree, return smb_raw_query_secdesc_recv(req, mem_ctx, query); } + + +/**************************************************************************** +set file ACL (async send) +****************************************************************************/ +struct cli_request *smb_raw_set_secdesc_send(struct cli_tree *tree, + struct smb_set_secdesc *set) +{ + struct smb_nttrans nt; + uint8 params[8]; + struct ndr_push *ndr; + struct cli_request *req; + NTSTATUS status; + + nt.in.max_setup = 0; + nt.in.max_param = 0; + nt.in.max_data = 0; + nt.in.setup_count = 0; + nt.in.function = NT_TRANSACT_SET_SECURITY_DESC; + nt.in.setup = NULL; + + SSVAL(params, 0, set->in.fnum); + SSVAL(params, 2, 0); /* padding */ + SIVAL(params, 4, set->in.secinfo_flags); + + nt.in.params.data = params; + nt.in.params.length = 8; + + ndr = ndr_push_init(); + if (!ndr) return NULL; + +// status = ndr_push_security_descriptor(ndr, set->in.sd); + if (!NT_STATUS_IS_OK(status)) { + ndr_push_free(ndr); + return NULL; + } + + nt.in.data = ndr_push_blob(ndr); + + req = smb_raw_nttrans_send(tree, &nt); + + ndr_push_free(ndr); + return req; +} diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index 1cc034de78..4a5159948d 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. raw dcerpc operations - Copyright (C) Tim Potter, 2003 + Copyright (C) Tim Potter 2003 + Copyright (C) Andrew Tridgell 2003 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 @@ -21,202 +22,62 @@ #include "includes.h" -static int put_uuid(char *data, int offset, struct dcerpc_uuid *uuid) -{ - int i; - - SIVAL(data, offset, uuid->time_low); offset += 4; - SSVAL(data, offset, uuid->time_mid); offset += 2; - SSVAL(data, offset, uuid->time_hi_and_version); offset += 2; - for (i = 0; i < 8; i++) - SCVAL(data, offset + i, uuid->remaining[i]); - offset += 8; - - return offset; -} - -DATA_BLOB dcerpc_raw_bind_setup(struct dcerpc_bind *parms) -{ - int i, offset, size; - char *data; - - /* Allocate storage for bind request */ - - size = 28; - for (i = 0; i < parms->in.num_contexts; i++) { - size += 24; /* as header + uuid */ - size += 20 * parms->in.ctx_list[i].num_ts; /* xfer syntaxes */ - } - size += parms->in.auth_verifier.length; - - data = smb_xmalloc(size); - memset(data, 0, size); - - parms->in.hdr.frag_len = size; - - /* Create bind request */ - - SCVAL(data, 0, parms->in.hdr.rpc_vers); - SCVAL(data, 1, parms->in.hdr.rpc_vers_minor); - SCVAL(data, 2, parms->in.hdr.ptype); - SCVAL(data, 3, parms->in.hdr.pfc_flags); - for (i = 0; i < 4; i++) - SCVAL(data, 4 + i, parms->in.hdr.drep[i]); - SSVAL(data, 8, parms->in.hdr.frag_len); - SSVAL(data, 10, parms->in.auth_verifier.length); - SIVAL(data, 12, parms->in.hdr.call_id); - - SSVAL(data, 16, parms->in.max_xmit_frag); - SSVAL(data, 18, parms->in.max_recv_frag); - SIVAL(data, 20, parms->in.assoc_group_id); - SIVAL(data, 24, parms->in.num_contexts); - - offset = 28; - for (i = 0; i < parms->in.num_contexts; i++) { - struct p_ctx_list *ctx = &parms->in.ctx_list[i]; - int j; - - SSVAL(data, offset, ctx->cont_id); offset += 2; - SSVAL(data, offset, ctx->num_ts); offset += 2; - offset = put_uuid(data, offset, &ctx->as->if_uuid); - SIVAL(data, offset, ctx->as->if_version); offset += 4; - for (j = 0; j < ctx->num_ts; j++) { - offset = put_uuid(data, offset, &ctx->ts[i].if_uuid); - SIVAL(data, offset, ctx->ts[i].if_version); - offset += 4; - } - } - - if (parms->in.auth_verifier.length) - memcpy(&data[offset], parms->in.auth_verifier.data, - parms->in.auth_verifier.length); - - return data_blob(data, size); -} - -NTSTATUS dcerpc_raw_bind_send(struct cli_dcerpc_pipe *p, - struct dcerpc_bind *parms) +struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob) { struct smb_trans2 trans; - DATA_BLOB blob; - NTSTATUS result; uint16 setup[2]; + struct cli_request *req; + TALLOC_CTX *mem_ctx; - blob = dcerpc_raw_bind_setup(parms); + mem_ctx = talloc_init("dcerpc_raw_send"); + if (!mem_ctx) return NULL; - ZERO_STRUCT(trans); + trans.in.data = *blob; + trans.in.params = data_blob(NULL, 0); + + setup[0] = TRANSACT_DCERPCCMD; + setup[1] = p->fnum; - trans.in.max_data = blob.length; + trans.in.max_param = 0; + trans.in.max_data = 0x8000; trans.in.setup_count = 2; trans.in.setup = setup; trans.in.trans_name = "\\PIPE\\"; - setup[0] = TRANSACT_DCERPCCMD; - setup[1] = p->fnum; - - trans.in.data = blob; - - result = smb_raw_trans(p->tree, p->mem_ctx, &trans); - - data_blob_free(&blob); + req = smb_raw_trans_send(p->tree, &trans); - return result; -} + talloc_destroy(mem_ctx); -NTSTATUS dcerpc_raw_bind_recv(struct cli_dcerpc_pipe *p, - struct dcerpc_bind *parms) -{ - return NT_STATUS_UNSUCCESSFUL; + return req; } -NTSTATUS dcerpc_raw_bind(struct cli_dcerpc_pipe *p, struct dcerpc_bind *parms) -{ - NTSTATUS result; - - result = dcerpc_raw_bind_send(p, parms); - if (NT_STATUS_IS_ERR(result)) - return result; - return dcerpc_raw_bind_recv(p, parms); -} - -DATA_BLOB dcerpc_raw_request_setup(struct dcerpc_request *parms) -{ - int size, i; - char *data; - - /* Allocate storage for request */ - - size = 24 + parms->in.stub_data.length; - - data = smb_xmalloc(size); - memset(data, 0, size); - - parms->in.hdr.frag_len = size; - parms->in.alloc_hint = parms->in.stub_data.length; - - SCVAL(data, 0, parms->in.hdr.rpc_vers); - SCVAL(data, 1, parms->in.hdr.rpc_vers_minor); - SCVAL(data, 2, parms->in.hdr.ptype); - SCVAL(data, 3, parms->in.hdr.pfc_flags); - for (i = 0; i < 4; i++) - SCVAL(data, 4 + i, parms->in.hdr.drep[i]); - SSVAL(data, 8, parms->in.hdr.frag_len); - SSVAL(data, 10, parms->in.auth_verifier.length); - SIVAL(data, 12, parms->in.hdr.call_id); - - SIVAL(data, 16, parms->in.alloc_hint); - SSVAL(data, 20, parms->in.cont_id); - SSVAL(data, 22, parms->in.opnum); - - if (parms->in.stub_data.length) - memcpy(&data[24], parms->in.stub_data.data, - parms->in.stub_data.length); - - return data_blob(data, size); -} - -NTSTATUS dcerpc_raw_request_send(struct cli_dcerpc_pipe *p, - struct dcerpc_request *parms) +NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p, + struct cli_request *req, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob) { struct smb_trans2 trans; - DATA_BLOB blob; - NTSTATUS result; - uint16 setup[2]; - - blob = dcerpc_raw_request_setup(parms); - - ZERO_STRUCT(trans); + NTSTATUS status; - trans.in.max_data = blob.length; - trans.in.setup_count = 2; - trans.in.setup = setup; - trans.in.trans_name = "\\PIPE\\"; - - setup[0] = TRANSACT_DCERPCCMD; - setup[1] = p->fnum; - - trans.in.data = blob; - - result = smb_raw_trans(p->tree, p->mem_ctx, &trans); + status = smb_raw_trans_recv(req, mem_ctx, &trans); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - data_blob_free(&blob); + if (blob) { + *blob = trans.out.data; + } - return result; + return status; } -NTSTATUS dcerpc_raw_request_recv(struct cli_dcerpc_pipe *p, - struct dcerpc_request *parms) +NTSTATUS dcerpc_raw_packet(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + DATA_BLOB *request_blob, + DATA_BLOB *reply_blob) { - return NT_STATUS_UNSUCCESSFUL; -} - -NTSTATUS dcerpc_raw_request(struct cli_dcerpc_pipe *p, - struct dcerpc_request *parms) -{ - NTSTATUS result; - - result = dcerpc_raw_request_send(p, parms); - if (NT_STATUS_IS_ERR(result)) - return result; - return dcerpc_raw_request_recv(p, parms); + struct cli_request *req; + req = dcerpc_raw_send(p, request_blob); + return dcerpc_raw_recv(p, req, mem_ctx, reply_blob); } + diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 430cf925a6..4c7da6ec4d 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -307,7 +307,7 @@ static int parse_trans2_search(struct cli_tree *tree, case RAW_SEARCH_FULL_DIRECTORY_INFO: if (blob->length < 69) return -1; - ofs = IVAL(blob->data, 0); + ofs = IVAL(blob->data, 0); data->full_directory_info.file_index = IVAL(blob->data, 4); data->full_directory_info.create_time = cli_pull_nttime(blob->data, 8); data->full_directory_info.access_time = cli_pull_nttime(blob->data, 16); @@ -364,7 +364,7 @@ static int parse_trans2_search(struct cli_tree *tree, case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: if (blob->length < 81) return -1; - ofs = IVAL(blob->data, 0); + ofs = IVAL(blob->data, 0); data->id_full_directory_info.file_index = IVAL(blob->data, 4); data->id_full_directory_info.create_time = cli_pull_nttime(blob->data, 8); data->id_full_directory_info.access_time = cli_pull_nttime(blob->data, 16); @@ -385,7 +385,7 @@ static int parse_trans2_search(struct cli_tree *tree, case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: if (blob->length < 105) return -1; - ofs = IVAL(blob->data, 0); + ofs = IVAL(blob->data, 0); data->id_both_directory_info.file_index = IVAL(blob->data, 4); data->id_both_directory_info.create_time = cli_pull_nttime(blob->data, 8); data->id_both_directory_info.access_time = cli_pull_nttime(blob->data, 16); @@ -481,7 +481,7 @@ NTSTATUS smb_raw_search_first(struct cli_tree *tree, return status; } - if (p_blob.length != 10) { + if (p_blob.length < 10) { DEBUG(1,("smb_raw_search_first: parms wrong size %d != expected_param_size\n", p_blob.length)); return NT_STATUS_INVALID_PARAMETER; diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c new file mode 100644 index 0000000000..56c6d95482 --- /dev/null +++ b/source4/libcli/rpc/dcerpc.c @@ -0,0 +1,644 @@ +/* + Unix SMB/CIFS implementation. + raw dcerpc operations + + Copyright (C) Tim Potter 2003 + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* initialise a dcerpc pipe. This currently assumes a SMB named pipe + transport */ +struct dcerpc_pipe *dcerpc_pipe_init(struct cli_tree *tree) +{ + struct dcerpc_pipe *p; + + TALLOC_CTX *mem_ctx = talloc_init("cli_dcerpc_tree"); + if (mem_ctx == NULL) + return NULL; + + p = talloc(mem_ctx, sizeof(*p)); + if (!p) { + talloc_destroy(mem_ctx); + return NULL; + } + + p->mem_ctx = mem_ctx; + p->tree = tree; + p->tree->reference_count++; + p->call_id = 1; + p->fnum = 0; + + return p; +} + +/* close down a dcerpc over SMB pipe */ +void dcerpc_pipe_close(struct dcerpc_pipe *p) +{ + if (!p) return; + p->reference_count--; + if (p->reference_count <= 0) { + cli_tree_close(p->tree); + talloc_destroy(p->mem_ctx); + } +} + +#define BLOB_CHECK_BOUNDS(blob, offset, len) do { \ + if ((offset) > blob->length || (blob->length - (offset) < (len))) { \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ +} while (0) + +#define DCERPC_ALIGN(offset, n) do { \ + (offset) = ((offset) + ((n)-1)) & ~((n)-1); \ +} while (0) + +/* + pull a wire format uuid into a string. This will consume 16 bytes +*/ +static char *dcerpc_pull_uuid(char *data, TALLOC_CTX *mem_ctx) +{ + uint32 time_low; + uint16 time_mid, time_hi_and_version; + uint8 clock_seq_hi_and_reserved; + uint8 clock_seq_low; + uint8 node[6]; + int i; + + time_low = IVAL(data, 0); + time_mid = SVAL(data, 4); + time_hi_and_version = SVAL(data, 6); + clock_seq_hi_and_reserved = CVAL(data, 8); + clock_seq_low = CVAL(data, 9); + for (i=0;i<6;i++) { + node[i] = CVAL(data, 10 + i); + } + + return talloc_asprintf(mem_ctx, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + time_low, time_mid, time_hi_and_version, + clock_seq_hi_and_reserved, clock_seq_low, + node[0], node[1], node[2], node[3], node[4], node[5]); +} + +/* + push a uuid_str into wire format. It will consume 16 bytes +*/ +static NTSTATUS push_uuid_str(char *data, const char *uuid_str) +{ + uint32 time_low; + uint32 time_mid, time_hi_and_version; + uint32 clock_seq_hi_and_reserved; + uint32 clock_seq_low; + uint32 node[6]; + int i; + + if (11 != sscanf(uuid_str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + &time_low, &time_mid, &time_hi_and_version, + &clock_seq_hi_and_reserved, &clock_seq_low, + &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { + return NT_STATUS_INVALID_PARAMETER; + } + + SIVAL(data, 0, time_low); + SSVAL(data, 4, time_mid); + SSVAL(data, 6, time_hi_and_version); + SCVAL(data, 8, clock_seq_hi_and_reserved); + SCVAL(data, 9, clock_seq_low); + for (i=0;i<6;i++) { + SCVAL(data, 10 + i, node[i]); + } + + return NT_STATUS_OK; +} + +/* + pull a dcerpc syntax id from a blob +*/ +static NTSTATUS dcerpc_pull_syntax_id(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + uint32 *offset, + struct dcerpc_syntax_id *syntax) +{ + syntax->uuid_str = dcerpc_pull_uuid(blob->data + (*offset), mem_ctx); + if (!syntax->uuid_str) { + return NT_STATUS_NO_MEMORY; + } + (*offset) += 16; + syntax->if_version = IVAL(blob->data, *offset); + (*offset) += 4; + return NT_STATUS_OK; +} + +/* + push a syntax id onto the wire. It will consume 20 bytes +*/ +static NTSTATUS push_syntax_id(char *data, const struct dcerpc_syntax_id *syntax) +{ + NTSTATUS status; + + status = push_uuid_str(data, syntax->uuid_str); + SIVAL(data, 16, syntax->if_version); + + return status; +} + +/* + pull an auth verifier from a packet +*/ +static NTSTATUS dcerpc_pull_auth_verifier(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + uint32 *offset, + struct dcerpc_hdr *hdr, + DATA_BLOB *auth) +{ + if (hdr->auth_length == 0) { + return NT_STATUS_OK; + } + + BLOB_CHECK_BOUNDS(blob, *offset, hdr->auth_length); + *auth = data_blob_talloc(mem_ctx, blob->data + (*offset), hdr->auth_length); + if (!auth->data) { + return NT_STATUS_NO_MEMORY; + } + (*offset) += hdr->auth_length; + return NT_STATUS_OK; +} + +/* + parse a struct dcerpc_response +*/ +static NTSTATUS dcerpc_pull_response(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + uint32 *offset, + struct dcerpc_hdr *hdr, + struct dcerpc_response *pkt) +{ + uint32 alloc_hint, stub_len; + + BLOB_CHECK_BOUNDS(blob, *offset, 8); + + alloc_hint = IVAL(blob->data, (*offset) + 0); + pkt->context_id = SVAL(blob->data, (*offset) + 4); + pkt->cancel_count = CVAL(blob->data, (*offset) + 6); + + (*offset) += 8; + + stub_len = blob->length - ((*offset) + hdr->auth_length); + BLOB_CHECK_BOUNDS(blob, *offset, stub_len); + pkt->stub_data = data_blob_talloc(mem_ctx, blob->data + (*offset), stub_len); + if (!pkt->stub_data.data) { + return NT_STATUS_NO_MEMORY; + } + (*offset) += stub_len; + + return dcerpc_pull_auth_verifier(blob, mem_ctx, offset, hdr, &pkt->auth_verifier); +} + + +/* + parse a struct bind_ack +*/ +static NTSTATUS dcerpc_pull_bind_ack(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + uint32 *offset, + struct dcerpc_hdr *hdr, + struct dcerpc_bind_ack *pkt) +{ + uint16 len; + int i; + + BLOB_CHECK_BOUNDS(blob, *offset, 10); + pkt->max_xmit_frag = SVAL(blob->data, (*offset) + 0); + pkt->max_recv_frag = SVAL(blob->data, (*offset) + 2); + pkt->assoc_group_id = IVAL(blob->data, (*offset) + 4); + len = SVAL(blob->data, (*offset) + 8); + (*offset) += 10; + + if (len) { + BLOB_CHECK_BOUNDS(blob, *offset, len); + pkt->secondary_address = talloc_strndup(mem_ctx, blob->data + (*offset), len); + if (!pkt->secondary_address) { + return NT_STATUS_NO_MEMORY; + } + (*offset) += len; + } + + DCERPC_ALIGN(*offset, 4); + BLOB_CHECK_BOUNDS(blob, *offset, 4); + pkt->num_results = CVAL(blob->data, *offset); + (*offset) += 4; + + if (pkt->num_results > 0) { + pkt->ctx_list = talloc(mem_ctx, sizeof(pkt->ctx_list[0]) * pkt->num_results); + if (!pkt->ctx_list) { + return NT_STATUS_NO_MEMORY; + } + } + + for (i=0;inum_results;i++) { + NTSTATUS status; + + BLOB_CHECK_BOUNDS(blob, *offset, 24); + pkt->ctx_list[i].result = IVAL(blob->data, *offset); + (*offset) += 4; + status = dcerpc_pull_syntax_id(blob, mem_ctx, offset, &pkt->ctx_list[i].syntax); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + return dcerpc_pull_auth_verifier(blob, mem_ctx, offset, hdr, &pkt->auth_verifier); +} + + +/* + parse a dcerpc header +*/ +static NTSTATUS dcerpc_pull_hdr(DATA_BLOB *blob, uint32 *offset, struct dcerpc_hdr *hdr) +{ + BLOB_CHECK_BOUNDS(blob, *offset, 16); + + hdr->rpc_vers = CVAL(blob->data, (*offset) + 0); + hdr->rpc_vers_minor = CVAL(blob->data, (*offset) + 1); + hdr->ptype = CVAL(blob->data, (*offset) + 2); + hdr->pfc_flags = CVAL(blob->data, (*offset) + 3); + memcpy(hdr->drep, blob->data + (*offset) + 4, 4); + hdr->frag_length = SVAL(blob->data, (*offset) + 8); + hdr->auth_length = SVAL(blob->data, (*offset) + 10); + hdr->call_id = IVAL(blob->data, (*offset) + 12); + + (*offset) += 16; + + return NT_STATUS_OK; +} + +/* + parse a dcerpc header. It consumes 16 bytes +*/ +static void dcerpc_push_hdr(char *data, struct dcerpc_hdr *hdr) +{ + SCVAL(data, 0, hdr->rpc_vers); + SCVAL(data, 1, hdr->rpc_vers_minor); + SCVAL(data, 2, hdr->ptype); + SCVAL(data, 3, hdr->pfc_flags); + memcpy(data + 4, hdr->drep, 4); + SSVAL(data, 8, hdr->frag_length); + SSVAL(data, 12, hdr->call_id); +} + + + +/* + parse a data blob into a dcerpc_packet structure. This handles both + input and output packets +*/ +NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_packet *pkt) +{ + NTSTATUS status; + uint32 offset = 0; + + status = dcerpc_pull_hdr(blob, &offset, &pkt->hdr); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (pkt->hdr.ptype) { + case DCERPC_PKT_BIND_ACK: + status = dcerpc_pull_bind_ack(blob, mem_ctx, &offset, &pkt->hdr, &pkt->out.bind_ack); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + break; + + case DCERPC_PKT_RESPONSE: + status = dcerpc_pull_response(blob, mem_ctx, &offset, &pkt->hdr, &pkt->out.response); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + break; + + default: + return NT_STATUS_INVALID_LEVEL; + } + + return status; +} + + +/* + push a dcerpc_bind into a blob +*/ +static NTSTATUS dcerpc_push_bind(DATA_BLOB *blob, uint32 *offset, + struct dcerpc_hdr *hdr, + struct dcerpc_bind *pkt) +{ + int i, j; + + SSVAL(blob->data, (*offset) + 0, pkt->max_xmit_frag); + SSVAL(blob->data, (*offset) + 2, pkt->max_recv_frag); + SIVAL(blob->data, (*offset) + 4, pkt->assoc_group_id); + SCVAL(blob->data, (*offset) + 8, pkt->num_contexts); + (*offset) += 12; + + for (i=0;inum_contexts;i++) { + NTSTATUS status; + + SSVAL(blob->data, (*offset) + 0, pkt->ctx_list[i].context_id); + SCVAL(blob->data, (*offset) + 2, pkt->ctx_list[i].num_transfer_syntaxes); + status = push_syntax_id(blob->data + (*offset) + 4, &pkt->ctx_list[i].abstract_syntax); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + (*offset) += 24; + for (j=0;jctx_list[i].num_transfer_syntaxes;j++) { + status = push_syntax_id(blob->data + (*offset), + &pkt->ctx_list[i].transfer_syntaxes[j]); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + (*offset) += 20; + } + } + + return NT_STATUS_OK; +} + +/* + push a dcerpc_request into a blob +*/ +static NTSTATUS dcerpc_push_request(DATA_BLOB *blob, uint32 *offset, + struct dcerpc_hdr *hdr, + struct dcerpc_request *pkt) +{ + uint32 alloc_hint = 8 + pkt->stub_data.length + pkt->auth_verifier.length; + + SIVAL(blob->data, (*offset) + 0, alloc_hint); + SSVAL(blob->data, (*offset) + 4, pkt->context_id); + SSVAL(blob->data, (*offset) + 6, pkt->opnum); + + (*offset) += 8; + + memcpy(blob->data + (*offset), pkt->stub_data.data, pkt->stub_data.length); + (*offset) += pkt->stub_data.length; + + memcpy(blob->data + (*offset), pkt->auth_verifier.data, pkt->auth_verifier.length); + (*offset) += pkt->auth_verifier.length; + + return NT_STATUS_OK; +} + + +/* + work out the wire size of a dcerpc packet +*/ +static uint32 dcerpc_wire_size(struct dcerpc_packet *pkt) +{ + int i; + uint32 size = 0; + + size += 16; /* header */ + + switch (pkt->hdr.ptype) { + case DCERPC_PKT_REQUEST: + size += 8; + size += pkt->in.request.stub_data.length; + size += pkt->in.request.auth_verifier.length; + break; + + case DCERPC_PKT_RESPONSE: + size += 8; + size += pkt->out.response.stub_data.length; + size += pkt->hdr.auth_length; + break; + + case DCERPC_PKT_BIND: + size += 12; + for (i=0;iin.bind.num_contexts;i++) { + size += 24; + size += pkt->in.bind.ctx_list[i].num_transfer_syntaxes * 20; + } + size += pkt->hdr.auth_length; + break; + + case DCERPC_PKT_BIND_ACK: + size += 10; + if (pkt->out.bind_ack.secondary_address) { + size += strlen(pkt->out.bind_ack.secondary_address) + 1; + } + size += 4; + size += pkt->out.bind_ack.num_results * 24; + size += pkt->hdr.auth_length; + break; + } + + return size; +} + +/* + push a dcerpc_packet into a blob. This handles both input and + output packets +*/ +NTSTATUS dcerpc_push(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_packet *pkt) +{ + uint32 offset = 0; + uint32 wire_size; + NTSTATUS status; + + /* work out how big the packet will be on the wire */ + wire_size = dcerpc_wire_size(pkt); + + (*blob) = data_blob_talloc(mem_ctx, NULL, wire_size); + if (!blob->data) { + return NT_STATUS_NO_MEMORY; + } + + pkt->hdr.frag_length = wire_size; + + dcerpc_push_hdr(blob->data + offset, &pkt->hdr); + offset += 16; + + switch (pkt->hdr.ptype) { + case DCERPC_PKT_BIND: + status = dcerpc_push_bind(blob, &offset, &pkt->hdr, &pkt->in.bind); + break; + + case DCERPC_PKT_REQUEST: + status = dcerpc_push_request(blob, &offset, &pkt->hdr, &pkt->in.request); + break; + + default: + status = NT_STATUS_INVALID_LEVEL; + } + + return status; +} + + + + +/* + fill in the fixed values in a dcerpc header +*/ +static void init_dcerpc_hdr(struct dcerpc_hdr *hdr) +{ + hdr->rpc_vers = 5; + hdr->rpc_vers_minor = 0; + hdr->drep[0] = 0x10; /* Little endian */ + hdr->drep[1] = 0; + hdr->drep[2] = 0; + hdr->drep[3] = 0; +} + + +/* + perform a bind using the given syntax +*/ +NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, + const struct dcerpc_syntax_id *syntax, + const struct dcerpc_syntax_id *transfer_syntax) +{ + TALLOC_CTX *mem_ctx; + struct dcerpc_packet pkt; + NTSTATUS status; + DATA_BLOB blob; + DATA_BLOB blob_out; + + mem_ctx = talloc_init("cli_dcerpc_bind"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + init_dcerpc_hdr(&pkt.hdr); + + pkt.hdr.ptype = DCERPC_PKT_BIND; + pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.hdr.call_id = p->call_id++; + pkt.hdr.auth_length = 0; + + pkt.in.bind.max_xmit_frag = 5680; + pkt.in.bind.max_recv_frag = 5680; + pkt.in.bind.assoc_group_id = 0; + pkt.in.bind.num_contexts = 1; + pkt.in.bind.ctx_list = talloc(mem_ctx, sizeof(pkt.in.bind.ctx_list[0])); + if (!pkt.in.bind.ctx_list) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + pkt.in.bind.ctx_list[0].context_id = 0; + pkt.in.bind.ctx_list[0].num_transfer_syntaxes = 1; + pkt.in.bind.ctx_list[0].abstract_syntax = *syntax; + pkt.in.bind.ctx_list[0].transfer_syntaxes = transfer_syntax; + + pkt.in.bind.auth_verifier = data_blob(NULL, 0); + + status = dcerpc_push(&blob, mem_ctx, &pkt); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + status = dcerpc_raw_packet(p, mem_ctx, &blob, &blob_out); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + status = dcerpc_pull(&blob_out, mem_ctx, &pkt); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + if (pkt.hdr.ptype != DCERPC_PKT_BIND_ACK) { + status = NT_STATUS_UNSUCCESSFUL; + } + + + p->srv_max_xmit_frag = pkt.out.bind_ack.max_xmit_frag; + p->srv_max_recv_frag = pkt.out.bind_ack.max_recv_frag; + + talloc_destroy(mem_ctx); + + return status; +} + +#define TRANSFER_SYNTAX_V2 {"8a885d04-1ceb-11c9-9fe8-08002b104860", 2} + +static const struct { + const char *name; + struct dcerpc_syntax_id syntax; + struct dcerpc_syntax_id transfer_syntax; +} known_pipes[] = { + { "lsarpc" , { "12345778-1234-abcd-ef00-0123456789ab", 0 }, TRANSFER_SYNTAX_V2 }, + { "samr" , { "12345778-1234-abcd-ef00-0123456789ac", 1 }, TRANSFER_SYNTAX_V2 }, + { "netlogon", { "12345778-1234-abcd-ef00-01234567cffb", 1 }, TRANSFER_SYNTAX_V2 }, + { "srvsvc" , { "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3 }, TRANSFER_SYNTAX_V2 }, + { "wkssvc" , { "6bffd098-a112-3610-9833-46c3f87e345a", 1 }, TRANSFER_SYNTAX_V2 }, + { "winreg" , { "338cd001-2244-31f1-aaaa-900038001003", 1 }, TRANSFER_SYNTAX_V2 }, + { "spoolss" , { "12345678-1234-abcd-ef00-0123456789ab", 1 }, TRANSFER_SYNTAX_V2 }, + { "netdfs" , { "4fc742e0-4a10-11cf-8273-00aa004ae673", 3 }, TRANSFER_SYNTAX_V2 }, + { NULL , } +}; + + +/* Perform a bind using the given well-known pipe name */ +NTSTATUS cli_dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) +{ + int i; + + for (i=0; known_pipes[i].name; i++) { + if (strcasecmp(known_pipes[i].name, pipe_name) == 0) + break; + } + + if (known_pipes[i].name == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + return dcerpc_bind(p, &known_pipes[i].syntax, &known_pipes[i].transfer_syntax); +} + +NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, + uint16 opnum, + TALLOC_CTX *mem_ctx, + DATA_BLOB *stub_data_in, + DATA_BLOB *stub_data_out) +{ + + struct dcerpc_packet pkt; + NTSTATUS status; + DATA_BLOB blob; + + init_dcerpc_hdr(&pkt.hdr); + + pkt.hdr.ptype = DCERPC_PKT_REQUEST; + pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.hdr.call_id = p->call_id++; + pkt.hdr.auth_length = 0; + + pkt.in.request.context_id = 0; + pkt.in.request.opnum = opnum; + pkt.in.request.stub_data = *stub_data_in; + pkt.in.request.auth_verifier = data_blob(NULL, 0); + + status = dcerpc_push(&blob, mem_ctx, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = dcerpc_raw_packet(p, mem_ctx, &blob, stub_data_out); + + return status; +} diff --git a/source4/libcli/rpc/dcerpc.h b/source4/libcli/rpc/dcerpc.h new file mode 100644 index 0000000000..cd1bc728e2 --- /dev/null +++ b/source4/libcli/rpc/dcerpc.h @@ -0,0 +1,124 @@ +/* + Unix SMB/CIFS implementation. + DCERPC interface structures + + Copyright (C) Tim Potter 2003 + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* + see http://www.opengroup.org/onlinepubs/9629399/chap12.htm for details + of these structures + + note that the structure definitions here don't include some of the + fields that are wire-artifacts. Those are put on the wire by the + marshalling/unmarshalling routines in decrpc.c +*/ + +struct dcerpc_pipe { + TALLOC_CTX *mem_ctx; + uint16 fnum; + int reference_count; + uint32 call_id; + uint32 srv_max_xmit_frag; + uint32 srv_max_recv_frag; + struct cli_tree *tree; +}; + +/* dcerpc packet types */ +#define DCERPC_PKT_REQUEST 0 +#define DCERPC_PKT_RESPONSE 2 +#define DCERPC_PKT_BIND 11 +#define DCERPC_PKT_BIND_ACK 12 +#define DCERPC_PKT_BIND_NAK 13 + +/* hdr.pfc_flags */ +#define DCERPC_PFC_FLAG_FIRST 0x01 +#define DCERPC_PFC_FLAG_LAST 0x02 +#define DCERPC_PFC_FLAG_NOCALL 0x20 + +/* + all dcerpc packets use this structure. +*/ +struct dcerpc_packet { + /* all requests and responses contain a dcerpc header */ + struct dcerpc_hdr { + uint8 rpc_vers; /* RPC version */ + uint8 rpc_vers_minor; /* Minor version */ + uint8 ptype; /* Packet type */ + uint8 pfc_flags; /* Fragmentation flags */ + uint8 drep[4]; /* NDR data representation */ + uint16 frag_length; /* Total length of fragment */ + uint16 auth_length; /* authenticator length */ + uint32 call_id; /* Call identifier */ + } hdr; + + union { + struct dcerpc_bind { + uint16 max_xmit_frag; + uint16 max_recv_frag; + uint32 assoc_group_id; + uint8 num_contexts; + struct { + uint16 context_id; + uint8 num_transfer_syntaxes; + struct dcerpc_syntax_id { + const char *uuid_str; + uint32 if_version; + } abstract_syntax; + const struct dcerpc_syntax_id *transfer_syntaxes; + } *ctx_list; + DATA_BLOB auth_verifier; + } bind; + + struct dcerpc_request { + uint16 context_id; + uint16 opnum; + DATA_BLOB stub_data; + DATA_BLOB auth_verifier; + } request; + } in; + + union { + struct dcerpc_bind_ack { + uint16 max_xmit_frag; + uint16 max_recv_frag; + uint32 assoc_group_id; + const char *secondary_address; + uint8 num_results; + struct { + uint32 result; + struct dcerpc_syntax_id syntax; + } *ctx_list; + DATA_BLOB auth_verifier; + } bind_ack; + + struct dcerpc_bind_nak { + uint16 reject_reason; + uint32 num_versions; + uint32 *versions; + } bind_nak; + + struct dcerpc_response { + uint16 context_id; + uint8 cancel_count; + DATA_BLOB stub_data; + DATA_BLOB auth_verifier; + } response; + } out; +}; + diff --git a/source4/libcli/rpc/librpc.h b/source4/libcli/rpc/librpc.h deleted file mode 100644 index f4f7101c90..0000000000 --- a/source4/libcli/rpc/librpc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Unix SMB/CIFS implementation. - rpc interface definitions - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - this provides definitions for the libcli/rpc/ MSRPC library -*/ - - -/* this is the base structure passed to routines that - parse MSRPC formatted data - - note that in Samba4 we use separate routines and structures for - MSRPC marshalling and unmarshalling. Also note that these routines - are being kept deliberately very simple, and are not tied to a - particular transport -*/ -struct ndr_parse { - uint32 flags; /* LIBNDR_FLAG_* */ - char *data; - uint32 data_size; - uint32 offset; - TALLOC_CTX *mem_ctx; -}; - -struct ndr_parse_save { - uint32 data_size; - uint32 offset; -}; - -#define LIBNDR_FLAG_BIGENDIAN 1 - - -/* these are used to make the error checking on each element in libndr - less tedious, hopefully making the code more readable */ -#define NDR_CHECK(call) do { NTSTATUS _status; \ - _status = call; \ - if (!NT_STATUS_IS_OK(_status)) \ - return _status; \ - } while (0) - - -#define NDR_ALLOC(ndr, s) do { \ - (s) = talloc(ndr->mem_ctx, sizeof(*(s))); \ - if (!(s)) return NT_STATUS_NO_MEMORY; \ - } while (0) - -#define NDR_ALLOC_N(ndr, s, n) do { \ - if ((n) == 0) { \ - (s) = NULL; \ - } else { \ - (s) = talloc(ndr->mem_ctx, (n) * sizeof(*(s))); \ - if (!(s)) return NT_STATUS_NO_MEMORY; \ - } \ - } while (0) diff --git a/source4/libcli/rpc/rpc_basic.c b/source4/libcli/rpc/rpc_basic.c deleted file mode 100644 index 5ff17f9d99..0000000000 --- a/source4/libcli/rpc/rpc_basic.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling basic types - - Copyright (C) Andrew Tridgell 2003 - - 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" - -#define NDR_NEED_BYTES(ndr, n) do { \ - if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \ - return NT_STATUS_BUFFER_TOO_SMALL; \ - } \ -} while(0) - -#define NDR_ALIGN(ndr, n) do { \ - ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ - if (ndr->offset >= ndr->data_size) { \ - return NT_STATUS_BUFFER_TOO_SMALL; \ - } \ -} while(0) - -/* - parse a GUID -*/ -NTSTATUS ndr_parse_guid(struct ndr_parse *ndr, GUID *guid) -{ - int i; - NDR_NEED_BYTES(ndr, GUID_SIZE); - for (i=0;iinfo[i] = CVAL(ndr->data, ndr->offset + i); - } - ndr->offset += i; - return NT_STATUS_OK; -} - - -/* - parse a u8 -*/ -NTSTATUS ndr_parse_u8(struct ndr_parse *ndr, uint8 *v) -{ - NDR_NEED_BYTES(ndr, 1); - *v = CVAL(ndr->data, ndr->offset); - ndr->offset += 1; - return NT_STATUS_OK; -} - - -/* - parse a u16 -*/ -NTSTATUS ndr_parse_u16(struct ndr_parse *ndr, uint16 *v) -{ - NDR_ALIGN(ndr, 2); - NDR_NEED_BYTES(ndr, 2); - if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { - *v = RSVAL(ndr->data, ndr->offset); - } else { - *v = SVAL(ndr->data, ndr->offset); - } - ndr->offset += 2; - return NT_STATUS_OK; -} - - -/* - parse a u32 -*/ -NTSTATUS ndr_parse_u32(struct ndr_parse *ndr, uint32 *v) -{ - NDR_ALIGN(ndr, 4); - NDR_NEED_BYTES(ndr, 4); - if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { - *v = RIVAL(ndr->data, ndr->offset); - } else { - *v = IVAL(ndr->data, ndr->offset); - } - ndr->offset += 2; - return NT_STATUS_OK; -} - diff --git a/source4/libcli/rpc/rpc_sec.c b/source4/libcli/rpc/rpc_sec.c deleted file mode 100644 index 49b50c758c..0000000000 --- a/source4/libcli/rpc/rpc_sec.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling security descriptors - and related structures - - Copyright (C) Andrew Tridgell 2003 - - 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" - -/* - parse a security_ace -*/ -NTSTATUS ndr_parse_security_ace(struct ndr_parse *ndr, struct security_ace *ace) -{ - uint16 size; - struct ndr_parse_save save; - - ndr_parse_save(ndr, &save); - - NDR_CHECK(ndr_parse_u8(ndr, &ace->type)); - NDR_CHECK(ndr_parse_u8(ndr, &ace->flags)); - NDR_CHECK(ndr_parse_u16(ndr, &size)); - NDR_CHECK(ndr_parse_limit_size(ndr, size, 4)); - - NDR_CHECK(ndr_parse_u32(ndr, &ace->access_mask)); - - if (sec_ace_object(ace->type)) { - NDR_ALLOC(ndr, ace->obj); - NDR_CHECK(ndr_parse_u32(ndr, &ace->obj->flags)); - if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) { - NDR_CHECK(ndr_parse_guid(ndr, &ace->obj->object_guid)); - } - if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - NDR_CHECK(ndr_parse_guid(ndr, &ace->obj->inherit_guid)); - } - } - - - NDR_CHECK(ndr_parse_dom_sid(ndr, &ace->trustee)); - - ndr_parse_restore(ndr, &save); - NDR_CHECK(ndr_parse_advance(ndr, size)); - - return NT_STATUS_OK; -} - -/* - parse a security_acl -*/ -NTSTATUS ndr_parse_security_acl(struct ndr_parse *ndr, struct security_acl *acl) -{ - int i; - uint16 size; - struct ndr_parse_save save; - - ndr_parse_save(ndr, &save); - - NDR_CHECK(ndr_parse_u16(ndr, &acl->revision)); - NDR_CHECK(ndr_parse_u16(ndr, &size)); - NDR_CHECK(ndr_parse_limit_size(ndr, size, 4)); - NDR_CHECK(ndr_parse_u32(ndr, &acl->num_aces)); - - NDR_ALLOC_N(ndr, acl->aces, acl->num_aces); - - for (i=0;inum_aces;i++) { - NDR_CHECK(ndr_parse_security_ace(ndr, &acl->aces[i])); - } - - ndr_parse_restore(ndr, &save); - NDR_CHECK(ndr_parse_advance(ndr, size)); - - return NT_STATUS_OK; -} - -/* - parse a security_acl offset and structure -*/ -NTSTATUS ndr_parse_security_acl_ofs(struct ndr_parse *ndr, struct security_acl **acl) -{ - uint32 ofs; - struct ndr_parse_save save; - - NDR_CHECK(ndr_parse_u32(ndr, &ofs)); - if (ofs == 0) { - /* it is valid for an acl ptr to be NULL */ - *acl = NULL; - return NT_STATUS_OK; - } - - ndr_parse_save(ndr, &save); - NDR_CHECK(ndr_parse_set_offset(ndr, ofs)); - NDR_ALLOC(ndr, *acl); - NDR_CHECK(ndr_parse_security_acl(ndr, *acl)); - ndr_parse_restore(ndr, &save); - - return NT_STATUS_OK; -} - - -/* - parse a dom_sid -*/ -NTSTATUS ndr_parse_dom_sid(struct ndr_parse *ndr, struct dom_sid *sid) -{ - int i; - - NDR_CHECK(ndr_parse_u8(ndr, &sid->sid_rev_num)); - NDR_CHECK(ndr_parse_u8(ndr, &sid->num_auths)); - for (i=0;i<6;i++) { - NDR_CHECK(ndr_parse_u8(ndr, &sid->id_auth[i])); - } - - NDR_ALLOC_N(ndr, sid->sub_auths, sid->num_auths); - - for (i=0;inum_auths;i++) { - NDR_CHECK(ndr_parse_u32(ndr, &sid->sub_auths[i])); - } - - return NT_STATUS_OK; -} - -/* - parse a dom_sid offset and structure -*/ -NTSTATUS ndr_parse_dom_sid_ofs(struct ndr_parse *ndr, struct dom_sid **sid) -{ - uint32 ofs; - struct ndr_parse_save save; - - NDR_CHECK(ndr_parse_u32(ndr, &ofs)); - if (ofs == 0) { - /* it is valid for a dom_sid ptr to be NULL */ - *sid = NULL; - return NT_STATUS_OK; - } - - ndr_parse_save(ndr, &save); - NDR_CHECK(ndr_parse_set_offset(ndr, ofs)); - NDR_ALLOC(ndr, *sid); - NDR_CHECK(ndr_parse_dom_sid(ndr, *sid)); - ndr_parse_restore(ndr, &save); - - return NT_STATUS_OK; -} - -/* - parse a security descriptor -*/ -NTSTATUS ndr_parse_security_descriptor(struct ndr_parse *ndr, - struct security_descriptor **sd) -{ - NDR_ALLOC(ndr, *sd); - - NDR_CHECK(ndr_parse_u8(ndr, &(*sd)->revision)); - NDR_CHECK(ndr_parse_u16(ndr, &(*sd)->type)); - NDR_CHECK(ndr_parse_dom_sid_ofs(ndr, &(*sd)->owner_sid)); - NDR_CHECK(ndr_parse_dom_sid_ofs(ndr, &(*sd)->group_sid)); - NDR_CHECK(ndr_parse_security_acl_ofs(ndr, &(*sd)->sacl)); - NDR_CHECK(ndr_parse_security_acl_ofs(ndr, &(*sd)->dacl)); - - return NT_STATUS_OK; -} diff --git a/source4/libcli/rpc/rpc_sec.h b/source4/libcli/rpc/rpc_sec.h deleted file mode 100644 index 3cda400eb2..0000000000 --- a/source4/libcli/rpc/rpc_sec.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - definitions for marshalling/unmarshalling security descriptors - and related structures - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - - -/* a domain SID. Note that unlike Samba3 this contains a pointer, - so you can't copy them using assignment */ -struct dom_sid { - uint8 sid_rev_num; /**< SID revision number */ - uint8 num_auths; /**< Number of sub-authorities */ - uint8 id_auth[6]; /**< Identifier Authority */ - uint32 *sub_auths; -}; - -/* an access control element */ -struct security_ace { - uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */ - uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */ - - uint32 access_mask; - - /* the 'obj' part is present when type is XXXX_TYPE_XXXX_OBJECT */ - struct { - uint32 flags; - GUID object_guid; - GUID inherit_guid; - } *obj; - - struct dom_sid trustee; -}; - - -/* a security ACL */ -struct security_acl { - uint16 revision; - uint32 num_aces; - - struct security_ace *aces; -}; - - -/* a security descriptor */ -struct security_descriptor { - uint8 revision; - uint16 type; /* SEC_DESC_xxxx flags */ - - struct dom_sid *owner_sid; - struct dom_sid *group_sid; - struct security_acl *sacl; /* system ACL */ - struct security_acl *dacl; /* user (discretionary) ACL */ -}; - -/* query security descriptor */ -struct smb_query_secdesc { - struct { - uint16 fnum; - uint32 secinfo_flags; - } in; - struct { - struct security_descriptor *sd; - } out; -}; diff --git a/source4/libcli/rpc/rpcparse.c b/source4/libcli/rpc/rpcparse.c deleted file mode 100644 index 41e6919b72..0000000000 --- a/source4/libcli/rpc/rpcparse.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - Unix SMB/CIFS implementation. - libndr interface - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - this provides the core routines for MSNDR parsing functions -*/ - -#include "includes.h" - -/* - initialise a ndr parse structure from a data blob -*/ -struct ndr_parse *ndr_parse_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx) -{ - struct ndr_parse *ndr; - - ndr = talloc(mem_ctx, sizeof(*ndr)); - if (!ndr) return NULL; - - ndr->data = blob->data; - ndr->data_size = blob->length; - ndr->offset = 0; - ndr->mem_ctx = mem_ctx; - - return ndr; -} - - -/* limit the remaining size of the current ndr parse structure to the - given size, starting at the given offset - - this is used when a ndr packet has an explicit size on the wire, and we - need to make sure that we don't use more data than is indicated - - the 'ofs' parameter indicates how many bytes back from the current - offset in the buffer the 'size' number of bytes starts -*/ -NTSTATUS ndr_parse_limit_size(struct ndr_parse *ndr, uint32 size, uint32 ofs) -{ - uint32 new_size; - new_size = ndr->offset + size - ofs; - - if (new_size > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - ndr->data_size = new_size; - - return NT_STATUS_OK; -} - - -/* - advance by 'size' bytes -*/ -NTSTATUS ndr_parse_advance(struct ndr_parse *ndr, uint32 size) -{ - ndr->offset += size; - if (ndr->offset > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - return NT_STATUS_OK; -} - -/* - set the parse offset to 'ofs' -*/ -NTSTATUS ndr_parse_set_offset(struct ndr_parse *ndr, uint32 ofs) -{ - ndr->offset = ofs; - if (ndr->offset > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - return NT_STATUS_OK; -} - -/* save the offset/size of the current ndr state */ -void ndr_parse_save(struct ndr_parse *ndr, struct ndr_parse_save *save) -{ - save->offset = ndr->offset; - save->data_size = ndr->data_size; -} - -/* restore the size/offset of a ndr structure */ -void ndr_parse_restore(struct ndr_parse *ndr, struct ndr_parse_save *save) -{ - ndr->offset = save->offset; - ndr->data_size = save->data_size; -} -- cgit From d064846d5f42bbb023a75a71d049b6a5037dbdd4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 06:30:33 +0000 Subject: we only want the per-call stub data (This used to be commit 95fa15cdcf2df5e8436281cdf96c84228a56cc4c) --- source4/libcli/rpc/dcerpc.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 56c6d95482..0e78e16ed3 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -527,8 +527,8 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, pkt.hdr.call_id = p->call_id++; pkt.hdr.auth_length = 0; - pkt.in.bind.max_xmit_frag = 5680; - pkt.in.bind.max_recv_frag = 5680; + pkt.in.bind.max_xmit_frag = 0x2000; + pkt.in.bind.max_recv_frag = 0x2000; pkt.in.bind.assoc_group_id = 0; pkt.in.bind.num_contexts = 1; pkt.in.bind.ctx_list = talloc(mem_ctx, sizeof(pkt.in.bind.ctx_list[0])); @@ -565,7 +565,6 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, status = NT_STATUS_UNSUCCESSFUL; } - p->srv_max_xmit_frag = pkt.out.bind_ack.max_xmit_frag; p->srv_max_recv_frag = pkt.out.bind_ack.max_recv_frag; @@ -610,6 +609,9 @@ NTSTATUS cli_dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) return dcerpc_bind(p, &known_pipes[i].syntax, &known_pipes[i].transfer_syntax); } +/* + perform a full request/response pair on a dcerpc pipe +*/ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, uint16 opnum, TALLOC_CTX *mem_ctx, @@ -619,7 +621,7 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, struct dcerpc_packet pkt; NTSTATUS status; - DATA_BLOB blob; + DATA_BLOB blob_in, blob_out; init_dcerpc_hdr(&pkt.hdr); @@ -633,12 +635,25 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, pkt.in.request.stub_data = *stub_data_in; pkt.in.request.auth_verifier = data_blob(NULL, 0); - status = dcerpc_push(&blob, mem_ctx, &pkt); + status = dcerpc_push(&blob_in, mem_ctx, &pkt); if (!NT_STATUS_IS_OK(status)) { return status; } - status = dcerpc_raw_packet(p, mem_ctx, &blob, stub_data_out); + status = dcerpc_raw_packet(p, mem_ctx, &blob_in, &blob_out); + + status = dcerpc_pull(&blob_out, mem_ctx, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { + status = NT_STATUS_UNSUCCESSFUL; + } + + if (stub_data_out) { + *stub_data_out = pkt.out.response.stub_data; + } return status; } -- cgit From dc2ffe07a8b25c117c7778fb706274198c11c2cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 07:26:30 +0000 Subject: started adding RPC-ECHO torture cases (This used to be commit 8cff335dab438aa2dbcca91a717e14ef5a8288dd) --- source4/libcli/ndr/libndr.h | 4 +++ source4/libcli/ndr/ndr_echo.c | 46 +++++++++++++++++++++++++ source4/libcli/ndr/ndr_echo.h | 45 ++++++++++++++++++++++++ source4/libcli/rpc/dcerpc.c | 21 ++++++------ source4/libcli/rpc/dcerpc.h | 3 ++ source4/libcli/rpc/rpc_echo.c | 79 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 187 insertions(+), 11 deletions(-) create mode 100644 source4/libcli/ndr/ndr_echo.c create mode 100644 source4/libcli/ndr/ndr_echo.h create mode 100644 source4/libcli/rpc/rpc_echo.c (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h index 4369ebeb30..d9d18299ab 100644 --- a/source4/libcli/ndr/libndr.h +++ b/source4/libcli/ndr/libndr.h @@ -83,3 +83,7 @@ struct ndr_push { if (!(s)) return NT_STATUS_NO_MEMORY; \ } \ } while (0) + +/* now pull in the individual parsers */ +#include "libcli/ndr/ndr_sec.h" +#include "libcli/ndr/ndr_echo.h" diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c new file mode 100644 index 0000000000..da4f28f30c --- /dev/null +++ b/source4/libcli/ndr/ndr_echo.c @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling rpcecho pipe + + Copyright (C) Andrew Tridgell 2003 + + 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" + + +/* + parse a addone +*/ +NTSTATUS ndr_pull_rpcecho_addone(struct ndr_pull *ndr, + struct rpcecho_addone *r) +{ + NDR_CHECK(ndr_pull_u32(ndr, &r->out.data)); + return NT_STATUS_OK; +} + + +/* + push a addone +*/ +NTSTATUS ndr_push_rpcecho_addone(struct ndr_push *ndr, + struct rpcecho_addone *r) +{ + NDR_CHECK(ndr_push_u32(ndr, r->in.data)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_echo.h b/source4/libcli/ndr/ndr_echo.h new file mode 100644 index 0000000000..6144d3885b --- /dev/null +++ b/source4/libcli/ndr/ndr_echo.h @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + + definitions for marshalling/unmarshalling the rpcecho pipe + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* + see http://samba.org/ftp/unpacked/junkcode/rpcecho-win32/ for the + definition of this pipe +*/ + +/* AddOne interface */ +struct rpcecho_addone { + struct { + int data; + } in; + struct { + int data; + } out; +}; + +/* define the command codes */ +enum { + RPCECHO_CALL_ADDONE=0, + RPCECHO_CALL_ECHODATA, + RPCECHO_CALL_SINKDATA, + RPCECHO_CALL_SOURCEDATA +}; + diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 0e78e16ed3..3f95bd914c 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -573,21 +573,20 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, return status; } -#define TRANSFER_SYNTAX_V2 {"8a885d04-1ceb-11c9-9fe8-08002b104860", 2} - static const struct { const char *name; struct dcerpc_syntax_id syntax; - struct dcerpc_syntax_id transfer_syntax; + const struct dcerpc_syntax_id transfer_syntax; } known_pipes[] = { - { "lsarpc" , { "12345778-1234-abcd-ef00-0123456789ab", 0 }, TRANSFER_SYNTAX_V2 }, - { "samr" , { "12345778-1234-abcd-ef00-0123456789ac", 1 }, TRANSFER_SYNTAX_V2 }, - { "netlogon", { "12345778-1234-abcd-ef00-01234567cffb", 1 }, TRANSFER_SYNTAX_V2 }, - { "srvsvc" , { "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3 }, TRANSFER_SYNTAX_V2 }, - { "wkssvc" , { "6bffd098-a112-3610-9833-46c3f87e345a", 1 }, TRANSFER_SYNTAX_V2 }, - { "winreg" , { "338cd001-2244-31f1-aaaa-900038001003", 1 }, TRANSFER_SYNTAX_V2 }, - { "spoolss" , { "12345678-1234-abcd-ef00-0123456789ab", 1 }, TRANSFER_SYNTAX_V2 }, - { "netdfs" , { "4fc742e0-4a10-11cf-8273-00aa004ae673", 3 }, TRANSFER_SYNTAX_V2 }, + { "lsarpc" , { "12345778-1234-abcd-ef00-0123456789ab", 0 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "samr" , { "12345778-1234-abcd-ef00-0123456789ac", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "netlogon", { "12345778-1234-abcd-ef00-01234567cffb", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "srvsvc" , { "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "wkssvc" , { "6bffd098-a112-3610-9833-46c3f87e345a", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "winreg" , { "338cd001-2244-31f1-aaaa-900038001003", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "spoolss" , { "12345678-1234-abcd-ef00-0123456789ab", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "netdfs" , { "4fc742e0-4a10-11cf-8273-00aa004ae673", 3 }, DCERPC_TRANSFER_SYNTAX_V2 }, + { "rpcecho" , { "60a15ec5-4de8-11d7-a637-005056a20182", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, { NULL , } }; diff --git a/source4/libcli/rpc/dcerpc.h b/source4/libcli/rpc/dcerpc.h index cd1bc728e2..7f24f46b91 100644 --- a/source4/libcli/rpc/dcerpc.h +++ b/source4/libcli/rpc/dcerpc.h @@ -122,3 +122,6 @@ struct dcerpc_packet { } out; }; +/* this seems to be the only transfer syntax used */ +#define DCERPC_TRANSFER_SYNTAX_V2 {"8a885d04-1ceb-11c9-9fe8-08002b104860", 2} + diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c new file mode 100644 index 0000000000..d2b2227823 --- /dev/null +++ b/source4/libcli/rpc/rpc_echo.c @@ -0,0 +1,79 @@ +/* + Unix SMB/CIFS implementation. + + rpc echo pipe calls + + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* + addone interface +*/ +NTSTATUS dcerpc_rpcecho_addone(struct dcerpc_pipe *p, + int in_data, int *out_data) +{ + struct rpcecho_addone r; + NTSTATUS status; + DATA_BLOB request, response; + TALLOC_CTX *mem_ctx; + struct ndr_push *push; + struct ndr_pull *pull; + + mem_ctx = talloc_init("dcerpc_rpcecho_addone"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + push = ndr_push_init(); + if (!push) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + r.in.data = in_data; + + status = ndr_push_rpcecho_addone(push, &r); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + request = ndr_push_blob(push); + + status = cli_dcerpc_request(p, RPCECHO_CALL_ADDONE, mem_ctx, &request, &response); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + pull = ndr_pull_init_blob(&response, mem_ctx); + if (!pull) { + goto failed; + } + + status = ndr_pull_rpcecho_addone(pull, &r); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + *out_data = r.out.data; + +failed: + ndr_push_free(push); + talloc_destroy(mem_ctx); + return status; +} -- cgit From dfc43cdf14f3752b6802e04f3571b5f925297d58 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 08:37:48 +0000 Subject: added a helper function to make building rpc functions a bit easier (This used to be commit a8feb80438680b9ec399c908987c58c4a6a998e6) --- source4/libcli/ndr/libndr.h | 4 ++++ source4/libcli/rpc/dcerpc.c | 55 +++++++++++++++++++++++++++++++++++++++++++ source4/libcli/rpc/rpc_echo.c | 39 ++++++------------------------ 3 files changed, 66 insertions(+), 32 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h index d9d18299ab..0205a64552 100644 --- a/source4/libcli/ndr/libndr.h +++ b/source4/libcli/ndr/libndr.h @@ -84,6 +84,10 @@ struct ndr_push { } \ } while (0) +/* these are used when generic fn pointers are needed for ndr push/pull fns */ +typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *); +typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *); + /* now pull in the individual parsers */ #include "libcli/ndr/ndr_sec.h" #include "libcli/ndr/ndr_echo.h" diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 3f95bd914c..7980b77757 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -656,3 +656,58 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, return status; } + + +/* + a useful helper function for synchronous rpc requests +*/ +NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, + uint32 opnum, + TALLOC_CTX *mem_ctx, + NTSTATUS (*ndr_push)(struct ndr_push *, void *), + NTSTATUS (*ndr_pull)(struct ndr_pull *, void *), + void *struct_ptr) +{ + struct ndr_push *push; + struct ndr_pull *pull; + NTSTATUS status; + DATA_BLOB request, response; + + /* setup for a ndr_push_* call */ + push = ndr_push_init(); + if (!push) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + /* push the structure into a blob */ + status = ndr_push_rpcecho_addone(push, struct_ptr); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + /* retrieve the blob */ + request = ndr_push_blob(push); + + /* make the actual dcerpc request */ + status = cli_dcerpc_request(p, RPCECHO_CALL_ADDONE, mem_ctx, &request, &response); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + /* prepare for ndr_pull_* */ + pull = ndr_pull_init_blob(&response, mem_ctx); + if (!pull) { + goto failed; + } + + /* pull the structure from the blob */ + status = ndr_pull_rpcecho_addone(pull, struct_ptr); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + +failed: + ndr_push_free(push); + return status; +} diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c index d2b2227823..c3075ecedc 100644 --- a/source4/libcli/rpc/rpc_echo.c +++ b/source4/libcli/rpc/rpc_echo.c @@ -30,50 +30,25 @@ NTSTATUS dcerpc_rpcecho_addone(struct dcerpc_pipe *p, { struct rpcecho_addone r; NTSTATUS status; - DATA_BLOB request, response; TALLOC_CTX *mem_ctx; - struct ndr_push *push; - struct ndr_pull *pull; mem_ctx = talloc_init("dcerpc_rpcecho_addone"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } - push = ndr_push_init(); - if (!push) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - + /* fill the .in side of the call */ r.in.data = in_data; - status = ndr_push_rpcecho_addone(push, &r); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - request = ndr_push_blob(push); - - status = cli_dcerpc_request(p, RPCECHO_CALL_ADDONE, mem_ctx, &request, &response); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - pull = ndr_pull_init_blob(&response, mem_ctx); - if (!pull) { - goto failed; - } - - status = ndr_pull_rpcecho_addone(pull, &r); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_ADDONE, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_addone, + (ndr_pull_fn_t) ndr_pull_rpcecho_addone, + &r); + /* and extract the .out parameters */ *out_data = r.out.data; -failed: - ndr_push_free(push); talloc_destroy(mem_ctx); return status; } -- cgit From 87ef172531add2672185ec8935180104c3667894 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 08:39:37 +0000 Subject: actually use the passed parameters! (This used to be commit 717803848afd7e1b443c3134183c171b54f192d7) --- source4/libcli/rpc/dcerpc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 7980b77757..96a355c9e1 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -681,7 +681,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, } /* push the structure into a blob */ - status = ndr_push_rpcecho_addone(push, struct_ptr); + status = ndr_push(push, struct_ptr); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -690,7 +690,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, request = ndr_push_blob(push); /* make the actual dcerpc request */ - status = cli_dcerpc_request(p, RPCECHO_CALL_ADDONE, mem_ctx, &request, &response); + status = cli_dcerpc_request(p, opnum, mem_ctx, &request, &response); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -702,7 +702,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, } /* pull the structure from the blob */ - status = ndr_pull_rpcecho_addone(pull, struct_ptr); + status = ndr_pull(pull, struct_ptr); if (!NT_STATUS_IS_OK(status)) { goto failed; } -- cgit From 399fff106d268a5ea95fd2e60735d92b80bcecb1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 09:18:38 +0000 Subject: added rpcecho EchoData test (This used to be commit 9c7e4db4712d1b2b7d8125e3ae535efd50b80f58) --- source4/libcli/ndr/ndr_basic.c | 25 ++++++++++++++++++++++++- source4/libcli/ndr/ndr_echo.c | 24 ++++++++++++++++++++++++ source4/libcli/ndr/ndr_echo.h | 12 ++++++++++++ source4/libcli/rpc/rpc_echo.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c index 736ad0b762..d06eac3ca9 100644 --- a/source4/libcli/ndr/ndr_basic.c +++ b/source4/libcli/ndr/ndr_basic.c @@ -91,7 +91,19 @@ NTSTATUS ndr_pull_u32(struct ndr_pull *ndr, uint32 *v) } else { *v = IVAL(ndr->data, ndr->offset); } - ndr->offset += 2; + ndr->offset += 4; + return NT_STATUS_OK; +} + +/* + parse a set of bytes +*/ +NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char **data, uint32 n) +{ + NDR_PULL_NEED_BYTES(ndr, n); + NDR_ALLOC_N(ndr, *data, n); + memcpy(*data, ndr->data + ndr->offset, n); + ndr->offset += n; return NT_STATUS_OK; } @@ -138,3 +150,14 @@ NTSTATUS ndr_push_u32(struct ndr_push *ndr, uint32 v) ndr->offset += 4; return NT_STATUS_OK; } + +/* + push some bytes +*/ +NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n) +{ + NDR_PUSH_NEED_BYTES(ndr, n); + memcpy(ndr->data + ndr->offset, data, n); + ndr->offset += n; + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c index da4f28f30c..456b254f3a 100644 --- a/source4/libcli/ndr/ndr_echo.c +++ b/source4/libcli/ndr/ndr_echo.c @@ -44,3 +44,27 @@ NTSTATUS ndr_push_rpcecho_addone(struct ndr_push *ndr, NDR_CHECK(ndr_push_u32(ndr, r->in.data)); return NT_STATUS_OK; } + + +/* + parse a echodata +*/ +NTSTATUS ndr_pull_rpcecho_echodata(struct ndr_pull *ndr, + struct rpcecho_echodata *r) +{ + NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); + NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len)); + return NT_STATUS_OK; +} + +/* + push a echodata +*/ +NTSTATUS ndr_push_rpcecho_echodata(struct ndr_push *ndr, + struct rpcecho_echodata *r) +{ + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_echo.h b/source4/libcli/ndr/ndr_echo.h index 6144d3885b..4a8a4f5ab5 100644 --- a/source4/libcli/ndr/ndr_echo.h +++ b/source4/libcli/ndr/ndr_echo.h @@ -35,6 +35,18 @@ struct rpcecho_addone { } out; }; +/* EchoData interface */ +struct rpcecho_echodata { + struct { + int len; + const char *data; + } in; + struct { + int len; + char *data; + } out; +}; + /* define the command codes */ enum { RPCECHO_CALL_ADDONE=0, diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c index c3075ecedc..ab793a1ffa 100644 --- a/source4/libcli/rpc/rpc_echo.c +++ b/source4/libcli/rpc/rpc_echo.c @@ -52,3 +52,34 @@ NTSTATUS dcerpc_rpcecho_addone(struct dcerpc_pipe *p, talloc_destroy(mem_ctx); return status; } + + +/* + echodata interface +*/ +NTSTATUS dcerpc_rpcecho_echodata(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + int len, + const char *in_data, + int *out_len, + char **out_data) +{ + struct rpcecho_echodata r; + NTSTATUS status; + + /* fill the .in side of the call */ + r.in.len = len; + r.in.data = in_data; + + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_ECHODATA, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_echodata, + (ndr_pull_fn_t) ndr_pull_rpcecho_echodata, + &r); + + /* and extract the .out parameters */ + *out_len = r.out.len; + *out_data = r.out.data; + + return status; +} -- cgit From 0a427a43c4464c05bdceb662fd6d3895790ea581 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Nov 2003 10:01:20 +0000 Subject: added SinkData and SourceData tests for rpcecho (This used to be commit 7c356350e6148078725de6b6829eb0855771ae17) --- source4/libcli/ndr/ndr_echo.c | 42 ++++++++++++++++++++++++++++++++++ source4/libcli/ndr/ndr_echo.h | 19 ++++++++++++++++ source4/libcli/rpc/dcerpc.c | 2 +- source4/libcli/rpc/rpc_echo.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c index 456b254f3a..a085a6534d 100644 --- a/source4/libcli/ndr/ndr_echo.c +++ b/source4/libcli/ndr/ndr_echo.c @@ -68,3 +68,45 @@ NTSTATUS ndr_push_rpcecho_echodata(struct ndr_push *ndr, NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); return NT_STATUS_OK; } + +/* + parse a sinkdata +*/ +NTSTATUS ndr_pull_rpcecho_sinkdata(struct ndr_pull *ndr, + struct rpcecho_sinkdata *r) +{ + return NT_STATUS_OK; +} + +/* + push a sinkdata +*/ +NTSTATUS ndr_push_rpcecho_sinkdata(struct ndr_push *ndr, + struct rpcecho_sinkdata *r) +{ + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); + return NT_STATUS_OK; +} + +/* + parse a sourcedata +*/ +NTSTATUS ndr_pull_rpcecho_sourcedata(struct ndr_pull *ndr, + struct rpcecho_sourcedata *r) +{ + NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); + NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len)); + return NT_STATUS_OK; +} + +/* + push a sourcedata +*/ +NTSTATUS ndr_push_rpcecho_sourcedata(struct ndr_push *ndr, + struct rpcecho_sourcedata *r) +{ + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_echo.h b/source4/libcli/ndr/ndr_echo.h index 4a8a4f5ab5..aecf68c4c0 100644 --- a/source4/libcli/ndr/ndr_echo.h +++ b/source4/libcli/ndr/ndr_echo.h @@ -47,6 +47,25 @@ struct rpcecho_echodata { } out; }; +/* SinkData interface */ +struct rpcecho_sinkdata { + struct { + int len; + char *data; + } in; +}; + +/* SourceData interface */ +struct rpcecho_sourcedata { + struct { + int len; + } in; + struct { + int len; + char *data; + } out; +}; + /* define the command codes */ enum { RPCECHO_CALL_ADDONE=0, diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 96a355c9e1..b620718755 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -199,7 +199,7 @@ static NTSTATUS dcerpc_pull_response(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, stub_len = blob->length - ((*offset) + hdr->auth_length); BLOB_CHECK_BOUNDS(blob, *offset, stub_len); pkt->stub_data = data_blob_talloc(mem_ctx, blob->data + (*offset), stub_len); - if (!pkt->stub_data.data) { + if (stub_len != 0 && !pkt->stub_data.data) { return NT_STATUS_NO_MEMORY; } (*offset) += stub_len; diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c index ab793a1ffa..d73f9bda9c 100644 --- a/source4/libcli/rpc/rpc_echo.c +++ b/source4/libcli/rpc/rpc_echo.c @@ -83,3 +83,55 @@ NTSTATUS dcerpc_rpcecho_echodata(struct dcerpc_pipe *p, return status; } + +/* + sourcedata interface +*/ +NTSTATUS dcerpc_rpcecho_sourcedata(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + int len, + int *out_len, + char **out_data) +{ + struct rpcecho_sourcedata r; + NTSTATUS status; + + /* fill the .in side of the call */ + r.in.len = len; + + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_SOURCEDATA, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_sourcedata, + (ndr_pull_fn_t) ndr_pull_rpcecho_sourcedata, + &r); + + /* and extract the .out parameters */ + *out_len = r.out.len; + *out_data = r.out.data; + + return status; +} + +/* + sinkdata interface +*/ +NTSTATUS dcerpc_rpcecho_sinkdata(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + int len, + char *data) +{ + struct rpcecho_sinkdata r; + NTSTATUS status; + + /* fill the .in side of the call */ + r.in.len = len; + r.in.data = data; + + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_SINKDATA, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_sinkdata, + (ndr_pull_fn_t) ndr_pull_rpcecho_sinkdata, + &r); + + return status; +} -- cgit From 994301bfec372f0b929a61425fc1eb180d16cbb1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 02:28:08 +0000 Subject: added fragmentation support on receive for dcerpc packets. I have successfully used SourceData with 200M of data in rpcecho (This used to be commit a9aa7954fe84c925bb158af8b73aa71b7ea84e2b) --- source4/libcli/raw/rawdcerpc.c | 141 ++++++++++++++++++++++++++++++++++++++++- source4/libcli/rpc/dcerpc.c | 52 ++++++++++++++- 2 files changed, 188 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index 4a5159948d..d548129ab1 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -51,6 +51,7 @@ struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob) return req; } + NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p, struct cli_request *req, TALLOC_CTX *mem_ctx, @@ -58,14 +59,78 @@ NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p, { struct smb_trans2 trans; NTSTATUS status; + uint16 frag_length; + DATA_BLOB payload; status = smb_raw_trans_recv(req, mem_ctx, &trans); - if (!NT_STATUS_IS_OK(status)) { + /* STATUS_BUFFER_OVERFLOW means that there is more data + available via SMBreadX */ + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { return status; } + payload = trans.out.data; + + if (trans.out.data.length < 16 || + !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + goto done; + } + + /* we might have recieved a partial fragment, in which case we + need to pull the rest of it */ + frag_length = SVAL(payload.data, 8); + if (frag_length <= payload.length) { + goto done; + } + + /* make sure the payload can hold the whole fragment */ + payload.data = talloc_realloc(mem_ctx, payload.data, frag_length); + if (!payload.data) { + return NT_STATUS_NO_MEMORY; + } + + /* the rest of the data is available via SMBreadX */ + while (frag_length > payload.length) { + uint32 n; + union smb_read io; + + n = frag_length - payload.length; + if (n > 0xFF00) { + n = 0xFF00; + } + + io.generic.level = RAW_READ_READX; + io.readx.in.fnum = p->fnum; + io.readx.in.mincnt = n; + io.readx.in.maxcnt = n; + io.readx.in.offset = 0; + io.readx.in.remaining = 0; + io.readx.out.data = payload.data + payload.length; + status = smb_raw_read(p->tree, &io); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + break; + } + + n = io.readx.out.nread; + if (n == 0) { + status = NT_STATUS_UNSUCCESSFUL; + break; + } + + payload.length += n; + + /* if the SMBreadX returns NT_STATUS_OK then there + isn't any more data to be read */ + if (NT_STATUS_IS_OK(status)) { + break; + } + } + +done: if (blob) { - *blob = trans.out.data; + *blob = payload; } return status; @@ -81,3 +146,75 @@ NTSTATUS dcerpc_raw_packet(struct dcerpc_pipe *p, return dcerpc_raw_recv(p, req, mem_ctx, reply_blob); } + +/* + retrieve a secondary pdu from a pipe +*/ +NTSTATUS dcerpc_raw_packet_secondary(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob) +{ + union smb_read io; + uint32 n = 0x2000; + uint32 frag_length; + NTSTATUS status; + + *blob = data_blob_talloc(mem_ctx, NULL, n); + if (!blob->data) { + return NT_STATUS_NO_MEMORY; + } + + io.generic.level = RAW_READ_READX; + io.readx.in.fnum = p->fnum; + io.readx.in.mincnt = n; + io.readx.in.maxcnt = n; + io.readx.in.offset = 0; + io.readx.in.remaining = 0; + io.readx.out.data = blob->data; + + status = smb_raw_read(p->tree, &io); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + return status; + } + + blob->length = io.readx.out.nread; + + if (blob->length < 16) { + return status; + } + + frag_length = SVAL(blob->data, 8); + if (frag_length <= blob->length) { + return status; + } + + blob->data = talloc_realloc(mem_ctx, blob->data, frag_length); + if (!blob->data) { + return NT_STATUS_NO_MEMORY; + } + + while (frag_length > blob->length && + NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + + n = frag_length - blob->length; + if (n > 0xFF00) { + n = 0xFF00; + } + + io.readx.in.mincnt = n; + io.readx.in.maxcnt = n; + io.readx.out.data = blob->data + blob->length; + status = smb_raw_read(p->tree, &io); + + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + return status; + } + + n = io.readx.out.nread; + blob->length += n; + } + + return status; +} diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index b620718755..d4f21f969a 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -620,7 +620,7 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, struct dcerpc_packet pkt; NTSTATUS status; - DATA_BLOB blob_in, blob_out; + DATA_BLOB blob_in, blob_out, payload; init_dcerpc_hdr(&pkt.hdr); @@ -647,11 +647,57 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, } if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { - status = NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_UNSUCCESSFUL; + } + + if (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { + /* something is badly wrong! */ + return NT_STATUS_UNSUCCESSFUL; + } + + payload = pkt.out.response.stub_data; + + /* continue receiving fragments */ + while (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_LAST)) { + uint32 length; + + status = dcerpc_raw_packet_secondary(p, mem_ctx, &blob_out); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = dcerpc_pull(&blob_out, mem_ctx, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST) { + /* start of another packet!? */ + return NT_STATUS_UNSUCCESSFUL; + } + + if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { + return NT_STATUS_UNSUCCESSFUL; + } + + length = pkt.out.response.stub_data.length; + + payload.data = talloc_realloc(mem_ctx, + payload.data, + payload.length + length); + if (!payload.data) { + return NT_STATUS_NO_MEMORY; + } + + memcpy(payload.data + payload.length, + pkt.out.response.stub_data.data, + length); + + payload.length += length; } if (stub_data_out) { - *stub_data_out = pkt.out.response.stub_data; + *stub_data_out = payload; } return status; -- cgit From d8cbe76b868eb6f2b3876fa540e0847bd2d4f9d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 03:38:46 +0000 Subject: added support for fragmented sends (This used to be commit f51a216136b7cc7d4d07d4acb80e0a710d82841a) --- source4/libcli/raw/rawdcerpc.c | 32 ++++++++++++++++++++++++ source4/libcli/rpc/dcerpc.c | 57 ++++++++++++++++++++++++++++++++++++------ source4/libcli/rpc/dcerpc.h | 2 ++ 3 files changed, 83 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index d548129ab1..a6cd75eeaa 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -218,3 +218,35 @@ NTSTATUS dcerpc_raw_packet_secondary(struct dcerpc_pipe *p, return status; } + + +/* + send an initial pdu in a multi-pdu sequence +*/ +NTSTATUS dcerpc_raw_packet_initial(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob) +{ + union smb_write io; + NTSTATUS status; + + io.generic.level = RAW_WRITE_WRITEX; + io.writex.in.fnum = p->fnum; + io.writex.in.offset = 0; + io.writex.in.wmode = PIPE_START_MESSAGE; + io.writex.in.remaining = blob->length; + io.writex.in.count = blob->length; + io.writex.in.data = blob->data; + + status = smb_raw_write(p->tree, &io); + if (NT_STATUS_IS_OK(status)) { + return status; + } + + /* make sure it accepted it all */ + if (io.writex.out.nwritten != blob->length) { + return NT_STATUS_UNSUCCESSFUL; + } + + return status; +} diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index d4f21f969a..7d6888dde7 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -186,11 +186,11 @@ static NTSTATUS dcerpc_pull_response(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_hdr *hdr, struct dcerpc_response *pkt) { - uint32 alloc_hint, stub_len; + uint32 stub_len; BLOB_CHECK_BOUNDS(blob, *offset, 8); - alloc_hint = IVAL(blob->data, (*offset) + 0); + pkt->alloc_hint = IVAL(blob->data, (*offset) + 0); pkt->context_id = SVAL(blob->data, (*offset) + 4); pkt->cancel_count = CVAL(blob->data, (*offset) + 6); @@ -382,9 +382,7 @@ static NTSTATUS dcerpc_push_request(DATA_BLOB *blob, uint32 *offset, struct dcerpc_hdr *hdr, struct dcerpc_request *pkt) { - uint32 alloc_hint = 8 + pkt->stub_data.length + pkt->auth_verifier.length; - - SIVAL(blob->data, (*offset) + 0, alloc_hint); + SIVAL(blob->data, (*offset) + 0, pkt->alloc_hint); SSVAL(blob->data, (*offset) + 4, pkt->context_id); SSVAL(blob->data, (*offset) + 6, pkt->opnum); @@ -621,24 +619,67 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, struct dcerpc_packet pkt; NTSTATUS status; DATA_BLOB blob_in, blob_out, payload; + uint32 remaining, chunk_size; init_dcerpc_hdr(&pkt.hdr); + remaining = stub_data_in->length; + + /* we can write a full max_recv_frag size, minus the dcerpc + request header size */ + chunk_size = p->srv_max_recv_frag - 24; + pkt.hdr.ptype = DCERPC_PKT_REQUEST; - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.hdr.call_id = p->call_id++; pkt.hdr.auth_length = 0; - + pkt.in.request.alloc_hint = remaining; pkt.in.request.context_id = 0; pkt.in.request.opnum = opnum; - pkt.in.request.stub_data = *stub_data_in; pkt.in.request.auth_verifier = data_blob(NULL, 0); + /* we send a series of pdus without waiting for a reply until + the last pdu */ + while (remaining > chunk_size) { + if (remaining == stub_data_in->length) { + pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST; + } else { + pkt.hdr.pfc_flags = 0; + } + + pkt.in.request.stub_data.data = stub_data_in->data + + (stub_data_in->length - remaining); + pkt.in.request.stub_data.length = chunk_size; + + status = dcerpc_push(&blob_in, mem_ctx, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = dcerpc_raw_packet_initial(p, mem_ctx, &blob_in); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + remaining -= chunk_size; + } + + /* now we send a pdu with LAST_FRAG sent and get the first + part of the reply */ + if (remaining == stub_data_in->length) { + pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + } else { + pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_LAST; + } + pkt.in.request.stub_data.data = stub_data_in->data + + (stub_data_in->length - remaining); + pkt.in.request.stub_data.length = remaining; + status = dcerpc_push(&blob_in, mem_ctx, &pkt); if (!NT_STATUS_IS_OK(status)) { return status; } + /* send the pdu and get the initial response pdu */ status = dcerpc_raw_packet(p, mem_ctx, &blob_in, &blob_out); status = dcerpc_pull(&blob_out, mem_ctx, &pkt); diff --git a/source4/libcli/rpc/dcerpc.h b/source4/libcli/rpc/dcerpc.h index 7f24f46b91..09ddc3625c 100644 --- a/source4/libcli/rpc/dcerpc.h +++ b/source4/libcli/rpc/dcerpc.h @@ -86,6 +86,7 @@ struct dcerpc_packet { } bind; struct dcerpc_request { + uint32 alloc_hint; uint16 context_id; uint16 opnum; DATA_BLOB stub_data; @@ -114,6 +115,7 @@ struct dcerpc_packet { } bind_nak; struct dcerpc_response { + uint32 alloc_hint; uint16 context_id; uint8 cancel_count; DATA_BLOB stub_data; -- cgit From 46046aa69be01d4868395b9b52b8bcd22c3859e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 09:10:31 +0000 Subject: yipee! we can now do lsaOpenPolicy() via the new interfaces, without using any of the old lsa code (This used to be commit f5bd301ff7befa223a1d761a37ae8f7ce7f1fcd1) --- source4/libcli/ndr/libndr.h | 6 +++ source4/libcli/ndr/ndr_basic.c | 96 ++++++++++++++++++++++++++++++++++-------- source4/libcli/ndr/ndr_echo.c | 6 ++- source4/libcli/ndr/ndr_lsa.c | 85 +++++++++++++++++++++++++++++++++++++ source4/libcli/ndr/ndr_lsa.h | 47 +++++++++++++++++++++ source4/libcli/ndr/ndr_misc.c | 45 ++++++++++++++++++++ source4/libcli/ndr/ndr_misc.h | 26 ++++++++++++ source4/libcli/raw/rawdcerpc.c | 62 +++++++++++++++++++++++++++ source4/libcli/rpc/dcerpc.c | 10 ++--- source4/libcli/rpc/rpc_lsa.c | 64 ++++++++++++++++++++++++++++ 10 files changed, 422 insertions(+), 25 deletions(-) create mode 100644 source4/libcli/ndr/ndr_lsa.c create mode 100644 source4/libcli/ndr/ndr_lsa.h create mode 100644 source4/libcli/ndr/ndr_misc.c create mode 100644 source4/libcli/ndr/ndr_misc.h create mode 100644 source4/libcli/rpc/rpc_lsa.c (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h index 0205a64552..931fc1c341 100644 --- a/source4/libcli/ndr/libndr.h +++ b/source4/libcli/ndr/libndr.h @@ -54,6 +54,10 @@ struct ndr_push { TALLOC_CTX *mem_ctx; }; +struct ndr_push_save { + uint32 offset; +}; + #define NDR_BASE_MARSHALL_SIZE 1024 @@ -90,4 +94,6 @@ typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *); /* now pull in the individual parsers */ #include "libcli/ndr/ndr_sec.h" +#include "libcli/ndr/ndr_misc.h" #include "libcli/ndr/ndr_echo.h" +#include "libcli/ndr/ndr_lsa.h" diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c index d06eac3ca9..8cbf375403 100644 --- a/source4/libcli/ndr/ndr_basic.c +++ b/source4/libcli/ndr/ndr_basic.c @@ -35,21 +35,6 @@ } \ } while(0) -/* - parse a GUID -*/ -NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid) -{ - int i; - NDR_PULL_NEED_BYTES(ndr, GUID_SIZE); - for (i=0;iinfo[i] = CVAL(ndr->data, ndr->offset + i); - } - ndr->offset += i; - return NT_STATUS_OK; -} - - /* parse a u8 */ @@ -95,18 +80,41 @@ NTSTATUS ndr_pull_u32(struct ndr_pull *ndr, uint32 *v) return NT_STATUS_OK; } +/* + pull a NTSTATUS +*/ +NTSTATUS ndr_pull_status(struct ndr_pull *ndr, NTSTATUS *status) +{ + uint32 v; + NDR_CHECK(ndr_pull_u32(ndr, &v)); + *status = NT_STATUS(v); + return NT_STATUS_OK; +} + /* parse a set of bytes */ -NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char **data, uint32 n) +NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n) { NDR_PULL_NEED_BYTES(ndr, n); - NDR_ALLOC_N(ndr, *data, n); - memcpy(*data, ndr->data + ndr->offset, n); + memcpy(data, ndr->data + ndr->offset, n); ndr->offset += n; return NT_STATUS_OK; } +/* + parse a GUID +*/ +NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid) +{ + int i; + NDR_PULL_NEED_BYTES(ndr, GUID_SIZE); + for (i=0;iinfo[i] = CVAL(ndr->data, ndr->offset + i); + } + ndr->offset += i; + return NT_STATUS_OK; +} #define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n))) @@ -161,3 +169,55 @@ NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n) ndr->offset += n; return NT_STATUS_OK; } + + +/* + this is used when a packet has a 4 byte length field. We remember the start position + and come back to it later to fill in the size +*/ +NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save) +{ + save->offset = ndr->offset; + return ndr_push_u32(ndr, 0); +} + +NTSTATUS ndr_push_length4_end(struct ndr_push *ndr, struct ndr_push_save *save) +{ + uint32 offset = ndr->offset; + ndr->offset = save->offset; + NDR_CHECK(ndr_push_u32(ndr, offset - save->offset)); + ndr->offset = offset; + return NT_STATUS_OK; +} + +/* + push a 1 if a pointer is non-NULL, otherwise 0 +*/ +NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p) +{ + return ndr_push_u32(ndr, p?1:0); +} + +/* + push a comformant, variable ucs2 string onto the wire from a C string +*/ +NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s) +{ + smb_ucs2_t *ws; + ssize_t len; + int i; + len = push_ucs2_talloc(ndr->mem_ctx, &ws, s); + if (len == -1) { + return NT_STATUS_INVALID_PARAMETER; + } + NDR_CHECK(ndr_push_u32(ndr, len)); + NDR_CHECK(ndr_push_u32(ndr, 0)); + NDR_CHECK(ndr_push_u32(ndr, len-2)); + NDR_PUSH_NEED_BYTES(ndr, len); + for (i=0;idata, ndr->offset + i, ws[i]); + } + ndr->offset += i; + return NT_STATUS_OK; +} + diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c index a085a6534d..c60569676c 100644 --- a/source4/libcli/ndr/ndr_echo.c +++ b/source4/libcli/ndr/ndr_echo.c @@ -53,7 +53,8 @@ NTSTATUS ndr_pull_rpcecho_echodata(struct ndr_pull *ndr, struct rpcecho_echodata *r) { NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); - NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len)); + NDR_ALLOC_N(ndr, r->out.data, r->out.len); + NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len)); return NT_STATUS_OK; } @@ -97,7 +98,8 @@ NTSTATUS ndr_pull_rpcecho_sourcedata(struct ndr_pull *ndr, struct rpcecho_sourcedata *r) { NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); - NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len)); + NDR_ALLOC_N(ndr, r->out.data, r->out.len); + NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len)); return NT_STATUS_OK; } diff --git a/source4/libcli/ndr/ndr_lsa.c b/source4/libcli/ndr/ndr_lsa.c new file mode 100644 index 0000000000..6649bd04c2 --- /dev/null +++ b/source4/libcli/ndr/ndr_lsa.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling lsa pipe + + Copyright (C) Andrew Tridgell 2003 + + 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" + +NTSTATUS ndr_push_lsa_QosInfo(struct ndr_push *ndr, + struct lsa_QosInfo *r) +{ + struct ndr_push_save length; + + NDR_CHECK(ndr_push_length4_start(ndr, &length)); + NDR_CHECK(ndr_push_u16(ndr, r->impersonation_level)); + NDR_CHECK(ndr_push_u8(ndr, r->context_mode)); + NDR_CHECK(ndr_push_u8(ndr, r->effective_only)); + NDR_CHECK(ndr_push_length4_end(ndr, &length)); + + return NT_STATUS_OK; +} + +NTSTATUS ndr_push_lsa_ObjectAttribute(struct ndr_push *ndr, + struct lsa_ObjectAttribute *r) +{ + struct ndr_push_save length; + + NDR_CHECK(ndr_push_length4_start(ndr, &length)); + NDR_CHECK(ndr_push_ptr(ndr, r->root_dir)); + NDR_CHECK(ndr_push_ptr(ndr, r->object_name)); + NDR_CHECK(ndr_push_u32(ndr, r->attributes)); + NDR_CHECK(ndr_push_ptr(ndr, r->sec_desc)); + NDR_CHECK(ndr_push_ptr(ndr, r->sec_qos)); + + if (r->root_dir) NDR_CHECK(ndr_push_u8(ndr, r->root_dir[0])); + if (r->object_name) NDR_CHECK(ndr_push_unistr(ndr, r->object_name)); + if (r->sec_desc) NDR_CHECK(ndr_push_security_descriptor(ndr, r->sec_desc)); + if (r->sec_qos) NDR_CHECK(ndr_push_lsa_QosInfo(ndr, r->sec_qos)); + + NDR_CHECK(ndr_push_length4_end(ndr, &length)); + + return NT_STATUS_OK; +} + +/* + push a openpolicy +*/ +NTSTATUS ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, + struct lsa_OpenPolicy *r) +{ + NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name)); + NDR_CHECK(ndr_push_u16(ndr, r->in.system_name[0])); + NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr)); + NDR_CHECK(ndr_push_u32(ndr, r->in.desired_access)); + return NT_STATUS_OK; +} + + +/* + parse a openpolicy +*/ +NTSTATUS ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, + struct lsa_OpenPolicy *r) +{ + NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle)); + NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_lsa.h b/source4/libcli/ndr/ndr_lsa.h new file mode 100644 index 0000000000..4a0aff8323 --- /dev/null +++ b/source4/libcli/ndr/ndr_lsa.h @@ -0,0 +1,47 @@ +/* + Unix SMB/CIFS implementation. + + definitions for marshalling/unmarshalling the lsa pipe + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +struct lsa_QosInfo { + uint16 impersonation_level; + uint8 context_mode; + uint8 effective_only; +}; + +struct lsa_ObjectAttribute { + const char *root_dir; + const char *object_name; + uint32 attributes; + struct security_descriptor *sec_desc; + struct lsa_QosInfo *sec_qos; +}; + +struct lsa_OpenPolicy { + struct { + const char *system_name; + struct lsa_ObjectAttribute *attr; + uint32 desired_access; + } in; + struct { + struct policy_handle handle; + NTSTATUS status; + } out; +}; diff --git a/source4/libcli/ndr/ndr_misc.c b/source4/libcli/ndr/ndr_misc.c new file mode 100644 index 0000000000..cdd6652068 --- /dev/null +++ b/source4/libcli/ndr/ndr_misc.c @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling miscellaneous rpc structures + + Copyright (C) Andrew Tridgell 2003 + + 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" + + +/* + parse a policy handle +*/ +NTSTATUS ndr_pull_policy_handle(struct ndr_pull *ndr, + struct policy_handle *r) +{ + NDR_CHECK(ndr_pull_bytes(ndr, r->data, 20)); + return NT_STATUS_OK; +} + +/* + push a policy handle +*/ +NTSTATUS ndr_push_policy_handle(struct ndr_push *ndr, + struct policy_handle *r) +{ + NDR_CHECK(ndr_push_bytes(ndr, r->data, 20)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_misc.h b/source4/libcli/ndr/ndr_misc.h new file mode 100644 index 0000000000..cc3576b3e8 --- /dev/null +++ b/source4/libcli/ndr/ndr_misc.h @@ -0,0 +1,26 @@ +/* + Unix SMB/CIFS implementation. + + definitions for marshalling/unmarshalling miscellaneous structures + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* policy handles are used all over the place */ +struct policy_handle { + char data[20]; +}; diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index a6cd75eeaa..6a3275c7a4 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -22,6 +22,68 @@ #include "includes.h" + +/* + open a rpc connection to a named pipe +*/ +NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p, const char *pipe_name) +{ + NTSTATUS status; + char *name = NULL; + union smb_open io; + TALLOC_CTX *mem_ctx; + + asprintf(&name, "\\%s", pipe_name); + if (!name) { + return NT_STATUS_NO_MEMORY; + } + + io.ntcreatex.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.access_mask = + STD_RIGHT_READ_CONTROL_ACCESS | + SA_RIGHT_FILE_WRITE_ATTRIBUTES | + SA_RIGHT_FILE_WRITE_EA | + GENERIC_RIGHTS_FILE_READ | + GENERIC_RIGHTS_FILE_WRITE; + io.ntcreatex.in.file_attr = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = name; + + mem_ctx = talloc_init("torture_rpc_connection"); + status = smb_raw_open(p->tree, mem_ctx, &io); + free(name); + talloc_destroy(mem_ctx); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + p->fnum = io.ntcreatex.out.fnum; + + /* bind to the pipe, using the pipe_name as the key */ + status = dcerpc_bind_byname(p, pipe_name); + + if (!NT_STATUS_IS_OK(status)) { + union smb_close c; + c.close.level = RAW_CLOSE_CLOSE; + c.close.in.fnum = p->fnum; + c.close.in.write_time = 0; + smb_raw_close(p->tree, &c); + } + + return status; +} + + struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob) { struct smb_trans2 trans; diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 7d6888dde7..89f2c6d5b1 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -28,7 +28,7 @@ struct dcerpc_pipe *dcerpc_pipe_init(struct cli_tree *tree) { struct dcerpc_pipe *p; - TALLOC_CTX *mem_ctx = talloc_init("cli_dcerpc_tree"); + TALLOC_CTX *mem_ctx = talloc_init("dcerpc_tree"); if (mem_ctx == NULL) return NULL; @@ -513,7 +513,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, DATA_BLOB blob; DATA_BLOB blob_out; - mem_ctx = talloc_init("cli_dcerpc_bind"); + mem_ctx = talloc_init("dcerpc_bind"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } @@ -590,7 +590,7 @@ static const struct { /* Perform a bind using the given well-known pipe name */ -NTSTATUS cli_dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) +NTSTATUS dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) { int i; @@ -609,7 +609,7 @@ NTSTATUS cli_dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) /* perform a full request/response pair on a dcerpc pipe */ -NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, +NTSTATUS dcerpc_request(struct dcerpc_pipe *p, uint16 opnum, TALLOC_CTX *mem_ctx, DATA_BLOB *stub_data_in, @@ -777,7 +777,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, request = ndr_push_blob(push); /* make the actual dcerpc request */ - status = cli_dcerpc_request(p, opnum, mem_ctx, &request, &response); + status = dcerpc_request(p, opnum, mem_ctx, &request, &response); if (!NT_STATUS_IS_OK(status)) { goto failed; } diff --git a/source4/libcli/rpc/rpc_lsa.c b/source4/libcli/rpc/rpc_lsa.c new file mode 100644 index 0000000000..b747762984 --- /dev/null +++ b/source4/libcli/rpc/rpc_lsa.c @@ -0,0 +1,64 @@ +/* + Unix SMB/CIFS implementation. + + rpc lsa pipe calls + + Copyright (C) Andrew Tridgell 2003 + + 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" + +/* + OpenPolicy interface +*/ +NTSTATUS dcerpc_lsa_OpenPolicy(struct dcerpc_pipe *p, + const char *server, + struct lsa_ObjectAttribute *attr, + uint32 access_mask, + struct policy_handle *handle) +{ + struct lsa_OpenPolicy r; + NTSTATUS status; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("dcerpc_rpcecho_addone"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + /* fill the .in side of the call */ + r.in.system_name = server; + r.in.attr = attr; + r.in.desired_access = access_mask; + + /* make the call */ + status = dcerpc_ndr_request(p, LSA_OPENPOLICY, mem_ctx, + (ndr_push_fn_t) ndr_push_lsa_OpenPolicy, + (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy, + &r); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + /* and extract the .out parameters */ + *handle = r.out.handle; + status = r.out.status; + +done: + talloc_destroy(mem_ctx); + return status; +} -- cgit From 485f930088b524d704bed668d4ef118ca2f31bbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 09:48:33 +0000 Subject: lsa_OpenPolicy2 now works (This used to be commit 9cf479873f3501776091c9d01551adadcf525794) --- source4/libcli/ndr/ndr_basic.c | 16 ++++++---------- source4/libcli/ndr/ndr_lsa.c | 25 +++++++++++++++++++++++++ source4/libcli/ndr/ndr_lsa.h | 12 ++++++++++++ source4/libcli/rpc/rpc_lsa.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c index 8cbf375403..21326c2a62 100644 --- a/source4/libcli/ndr/ndr_basic.c +++ b/source4/libcli/ndr/ndr_basic.c @@ -177,6 +177,7 @@ NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n) */ NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save) { + NDR_PUSH_ALIGN(ndr, 4); save->offset = ndr->offset; return ndr_push_u32(ndr, 0); } @@ -203,21 +204,16 @@ NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p) */ NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s) { - smb_ucs2_t *ws; + char *ws; ssize_t len; - int i; - len = push_ucs2_talloc(ndr->mem_ctx, &ws, s); + len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s); if (len == -1) { return NT_STATUS_INVALID_PARAMETER; } - NDR_CHECK(ndr_push_u32(ndr, len)); + NDR_CHECK(ndr_push_u32(ndr, len/2)); NDR_CHECK(ndr_push_u32(ndr, 0)); - NDR_CHECK(ndr_push_u32(ndr, len-2)); - NDR_PUSH_NEED_BYTES(ndr, len); - for (i=0;idata, ndr->offset + i, ws[i]); - } - ndr->offset += i; + NDR_CHECK(ndr_push_u32(ndr, len/2)); + NDR_CHECK(ndr_push_bytes(ndr, ws, len)); return NT_STATUS_OK; } diff --git a/source4/libcli/ndr/ndr_lsa.c b/source4/libcli/ndr/ndr_lsa.c index 6649bd04c2..5955432915 100644 --- a/source4/libcli/ndr/ndr_lsa.c +++ b/source4/libcli/ndr/ndr_lsa.c @@ -83,3 +83,28 @@ NTSTATUS ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); return NT_STATUS_OK; } + +/* + push a openpolicy2 +*/ +NTSTATUS ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, + struct lsa_OpenPolicy2 *r) +{ + NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name)); + NDR_CHECK(ndr_push_unistr(ndr, r->in.system_name)); + NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr)); + NDR_CHECK(ndr_push_u32(ndr, r->in.desired_access)); + return NT_STATUS_OK; +} + + +/* + parse a openpolicy2 +*/ +NTSTATUS ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, + struct lsa_OpenPolicy2 *r) +{ + NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle)); + NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_lsa.h b/source4/libcli/ndr/ndr_lsa.h index 4a0aff8323..cfdd98e24e 100644 --- a/source4/libcli/ndr/ndr_lsa.h +++ b/source4/libcli/ndr/ndr_lsa.h @@ -45,3 +45,15 @@ struct lsa_OpenPolicy { NTSTATUS status; } out; }; + +struct lsa_OpenPolicy2 { + struct { + const char *system_name; + struct lsa_ObjectAttribute *attr; + uint32 desired_access; + } in; + struct { + struct policy_handle handle; + NTSTATUS status; + } out; +}; diff --git a/source4/libcli/rpc/rpc_lsa.c b/source4/libcli/rpc/rpc_lsa.c index b747762984..8e1a48857e 100644 --- a/source4/libcli/rpc/rpc_lsa.c +++ b/source4/libcli/rpc/rpc_lsa.c @@ -62,3 +62,45 @@ done: talloc_destroy(mem_ctx); return status; } + + +/* + OpenPolicy2 interface +*/ +NTSTATUS dcerpc_lsa_OpenPolicy2(struct dcerpc_pipe *p, + const char *server, + struct lsa_ObjectAttribute *attr, + uint32 access_mask, + struct policy_handle *handle) +{ + struct lsa_OpenPolicy2 r; + NTSTATUS status; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("dcerpc_rpcecho_addone"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + /* fill the .in side of the call */ + r.in.system_name = server; + r.in.attr = attr; + r.in.desired_access = access_mask; + + /* make the call */ + status = dcerpc_ndr_request(p, LSA_OPENPOLICY2, mem_ctx, + (ndr_push_fn_t) ndr_push_lsa_OpenPolicy2, + (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy2, + &r); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + /* and extract the .out parameters */ + *handle = r.out.handle; + status = r.out.status; + +done: + talloc_destroy(mem_ctx); + return status; +} -- cgit From 41304b3c5791be0a5492844a048784c4ef4acfe9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 11:16:07 +0000 Subject: lsa_EnumSids() now works (This used to be commit 25a8692fede323b53240192e5d349b39fe0b7342) --- source4/libcli/ndr/ndr_lsa.c | 45 ++++++++++++++++++++++++++++++++++++++++++ source4/libcli/ndr/ndr_lsa.h | 13 ++++++++++++ source4/libcli/ndr/ndr_sec.c | 10 ++++++++++ source4/libcli/raw/rawdcerpc.c | 3 +++ source4/libcli/rpc/rpc_lsa.c | 40 +++++++++++++++++++++++++++++++++++-- 5 files changed, 109 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/ndr_lsa.c b/source4/libcli/ndr/ndr_lsa.c index 5955432915..dfe978f9d4 100644 --- a/source4/libcli/ndr/ndr_lsa.c +++ b/source4/libcli/ndr/ndr_lsa.c @@ -108,3 +108,48 @@ NTSTATUS ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); return NT_STATUS_OK; } + + +/* + push a EnumSids +*/ +NTSTATUS ndr_push_lsa_EnumSids(struct ndr_push *ndr, + struct lsa_EnumSids *r) +{ + NDR_CHECK(ndr_push_policy_handle(ndr, r->in.handle)); + NDR_CHECK(ndr_push_u32(ndr, r->in.start_at)); + NDR_CHECK(ndr_push_u32(ndr, r->in.num_entries)); + return NT_STATUS_OK; +} + +/* + pull a EnumSids +*/ +NTSTATUS ndr_pull_lsa_EnumSids(struct ndr_pull *ndr, + struct lsa_EnumSids *r) +{ + uint32 nptrs, asize, i, ptr; + + NDR_CHECK(ndr_pull_u32(ndr, &r->out.num_entries)); + NDR_CHECK(ndr_pull_u32(ndr, &nptrs)); + NDR_CHECK(ndr_pull_u32(ndr, &ptr)); + if (!ptr) goto done; + + NDR_CHECK(ndr_pull_u32(ndr, &asize)); + NDR_ALLOC_N(ndr, r->out.sids, nptrs); + for (i=0;iout.sids[i]); + } else { + r->out.sids[i] = NULL; + } + } + for (i=0;iout.sids[i]) NDR_CHECK(ndr_pull_dom_sid2(ndr, r->out.sids[i])); + } + +done: + NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_lsa.h b/source4/libcli/ndr/ndr_lsa.h index cfdd98e24e..0cc43b5f86 100644 --- a/source4/libcli/ndr/ndr_lsa.h +++ b/source4/libcli/ndr/ndr_lsa.h @@ -57,3 +57,16 @@ struct lsa_OpenPolicy2 { NTSTATUS status; } out; }; + +struct lsa_EnumSids { + struct { + struct policy_handle *handle; + uint32 start_at; + uint32 num_entries; + } in; + struct { + uint32 num_entries; + struct dom_sid **sids; + NTSTATUS status; + } out; +}; diff --git a/source4/libcli/ndr/ndr_sec.c b/source4/libcli/ndr/ndr_sec.c index 6b83a09d7a..52578089e6 100644 --- a/source4/libcli/ndr/ndr_sec.c +++ b/source4/libcli/ndr/ndr_sec.c @@ -136,6 +136,16 @@ NTSTATUS ndr_pull_dom_sid(struct ndr_pull *ndr, struct dom_sid *sid) return NT_STATUS_OK; } +/* + parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field +*/ +NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, struct dom_sid *sid) +{ + uint32 num_auths; + NDR_CHECK(ndr_pull_u32(ndr, &num_auths)); + return ndr_pull_dom_sid(ndr, sid); +} + /* parse a dom_sid offset and structure */ diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index 6a3275c7a4..a253e0eb65 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -59,6 +59,9 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p, const char *pipe_name) io.ntcreatex.in.fname = name; mem_ctx = talloc_init("torture_rpc_connection"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } status = smb_raw_open(p->tree, mem_ctx, &io); free(name); talloc_destroy(mem_ctx); diff --git a/source4/libcli/rpc/rpc_lsa.c b/source4/libcli/rpc/rpc_lsa.c index 8e1a48857e..65d6a81491 100644 --- a/source4/libcli/rpc/rpc_lsa.c +++ b/source4/libcli/rpc/rpc_lsa.c @@ -35,7 +35,7 @@ NTSTATUS dcerpc_lsa_OpenPolicy(struct dcerpc_pipe *p, NTSTATUS status; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("dcerpc_rpcecho_addone"); + mem_ctx = talloc_init("dcerpc_lsa_openpolicy"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } @@ -77,7 +77,7 @@ NTSTATUS dcerpc_lsa_OpenPolicy2(struct dcerpc_pipe *p, NTSTATUS status; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("dcerpc_rpcecho_addone"); + mem_ctx = talloc_init("dcerpc_lsa_openpolicy2"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } @@ -104,3 +104,39 @@ done: talloc_destroy(mem_ctx); return status; } + +/* + EnumSids interface +*/ +NTSTATUS dcerpc_lsa_EnumSids(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32 resume_handle, + uint32 *num_entries, + struct dom_sid ***sids) +{ + struct lsa_EnumSids r; + NTSTATUS status; + + /* fill the .in side of the call */ + r.in.handle = handle; + r.in.start_at = 0; + r.in.num_entries = *num_entries; + + /* make the call */ + status = dcerpc_ndr_request(p, LSA_ENUM_ACCOUNTS, mem_ctx, + (ndr_push_fn_t) ndr_push_lsa_EnumSids, + (ndr_pull_fn_t) ndr_pull_lsa_EnumSids, + &r); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + /* and extract the .out parameters */ + *num_entries = r.out.num_entries; + *sids = r.out.sids; + status = r.out.status; + +done: + return status; +} -- cgit From c1b3ebb1fa51a8b91e94d48ec272846235de1c03 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 22:42:00 +0000 Subject: fixed some error found by valgrind (This used to be commit ca5f0ccb6cd10d51c96a5cd8e0cd97d50cbb9a73) --- source4/libcli/ndr/ndr.c | 1 + source4/libcli/ndr/ndr_basic.c | 4 ++-- source4/libcli/raw/rawdcerpc.c | 3 +++ source4/libcli/rpc/dcerpc.c | 6 +++++- 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/ndr.c b/source4/libcli/ndr/ndr.c index d9a5ff7735..eca5799d8e 100644 --- a/source4/libcli/ndr/ndr.c +++ b/source4/libcli/ndr/ndr.c @@ -39,6 +39,7 @@ struct ndr_pull *ndr_pull_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx) ndr = talloc(mem_ctx, sizeof(*ndr)); if (!ndr) return NULL; + ndr->flags = 0; ndr->data = blob->data; ndr->data_size = blob->length; ndr->offset = 0; diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c index 21326c2a62..138e1f1a6c 100644 --- a/source4/libcli/ndr/ndr_basic.c +++ b/source4/libcli/ndr/ndr_basic.c @@ -120,8 +120,8 @@ NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid) #define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n))) #define NDR_PUSH_ALIGN(ndr, n) do { \ - ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ - NDR_CHECK(ndr_push_expand(ndr, ndr->offset)); \ + uint32 _pad = (ndr->offset & (n-1)); \ + while (_pad--) NDR_CHECK(ndr_push_u8(ndr, 0)); \ } while(0) /* diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c index a253e0eb65..0541200015 100644 --- a/source4/libcli/raw/rawdcerpc.c +++ b/source4/libcli/raw/rawdcerpc.c @@ -105,7 +105,10 @@ struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob) trans.in.max_param = 0; trans.in.max_data = 0x8000; + trans.in.max_setup = 0; trans.in.setup_count = 2; + trans.in.flags = 0; + trans.in.timeout = 0; trans.in.setup = setup; trans.in.trans_name = "\\PIPE\\"; diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 89f2c6d5b1..9e6c05e7ae 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -38,6 +38,7 @@ struct dcerpc_pipe *dcerpc_pipe_init(struct cli_tree *tree) return NULL; } + p->reference_count = 0; p->mem_ctx = mem_ctx; p->tree = tree; p->tree->reference_count++; @@ -746,7 +747,10 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p, /* - a useful helper function for synchronous rpc requests + a useful helper function for synchronous rpc requests + + this can be used when you have ndr push/pull functions in the + standard format */ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, uint32 opnum, -- cgit From 18d7a41acec8202b29c152f17bca3f7fe8d44ac0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 23:12:44 +0000 Subject: fixed another error found by valgrind (This used to be commit 4368eaa523830f3101f0bb052346ed26bc70ae73) --- source4/libcli/ndr/libndr.h | 4 ---- source4/libcli/ndr/ndr.c | 4 +++- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h index 931fc1c341..7bd92b4cd1 100644 --- a/source4/libcli/ndr/libndr.h +++ b/source4/libcli/ndr/libndr.h @@ -58,10 +58,6 @@ struct ndr_push_save { uint32 offset; }; -#define NDR_BASE_MARSHALL_SIZE 1024 - - - #define LIBNDR_FLAG_BIGENDIAN 1 diff --git a/source4/libcli/ndr/ndr.c b/source4/libcli/ndr/ndr.c index eca5799d8e..4e5f199835 100644 --- a/source4/libcli/ndr/ndr.c +++ b/source4/libcli/ndr/ndr.c @@ -29,6 +29,8 @@ #include "includes.h" +#define NDR_BASE_MARSHALL_SIZE 1024 + /* initialise a ndr parse structure from a data blob */ @@ -166,7 +168,7 @@ NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32 size) } ndr->alloc_size = size; - ndr->data = realloc(ndr->data, ndr->alloc_size); + ndr->data = talloc_realloc(ndr->mem_ctx, ndr->data, ndr->alloc_size); if (!ndr->data) { return NT_STATUS_NO_MEMORY; } -- cgit From eeffb71c727d6142f70865cfc512595aef36ed90 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Nov 2003 00:49:42 +0000 Subject: finished off the ndr_sec.c module (This used to be commit 6a8f297c45c9897b3dba18467cb449a70abf0b56) --- source4/libcli/ndr/ndr_basic.c | 61 +++++++++++++++++++-- source4/libcli/ndr/ndr_sec.c | 118 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 164 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c index 138e1f1a6c..394d1e2eb1 100644 --- a/source4/libcli/ndr/ndr_basic.c +++ b/source4/libcli/ndr/ndr_basic.c @@ -170,6 +170,21 @@ NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n) return NT_STATUS_OK; } +/* + save the current position + */ +void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save) +{ + save->offset = ndr->offset; +} + +/* + restore the position + */ +void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save) +{ + ndr->offset = save->offset; +} /* this is used when a packet has a 4 byte length field. We remember the start position @@ -178,16 +193,17 @@ NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n) NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save) { NDR_PUSH_ALIGN(ndr, 4); - save->offset = ndr->offset; + ndr_push_save(ndr, save); return ndr_push_u32(ndr, 0); } NTSTATUS ndr_push_length4_end(struct ndr_push *ndr, struct ndr_push_save *save) { - uint32 offset = ndr->offset; - ndr->offset = save->offset; - NDR_CHECK(ndr_push_u32(ndr, offset - save->offset)); - ndr->offset = offset; + struct ndr_push_save save2; + ndr_push_save(ndr, &save2); + ndr_push_restore(ndr, save); + NDR_CHECK(ndr_push_u32(ndr, save2.offset - ndr->offset)); + ndr_push_restore(ndr, &save2); return NT_STATUS_OK; } @@ -217,3 +233,38 @@ NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s) return NT_STATUS_OK; } +/* + push a 4 byte offset pointer, remembering where we are so we can later fill + in the correct value +*/ +NTSTATUS ndr_push_offset(struct ndr_push *ndr, struct ndr_push_save *ofs) +{ + NDR_PUSH_ALIGN(ndr, 4); + ndr_push_save(ndr, ofs); + return ndr_push_u32(ndr, 0); +} + +/* + fill in the correct offset in a saved offset pointer + the offset is taken relative to 'save' +*/ +NTSTATUS ndr_push_offset_ptr(struct ndr_push *ndr, + struct ndr_push_save *ofs, + struct ndr_push_save *save) +{ + struct ndr_push_save save2; + ndr_push_save(ndr, &save2); + ndr_push_restore(ndr, ofs); + NDR_CHECK(ndr_push_u32(ndr, save2.offset - save->offset)); + ndr_push_restore(ndr, &save2); + return NT_STATUS_OK; +} + + +/* + push a GUID +*/ +NTSTATUS ndr_push_guid(struct ndr_push *ndr, GUID *guid) +{ + return ndr_push_bytes(ndr, guid->info, GUID_SIZE); +} diff --git a/source4/libcli/ndr/ndr_sec.c b/source4/libcli/ndr/ndr_sec.c index 52578089e6..9ac5240b0f 100644 --- a/source4/libcli/ndr/ndr_sec.c +++ b/source4/libcli/ndr/ndr_sec.c @@ -174,7 +174,7 @@ NTSTATUS ndr_pull_dom_sid_ofs(struct ndr_pull *ndr, struct dom_sid **sid) parse a security descriptor */ NTSTATUS ndr_pull_security_descriptor(struct ndr_pull *ndr, - struct security_descriptor **sd) + struct security_descriptor **sd) { NDR_ALLOC(ndr, *sd); @@ -188,24 +188,122 @@ NTSTATUS ndr_pull_security_descriptor(struct ndr_pull *ndr, return NT_STATUS_OK; } + +/* + parse a security_ace +*/ +NTSTATUS ndr_push_security_ace(struct ndr_push *ndr, struct security_ace *ace) +{ + struct ndr_push_save save1, save2; + + NDR_CHECK(ndr_push_u8(ndr, ace->type)); + NDR_CHECK(ndr_push_u8(ndr, ace->flags)); + ndr_push_save(ndr, &save1); + NDR_CHECK(ndr_push_u16(ndr, 0)); + NDR_CHECK(ndr_push_u32(ndr, ace->access_mask)); + + if (sec_ace_object(ace->type)) { + NDR_CHECK(ndr_push_u32(ndr, ace->obj->flags)); + if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) { + NDR_CHECK(ndr_push_guid(ndr, &ace->obj->object_guid)); + } + if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { + NDR_CHECK(ndr_push_guid(ndr, &ace->obj->inherit_guid)); + } + } + + NDR_CHECK(ndr_push_dom_sid(ndr, &ace->trustee)); + + ndr_push_save(ndr, &save2); + ndr_push_restore(ndr, &save1); + NDR_CHECK(ndr_push_u16(ndr, 2 + save2.offset - save1.offset)); + ndr_push_restore(ndr, &save2); + + return NT_STATUS_OK; +} + + +/* + push a security_acl +*/ +NTSTATUS ndr_push_security_acl(struct ndr_push *ndr, struct security_acl *acl) +{ + int i; + struct ndr_push_save save1, save2; + + NDR_CHECK(ndr_push_u16(ndr, acl->revision)); + ndr_push_save(ndr, &save1); + NDR_CHECK(ndr_push_u16(ndr, 0)); + NDR_CHECK(ndr_push_u32(ndr, acl->num_aces)); + for (i=0;inum_aces;i++) { + NDR_CHECK(ndr_push_security_ace(ndr, &acl->aces[i])); + } + ndr_push_save(ndr, &save2); + ndr_push_restore(ndr, &save1); + NDR_CHECK(ndr_push_u16(ndr, 2 + save2.offset - save1.offset)); + ndr_push_restore(ndr, &save2); + + return NT_STATUS_OK; +} + +/* + push a dom_sid +*/ +NTSTATUS ndr_push_dom_sid(struct ndr_push *ndr, struct dom_sid *sid) +{ + int i; + + NDR_CHECK(ndr_push_u8(ndr, sid->sid_rev_num)); + NDR_CHECK(ndr_push_u8(ndr, sid->num_auths)); + for (i=0;i<6;i++) { + NDR_CHECK(ndr_push_u8(ndr, sid->id_auth[i])); + } + for (i=0;inum_auths;i++) { + NDR_CHECK(ndr_push_u32(ndr, sid->sub_auths[i])); + } + + return NT_STATUS_OK; +} + + /* generate a ndr security descriptor */ NTSTATUS ndr_push_security_descriptor(struct ndr_push *ndr, struct security_descriptor *sd) { - uint32 var_offset; + struct ndr_push_save save; + struct ndr_push_save ofs1, ofs2, ofs3, ofs4; - var_offset = 20; + ndr_push_save(ndr, &save); NDR_CHECK(ndr_push_u8(ndr, sd->revision)); NDR_CHECK(ndr_push_u16(ndr, sd->type)); -/* - NDR_CHECK(ndr_push_dom_sid_ofs(ndr, sd->owner_sid, &var_offset)); - NDR_CHECK(ndr_push_dom_sid_ofs(ndr, sd->group_sid, &var_offset)); - NDR_CHECK(ndr_push_security_acl_ofs(ndr, sd->sacl, &var_offset)); - NDR_CHECK(ndr_push_security_acl_ofs(ndr, sd->dacl, &var_offset)); -*/ + + NDR_CHECK(ndr_push_offset(ndr, &ofs1)); + NDR_CHECK(ndr_push_offset(ndr, &ofs2)); + NDR_CHECK(ndr_push_offset(ndr, &ofs3)); + NDR_CHECK(ndr_push_offset(ndr, &ofs4)); + + if (sd->owner_sid) { + NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs1, &save)); + NDR_CHECK(ndr_push_dom_sid(ndr, sd->owner_sid)); + } + + if (sd->group_sid) { + NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs2, &save)); + NDR_CHECK(ndr_push_dom_sid(ndr, sd->group_sid)); + } + + if (sd->sacl) { + NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs3, &save)); + NDR_CHECK(ndr_push_security_acl(ndr, sd->sacl)); + } + + if (sd->dacl) { + NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs4, &save)); + NDR_CHECK(ndr_push_security_acl(ndr, sd->dacl)); + } + return NT_STATUS_OK; } - -- cgit From 4fa0f615f286631820316f8c87dd61eda494e203 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Nov 2003 12:34:04 +0000 Subject: another major bit of restructuring of rpc in Samba4. Mostly moving files around, but also added the first bits of auto-generated code for the lsa pipe. I haven't updated the Makefile to call pidl yet, so for now the code was cut-and-pasted into librpc/ndr/ndr_lsa.c manually (This used to be commit 6b222d3b6541ee74cf8bf3f0913cd444903ca991) --- source4/libcli/ndr/libndr.h | 95 ----- source4/libcli/ndr/ndr.c | 187 ---------- source4/libcli/ndr/ndr_basic.c | 270 -------------- source4/libcli/ndr/ndr_echo.c | 114 ------ source4/libcli/ndr/ndr_echo.h | 76 ---- source4/libcli/ndr/ndr_lsa.c | 155 -------- source4/libcli/ndr/ndr_lsa.h | 72 ---- source4/libcli/ndr/ndr_misc.c | 45 --- source4/libcli/ndr/ndr_misc.h | 26 -- source4/libcli/ndr/ndr_sec.c | 309 ---------------- source4/libcli/ndr/ndr_sec.h | 90 ----- source4/libcli/raw/rawdcerpc.c | 320 ---------------- source4/libcli/rpc/dcerpc.c | 804 ----------------------------------------- source4/libcli/rpc/dcerpc.h | 129 ------- source4/libcli/rpc/rpc_echo.c | 137 ------- source4/libcli/rpc/rpc_lsa.c | 142 -------- 16 files changed, 2971 deletions(-) delete mode 100644 source4/libcli/ndr/libndr.h delete mode 100644 source4/libcli/ndr/ndr.c delete mode 100644 source4/libcli/ndr/ndr_basic.c delete mode 100644 source4/libcli/ndr/ndr_echo.c delete mode 100644 source4/libcli/ndr/ndr_echo.h delete mode 100644 source4/libcli/ndr/ndr_lsa.c delete mode 100644 source4/libcli/ndr/ndr_lsa.h delete mode 100644 source4/libcli/ndr/ndr_misc.c delete mode 100644 source4/libcli/ndr/ndr_misc.h delete mode 100644 source4/libcli/ndr/ndr_sec.c delete mode 100644 source4/libcli/ndr/ndr_sec.h delete mode 100644 source4/libcli/raw/rawdcerpc.c delete mode 100644 source4/libcli/rpc/dcerpc.c delete mode 100644 source4/libcli/rpc/dcerpc.h delete mode 100644 source4/libcli/rpc/rpc_echo.c delete mode 100644 source4/libcli/rpc/rpc_lsa.c (limited to 'source4/libcli') diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h deleted file mode 100644 index 7bd92b4cd1..0000000000 --- a/source4/libcli/ndr/libndr.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - Unix SMB/CIFS implementation. - rpc interface definitions - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - this provides definitions for the libcli/rpc/ MSRPC library -*/ - - -/* this is the base structure passed to routines that - parse MSRPC formatted data - - note that in Samba4 we use separate routines and structures for - MSRPC marshalling and unmarshalling. Also note that these routines - are being kept deliberately very simple, and are not tied to a - particular transport -*/ -struct ndr_pull { - uint32 flags; /* LIBNDR_FLAG_* */ - char *data; - uint32 data_size; - uint32 offset; - TALLOC_CTX *mem_ctx; -}; - -struct ndr_pull_save { - uint32 data_size; - uint32 offset; -}; - - -/* structure passed to functions that generate NDR formatted data */ -struct ndr_push { - uint32 flags; /* LIBNDR_FLAG_* */ - char *data; - uint32 alloc_size; - uint32 offset; - TALLOC_CTX *mem_ctx; -}; - -struct ndr_push_save { - uint32 offset; -}; - -#define LIBNDR_FLAG_BIGENDIAN 1 - - -/* these are used to make the error checking on each element in libndr - less tedious, hopefully making the code more readable */ -#define NDR_CHECK(call) do { NTSTATUS _status; \ - _status = call; \ - if (!NT_STATUS_IS_OK(_status)) \ - return _status; \ - } while (0) - - -#define NDR_ALLOC(ndr, s) do { \ - (s) = talloc(ndr->mem_ctx, sizeof(*(s))); \ - if (!(s)) return NT_STATUS_NO_MEMORY; \ - } while (0) - -#define NDR_ALLOC_N(ndr, s, n) do { \ - if ((n) == 0) { \ - (s) = NULL; \ - } else { \ - (s) = talloc(ndr->mem_ctx, (n) * sizeof(*(s))); \ - if (!(s)) return NT_STATUS_NO_MEMORY; \ - } \ - } while (0) - -/* these are used when generic fn pointers are needed for ndr push/pull fns */ -typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *); -typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *); - -/* now pull in the individual parsers */ -#include "libcli/ndr/ndr_sec.h" -#include "libcli/ndr/ndr_misc.h" -#include "libcli/ndr/ndr_echo.h" -#include "libcli/ndr/ndr_lsa.h" diff --git a/source4/libcli/ndr/ndr.c b/source4/libcli/ndr/ndr.c deleted file mode 100644 index 4e5f199835..0000000000 --- a/source4/libcli/ndr/ndr.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - libndr interface - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - this provides the core routines for NDR parsing functions - - see http://www.opengroup.org/onlinepubs/9629399/chap14.htm for details - of NDR encoding rules -*/ - -#include "includes.h" - -#define NDR_BASE_MARSHALL_SIZE 1024 - -/* - initialise a ndr parse structure from a data blob -*/ -struct ndr_pull *ndr_pull_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx) -{ - struct ndr_pull *ndr; - - ndr = talloc(mem_ctx, sizeof(*ndr)); - if (!ndr) return NULL; - - ndr->flags = 0; - ndr->data = blob->data; - ndr->data_size = blob->length; - ndr->offset = 0; - ndr->mem_ctx = mem_ctx; - - return ndr; -} - - -/* limit the remaining size of the current ndr parse structure to the - given size, starting at the given offset - - this is used when a ndr packet has an explicit size on the wire, and we - need to make sure that we don't use more data than is indicated - - the 'ofs' parameter indicates how many bytes back from the current - offset in the buffer the 'size' number of bytes starts -*/ -NTSTATUS ndr_pull_limit_size(struct ndr_pull *ndr, uint32 size, uint32 ofs) -{ - uint32 new_size; - new_size = ndr->offset + size - ofs; - - if (new_size > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - ndr->data_size = new_size; - - return NT_STATUS_OK; -} - - -/* - advance by 'size' bytes -*/ -NTSTATUS ndr_pull_advance(struct ndr_pull *ndr, uint32 size) -{ - ndr->offset += size; - if (ndr->offset > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - return NT_STATUS_OK; -} - -/* - set the parse offset to 'ofs' -*/ -NTSTATUS ndr_pull_set_offset(struct ndr_pull *ndr, uint32 ofs) -{ - ndr->offset = ofs; - if (ndr->offset > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - return NT_STATUS_OK; -} - -/* save the offset/size of the current ndr state */ -void ndr_pull_save(struct ndr_pull *ndr, struct ndr_pull_save *save) -{ - save->offset = ndr->offset; - save->data_size = ndr->data_size; -} - -/* restore the size/offset of a ndr structure */ -void ndr_pull_restore(struct ndr_pull *ndr, struct ndr_pull_save *save) -{ - ndr->offset = save->offset; - ndr->data_size = save->data_size; -} - - - - -/* create a ndr_push structure, ready for some marshalling */ -struct ndr_push *ndr_push_init(void) -{ - struct ndr_push *ndr; - TALLOC_CTX *mem_ctx = talloc_init("ndr_push_init"); - if (!mem_ctx) return NULL; - - ndr = talloc(mem_ctx, sizeof(*ndr)); - if (!ndr) { - talloc_destroy(mem_ctx); - return NULL; - } - - ndr->mem_ctx = mem_ctx; - ndr->flags = 0; - ndr->alloc_size = NDR_BASE_MARSHALL_SIZE; - ndr->data = talloc(ndr->mem_ctx, ndr->alloc_size); - if (!ndr->data) { - ndr_push_free(ndr); - return NULL; - } - ndr->offset = 0; - - return ndr; -} - -/* free a ndr_push structure */ -void ndr_push_free(struct ndr_push *ndr) -{ - talloc_destroy(ndr->mem_ctx); -} - - -/* return a DATA_BLOB structure for the current ndr_push marshalled data */ -DATA_BLOB ndr_push_blob(struct ndr_push *ndr) -{ - DATA_BLOB blob; - blob.data = ndr->data; - blob.length = ndr->offset; - return blob; -} - - -/* - expand the available space in the buffer to 'size' -*/ -NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32 size) -{ - if (ndr->alloc_size >= size) { - return NT_STATUS_OK; - } - - ndr->alloc_size = size; - ndr->data = talloc_realloc(ndr->mem_ctx, ndr->data, ndr->alloc_size); - if (!ndr->data) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -/* - set the push offset to 'ofs' -*/ -NTSTATUS ndr_push_set_offset(struct ndr_push *ndr, uint32 ofs) -{ - NDR_CHECK(ndr_push_expand(ndr, ofs)); - ndr->offset = ofs; - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c deleted file mode 100644 index 394d1e2eb1..0000000000 --- a/source4/libcli/ndr/ndr_basic.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling basic types - - Copyright (C) Andrew Tridgell 2003 - - 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" - -#define NDR_PULL_NEED_BYTES(ndr, n) do { \ - if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \ - return NT_STATUS_BUFFER_TOO_SMALL; \ - } \ -} while(0) - -#define NDR_PULL_ALIGN(ndr, n) do { \ - ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ - if (ndr->offset >= ndr->data_size) { \ - return NT_STATUS_BUFFER_TOO_SMALL; \ - } \ -} while(0) - -/* - parse a u8 -*/ -NTSTATUS ndr_pull_u8(struct ndr_pull *ndr, uint8 *v) -{ - NDR_PULL_NEED_BYTES(ndr, 1); - *v = CVAL(ndr->data, ndr->offset); - ndr->offset += 1; - return NT_STATUS_OK; -} - - -/* - parse a u16 -*/ -NTSTATUS ndr_pull_u16(struct ndr_pull *ndr, uint16 *v) -{ - NDR_PULL_ALIGN(ndr, 2); - NDR_PULL_NEED_BYTES(ndr, 2); - if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { - *v = RSVAL(ndr->data, ndr->offset); - } else { - *v = SVAL(ndr->data, ndr->offset); - } - ndr->offset += 2; - return NT_STATUS_OK; -} - - -/* - parse a u32 -*/ -NTSTATUS ndr_pull_u32(struct ndr_pull *ndr, uint32 *v) -{ - NDR_PULL_ALIGN(ndr, 4); - NDR_PULL_NEED_BYTES(ndr, 4); - if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { - *v = RIVAL(ndr->data, ndr->offset); - } else { - *v = IVAL(ndr->data, ndr->offset); - } - ndr->offset += 4; - return NT_STATUS_OK; -} - -/* - pull a NTSTATUS -*/ -NTSTATUS ndr_pull_status(struct ndr_pull *ndr, NTSTATUS *status) -{ - uint32 v; - NDR_CHECK(ndr_pull_u32(ndr, &v)); - *status = NT_STATUS(v); - return NT_STATUS_OK; -} - -/* - parse a set of bytes -*/ -NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n) -{ - NDR_PULL_NEED_BYTES(ndr, n); - memcpy(data, ndr->data + ndr->offset, n); - ndr->offset += n; - return NT_STATUS_OK; -} - -/* - parse a GUID -*/ -NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid) -{ - int i; - NDR_PULL_NEED_BYTES(ndr, GUID_SIZE); - for (i=0;iinfo[i] = CVAL(ndr->data, ndr->offset + i); - } - ndr->offset += i; - return NT_STATUS_OK; -} - - -#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n))) - -#define NDR_PUSH_ALIGN(ndr, n) do { \ - uint32 _pad = (ndr->offset & (n-1)); \ - while (_pad--) NDR_CHECK(ndr_push_u8(ndr, 0)); \ -} while(0) - -/* - push a u8 -*/ -NTSTATUS ndr_push_u8(struct ndr_push *ndr, uint8 v) -{ - NDR_PUSH_NEED_BYTES(ndr, 1); - SCVAL(ndr->data, ndr->offset, v); - ndr->offset += 1; - return NT_STATUS_OK; -} - -/* - push a u16 -*/ -NTSTATUS ndr_push_u16(struct ndr_push *ndr, uint16 v) -{ - NDR_PUSH_ALIGN(ndr, 2); - NDR_PUSH_NEED_BYTES(ndr, 2); - SSVAL(ndr->data, ndr->offset, v); - ndr->offset += 2; - return NT_STATUS_OK; -} - -/* - push a u32 -*/ -NTSTATUS ndr_push_u32(struct ndr_push *ndr, uint32 v) -{ - NDR_PUSH_ALIGN(ndr, 4); - NDR_PUSH_NEED_BYTES(ndr, 4); - SIVAL(ndr->data, ndr->offset, v); - ndr->offset += 4; - return NT_STATUS_OK; -} - -/* - push some bytes -*/ -NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n) -{ - NDR_PUSH_NEED_BYTES(ndr, n); - memcpy(ndr->data + ndr->offset, data, n); - ndr->offset += n; - return NT_STATUS_OK; -} - -/* - save the current position - */ -void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save) -{ - save->offset = ndr->offset; -} - -/* - restore the position - */ -void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save) -{ - ndr->offset = save->offset; -} - -/* - this is used when a packet has a 4 byte length field. We remember the start position - and come back to it later to fill in the size -*/ -NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save) -{ - NDR_PUSH_ALIGN(ndr, 4); - ndr_push_save(ndr, save); - return ndr_push_u32(ndr, 0); -} - -NTSTATUS ndr_push_length4_end(struct ndr_push *ndr, struct ndr_push_save *save) -{ - struct ndr_push_save save2; - ndr_push_save(ndr, &save2); - ndr_push_restore(ndr, save); - NDR_CHECK(ndr_push_u32(ndr, save2.offset - ndr->offset)); - ndr_push_restore(ndr, &save2); - return NT_STATUS_OK; -} - -/* - push a 1 if a pointer is non-NULL, otherwise 0 -*/ -NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p) -{ - return ndr_push_u32(ndr, p?1:0); -} - -/* - push a comformant, variable ucs2 string onto the wire from a C string -*/ -NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s) -{ - char *ws; - ssize_t len; - len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s); - if (len == -1) { - return NT_STATUS_INVALID_PARAMETER; - } - NDR_CHECK(ndr_push_u32(ndr, len/2)); - NDR_CHECK(ndr_push_u32(ndr, 0)); - NDR_CHECK(ndr_push_u32(ndr, len/2)); - NDR_CHECK(ndr_push_bytes(ndr, ws, len)); - return NT_STATUS_OK; -} - -/* - push a 4 byte offset pointer, remembering where we are so we can later fill - in the correct value -*/ -NTSTATUS ndr_push_offset(struct ndr_push *ndr, struct ndr_push_save *ofs) -{ - NDR_PUSH_ALIGN(ndr, 4); - ndr_push_save(ndr, ofs); - return ndr_push_u32(ndr, 0); -} - -/* - fill in the correct offset in a saved offset pointer - the offset is taken relative to 'save' -*/ -NTSTATUS ndr_push_offset_ptr(struct ndr_push *ndr, - struct ndr_push_save *ofs, - struct ndr_push_save *save) -{ - struct ndr_push_save save2; - ndr_push_save(ndr, &save2); - ndr_push_restore(ndr, ofs); - NDR_CHECK(ndr_push_u32(ndr, save2.offset - save->offset)); - ndr_push_restore(ndr, &save2); - return NT_STATUS_OK; -} - - -/* - push a GUID -*/ -NTSTATUS ndr_push_guid(struct ndr_push *ndr, GUID *guid) -{ - return ndr_push_bytes(ndr, guid->info, GUID_SIZE); -} diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c deleted file mode 100644 index c60569676c..0000000000 --- a/source4/libcli/ndr/ndr_echo.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling rpcecho pipe - - Copyright (C) Andrew Tridgell 2003 - - 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" - - -/* - parse a addone -*/ -NTSTATUS ndr_pull_rpcecho_addone(struct ndr_pull *ndr, - struct rpcecho_addone *r) -{ - NDR_CHECK(ndr_pull_u32(ndr, &r->out.data)); - return NT_STATUS_OK; -} - - -/* - push a addone -*/ -NTSTATUS ndr_push_rpcecho_addone(struct ndr_push *ndr, - struct rpcecho_addone *r) -{ - NDR_CHECK(ndr_push_u32(ndr, r->in.data)); - return NT_STATUS_OK; -} - - -/* - parse a echodata -*/ -NTSTATUS ndr_pull_rpcecho_echodata(struct ndr_pull *ndr, - struct rpcecho_echodata *r) -{ - NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); - NDR_ALLOC_N(ndr, r->out.data, r->out.len); - NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len)); - return NT_STATUS_OK; -} - -/* - push a echodata -*/ -NTSTATUS ndr_push_rpcecho_echodata(struct ndr_push *ndr, - struct rpcecho_echodata *r) -{ - NDR_CHECK(ndr_push_u32(ndr, r->in.len)); - NDR_CHECK(ndr_push_u32(ndr, r->in.len)); - NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); - return NT_STATUS_OK; -} - -/* - parse a sinkdata -*/ -NTSTATUS ndr_pull_rpcecho_sinkdata(struct ndr_pull *ndr, - struct rpcecho_sinkdata *r) -{ - return NT_STATUS_OK; -} - -/* - push a sinkdata -*/ -NTSTATUS ndr_push_rpcecho_sinkdata(struct ndr_push *ndr, - struct rpcecho_sinkdata *r) -{ - NDR_CHECK(ndr_push_u32(ndr, r->in.len)); - NDR_CHECK(ndr_push_u32(ndr, r->in.len)); - NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); - return NT_STATUS_OK; -} - -/* - parse a sourcedata -*/ -NTSTATUS ndr_pull_rpcecho_sourcedata(struct ndr_pull *ndr, - struct rpcecho_sourcedata *r) -{ - NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); - NDR_ALLOC_N(ndr, r->out.data, r->out.len); - NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len)); - return NT_STATUS_OK; -} - -/* - push a sourcedata -*/ -NTSTATUS ndr_push_rpcecho_sourcedata(struct ndr_push *ndr, - struct rpcecho_sourcedata *r) -{ - NDR_CHECK(ndr_push_u32(ndr, r->in.len)); - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_echo.h b/source4/libcli/ndr/ndr_echo.h deleted file mode 100644 index aecf68c4c0..0000000000 --- a/source4/libcli/ndr/ndr_echo.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - definitions for marshalling/unmarshalling the rpcecho pipe - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - see http://samba.org/ftp/unpacked/junkcode/rpcecho-win32/ for the - definition of this pipe -*/ - -/* AddOne interface */ -struct rpcecho_addone { - struct { - int data; - } in; - struct { - int data; - } out; -}; - -/* EchoData interface */ -struct rpcecho_echodata { - struct { - int len; - const char *data; - } in; - struct { - int len; - char *data; - } out; -}; - -/* SinkData interface */ -struct rpcecho_sinkdata { - struct { - int len; - char *data; - } in; -}; - -/* SourceData interface */ -struct rpcecho_sourcedata { - struct { - int len; - } in; - struct { - int len; - char *data; - } out; -}; - -/* define the command codes */ -enum { - RPCECHO_CALL_ADDONE=0, - RPCECHO_CALL_ECHODATA, - RPCECHO_CALL_SINKDATA, - RPCECHO_CALL_SOURCEDATA -}; - diff --git a/source4/libcli/ndr/ndr_lsa.c b/source4/libcli/ndr/ndr_lsa.c deleted file mode 100644 index dfe978f9d4..0000000000 --- a/source4/libcli/ndr/ndr_lsa.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling lsa pipe - - Copyright (C) Andrew Tridgell 2003 - - 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" - -NTSTATUS ndr_push_lsa_QosInfo(struct ndr_push *ndr, - struct lsa_QosInfo *r) -{ - struct ndr_push_save length; - - NDR_CHECK(ndr_push_length4_start(ndr, &length)); - NDR_CHECK(ndr_push_u16(ndr, r->impersonation_level)); - NDR_CHECK(ndr_push_u8(ndr, r->context_mode)); - NDR_CHECK(ndr_push_u8(ndr, r->effective_only)); - NDR_CHECK(ndr_push_length4_end(ndr, &length)); - - return NT_STATUS_OK; -} - -NTSTATUS ndr_push_lsa_ObjectAttribute(struct ndr_push *ndr, - struct lsa_ObjectAttribute *r) -{ - struct ndr_push_save length; - - NDR_CHECK(ndr_push_length4_start(ndr, &length)); - NDR_CHECK(ndr_push_ptr(ndr, r->root_dir)); - NDR_CHECK(ndr_push_ptr(ndr, r->object_name)); - NDR_CHECK(ndr_push_u32(ndr, r->attributes)); - NDR_CHECK(ndr_push_ptr(ndr, r->sec_desc)); - NDR_CHECK(ndr_push_ptr(ndr, r->sec_qos)); - - if (r->root_dir) NDR_CHECK(ndr_push_u8(ndr, r->root_dir[0])); - if (r->object_name) NDR_CHECK(ndr_push_unistr(ndr, r->object_name)); - if (r->sec_desc) NDR_CHECK(ndr_push_security_descriptor(ndr, r->sec_desc)); - if (r->sec_qos) NDR_CHECK(ndr_push_lsa_QosInfo(ndr, r->sec_qos)); - - NDR_CHECK(ndr_push_length4_end(ndr, &length)); - - return NT_STATUS_OK; -} - -/* - push a openpolicy -*/ -NTSTATUS ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, - struct lsa_OpenPolicy *r) -{ - NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name)); - NDR_CHECK(ndr_push_u16(ndr, r->in.system_name[0])); - NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr)); - NDR_CHECK(ndr_push_u32(ndr, r->in.desired_access)); - return NT_STATUS_OK; -} - - -/* - parse a openpolicy -*/ -NTSTATUS ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, - struct lsa_OpenPolicy *r) -{ - NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle)); - NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); - return NT_STATUS_OK; -} - -/* - push a openpolicy2 -*/ -NTSTATUS ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, - struct lsa_OpenPolicy2 *r) -{ - NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name)); - NDR_CHECK(ndr_push_unistr(ndr, r->in.system_name)); - NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr)); - NDR_CHECK(ndr_push_u32(ndr, r->in.desired_access)); - return NT_STATUS_OK; -} - - -/* - parse a openpolicy2 -*/ -NTSTATUS ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, - struct lsa_OpenPolicy2 *r) -{ - NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle)); - NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); - return NT_STATUS_OK; -} - - -/* - push a EnumSids -*/ -NTSTATUS ndr_push_lsa_EnumSids(struct ndr_push *ndr, - struct lsa_EnumSids *r) -{ - NDR_CHECK(ndr_push_policy_handle(ndr, r->in.handle)); - NDR_CHECK(ndr_push_u32(ndr, r->in.start_at)); - NDR_CHECK(ndr_push_u32(ndr, r->in.num_entries)); - return NT_STATUS_OK; -} - -/* - pull a EnumSids -*/ -NTSTATUS ndr_pull_lsa_EnumSids(struct ndr_pull *ndr, - struct lsa_EnumSids *r) -{ - uint32 nptrs, asize, i, ptr; - - NDR_CHECK(ndr_pull_u32(ndr, &r->out.num_entries)); - NDR_CHECK(ndr_pull_u32(ndr, &nptrs)); - NDR_CHECK(ndr_pull_u32(ndr, &ptr)); - if (!ptr) goto done; - - NDR_CHECK(ndr_pull_u32(ndr, &asize)); - NDR_ALLOC_N(ndr, r->out.sids, nptrs); - for (i=0;iout.sids[i]); - } else { - r->out.sids[i] = NULL; - } - } - for (i=0;iout.sids[i]) NDR_CHECK(ndr_pull_dom_sid2(ndr, r->out.sids[i])); - } - -done: - NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_lsa.h b/source4/libcli/ndr/ndr_lsa.h deleted file mode 100644 index 0cc43b5f86..0000000000 --- a/source4/libcli/ndr/ndr_lsa.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - definitions for marshalling/unmarshalling the lsa pipe - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -struct lsa_QosInfo { - uint16 impersonation_level; - uint8 context_mode; - uint8 effective_only; -}; - -struct lsa_ObjectAttribute { - const char *root_dir; - const char *object_name; - uint32 attributes; - struct security_descriptor *sec_desc; - struct lsa_QosInfo *sec_qos; -}; - -struct lsa_OpenPolicy { - struct { - const char *system_name; - struct lsa_ObjectAttribute *attr; - uint32 desired_access; - } in; - struct { - struct policy_handle handle; - NTSTATUS status; - } out; -}; - -struct lsa_OpenPolicy2 { - struct { - const char *system_name; - struct lsa_ObjectAttribute *attr; - uint32 desired_access; - } in; - struct { - struct policy_handle handle; - NTSTATUS status; - } out; -}; - -struct lsa_EnumSids { - struct { - struct policy_handle *handle; - uint32 start_at; - uint32 num_entries; - } in; - struct { - uint32 num_entries; - struct dom_sid **sids; - NTSTATUS status; - } out; -}; diff --git a/source4/libcli/ndr/ndr_misc.c b/source4/libcli/ndr/ndr_misc.c deleted file mode 100644 index cdd6652068..0000000000 --- a/source4/libcli/ndr/ndr_misc.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling miscellaneous rpc structures - - Copyright (C) Andrew Tridgell 2003 - - 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" - - -/* - parse a policy handle -*/ -NTSTATUS ndr_pull_policy_handle(struct ndr_pull *ndr, - struct policy_handle *r) -{ - NDR_CHECK(ndr_pull_bytes(ndr, r->data, 20)); - return NT_STATUS_OK; -} - -/* - push a policy handle -*/ -NTSTATUS ndr_push_policy_handle(struct ndr_push *ndr, - struct policy_handle *r) -{ - NDR_CHECK(ndr_push_bytes(ndr, r->data, 20)); - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_misc.h b/source4/libcli/ndr/ndr_misc.h deleted file mode 100644 index cc3576b3e8..0000000000 --- a/source4/libcli/ndr/ndr_misc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - definitions for marshalling/unmarshalling miscellaneous structures - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* policy handles are used all over the place */ -struct policy_handle { - char data[20]; -}; diff --git a/source4/libcli/ndr/ndr_sec.c b/source4/libcli/ndr/ndr_sec.c deleted file mode 100644 index 9ac5240b0f..0000000000 --- a/source4/libcli/ndr/ndr_sec.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling security descriptors - and related structures - - Copyright (C) Andrew Tridgell 2003 - - 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" - -/* - parse a security_ace -*/ -NTSTATUS ndr_pull_security_ace(struct ndr_pull *ndr, struct security_ace *ace) -{ - uint16 size; - struct ndr_pull_save save; - - ndr_pull_save(ndr, &save); - - NDR_CHECK(ndr_pull_u8(ndr, &ace->type)); - NDR_CHECK(ndr_pull_u8(ndr, &ace->flags)); - NDR_CHECK(ndr_pull_u16(ndr, &size)); - NDR_CHECK(ndr_pull_limit_size(ndr, size, 4)); - - NDR_CHECK(ndr_pull_u32(ndr, &ace->access_mask)); - - if (sec_ace_object(ace->type)) { - NDR_ALLOC(ndr, ace->obj); - NDR_CHECK(ndr_pull_u32(ndr, &ace->obj->flags)); - if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) { - NDR_CHECK(ndr_pull_guid(ndr, &ace->obj->object_guid)); - } - if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - NDR_CHECK(ndr_pull_guid(ndr, &ace->obj->inherit_guid)); - } - } - - - NDR_CHECK(ndr_pull_dom_sid(ndr, &ace->trustee)); - - ndr_pull_restore(ndr, &save); - NDR_CHECK(ndr_pull_advance(ndr, size)); - - return NT_STATUS_OK; -} - -/* - parse a security_acl -*/ -NTSTATUS ndr_pull_security_acl(struct ndr_pull *ndr, struct security_acl *acl) -{ - int i; - uint16 size; - struct ndr_pull_save save; - - ndr_pull_save(ndr, &save); - - NDR_CHECK(ndr_pull_u16(ndr, &acl->revision)); - NDR_CHECK(ndr_pull_u16(ndr, &size)); - NDR_CHECK(ndr_pull_limit_size(ndr, size, 4)); - NDR_CHECK(ndr_pull_u32(ndr, &acl->num_aces)); - - NDR_ALLOC_N(ndr, acl->aces, acl->num_aces); - - for (i=0;inum_aces;i++) { - NDR_CHECK(ndr_pull_security_ace(ndr, &acl->aces[i])); - } - - ndr_pull_restore(ndr, &save); - NDR_CHECK(ndr_pull_advance(ndr, size)); - - return NT_STATUS_OK; -} - -/* - parse a security_acl offset and structure -*/ -NTSTATUS ndr_pull_security_acl_ofs(struct ndr_pull *ndr, struct security_acl **acl) -{ - uint32 ofs; - struct ndr_pull_save save; - - NDR_CHECK(ndr_pull_u32(ndr, &ofs)); - if (ofs == 0) { - /* it is valid for an acl ptr to be NULL */ - *acl = NULL; - return NT_STATUS_OK; - } - - ndr_pull_save(ndr, &save); - NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); - NDR_ALLOC(ndr, *acl); - NDR_CHECK(ndr_pull_security_acl(ndr, *acl)); - ndr_pull_restore(ndr, &save); - - return NT_STATUS_OK; -} - - -/* - parse a dom_sid -*/ -NTSTATUS ndr_pull_dom_sid(struct ndr_pull *ndr, struct dom_sid *sid) -{ - int i; - - NDR_CHECK(ndr_pull_u8(ndr, &sid->sid_rev_num)); - NDR_CHECK(ndr_pull_u8(ndr, &sid->num_auths)); - for (i=0;i<6;i++) { - NDR_CHECK(ndr_pull_u8(ndr, &sid->id_auth[i])); - } - - NDR_ALLOC_N(ndr, sid->sub_auths, sid->num_auths); - - for (i=0;inum_auths;i++) { - NDR_CHECK(ndr_pull_u32(ndr, &sid->sub_auths[i])); - } - - return NT_STATUS_OK; -} - -/* - parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field -*/ -NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, struct dom_sid *sid) -{ - uint32 num_auths; - NDR_CHECK(ndr_pull_u32(ndr, &num_auths)); - return ndr_pull_dom_sid(ndr, sid); -} - -/* - parse a dom_sid offset and structure -*/ -NTSTATUS ndr_pull_dom_sid_ofs(struct ndr_pull *ndr, struct dom_sid **sid) -{ - uint32 ofs; - struct ndr_pull_save save; - - NDR_CHECK(ndr_pull_u32(ndr, &ofs)); - if (ofs == 0) { - /* it is valid for a dom_sid ptr to be NULL */ - *sid = NULL; - return NT_STATUS_OK; - } - - ndr_pull_save(ndr, &save); - NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); - NDR_ALLOC(ndr, *sid); - NDR_CHECK(ndr_pull_dom_sid(ndr, *sid)); - ndr_pull_restore(ndr, &save); - - return NT_STATUS_OK; -} - -/* - parse a security descriptor -*/ -NTSTATUS ndr_pull_security_descriptor(struct ndr_pull *ndr, - struct security_descriptor **sd) -{ - NDR_ALLOC(ndr, *sd); - - NDR_CHECK(ndr_pull_u8(ndr, &(*sd)->revision)); - NDR_CHECK(ndr_pull_u16(ndr, &(*sd)->type)); - NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &(*sd)->owner_sid)); - NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &(*sd)->group_sid)); - NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &(*sd)->sacl)); - NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &(*sd)->dacl)); - - return NT_STATUS_OK; -} - - -/* - parse a security_ace -*/ -NTSTATUS ndr_push_security_ace(struct ndr_push *ndr, struct security_ace *ace) -{ - struct ndr_push_save save1, save2; - - NDR_CHECK(ndr_push_u8(ndr, ace->type)); - NDR_CHECK(ndr_push_u8(ndr, ace->flags)); - ndr_push_save(ndr, &save1); - NDR_CHECK(ndr_push_u16(ndr, 0)); - NDR_CHECK(ndr_push_u32(ndr, ace->access_mask)); - - if (sec_ace_object(ace->type)) { - NDR_CHECK(ndr_push_u32(ndr, ace->obj->flags)); - if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) { - NDR_CHECK(ndr_push_guid(ndr, &ace->obj->object_guid)); - } - if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - NDR_CHECK(ndr_push_guid(ndr, &ace->obj->inherit_guid)); - } - } - - NDR_CHECK(ndr_push_dom_sid(ndr, &ace->trustee)); - - ndr_push_save(ndr, &save2); - ndr_push_restore(ndr, &save1); - NDR_CHECK(ndr_push_u16(ndr, 2 + save2.offset - save1.offset)); - ndr_push_restore(ndr, &save2); - - return NT_STATUS_OK; -} - - -/* - push a security_acl -*/ -NTSTATUS ndr_push_security_acl(struct ndr_push *ndr, struct security_acl *acl) -{ - int i; - struct ndr_push_save save1, save2; - - NDR_CHECK(ndr_push_u16(ndr, acl->revision)); - ndr_push_save(ndr, &save1); - NDR_CHECK(ndr_push_u16(ndr, 0)); - NDR_CHECK(ndr_push_u32(ndr, acl->num_aces)); - for (i=0;inum_aces;i++) { - NDR_CHECK(ndr_push_security_ace(ndr, &acl->aces[i])); - } - ndr_push_save(ndr, &save2); - ndr_push_restore(ndr, &save1); - NDR_CHECK(ndr_push_u16(ndr, 2 + save2.offset - save1.offset)); - ndr_push_restore(ndr, &save2); - - return NT_STATUS_OK; -} - -/* - push a dom_sid -*/ -NTSTATUS ndr_push_dom_sid(struct ndr_push *ndr, struct dom_sid *sid) -{ - int i; - - NDR_CHECK(ndr_push_u8(ndr, sid->sid_rev_num)); - NDR_CHECK(ndr_push_u8(ndr, sid->num_auths)); - for (i=0;i<6;i++) { - NDR_CHECK(ndr_push_u8(ndr, sid->id_auth[i])); - } - for (i=0;inum_auths;i++) { - NDR_CHECK(ndr_push_u32(ndr, sid->sub_auths[i])); - } - - return NT_STATUS_OK; -} - - -/* - generate a ndr security descriptor -*/ -NTSTATUS ndr_push_security_descriptor(struct ndr_push *ndr, - struct security_descriptor *sd) -{ - struct ndr_push_save save; - struct ndr_push_save ofs1, ofs2, ofs3, ofs4; - - ndr_push_save(ndr, &save); - - NDR_CHECK(ndr_push_u8(ndr, sd->revision)); - NDR_CHECK(ndr_push_u16(ndr, sd->type)); - - NDR_CHECK(ndr_push_offset(ndr, &ofs1)); - NDR_CHECK(ndr_push_offset(ndr, &ofs2)); - NDR_CHECK(ndr_push_offset(ndr, &ofs3)); - NDR_CHECK(ndr_push_offset(ndr, &ofs4)); - - if (sd->owner_sid) { - NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs1, &save)); - NDR_CHECK(ndr_push_dom_sid(ndr, sd->owner_sid)); - } - - if (sd->group_sid) { - NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs2, &save)); - NDR_CHECK(ndr_push_dom_sid(ndr, sd->group_sid)); - } - - if (sd->sacl) { - NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs3, &save)); - NDR_CHECK(ndr_push_security_acl(ndr, sd->sacl)); - } - - if (sd->dacl) { - NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs4, &save)); - NDR_CHECK(ndr_push_security_acl(ndr, sd->dacl)); - } - - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_sec.h b/source4/libcli/ndr/ndr_sec.h deleted file mode 100644 index 0c9d542006..0000000000 --- a/source4/libcli/ndr/ndr_sec.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - definitions for marshalling/unmarshalling security descriptors - and related structures - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - - -/* a domain SID. Note that unlike Samba3 this contains a pointer, - so you can't copy them using assignment */ -struct dom_sid { - uint8 sid_rev_num; /**< SID revision number */ - uint8 num_auths; /**< Number of sub-authorities */ - uint8 id_auth[6]; /**< Identifier Authority */ - uint32 *sub_auths; -}; - -/* an access control element */ -struct security_ace { - uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */ - uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */ - - uint32 access_mask; - - /* the 'obj' part is present when type is XXXX_TYPE_XXXX_OBJECT */ - struct { - uint32 flags; - GUID object_guid; - GUID inherit_guid; - } *obj; - - struct dom_sid trustee; -}; - - -/* a security ACL */ -struct security_acl { - uint16 revision; - uint32 num_aces; - - struct security_ace *aces; -}; - - -/* a security descriptor */ -struct security_descriptor { - uint8 revision; - uint16 type; /* SEC_DESC_xxxx flags */ - - struct dom_sid *owner_sid; - struct dom_sid *group_sid; - struct security_acl *sacl; /* system ACL */ - struct security_acl *dacl; /* user (discretionary) ACL */ -}; - -/* query security descriptor */ -struct smb_query_secdesc { - struct { - uint16 fnum; - uint32 secinfo_flags; - } in; - struct { - struct security_descriptor *sd; - } out; -}; - -/* set security descriptor */ -struct smb_set_secdesc { - struct { - uint16 fnum; - uint32 secinfo_flags; - struct security_descriptor *sd; - } in; -}; diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c deleted file mode 100644 index 0541200015..0000000000 --- a/source4/libcli/raw/rawdcerpc.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - Unix SMB/CIFS implementation. - raw dcerpc operations - - Copyright (C) Tim Potter 2003 - Copyright (C) Andrew Tridgell 2003 - - 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" - - -/* - open a rpc connection to a named pipe -*/ -NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p, const char *pipe_name) -{ - NTSTATUS status; - char *name = NULL; - union smb_open io; - TALLOC_CTX *mem_ctx; - - asprintf(&name, "\\%s", pipe_name); - if (!name) { - return NT_STATUS_NO_MEMORY; - } - - io.ntcreatex.level = RAW_OPEN_NTCREATEX; - io.ntcreatex.in.flags = 0; - io.ntcreatex.in.root_fid = 0; - io.ntcreatex.in.access_mask = - STD_RIGHT_READ_CONTROL_ACCESS | - SA_RIGHT_FILE_WRITE_ATTRIBUTES | - SA_RIGHT_FILE_WRITE_EA | - GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; - io.ntcreatex.in.file_attr = 0; - io.ntcreatex.in.alloc_size = 0; - io.ntcreatex.in.share_access = - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE; - io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; - io.ntcreatex.in.create_options = 0; - io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; - io.ntcreatex.in.security_flags = 0; - io.ntcreatex.in.fname = name; - - mem_ctx = talloc_init("torture_rpc_connection"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - status = smb_raw_open(p->tree, mem_ctx, &io); - free(name); - talloc_destroy(mem_ctx); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - p->fnum = io.ntcreatex.out.fnum; - - /* bind to the pipe, using the pipe_name as the key */ - status = dcerpc_bind_byname(p, pipe_name); - - if (!NT_STATUS_IS_OK(status)) { - union smb_close c; - c.close.level = RAW_CLOSE_CLOSE; - c.close.in.fnum = p->fnum; - c.close.in.write_time = 0; - smb_raw_close(p->tree, &c); - } - - return status; -} - - -struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob) -{ - struct smb_trans2 trans; - uint16 setup[2]; - struct cli_request *req; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_raw_send"); - if (!mem_ctx) return NULL; - - trans.in.data = *blob; - trans.in.params = data_blob(NULL, 0); - - setup[0] = TRANSACT_DCERPCCMD; - setup[1] = p->fnum; - - trans.in.max_param = 0; - trans.in.max_data = 0x8000; - trans.in.max_setup = 0; - trans.in.setup_count = 2; - trans.in.flags = 0; - trans.in.timeout = 0; - trans.in.setup = setup; - trans.in.trans_name = "\\PIPE\\"; - - req = smb_raw_trans_send(p->tree, &trans); - - talloc_destroy(mem_ctx); - - return req; -} - - -NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p, - struct cli_request *req, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) -{ - struct smb_trans2 trans; - NTSTATUS status; - uint16 frag_length; - DATA_BLOB payload; - - status = smb_raw_trans_recv(req, mem_ctx, &trans); - /* STATUS_BUFFER_OVERFLOW means that there is more data - available via SMBreadX */ - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - return status; - } - - payload = trans.out.data; - - if (trans.out.data.length < 16 || - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - goto done; - } - - /* we might have recieved a partial fragment, in which case we - need to pull the rest of it */ - frag_length = SVAL(payload.data, 8); - if (frag_length <= payload.length) { - goto done; - } - - /* make sure the payload can hold the whole fragment */ - payload.data = talloc_realloc(mem_ctx, payload.data, frag_length); - if (!payload.data) { - return NT_STATUS_NO_MEMORY; - } - - /* the rest of the data is available via SMBreadX */ - while (frag_length > payload.length) { - uint32 n; - union smb_read io; - - n = frag_length - payload.length; - if (n > 0xFF00) { - n = 0xFF00; - } - - io.generic.level = RAW_READ_READX; - io.readx.in.fnum = p->fnum; - io.readx.in.mincnt = n; - io.readx.in.maxcnt = n; - io.readx.in.offset = 0; - io.readx.in.remaining = 0; - io.readx.out.data = payload.data + payload.length; - status = smb_raw_read(p->tree, &io); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - break; - } - - n = io.readx.out.nread; - if (n == 0) { - status = NT_STATUS_UNSUCCESSFUL; - break; - } - - payload.length += n; - - /* if the SMBreadX returns NT_STATUS_OK then there - isn't any more data to be read */ - if (NT_STATUS_IS_OK(status)) { - break; - } - } - -done: - if (blob) { - *blob = payload; - } - - return status; -} - -NTSTATUS dcerpc_raw_packet(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - DATA_BLOB *request_blob, - DATA_BLOB *reply_blob) -{ - struct cli_request *req; - req = dcerpc_raw_send(p, request_blob); - return dcerpc_raw_recv(p, req, mem_ctx, reply_blob); -} - - -/* - retrieve a secondary pdu from a pipe -*/ -NTSTATUS dcerpc_raw_packet_secondary(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) -{ - union smb_read io; - uint32 n = 0x2000; - uint32 frag_length; - NTSTATUS status; - - *blob = data_blob_talloc(mem_ctx, NULL, n); - if (!blob->data) { - return NT_STATUS_NO_MEMORY; - } - - io.generic.level = RAW_READ_READX; - io.readx.in.fnum = p->fnum; - io.readx.in.mincnt = n; - io.readx.in.maxcnt = n; - io.readx.in.offset = 0; - io.readx.in.remaining = 0; - io.readx.out.data = blob->data; - - status = smb_raw_read(p->tree, &io); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - return status; - } - - blob->length = io.readx.out.nread; - - if (blob->length < 16) { - return status; - } - - frag_length = SVAL(blob->data, 8); - if (frag_length <= blob->length) { - return status; - } - - blob->data = talloc_realloc(mem_ctx, blob->data, frag_length); - if (!blob->data) { - return NT_STATUS_NO_MEMORY; - } - - while (frag_length > blob->length && - NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - - n = frag_length - blob->length; - if (n > 0xFF00) { - n = 0xFF00; - } - - io.readx.in.mincnt = n; - io.readx.in.maxcnt = n; - io.readx.out.data = blob->data + blob->length; - status = smb_raw_read(p->tree, &io); - - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - return status; - } - - n = io.readx.out.nread; - blob->length += n; - } - - return status; -} - - -/* - send an initial pdu in a multi-pdu sequence -*/ -NTSTATUS dcerpc_raw_packet_initial(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) -{ - union smb_write io; - NTSTATUS status; - - io.generic.level = RAW_WRITE_WRITEX; - io.writex.in.fnum = p->fnum; - io.writex.in.offset = 0; - io.writex.in.wmode = PIPE_START_MESSAGE; - io.writex.in.remaining = blob->length; - io.writex.in.count = blob->length; - io.writex.in.data = blob->data; - - status = smb_raw_write(p->tree, &io); - if (NT_STATUS_IS_OK(status)) { - return status; - } - - /* make sure it accepted it all */ - if (io.writex.out.nwritten != blob->length) { - return NT_STATUS_UNSUCCESSFUL; - } - - return status; -} diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c deleted file mode 100644 index 9e6c05e7ae..0000000000 --- a/source4/libcli/rpc/dcerpc.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - Unix SMB/CIFS implementation. - raw dcerpc operations - - Copyright (C) Tim Potter 2003 - Copyright (C) Andrew Tridgell 2003 - - 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" - -/* initialise a dcerpc pipe. This currently assumes a SMB named pipe - transport */ -struct dcerpc_pipe *dcerpc_pipe_init(struct cli_tree *tree) -{ - struct dcerpc_pipe *p; - - TALLOC_CTX *mem_ctx = talloc_init("dcerpc_tree"); - if (mem_ctx == NULL) - return NULL; - - p = talloc(mem_ctx, sizeof(*p)); - if (!p) { - talloc_destroy(mem_ctx); - return NULL; - } - - p->reference_count = 0; - p->mem_ctx = mem_ctx; - p->tree = tree; - p->tree->reference_count++; - p->call_id = 1; - p->fnum = 0; - - return p; -} - -/* close down a dcerpc over SMB pipe */ -void dcerpc_pipe_close(struct dcerpc_pipe *p) -{ - if (!p) return; - p->reference_count--; - if (p->reference_count <= 0) { - cli_tree_close(p->tree); - talloc_destroy(p->mem_ctx); - } -} - -#define BLOB_CHECK_BOUNDS(blob, offset, len) do { \ - if ((offset) > blob->length || (blob->length - (offset) < (len))) { \ - return NT_STATUS_INVALID_PARAMETER; \ - } \ -} while (0) - -#define DCERPC_ALIGN(offset, n) do { \ - (offset) = ((offset) + ((n)-1)) & ~((n)-1); \ -} while (0) - -/* - pull a wire format uuid into a string. This will consume 16 bytes -*/ -static char *dcerpc_pull_uuid(char *data, TALLOC_CTX *mem_ctx) -{ - uint32 time_low; - uint16 time_mid, time_hi_and_version; - uint8 clock_seq_hi_and_reserved; - uint8 clock_seq_low; - uint8 node[6]; - int i; - - time_low = IVAL(data, 0); - time_mid = SVAL(data, 4); - time_hi_and_version = SVAL(data, 6); - clock_seq_hi_and_reserved = CVAL(data, 8); - clock_seq_low = CVAL(data, 9); - for (i=0;i<6;i++) { - node[i] = CVAL(data, 10 + i); - } - - return talloc_asprintf(mem_ctx, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - time_low, time_mid, time_hi_and_version, - clock_seq_hi_and_reserved, clock_seq_low, - node[0], node[1], node[2], node[3], node[4], node[5]); -} - -/* - push a uuid_str into wire format. It will consume 16 bytes -*/ -static NTSTATUS push_uuid_str(char *data, const char *uuid_str) -{ - uint32 time_low; - uint32 time_mid, time_hi_and_version; - uint32 clock_seq_hi_and_reserved; - uint32 clock_seq_low; - uint32 node[6]; - int i; - - if (11 != sscanf(uuid_str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - &time_low, &time_mid, &time_hi_and_version, - &clock_seq_hi_and_reserved, &clock_seq_low, - &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { - return NT_STATUS_INVALID_PARAMETER; - } - - SIVAL(data, 0, time_low); - SSVAL(data, 4, time_mid); - SSVAL(data, 6, time_hi_and_version); - SCVAL(data, 8, clock_seq_hi_and_reserved); - SCVAL(data, 9, clock_seq_low); - for (i=0;i<6;i++) { - SCVAL(data, 10 + i, node[i]); - } - - return NT_STATUS_OK; -} - -/* - pull a dcerpc syntax id from a blob -*/ -static NTSTATUS dcerpc_pull_syntax_id(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_syntax_id *syntax) -{ - syntax->uuid_str = dcerpc_pull_uuid(blob->data + (*offset), mem_ctx); - if (!syntax->uuid_str) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += 16; - syntax->if_version = IVAL(blob->data, *offset); - (*offset) += 4; - return NT_STATUS_OK; -} - -/* - push a syntax id onto the wire. It will consume 20 bytes -*/ -static NTSTATUS push_syntax_id(char *data, const struct dcerpc_syntax_id *syntax) -{ - NTSTATUS status; - - status = push_uuid_str(data, syntax->uuid_str); - SIVAL(data, 16, syntax->if_version); - - return status; -} - -/* - pull an auth verifier from a packet -*/ -static NTSTATUS dcerpc_pull_auth_verifier(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_hdr *hdr, - DATA_BLOB *auth) -{ - if (hdr->auth_length == 0) { - return NT_STATUS_OK; - } - - BLOB_CHECK_BOUNDS(blob, *offset, hdr->auth_length); - *auth = data_blob_talloc(mem_ctx, blob->data + (*offset), hdr->auth_length); - if (!auth->data) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += hdr->auth_length; - return NT_STATUS_OK; -} - -/* - parse a struct dcerpc_response -*/ -static NTSTATUS dcerpc_pull_response(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_response *pkt) -{ - uint32 stub_len; - - BLOB_CHECK_BOUNDS(blob, *offset, 8); - - pkt->alloc_hint = IVAL(blob->data, (*offset) + 0); - pkt->context_id = SVAL(blob->data, (*offset) + 4); - pkt->cancel_count = CVAL(blob->data, (*offset) + 6); - - (*offset) += 8; - - stub_len = blob->length - ((*offset) + hdr->auth_length); - BLOB_CHECK_BOUNDS(blob, *offset, stub_len); - pkt->stub_data = data_blob_talloc(mem_ctx, blob->data + (*offset), stub_len); - if (stub_len != 0 && !pkt->stub_data.data) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += stub_len; - - return dcerpc_pull_auth_verifier(blob, mem_ctx, offset, hdr, &pkt->auth_verifier); -} - - -/* - parse a struct bind_ack -*/ -static NTSTATUS dcerpc_pull_bind_ack(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_bind_ack *pkt) -{ - uint16 len; - int i; - - BLOB_CHECK_BOUNDS(blob, *offset, 10); - pkt->max_xmit_frag = SVAL(blob->data, (*offset) + 0); - pkt->max_recv_frag = SVAL(blob->data, (*offset) + 2); - pkt->assoc_group_id = IVAL(blob->data, (*offset) + 4); - len = SVAL(blob->data, (*offset) + 8); - (*offset) += 10; - - if (len) { - BLOB_CHECK_BOUNDS(blob, *offset, len); - pkt->secondary_address = talloc_strndup(mem_ctx, blob->data + (*offset), len); - if (!pkt->secondary_address) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += len; - } - - DCERPC_ALIGN(*offset, 4); - BLOB_CHECK_BOUNDS(blob, *offset, 4); - pkt->num_results = CVAL(blob->data, *offset); - (*offset) += 4; - - if (pkt->num_results > 0) { - pkt->ctx_list = talloc(mem_ctx, sizeof(pkt->ctx_list[0]) * pkt->num_results); - if (!pkt->ctx_list) { - return NT_STATUS_NO_MEMORY; - } - } - - for (i=0;inum_results;i++) { - NTSTATUS status; - - BLOB_CHECK_BOUNDS(blob, *offset, 24); - pkt->ctx_list[i].result = IVAL(blob->data, *offset); - (*offset) += 4; - status = dcerpc_pull_syntax_id(blob, mem_ctx, offset, &pkt->ctx_list[i].syntax); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } - - return dcerpc_pull_auth_verifier(blob, mem_ctx, offset, hdr, &pkt->auth_verifier); -} - - -/* - parse a dcerpc header -*/ -static NTSTATUS dcerpc_pull_hdr(DATA_BLOB *blob, uint32 *offset, struct dcerpc_hdr *hdr) -{ - BLOB_CHECK_BOUNDS(blob, *offset, 16); - - hdr->rpc_vers = CVAL(blob->data, (*offset) + 0); - hdr->rpc_vers_minor = CVAL(blob->data, (*offset) + 1); - hdr->ptype = CVAL(blob->data, (*offset) + 2); - hdr->pfc_flags = CVAL(blob->data, (*offset) + 3); - memcpy(hdr->drep, blob->data + (*offset) + 4, 4); - hdr->frag_length = SVAL(blob->data, (*offset) + 8); - hdr->auth_length = SVAL(blob->data, (*offset) + 10); - hdr->call_id = IVAL(blob->data, (*offset) + 12); - - (*offset) += 16; - - return NT_STATUS_OK; -} - -/* - parse a dcerpc header. It consumes 16 bytes -*/ -static void dcerpc_push_hdr(char *data, struct dcerpc_hdr *hdr) -{ - SCVAL(data, 0, hdr->rpc_vers); - SCVAL(data, 1, hdr->rpc_vers_minor); - SCVAL(data, 2, hdr->ptype); - SCVAL(data, 3, hdr->pfc_flags); - memcpy(data + 4, hdr->drep, 4); - SSVAL(data, 8, hdr->frag_length); - SSVAL(data, 12, hdr->call_id); -} - - - -/* - parse a data blob into a dcerpc_packet structure. This handles both - input and output packets -*/ -NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_packet *pkt) -{ - NTSTATUS status; - uint32 offset = 0; - - status = dcerpc_pull_hdr(blob, &offset, &pkt->hdr); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - switch (pkt->hdr.ptype) { - case DCERPC_PKT_BIND_ACK: - status = dcerpc_pull_bind_ack(blob, mem_ctx, &offset, &pkt->hdr, &pkt->out.bind_ack); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - - case DCERPC_PKT_RESPONSE: - status = dcerpc_pull_response(blob, mem_ctx, &offset, &pkt->hdr, &pkt->out.response); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - - default: - return NT_STATUS_INVALID_LEVEL; - } - - return status; -} - - -/* - push a dcerpc_bind into a blob -*/ -static NTSTATUS dcerpc_push_bind(DATA_BLOB *blob, uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_bind *pkt) -{ - int i, j; - - SSVAL(blob->data, (*offset) + 0, pkt->max_xmit_frag); - SSVAL(blob->data, (*offset) + 2, pkt->max_recv_frag); - SIVAL(blob->data, (*offset) + 4, pkt->assoc_group_id); - SCVAL(blob->data, (*offset) + 8, pkt->num_contexts); - (*offset) += 12; - - for (i=0;inum_contexts;i++) { - NTSTATUS status; - - SSVAL(blob->data, (*offset) + 0, pkt->ctx_list[i].context_id); - SCVAL(blob->data, (*offset) + 2, pkt->ctx_list[i].num_transfer_syntaxes); - status = push_syntax_id(blob->data + (*offset) + 4, &pkt->ctx_list[i].abstract_syntax); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - (*offset) += 24; - for (j=0;jctx_list[i].num_transfer_syntaxes;j++) { - status = push_syntax_id(blob->data + (*offset), - &pkt->ctx_list[i].transfer_syntaxes[j]); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - (*offset) += 20; - } - } - - return NT_STATUS_OK; -} - -/* - push a dcerpc_request into a blob -*/ -static NTSTATUS dcerpc_push_request(DATA_BLOB *blob, uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_request *pkt) -{ - SIVAL(blob->data, (*offset) + 0, pkt->alloc_hint); - SSVAL(blob->data, (*offset) + 4, pkt->context_id); - SSVAL(blob->data, (*offset) + 6, pkt->opnum); - - (*offset) += 8; - - memcpy(blob->data + (*offset), pkt->stub_data.data, pkt->stub_data.length); - (*offset) += pkt->stub_data.length; - - memcpy(blob->data + (*offset), pkt->auth_verifier.data, pkt->auth_verifier.length); - (*offset) += pkt->auth_verifier.length; - - return NT_STATUS_OK; -} - - -/* - work out the wire size of a dcerpc packet -*/ -static uint32 dcerpc_wire_size(struct dcerpc_packet *pkt) -{ - int i; - uint32 size = 0; - - size += 16; /* header */ - - switch (pkt->hdr.ptype) { - case DCERPC_PKT_REQUEST: - size += 8; - size += pkt->in.request.stub_data.length; - size += pkt->in.request.auth_verifier.length; - break; - - case DCERPC_PKT_RESPONSE: - size += 8; - size += pkt->out.response.stub_data.length; - size += pkt->hdr.auth_length; - break; - - case DCERPC_PKT_BIND: - size += 12; - for (i=0;iin.bind.num_contexts;i++) { - size += 24; - size += pkt->in.bind.ctx_list[i].num_transfer_syntaxes * 20; - } - size += pkt->hdr.auth_length; - break; - - case DCERPC_PKT_BIND_ACK: - size += 10; - if (pkt->out.bind_ack.secondary_address) { - size += strlen(pkt->out.bind_ack.secondary_address) + 1; - } - size += 4; - size += pkt->out.bind_ack.num_results * 24; - size += pkt->hdr.auth_length; - break; - } - - return size; -} - -/* - push a dcerpc_packet into a blob. This handles both input and - output packets -*/ -NTSTATUS dcerpc_push(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_packet *pkt) -{ - uint32 offset = 0; - uint32 wire_size; - NTSTATUS status; - - /* work out how big the packet will be on the wire */ - wire_size = dcerpc_wire_size(pkt); - - (*blob) = data_blob_talloc(mem_ctx, NULL, wire_size); - if (!blob->data) { - return NT_STATUS_NO_MEMORY; - } - - pkt->hdr.frag_length = wire_size; - - dcerpc_push_hdr(blob->data + offset, &pkt->hdr); - offset += 16; - - switch (pkt->hdr.ptype) { - case DCERPC_PKT_BIND: - status = dcerpc_push_bind(blob, &offset, &pkt->hdr, &pkt->in.bind); - break; - - case DCERPC_PKT_REQUEST: - status = dcerpc_push_request(blob, &offset, &pkt->hdr, &pkt->in.request); - break; - - default: - status = NT_STATUS_INVALID_LEVEL; - } - - return status; -} - - - - -/* - fill in the fixed values in a dcerpc header -*/ -static void init_dcerpc_hdr(struct dcerpc_hdr *hdr) -{ - hdr->rpc_vers = 5; - hdr->rpc_vers_minor = 0; - hdr->drep[0] = 0x10; /* Little endian */ - hdr->drep[1] = 0; - hdr->drep[2] = 0; - hdr->drep[3] = 0; -} - - -/* - perform a bind using the given syntax -*/ -NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, - const struct dcerpc_syntax_id *syntax, - const struct dcerpc_syntax_id *transfer_syntax) -{ - TALLOC_CTX *mem_ctx; - struct dcerpc_packet pkt; - NTSTATUS status; - DATA_BLOB blob; - DATA_BLOB blob_out; - - mem_ctx = talloc_init("dcerpc_bind"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - init_dcerpc_hdr(&pkt.hdr); - - pkt.hdr.ptype = DCERPC_PKT_BIND; - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.hdr.call_id = p->call_id++; - pkt.hdr.auth_length = 0; - - pkt.in.bind.max_xmit_frag = 0x2000; - pkt.in.bind.max_recv_frag = 0x2000; - pkt.in.bind.assoc_group_id = 0; - pkt.in.bind.num_contexts = 1; - pkt.in.bind.ctx_list = talloc(mem_ctx, sizeof(pkt.in.bind.ctx_list[0])); - if (!pkt.in.bind.ctx_list) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - pkt.in.bind.ctx_list[0].context_id = 0; - pkt.in.bind.ctx_list[0].num_transfer_syntaxes = 1; - pkt.in.bind.ctx_list[0].abstract_syntax = *syntax; - pkt.in.bind.ctx_list[0].transfer_syntaxes = transfer_syntax; - - pkt.in.bind.auth_verifier = data_blob(NULL, 0); - - status = dcerpc_push(&blob, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - - status = dcerpc_raw_packet(p, mem_ctx, &blob, &blob_out); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - - status = dcerpc_pull(&blob_out, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - - if (pkt.hdr.ptype != DCERPC_PKT_BIND_ACK) { - status = NT_STATUS_UNSUCCESSFUL; - } - - p->srv_max_xmit_frag = pkt.out.bind_ack.max_xmit_frag; - p->srv_max_recv_frag = pkt.out.bind_ack.max_recv_frag; - - talloc_destroy(mem_ctx); - - return status; -} - -static const struct { - const char *name; - struct dcerpc_syntax_id syntax; - const struct dcerpc_syntax_id transfer_syntax; -} known_pipes[] = { - { "lsarpc" , { "12345778-1234-abcd-ef00-0123456789ab", 0 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "samr" , { "12345778-1234-abcd-ef00-0123456789ac", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "netlogon", { "12345778-1234-abcd-ef00-01234567cffb", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "srvsvc" , { "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "wkssvc" , { "6bffd098-a112-3610-9833-46c3f87e345a", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "winreg" , { "338cd001-2244-31f1-aaaa-900038001003", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "spoolss" , { "12345678-1234-abcd-ef00-0123456789ab", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "netdfs" , { "4fc742e0-4a10-11cf-8273-00aa004ae673", 3 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "rpcecho" , { "60a15ec5-4de8-11d7-a637-005056a20182", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { NULL , } -}; - - -/* Perform a bind using the given well-known pipe name */ -NTSTATUS dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) -{ - int i; - - for (i=0; known_pipes[i].name; i++) { - if (strcasecmp(known_pipes[i].name, pipe_name) == 0) - break; - } - - if (known_pipes[i].name == NULL) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - return dcerpc_bind(p, &known_pipes[i].syntax, &known_pipes[i].transfer_syntax); -} - -/* - perform a full request/response pair on a dcerpc pipe -*/ -NTSTATUS dcerpc_request(struct dcerpc_pipe *p, - uint16 opnum, - TALLOC_CTX *mem_ctx, - DATA_BLOB *stub_data_in, - DATA_BLOB *stub_data_out) -{ - - struct dcerpc_packet pkt; - NTSTATUS status; - DATA_BLOB blob_in, blob_out, payload; - uint32 remaining, chunk_size; - - init_dcerpc_hdr(&pkt.hdr); - - remaining = stub_data_in->length; - - /* we can write a full max_recv_frag size, minus the dcerpc - request header size */ - chunk_size = p->srv_max_recv_frag - 24; - - pkt.hdr.ptype = DCERPC_PKT_REQUEST; - pkt.hdr.call_id = p->call_id++; - pkt.hdr.auth_length = 0; - pkt.in.request.alloc_hint = remaining; - pkt.in.request.context_id = 0; - pkt.in.request.opnum = opnum; - pkt.in.request.auth_verifier = data_blob(NULL, 0); - - /* we send a series of pdus without waiting for a reply until - the last pdu */ - while (remaining > chunk_size) { - if (remaining == stub_data_in->length) { - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST; - } else { - pkt.hdr.pfc_flags = 0; - } - - pkt.in.request.stub_data.data = stub_data_in->data + - (stub_data_in->length - remaining); - pkt.in.request.stub_data.length = chunk_size; - - status = dcerpc_push(&blob_in, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = dcerpc_raw_packet_initial(p, mem_ctx, &blob_in); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - remaining -= chunk_size; - } - - /* now we send a pdu with LAST_FRAG sent and get the first - part of the reply */ - if (remaining == stub_data_in->length) { - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - } else { - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_LAST; - } - pkt.in.request.stub_data.data = stub_data_in->data + - (stub_data_in->length - remaining); - pkt.in.request.stub_data.length = remaining; - - status = dcerpc_push(&blob_in, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* send the pdu and get the initial response pdu */ - status = dcerpc_raw_packet(p, mem_ctx, &blob_in, &blob_out); - - status = dcerpc_pull(&blob_out, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { - return NT_STATUS_UNSUCCESSFUL; - } - - if (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { - /* something is badly wrong! */ - return NT_STATUS_UNSUCCESSFUL; - } - - payload = pkt.out.response.stub_data; - - /* continue receiving fragments */ - while (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_LAST)) { - uint32 length; - - status = dcerpc_raw_packet_secondary(p, mem_ctx, &blob_out); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = dcerpc_pull(&blob_out, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST) { - /* start of another packet!? */ - return NT_STATUS_UNSUCCESSFUL; - } - - if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { - return NT_STATUS_UNSUCCESSFUL; - } - - length = pkt.out.response.stub_data.length; - - payload.data = talloc_realloc(mem_ctx, - payload.data, - payload.length + length); - if (!payload.data) { - return NT_STATUS_NO_MEMORY; - } - - memcpy(payload.data + payload.length, - pkt.out.response.stub_data.data, - length); - - payload.length += length; - } - - if (stub_data_out) { - *stub_data_out = payload; - } - - return status; -} - - -/* - a useful helper function for synchronous rpc requests - - this can be used when you have ndr push/pull functions in the - standard format -*/ -NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, - uint32 opnum, - TALLOC_CTX *mem_ctx, - NTSTATUS (*ndr_push)(struct ndr_push *, void *), - NTSTATUS (*ndr_pull)(struct ndr_pull *, void *), - void *struct_ptr) -{ - struct ndr_push *push; - struct ndr_pull *pull; - NTSTATUS status; - DATA_BLOB request, response; - - /* setup for a ndr_push_* call */ - push = ndr_push_init(); - if (!push) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - /* push the structure into a blob */ - status = ndr_push(push, struct_ptr); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - /* retrieve the blob */ - request = ndr_push_blob(push); - - /* make the actual dcerpc request */ - status = dcerpc_request(p, opnum, mem_ctx, &request, &response); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - /* prepare for ndr_pull_* */ - pull = ndr_pull_init_blob(&response, mem_ctx); - if (!pull) { - goto failed; - } - - /* pull the structure from the blob */ - status = ndr_pull(pull, struct_ptr); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - -failed: - ndr_push_free(push); - return status; -} diff --git a/source4/libcli/rpc/dcerpc.h b/source4/libcli/rpc/dcerpc.h deleted file mode 100644 index 09ddc3625c..0000000000 --- a/source4/libcli/rpc/dcerpc.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - Unix SMB/CIFS implementation. - DCERPC interface structures - - Copyright (C) Tim Potter 2003 - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - see http://www.opengroup.org/onlinepubs/9629399/chap12.htm for details - of these structures - - note that the structure definitions here don't include some of the - fields that are wire-artifacts. Those are put on the wire by the - marshalling/unmarshalling routines in decrpc.c -*/ - -struct dcerpc_pipe { - TALLOC_CTX *mem_ctx; - uint16 fnum; - int reference_count; - uint32 call_id; - uint32 srv_max_xmit_frag; - uint32 srv_max_recv_frag; - struct cli_tree *tree; -}; - -/* dcerpc packet types */ -#define DCERPC_PKT_REQUEST 0 -#define DCERPC_PKT_RESPONSE 2 -#define DCERPC_PKT_BIND 11 -#define DCERPC_PKT_BIND_ACK 12 -#define DCERPC_PKT_BIND_NAK 13 - -/* hdr.pfc_flags */ -#define DCERPC_PFC_FLAG_FIRST 0x01 -#define DCERPC_PFC_FLAG_LAST 0x02 -#define DCERPC_PFC_FLAG_NOCALL 0x20 - -/* - all dcerpc packets use this structure. -*/ -struct dcerpc_packet { - /* all requests and responses contain a dcerpc header */ - struct dcerpc_hdr { - uint8 rpc_vers; /* RPC version */ - uint8 rpc_vers_minor; /* Minor version */ - uint8 ptype; /* Packet type */ - uint8 pfc_flags; /* Fragmentation flags */ - uint8 drep[4]; /* NDR data representation */ - uint16 frag_length; /* Total length of fragment */ - uint16 auth_length; /* authenticator length */ - uint32 call_id; /* Call identifier */ - } hdr; - - union { - struct dcerpc_bind { - uint16 max_xmit_frag; - uint16 max_recv_frag; - uint32 assoc_group_id; - uint8 num_contexts; - struct { - uint16 context_id; - uint8 num_transfer_syntaxes; - struct dcerpc_syntax_id { - const char *uuid_str; - uint32 if_version; - } abstract_syntax; - const struct dcerpc_syntax_id *transfer_syntaxes; - } *ctx_list; - DATA_BLOB auth_verifier; - } bind; - - struct dcerpc_request { - uint32 alloc_hint; - uint16 context_id; - uint16 opnum; - DATA_BLOB stub_data; - DATA_BLOB auth_verifier; - } request; - } in; - - union { - struct dcerpc_bind_ack { - uint16 max_xmit_frag; - uint16 max_recv_frag; - uint32 assoc_group_id; - const char *secondary_address; - uint8 num_results; - struct { - uint32 result; - struct dcerpc_syntax_id syntax; - } *ctx_list; - DATA_BLOB auth_verifier; - } bind_ack; - - struct dcerpc_bind_nak { - uint16 reject_reason; - uint32 num_versions; - uint32 *versions; - } bind_nak; - - struct dcerpc_response { - uint32 alloc_hint; - uint16 context_id; - uint8 cancel_count; - DATA_BLOB stub_data; - DATA_BLOB auth_verifier; - } response; - } out; -}; - -/* this seems to be the only transfer syntax used */ -#define DCERPC_TRANSFER_SYNTAX_V2 {"8a885d04-1ceb-11c9-9fe8-08002b104860", 2} - diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c deleted file mode 100644 index d73f9bda9c..0000000000 --- a/source4/libcli/rpc/rpc_echo.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - rpc echo pipe calls - - Copyright (C) Andrew Tridgell 2003 - - 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" - -/* - addone interface -*/ -NTSTATUS dcerpc_rpcecho_addone(struct dcerpc_pipe *p, - int in_data, int *out_data) -{ - struct rpcecho_addone r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_rpcecho_addone"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* fill the .in side of the call */ - r.in.data = in_data; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_ADDONE, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_addone, - (ndr_pull_fn_t) ndr_pull_rpcecho_addone, - &r); - - /* and extract the .out parameters */ - *out_data = r.out.data; - - talloc_destroy(mem_ctx); - return status; -} - - -/* - echodata interface -*/ -NTSTATUS dcerpc_rpcecho_echodata(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - int len, - const char *in_data, - int *out_len, - char **out_data) -{ - struct rpcecho_echodata r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.len = len; - r.in.data = in_data; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_ECHODATA, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_echodata, - (ndr_pull_fn_t) ndr_pull_rpcecho_echodata, - &r); - - /* and extract the .out parameters */ - *out_len = r.out.len; - *out_data = r.out.data; - - return status; -} - -/* - sourcedata interface -*/ -NTSTATUS dcerpc_rpcecho_sourcedata(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - int len, - int *out_len, - char **out_data) -{ - struct rpcecho_sourcedata r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.len = len; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_SOURCEDATA, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_sourcedata, - (ndr_pull_fn_t) ndr_pull_rpcecho_sourcedata, - &r); - - /* and extract the .out parameters */ - *out_len = r.out.len; - *out_data = r.out.data; - - return status; -} - -/* - sinkdata interface -*/ -NTSTATUS dcerpc_rpcecho_sinkdata(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - int len, - char *data) -{ - struct rpcecho_sinkdata r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.len = len; - r.in.data = data; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_SINKDATA, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_sinkdata, - (ndr_pull_fn_t) ndr_pull_rpcecho_sinkdata, - &r); - - return status; -} diff --git a/source4/libcli/rpc/rpc_lsa.c b/source4/libcli/rpc/rpc_lsa.c deleted file mode 100644 index 65d6a81491..0000000000 --- a/source4/libcli/rpc/rpc_lsa.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - rpc lsa pipe calls - - Copyright (C) Andrew Tridgell 2003 - - 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" - -/* - OpenPolicy interface -*/ -NTSTATUS dcerpc_lsa_OpenPolicy(struct dcerpc_pipe *p, - const char *server, - struct lsa_ObjectAttribute *attr, - uint32 access_mask, - struct policy_handle *handle) -{ - struct lsa_OpenPolicy r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_lsa_openpolicy"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* fill the .in side of the call */ - r.in.system_name = server; - r.in.attr = attr; - r.in.desired_access = access_mask; - - /* make the call */ - status = dcerpc_ndr_request(p, LSA_OPENPOLICY, mem_ctx, - (ndr_push_fn_t) ndr_push_lsa_OpenPolicy, - (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy, - &r); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - /* and extract the .out parameters */ - *handle = r.out.handle; - status = r.out.status; - -done: - talloc_destroy(mem_ctx); - return status; -} - - -/* - OpenPolicy2 interface -*/ -NTSTATUS dcerpc_lsa_OpenPolicy2(struct dcerpc_pipe *p, - const char *server, - struct lsa_ObjectAttribute *attr, - uint32 access_mask, - struct policy_handle *handle) -{ - struct lsa_OpenPolicy2 r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_lsa_openpolicy2"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* fill the .in side of the call */ - r.in.system_name = server; - r.in.attr = attr; - r.in.desired_access = access_mask; - - /* make the call */ - status = dcerpc_ndr_request(p, LSA_OPENPOLICY2, mem_ctx, - (ndr_push_fn_t) ndr_push_lsa_OpenPolicy2, - (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy2, - &r); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - /* and extract the .out parameters */ - *handle = r.out.handle; - status = r.out.status; - -done: - talloc_destroy(mem_ctx); - return status; -} - -/* - EnumSids interface -*/ -NTSTATUS dcerpc_lsa_EnumSids(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct policy_handle *handle, - uint32 resume_handle, - uint32 *num_entries, - struct dom_sid ***sids) -{ - struct lsa_EnumSids r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.handle = handle; - r.in.start_at = 0; - r.in.num_entries = *num_entries; - - /* make the call */ - status = dcerpc_ndr_request(p, LSA_ENUM_ACCOUNTS, mem_ctx, - (ndr_push_fn_t) ndr_push_lsa_EnumSids, - (ndr_pull_fn_t) ndr_pull_lsa_EnumSids, - &r); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - /* and extract the .out parameters */ - *num_entries = r.out.num_entries; - *sids = r.out.sids; - status = r.out.status; - -done: - return status; -} -- cgit From 7d212460a5c00b4039440c2db0dde56e7d519d66 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Nov 2003 11:21:57 +0000 Subject: - corrected some lsa idl - updated lsa parse code from pidl (This used to be commit 3983b2aee77b0e093847bfc02e02b83ab281f5dd) --- source4/libcli/raw/rawacl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index c45152381d..067189d987 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -78,7 +78,11 @@ NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, return NT_STATUS_INVALID_PARAMETER; } - status = ndr_pull_security_descriptor(ndr, &query->out.sd); + query->out.sd = talloc(mem_ctx, sizeof(query->out.sd)); + if (!query->out.sd) { + return NT_STATUS_NO_MEMORY; + } + status = ndr_pull_security_descriptor(ndr, query->out.sd); return NT_STATUS_OK; } -- cgit From bf48b6e69a638dc78ab119424e27adc0ccc6c610 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Nov 2003 03:38:13 +0000 Subject: added OpenPrinter and a test function. Note that the Samba3 structure for OpenPrinter was wrong. (This used to be commit 186ddbbf8774d0960852ea9186c8e4e6f7be7a0f) --- source4/libcli/raw/clitransport.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 80bb1e301f..2d614cc3bd 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -42,6 +42,8 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) cli_null_set_signing(transport); transport->socket->reference_count++; + ZERO_STRUCT(transport->called); + return transport; } @@ -71,6 +73,10 @@ BOOL cli_transport_connect(struct cli_transport *transport, int len = NBT_HDR_SIZE; struct cli_request *req; + if (called) { + transport->called = *called; + } + /* 445 doesn't have session request */ if (transport->socket->port == 445) { return True; -- cgit From 59df3ce5b5c5b484793a0e16faeb581ef343e167 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Nov 2003 06:27:45 +0000 Subject: security descriptors are no longer a "special" type, they are handled using the [relative] property this also fixes level3 of PrinterInfo (a relative secdesc) (This used to be commit d5a15257fdd5f6cfe2706765a7c29f623ec1c6f8) --- source4/libcli/raw/rawacl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 067189d987..cfc086c7ce 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -82,7 +82,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, if (!query->out.sd) { return NT_STATUS_NO_MEMORY; } - status = ndr_pull_security_descriptor(ndr, query->out.sd); + status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, query->out.sd); return NT_STATUS_OK; } -- cgit From d285c6f14f7ad7037e1a81d59da8b3c892a49884 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Nov 2003 11:55:56 +0000 Subject: * add another WERR err code * use the top-level function argument printing to show more detail in RPC-* tests (This used to be commit 33bb8785625b1845750f28f2d810e7096afe9f8e) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 28bad6109d..c4ec869961 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -35,6 +35,7 @@ werror_code_struct dos_errs[] = { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED }, { "WERR_BADFID", WERR_BADFID }, { "WERR_BADFUNC", WERR_BADFUNC }, + { "WERR_BAD_NETPATH", WERR_BAD_NETPATH }, { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, -- cgit From e1e98ab0496ae38b2d68d50133ec1da532f02757 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Nov 2003 23:17:55 +0000 Subject: updated copyright year (This used to be commit 4dcc06d04c67c6e063c5b2a88f693423c77f342d) --- source4/libcli/raw/clisocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index f0e05085c4..6ccdeef366 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. SMB client socket context management functions - Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Tridgell 1994-2003 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify -- cgit From 940ce958a6914fb9b70de3cf95a0c062063e2253 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Nov 2003 00:36:10 +0000 Subject: make the socket send code a little clearer (This used to be commit 48028fbb856ea7ee642f36ba9ed0d5815763f52b) --- source4/libcli/raw/rawrequest.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 139f031178..4191d3775e 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -269,13 +269,17 @@ static void cli_req_grow_data(struct cli_request *req, unsigned new_size) */ BOOL cli_request_send(struct cli_request *req) { + uint_t ret; + if (IVAL(req->out.buffer, 0) == 0) { _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); } cli_request_calculate_sign_mac(req); - if (req->out.size != cli_sock_write(req->transport->socket, req->out.buffer, req->out.size)) { + ret = cli_sock_write(req->transport->socket, req->out.buffer, req->out.size); + + if (req->out.size != ret) { req->transport->error.etype = ETYPE_SOCKET; req->transport->error.e.socket_error = SOCKET_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to server - %s\n", -- cgit From d47d14f2ffc7a6d2cc306530b777f364767998b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 2003 01:53:54 +0000 Subject: reduced the number of magic types we need in mkproto.pl In general I prefer "struct foo" to just "foo" for most structures. There are exceptions. (This used to be commit 04eb12b56c653f98801ab29411f47564ab32fa58) --- source4/libcli/util/cliutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/cliutil.c b/source4/libcli/util/cliutil.c index 47f94992a4..13b3dad0bf 100644 --- a/source4/libcli/util/cliutil.c +++ b/source4/libcli/util/cliutil.c @@ -76,13 +76,13 @@ BOOL yesno(char *p) const char *readdirname(DIR *p) { - SMB_STRUCT_DIRENT *ptr; + struct smb_dirent *ptr; char *dname; if (!p) return(NULL); - ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p); + ptr = (struct smb_dirent *)sys_readdir(p); if (!ptr) return(NULL); -- cgit From e0ac659917066dbf7f8fdbcc7684ce2b49dd04d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Nov 2003 01:16:41 +0000 Subject: signed DCERPC over TCP now works ! * moved ntlmssp code into libcli/auth/, and updated to latest ntlmssp code from samba3 (thanks Andrew! the new interface is great) * added signing/ntlmssp support in the dcerpc code * added a dcerpc_auth.c module for the various dcerpc auth mechanisms (This used to be commit c18c9b5585a3e5f7868562820c14f7cb529cdbcd) --- source4/libcli/auth/ntlmssp.c | 1055 +++++++++++++++++++++++++++++++++++ source4/libcli/auth/ntlmssp.h | 169 ++++++ source4/libcli/auth/ntlmssp_parse.c | 299 ++++++++++ source4/libcli/auth/ntlmssp_sign.c | 378 +++++++++++++ source4/libcli/ntlmssp.c | 625 --------------------- source4/libcli/ntlmssp_parse.c | 303 ---------- source4/libcli/util/ntlmssp_sign.c | 226 -------- source4/libcli/util/smbencrypt.c | 162 +++++- 8 files changed, 2032 insertions(+), 1185 deletions(-) create mode 100644 source4/libcli/auth/ntlmssp.c create mode 100644 source4/libcli/auth/ntlmssp.h create mode 100644 source4/libcli/auth/ntlmssp_parse.c create mode 100644 source4/libcli/auth/ntlmssp_sign.c delete mode 100644 source4/libcli/ntlmssp.c delete mode 100644 source4/libcli/ntlmssp_parse.c delete mode 100644 source4/libcli/util/ntlmssp_sign.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c new file mode 100644 index 0000000000..9ee71a2d28 --- /dev/null +++ b/source4/libcli/auth/ntlmssp.c @@ -0,0 +1,1055 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + handle NLTMSSP, server side + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001-2003 + + 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" + +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request); +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB in, DATA_BLOB *out); +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request); +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply); + +/** + * Callbacks for NTLMSSP - for both client and server operating modes + * + */ + +static const struct ntlmssp_callbacks { + enum NTLMSSP_ROLE role; + enum NTLM_MESSAGE_TYPE ntlmssp_command; + NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB in, DATA_BLOB *out); +} ntlmssp_callbacks[] = { + {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial}, + {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate}, + {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge}, + {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth}, + {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL}, + {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL} +}; + + +/** + * Print out the NTLMSSP flags for debugging + * @param neg_flags The flags from the packet + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + +/** + * Default challenge generation code. + * + */ + +static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + static uchar chal[8]; + generate_random_buffer(chal, sizeof(chal), False); + + return chal; +} + +/** + * Default 'we can set the challenge to anything we like' implementation + * + */ + +static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + return True; +} + +/** + * Default 'we can set the challenge to anything we like' implementation + * + * Does not actually do anything, as the value is always in the structure anyway. + * + */ + +static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) +{ + SMB_ASSERT(challenge->length == 8); + return NT_STATUS_OK; +} + +/** + * Set a username on an NTLMSSP context - ensures it is talloc()ed + * + */ + +NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) +{ + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + if (!ntlmssp_state->user) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a password on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) +{ + if (!password) { + ntlmssp_state->password = NULL; + } else { + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; +} + +/** + * Set a domain on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) +{ + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a workstation on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) +{ + ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Store a DATA_BLOB containing an NTLMSSP response, for use later. + * This copies the data blob + */ + +NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB response) +{ + ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, + response.data, response.length); + return NT_STATUS_OK; +} + +/** + * Next state function for the NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State + * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB + * @param out The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + */ + +NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, + const DATA_BLOB in, DATA_BLOB *out) +{ + DATA_BLOB input; + uint32 ntlmssp_command; + int i; + + *out = data_blob(NULL, 0); + + if (!in.length && ntlmssp_state->stored_response.length) { + input = ntlmssp_state->stored_response; + + /* we only want to read the stored response once - overwrite it */ + ntlmssp_state->stored_response = data_blob(NULL, 0); + } else { + input = in; + } + + if (!input.length) { + switch (ntlmssp_state->role) { + case NTLMSSP_CLIENT: + ntlmssp_command = NTLMSSP_INITIAL; + break; + case NTLMSSP_SERVER: + /* 'datagram' mode - no neg packet */ + ntlmssp_command = NTLMSSP_NEGOTIATE; + break; + } + } else { + if (!msrpc_parse(&input, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); + dump_data(2, (const char *)input.data, input.length); + return NT_STATUS_INVALID_PARAMETER; + } + } + + if (ntlmssp_command != ntlmssp_state->expected_state) { + DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); + return NT_STATUS_INVALID_PARAMETER; + } + + for (i=0; ntlmssp_callbacks[i].fn; i++) { + if (ntlmssp_callbacks[i].role == ntlmssp_state->role + && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { + return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out); + } + } + + DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", + ntlmssp_state->role, ntlmssp_command)); + + return NT_STATUS_INVALID_PARAMETER; +} + +/** + * End an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, free()ed by this function + */ + +void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + (*ntlmssp_state)->ref_count--; + + if ((*ntlmssp_state)->ref_count == 0) { + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + talloc_destroy(mem_ctx); + } + + *ntlmssp_state = NULL; + return; +} + +/** + * Determine correct target name flags for reply, given server role + * and negotiated flags + * + * @param ntlmssp_state NTLMSSP State + * @param neg_flags The flags from the packet + * @param chal_flags The flags to be set in the reply packet + * @return The 'target name' string. + */ + +static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, + uint32 neg_flags, uint32 *chal_flags) +{ + if (neg_flags & NTLMSSP_REQUEST_TARGET) { + *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; + *chal_flags |= NTLMSSP_REQUEST_TARGET; + if (ntlmssp_state->server_role == ROLE_STANDALONE) { + *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; + return ntlmssp_state->get_global_myname(); + } else { + *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; + return ntlmssp_state->get_domain(); + }; + } else { + return ""; + } +} + +static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32 neg_flags, BOOL allow_lm) { + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; + ntlmssp_state->unicode = True; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + ntlmssp_state->unicode = False; + } + + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) { + /* other end forcing us to use LM */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + ntlmssp_state->use_ntlmv2 = False; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; + } + + if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { + ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; + } + +} + + +/** + * Next state function for the Negotiate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. + */ + +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB struct_blob; + fstring dnsname, dnsdomname; + uint32 neg_flags = 0; + uint32 ntlmssp_command, chal_flags; + char *cliname=NULL, *domname=NULL; + const uint8 *cryptkey; + const char *target_name; + + /* parse the NTLMSSP packet */ +#if 0 + file_save("ntlmssp_negotiate.dat", request.data, request.length); +#endif + + if (request.length) { + if (!msrpc_parse(&request, "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname)) { + DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); + dump_data(2, (const char *)request.data, request.length); + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(cliname); + SAFE_FREE(domname); + + debug_ntlmssp_flags(neg_flags); + } + + ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); + + chal_flags = ntlmssp_state->neg_flags; + + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + if (target_name == NULL) + return NT_STATUS_INVALID_PARAMETER; + + /* Ask our caller what challenge they would like in the packet */ + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + + /* Check if we may set the challenge */ + if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + } + + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + + + /* This should be a 'netbios domain -> DNS domain' mapping */ + dnsdomname[0] = '\0'; + get_mydomname(dnsdomname); + strlower_m(dnsdomname); + + dnsname[0] = '\0'; + get_myfullname(dnsname); + strlower_m(dnsname); + + /* This creates the 'blob' of names that appears at the end of the packet */ + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) + { + const char *target_name_dns = ""; + if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { + target_name_dns = dnsdomname; + } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { + target_name_dns = dnsname; + } + + msrpc_gen(&struct_blob, "aaaaa", + NTLMSSP_NAME_TYPE_DOMAIN, target_name, + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, + NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, + 0, ""); + } else { + struct_blob = data_blob(NULL, 0); + } + + { + /* Marshel the packet in the right format, be it unicode or ASCII */ + const char *gen_string; + if (ntlmssp_state->unicode) { + gen_string = "CdUdbddB"; + } else { + gen_string = "CdAdbddB"; + } + + msrpc_gen(reply, gen_string, + "NTLMSSP", + NTLMSSP_CHALLENGE, + target_name, + chal_flags, + cryptkey, 8, + 0, 0, + struct_blob.data, struct_blob.length); + } + + data_blob_free(&struct_blob); + + ntlmssp_state->expected_state = NTLMSSP_AUTH; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * Next state function for the Authenticate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB lm_session_key = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + uint32 ntlmssp_command, auth_flags; + NTSTATUS nt_status; + + /* used by NTLM2 */ + BOOL doing_ntlm2 = False; + + uchar session_nonce[16]; + uchar session_nonce_hash[16]; + + const char *parse_string; + char *domain = NULL; + char *user = NULL; + char *workstation = NULL; + + /* parse the NTLMSSP packet */ + *reply = data_blob(NULL, 0); + +#if 0 + file_save("ntlmssp_auth.dat", request.data, request.length); +#endif + + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUUBd"; + } else { + parse_string = "CdBBAAABd"; + } + + data_blob_free(&ntlmssp_state->lm_resp); + data_blob_free(&ntlmssp_state->nt_resp); + + ntlmssp_state->user = NULL; + ntlmssp_state->domain = NULL; + ntlmssp_state->workstation = NULL; + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation, + &encrypted_session_key, + &auth_flags)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + dump_data(2, (const char *)request.data, request.length); + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + auth_flags = 0; + + /* Try again with a shorter string (Win9X truncates this packet) */ + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUU"; + } else { + parse_string = "CdBBAAA"; + } + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + dump_data(2, (const char *)request.data, request.length); + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + + return NT_STATUS_INVALID_PARAMETER; + } + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", + ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); + +#if 0 + file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); + file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); +#endif + + /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a + client challenge + + However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful. + */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) { + struct MD5Context md5_session_nonce_ctx; + SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8); + + doing_ntlm2 = True; + + memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8); + memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8); + + MD5Init(&md5_session_nonce_ctx); + MD5Update(&md5_session_nonce_ctx, session_nonce, 16); + MD5Final(session_nonce_hash, &md5_session_nonce_ctx); + + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8); + + /* LM response is no longer useful */ + data_blob_free(&ntlmssp_state->lm_resp); + + /* We changed the effective challenge - set it */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) { + data_blob_free(&encrypted_session_key); + return nt_status; + } + } + } + + /* Finally, actually ask if the password is OK */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { + data_blob_free(&encrypted_session_key); + return nt_status; + } + + dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length); + dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length); + + /* Handle the different session key derivation for NTLM2 */ + if (doing_ntlm2) { + if (nt_session_key.data && nt_session_key.length == 16) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + hmac_md5(nt_session_key.data, session_nonce, + sizeof(session_nonce), session_key.data); + dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + + } + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (lm_session_key.data && lm_session_key.length >= 8 && + ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, + session_key.data); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } + } else if (nt_session_key.data) { + session_key = nt_session_key; + dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } + + /* With KEY_EXCH, the client supplies the proposed session key, + but encrypts it with the long-term key */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + if (!encrypted_session_key.data || encrypted_session_key.length != 16) { + data_blob_free(&encrypted_session_key); + DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", + encrypted_session_key.length)); + return NT_STATUS_INVALID_PARAMETER; + } else if (!session_key.data || session_key.length != 16) { + DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", + session_key.length)); + } else { + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + SamOEMhash(encrypted_session_key.data, + session_key.data, + encrypted_session_key.length); + ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + encrypted_session_key.data, + encrypted_session_key.length); + dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length); + } + } else { + ntlmssp_state->session_key = session_key; + } + + data_blob_free(&encrypted_session_key); + + /* allow arbitarily many authentications */ + ntlmssp_state->expected_state = NTLMSSP_AUTH; + + return nt_status; +} + +/** + * Create an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, allocated by this function + */ + +NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*ntlmssp_state)->role = NTLMSSP_SERVER; + + (*ntlmssp_state)->mem_ctx = mem_ctx; + (*ntlmssp_state)->get_challenge = get_challenge; + (*ntlmssp_state)->set_challenge = set_challenge; + (*ntlmssp_state)->may_set_challenge = may_set_challenge; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ + + (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; + + (*ntlmssp_state)->ref_count = 1; + + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | +// NTLMSSP_NEGOTIATE_NTLM2 | + NTLMSSP_NEGOTIATE_KEY_EXCH | + NTLMSSP_NEGOTIATE_SIGN; + + return NT_STATUS_OK; +} + +/********************************************************************* + Client side NTLMSSP +*********************************************************************/ + +/** + * Next state function for the Initial packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + if (ntlmssp_state->unicode) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } else { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + } + + if (ntlmssp_state->use_ntlmv2) { +// ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(next_request, "CddAA", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + ntlmssp_state->neg_flags, + ntlmssp_state->get_domain(), + ntlmssp_state->get_global_myname()); + + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * Next state function for the Challenge Packet. Generate an auth packet. + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 chal_flags, ntlmssp_command, unkn1, unkn2; + DATA_BLOB server_domain_blob; + DATA_BLOB challenge_blob; + DATA_BLOB struct_blob = data_blob(NULL, 0); + char *server_domain; + const char *chal_parse_string; + const char *auth_gen_string; + DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB nt_response = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + NTSTATUS nt_status; + + if (!msrpc_parse(&reply, "CdBd", + "NTLMSSP", + &ntlmssp_command, + &server_domain_blob, + &chal_flags)) { + DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); + dump_data(2, (const char *)reply.data, reply.length); + + return NT_STATUS_INVALID_PARAMETER; + } + + data_blob_free(&server_domain_blob); + + DEBUG(3, ("Got challenge flags:\n")); + debug_ntlmssp_flags(chal_flags); + + ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); + + if (ntlmssp_state->unicode) { + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { + chal_parse_string = "CdUdbddB"; + } else { + chal_parse_string = "CdUdbdd"; + } + auth_gen_string = "CdBBUUUBd"; + } else { + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { + chal_parse_string = "CdAdbddB"; + } else { + chal_parse_string = "CdAdbdd"; + } + + auth_gen_string = "CdBBAAABd"; + } + + DEBUG(3, ("NTLMSSP: Set final flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); + + if (!msrpc_parse(&reply, chal_parse_string, + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { + DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); + dump_data(2, (const char *)reply.data, reply.length); + return NT_STATUS_INVALID_PARAMETER; + } + + ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx, + server_domain); + + SAFE_FREE(server_domain); + if (challenge_blob.length != 8) { + data_blob_free(&struct_blob); + return NT_STATUS_INVALID_PARAMETER; + } + + if (!ntlmssp_state->password) { + /* do nothing - blobs are zero length */ + } else if (ntlmssp_state->use_ntlmv2) { + + if (!struct_blob.length) { + /* be lazy, match win2k - we can't do NTLMv2 without it */ + DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* TODO: if the remote server is standalone, then we should replace 'domain' + with the server name as supplied above */ + + if (!SMBNTLMv2encrypt(ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->password, &challenge_blob, + &struct_blob, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&challenge_blob); + data_blob_free(&struct_blob); + return NT_STATUS_NO_MEMORY; + } + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + struct MD5Context md5_session_nonce_ctx; + uchar nt_hash[16]; + uchar session_nonce[16]; + uchar session_nonce_hash[16]; + uchar nt_session_key[16]; + E_md4hash(ntlmssp_state->password, nt_hash); + + lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + generate_random_buffer(lm_response.data, 8, False); + memset(lm_response.data+8, 0, 16); + + memcpy(session_nonce, challenge_blob.data, 8); + memcpy(&session_nonce[8], lm_response.data, 8); + + MD5Init(&md5_session_nonce_ctx); + MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); + MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); + MD5Final(session_nonce_hash, &md5_session_nonce_ctx); + + DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); + DEBUG(5, ("challenge is: \n")); + dump_data(5, session_nonce_hash, 8); + + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + SMBNTencrypt(ntlmssp_state->password, + session_nonce_hash, + nt_response.data); + + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + + SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); + hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); + dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + } else { + + + uchar lm_hash[16]; + uchar nt_hash[16]; + E_deshash(ntlmssp_state->password, lm_hash); + E_md4hash(ntlmssp_state->password, nt_hash); + + /* lanman auth is insecure, it may be disabled */ + if (lp_client_lanman_auth()) { + lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + SMBencrypt(ntlmssp_state->password,challenge_blob.data, + lm_response.data); + } + + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, + nt_response.data); + + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + && lp_client_lanman_auth()) { + SMBsesskeygen_lmv1(lm_hash, lm_response.data, + session_key.data); + dump_data_pw("LM session key\n", session_key.data, session_key.length); + } else { + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + dump_data_pw("NT session key:\n", session_key.data, session_key.length); + } + } + data_blob_free(&struct_blob); + + /* Key exchange encryptes a new client-generated session key with + the password-derived key */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + uint8 client_session_key[16]; + + generate_random_buffer(client_session_key, sizeof(client_session_key), False); + encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); + + SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + data_blob_free(&session_key); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + } + + /* this generates the actual auth packet */ + if (!msrpc_gen(next_request, auth_gen_string, + "NTLMSSP", + NTLMSSP_AUTH, + lm_response.data, lm_response.length, + nt_response.data, nt_response.length, + ntlmssp_state->domain, + ntlmssp_state->user, + ntlmssp_state->get_global_myname(), + encrypted_session_key.data, encrypted_session_key.length, + ntlmssp_state->neg_flags)) { + + return NT_STATUS_NO_MEMORY; + } + + data_blob_free(&encrypted_session_key); + + data_blob_free(&ntlmssp_state->chal); + + ntlmssp_state->chal = challenge_blob; + ntlmssp_state->lm_resp = lm_response; + ntlmssp_state->nt_resp = nt_response; + ntlmssp_state->session_key = session_key; + + ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { + DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); + return nt_status; + } + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP Client context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*ntlmssp_state)->role = NTLMSSP_CLIENT; + + (*ntlmssp_state)->mem_ctx = mem_ctx; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + + (*ntlmssp_state)->unicode = True; + + (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); + + (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL; + + (*ntlmssp_state)->ref_count = 1; + + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | +// NTLMSSP_NEGOTIATE_NTLM2 | + NTLMSSP_NEGOTIATE_KEY_EXCH | + /* + * We need to set this to allow a later SetPassword + * via the SAMR pipe to succeed. Strange.... We could + * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. + * */ + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_REQUEST_TARGET; + + return NT_STATUS_OK; +} + diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h new file mode 100644 index 0000000000..681d4071db --- /dev/null +++ b/source4/libcli/auth/ntlmssp.h @@ -0,0 +1,169 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + Copyright (C) Paul Ashton 1997 + + 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. +*/ + +/* NTLMSSP mode */ +enum NTLMSSP_ROLE +{ + NTLMSSP_SERVER, + NTLMSSP_CLIENT +}; + +/* NTLMSSP message types */ +enum NTLM_MESSAGE_TYPE +{ + NTLMSSP_INITIAL = 0 /* samba internal state */, + NTLMSSP_NEGOTIATE = 1, + NTLMSSP_CHALLENGE = 2, + NTLMSSP_AUTH = 3, + NTLMSSP_UNKNOWN = 4 +}; + +/* NTLMSSP negotiation flags */ +#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 +#define NTLMSSP_NEGOTIATE_OEM 0x00000002 +#define NTLMSSP_REQUEST_TARGET 0x00000004 +#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 /* Message integrity */ +#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 /* Message confidentiality */ +#define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040 +#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 +#define NTLMSSP_NEGOTIATE_NETWARE 0x00000100 +#define NTLMSSP_NEGOTIATE_NTLM 0x00000200 +#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000 +#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000 +#define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000 +#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 +#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000 +#define NTLMSSP_TARGET_TYPE_SERVER 0x20000 +#define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000 + +#define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000 +#define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000 +#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 +#define NTLMSSP_CHAL_TARGET_INFO 0x00800000 +#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */ +#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 +#define NTLMSSP_NEGOTIATE_080000000 0x80000000 + +#define NTLMSSP_NAME_TYPE_SERVER 0x01 +#define NTLMSSP_NAME_TYPE_DOMAIN 0x02 +#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 +#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04 + +typedef struct ntlmssp_state +{ + TALLOC_CTX *mem_ctx; + unsigned int ref_count; + enum NTLMSSP_ROLE role; + enum server_types server_role; + uint32 expected_state; + + BOOL unicode; + BOOL use_ntlmv2; + char *user; + char *domain; + char *workstation; + char *password; + char *server_domain; + + DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ + + DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */ + DATA_BLOB lm_resp; + DATA_BLOB nt_resp; + DATA_BLOB session_key; + + uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + + void *auth_context; + + /** + * Callback to get the 'challenge' used for NTLM authentication. + * + * @param ntlmssp_state This structure + * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication + * + */ + const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); + + /** + * Callback to find if the challenge used by NTLM authentication may be modified + * + * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the + * current 'security=server' implementation.. + * + * @param ntlmssp_state This structure + * @return Can the challenge be set to arbitary values? + * + */ + BOOL (*may_set_challenge)(const struct ntlmssp_state *ntlmssp_state); + + /** + * Callback to set the 'challenge' used for NTLM authentication. + * + * The callback may use the void *auth_context to store state information, but the same value is always available + * from the DATA_BLOB chal on this structure. + * + * @param ntlmssp_state This structure + * @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication + * + */ + NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge); + + /** + * Callback to check the user's password. + * + * The callback must reads the feilds of this structure for the information it needs on the user + * @param ntlmssp_state This structure + * @param nt_session_key If an NT session key is returned by the authentication process, return it here + * @param lm_session_key If an LM session key is returned by the authentication process, return it here + * + */ + NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); + + const char *(*get_global_myname)(void); + const char *(*get_domain)(void); + + /* SMB Signing */ + + uint32 ntlmssp_seq_num; + + /* ntlmv2 */ + char send_sign_const[16]; + char send_seal_const[16]; + char recv_sign_const[16]; + char recv_seal_const[16]; + + unsigned char send_sign_hash[258]; + unsigned char send_seal_hash[258]; + unsigned char recv_sign_hash[258]; + unsigned char recv_seal_hash[258]; + + /* ntlmv1 */ + unsigned char ntlmssp_hash[258]; + + /* it turns out that we don't always get the + response in at the time we want to process it. + Store it here, until we need it */ + DATA_BLOB stored_response; + +} NTLMSSP_STATE; + diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c new file mode 100644 index 0000000000..3444db0306 --- /dev/null +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -0,0 +1,299 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 + Copyright (C) Andrew Bartlett 2002-2003 + + 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" + +/* + this is a tiny msrpc packet generator. I am only using this to + avoid tying this code to a particular varient of our rpc code. This + generator is not general enough for all our rpc needs, its just + enough for the spnego/ntlmssp code + + format specifiers are: + + U = unicode string (input is unix string) + a = address (input is char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) + B = data blob (pointer + length) + b = data blob in header (pointer + length) + D + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_gen(DATA_BLOB *blob, + const char *format, ...) +{ + int i, n; + va_list ap; + char *s; + uint8 *b; + int head_size=0, data_size=0; + int head_ofs, data_ofs; + + /* first scan the format to work out the header and body size */ + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_charnum(s) * 2; + break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; + case 'a': + n = va_arg(ap, int); + s = va_arg(ap, char *); + data_size += (str_charnum(s) * 2) + 4; + break; + case 'B': + b = va_arg(ap, uint8 *); + head_size += 8; + data_size += va_arg(ap, int); + break; + case 'b': + b = va_arg(ap, uint8 *); + head_size += va_arg(ap, int); + break; + case 'd': + n = va_arg(ap, int); + head_size += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_size += str_charnum(s) + 1; + break; + } + } + va_end(ap); + + /* allocate the space, then scan the format again to fill in the values */ + *blob = data_blob(NULL, head_size + data_size); + + head_ofs = 0; + data_ofs = head_size; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + data_ofs += n*2; + break; + case 'A': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; + case 'a': + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + break; + + case 'B': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + if (n && b) /* don't follow null pointers... */ + memcpy(blob->data+data_ofs, b, n); + data_ofs += n; + break; + case 'd': + n = va_arg(ap, int); + SIVAL(blob->data, head_ofs, n); head_ofs += 4; + break; + case 'b': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + memcpy(blob->data + head_ofs, b, n); + head_ofs += n; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + STR_ASCII|STR_TERMINATE); + break; + } + } + va_end(ap); + + return True; +} + + +/* a helpful macro to avoid running over the end of our blob */ +#define NEED_DATA(amount) \ +if ((head_ofs + amount) > blob->length) { \ + return False; \ +} + +/* + this is a tiny msrpc packet parser. This the the partner of msrpc_gen + + format specifiers are: + + U = unicode string (output is unix string) + A = ascii string + B = data blob + b = data blob in header + d = word (4 bytes) + C = constant ascii string + */ + +BOOL msrpc_parse(const DATA_BLOB *blob, + const char *format, ...) +{ + int i; + va_list ap; + char **ps, *s; + DATA_BLOB *b; + size_t head_ofs = 0; + uint16 len1, len2; + uint32 ptr; + uint32 *v; + pstring p; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + ps = va_arg(ap, char **); + if (len1 == 0 && len2 == 0) { + *ps = smb_xstrdup(""); + } else { + /* make sure its in the right format - be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + return False; + } + if (len1 & 1) { + /* if odd length and unicode */ + return False; + } + + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = smb_xstrdup(p); + } else { + (*ps) = smb_xstrdup(""); + } + } + break; + case 'A': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + ps = va_arg(ap, char **); + /* make sure its in the right format - be strict */ + if (len1 == 0 && len2 == 0) { + *ps = smb_xstrdup(""); + } else { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + return False; + } + + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_ASCII|STR_NOALIGN); + (*ps) = smb_xstrdup(p); + } else { + (*ps) = smb_xstrdup(""); + } + } + break; + case 'B': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + b = (DATA_BLOB *)va_arg(ap, void *); + if (len1 == 0 && len2 == 0) { + *b = data_blob(NULL, 0); + } else { + /* make sure its in the right format - be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + return False; + } + *b = data_blob(blob->data + ptr, len1); + } + break; + case 'b': + b = (DATA_BLOB *)va_arg(ap, void *); + len1 = va_arg(ap, unsigned); + /* make sure its in the right format - be strict */ + NEED_DATA(len1); + *b = data_blob(blob->data + head_ofs, len1); + head_ofs += len1; + break; + case 'd': + v = va_arg(ap, uint32 *); + NEED_DATA(4); + *v = IVAL(blob->data, head_ofs); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (strcmp(s, p) != 0) { + return False; + } + break; + } + } + va_end(ap); + + return True; +} diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c new file mode 100644 index 0000000000..11d63ec5f3 --- /dev/null +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -0,0 +1,378 @@ +/* + * Unix SMB/CIFS implementation. + * Version 3.0 + * NTLMSSP Signing routines + * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 + * Copyright (C) Andrew Bartlett 2003 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "includes.h" + +#define CLI_SIGN "session key to client-to-server signing key magic constant" +#define CLI_SEAL "session key to client-to-server sealing key magic constant" +#define SRV_SIGN "session key to server-to-client signing key magic constant" +#define SRV_SEAL "session key to server-to-client sealing key magic constant" + +static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; + + for (ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +static void calc_hash(unsigned char *hash, const char *k2, int k2l) +{ + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (unsigned char)ind; + } + + for (ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (hash[ind] + k2[ind%k2l]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], + DATA_BLOB session_key, + const char *constant) +{ + struct MD5Context ctx3; + + /* NOTE: This code is currently complate fantasy - it's + got more in common with reality than the previous code + (the LM session key is not the right thing to use) but + it still needs work */ + + MD5Init(&ctx3); + MD5Update(&ctx3, session_key.data, session_key.length); + MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)); + MD5Final((unsigned char *)digest, &ctx3); + + calc_hash(hash, digest, 16); +} + +enum ntlmssp_direction { + NTLMSSP_SEND, + NTLMSSP_RECEIVE +}; + +static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + enum ntlmssp_direction direction, + DATA_BLOB *sig) +{ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; + char seq_num[4]; + uchar digest[16]; + SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); + + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); + hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); + hmac_md5_update(data, length, &ctx); + hmac_md5_final(digest, &ctx); + + if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ + , ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); + break; + } + } else { + uint32 crc; + crc = crc32_calc_buffer((const char *)data, length); + if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + + /* increment counter on send */ + ntlmssp_state->ntlmssp_seq_num++; + return nt_status; +} + +/** + * Check the signature of an incoming packet + * @note caller *must* check that the signature is the size it expects + * + */ + +NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + const DATA_BLOB *sig) +{ + DATA_BLOB local_sig; + NTSTATUS nt_status; + + if (sig->length < 8) { + DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", + (unsigned long)sig->length)); + } + + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, + length, NTLMSSP_RECEIVE, &local_sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); + return nt_status; + } + + if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) { + DEBUG(5, ("BAD SIG: wanted signature of\n")); + dump_data(5, (const char *)local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, (const char *)(sig->data), sig->length); + + DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n")); + return NT_STATUS_ACCESS_DENIED; + } + + /* increment counter on recieive */ + ntlmssp_state->ntlmssp_seq_num++; + + return NT_STATUS_OK; +} + + +/** + * Seal data with the NTLMSSP algorithm + * + */ + +NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, + uchar *data, size_t length, + DATA_BLOB *sig) +{ + DEBUG(10,("ntlmssp_seal_data: seal\n")); + dump_data_pw("ntlmssp clear data\n", data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; + char seq_num[4]; + uchar digest[16]; + SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); + + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); + hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); + hmac_md5_update(data, length, &ctx); + hmac_md5_final(digest, &ctx); + + if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ + , ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + dump_data_pw("ntlmssp client sealing hash:\n", + ntlmssp_state->send_seal_hash, + sizeof(ntlmssp_state->send_seal_hash)); + NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); + dump_data_pw("ntlmssp client signing hash:\n", + ntlmssp_state->send_sign_hash, + sizeof(ntlmssp_state->send_sign_hash)); + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + } else { + uint32 crc; + crc = crc32_calc_buffer((const char *)data, length); + if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + /* The order of these two operations matters - we must first seal the packet, + then seal the sequence number - this is becouse the ntlmssp_hash is not + constant, but is is rather updated with each iteration */ + + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + } + dump_data_pw("ntlmssp sealed data\n", data, length); + + /* increment counter on send */ + ntlmssp_state->ntlmssp_seq_num++; + + return NT_STATUS_OK; +} + +/** + * Unseal data with the NTLMSSP algorithm + * + */ + +NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, + uchar *data, size_t length, + DATA_BLOB *sig) +{ + DEBUG(10,("ntlmssp__unseal_data: seal\n")); + dump_data_pw("ntlmssp sealed data\n", data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length); + } else { + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + } + dump_data_pw("ntlmssp clear data\n", data, length); + + return ntlmssp_check_packet(ntlmssp_state, data, length, sig); +} + +/** + Initialise the state for NTLMSSP signing. +*/ +NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) +{ + unsigned char p24[24]; + ZERO_STRUCT(p24); + + DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + { + const char *send_sign_const; + const char *send_seal_const; + const char *recv_sign_const; + const char *recv_seal_const; + + switch (ntlmssp_state->role) { + case NTLMSSP_CLIENT: + send_sign_const = CLI_SIGN; + send_seal_const = CLI_SEAL; + recv_sign_const = SRV_SIGN; + recv_seal_const = SRV_SEAL; + break; + case NTLMSSP_SERVER: + send_sign_const = SRV_SIGN; + send_seal_const = SRV_SEAL; + recv_sign_const = CLI_SIGN; + recv_seal_const = CLI_SEAL; + break; + } + + calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, + ntlmssp_state->send_sign_const, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP send sign hash:\n", + ntlmssp_state->send_sign_hash, + sizeof(ntlmssp_state->send_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, + ntlmssp_state->send_seal_const, + ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP send sesl hash:\n", + ntlmssp_state->send_seal_hash, + sizeof(ntlmssp_state->send_seal_hash)); + + calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, + ntlmssp_state->recv_sign_const, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP receive sign hash:\n", + ntlmssp_state->recv_sign_hash, + sizeof(ntlmssp_state->recv_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, + ntlmssp_state->recv_seal_const, + ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP receive seal hash:\n", + ntlmssp_state->recv_sign_hash, + sizeof(ntlmssp_state->recv_sign_hash)); + + } + else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { + /* can't sign or check signatures yet */ + DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); + + calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8); + dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + } else { + if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { + /* can't sign or check signatures yet */ + DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); + + calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); + dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + } + + ntlmssp_state->ntlmssp_seq_num = 0; + + return NT_STATUS_OK; +} diff --git a/source4/libcli/ntlmssp.c b/source4/libcli/ntlmssp.c deleted file mode 100644 index c4ad260a1a..0000000000 --- a/source4/libcli/ntlmssp.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 3.0 - handle NLTMSSP, server side - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2003 - - 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" - -/** - * Print out the NTLMSSP flags for debugging - * @param neg_flags The flags from the packet - */ - -void debug_ntlmssp_flags(uint32 neg_flags) -{ - DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); -} - -/** - * Default challenge generation code. - * - */ - -static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) -{ - static uchar chal[8]; - generate_random_buffer(chal, sizeof(chal), False); - - return chal; -} - -/** - * Determine correct target name flags for reply, given server role - * and negoitated falgs - * - * @param ntlmssp_state NTLMSSP State - * @param neg_flags The flags from the packet - * @param chal_flags The flags to be set in the reply packet - * @return The 'target name' string. - */ - -static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, - uint32 neg_flags, uint32 *chal_flags) -{ - if (neg_flags & NTLMSSP_REQUEST_TARGET) { - *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; - *chal_flags |= NTLMSSP_REQUEST_TARGET; - if (ntlmssp_state->server_role == ROLE_STANDALONE) { - *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; - return ntlmssp_state->get_global_myname(); - } else { - *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; - return ntlmssp_state->get_domain(); - }; - } else { - return ""; - } -} - -/** - * Next state function for the Negotiate packet - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. - */ - -static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) -{ - DATA_BLOB struct_blob; - fstring dnsname, dnsdomname; - uint32 ntlmssp_command, neg_flags, chal_flags; - char *cliname=NULL, *domname=NULL; - const uint8 *cryptkey; - const char *target_name; - - /* parse the NTLMSSP packet */ -#if 0 - file_save("ntlmssp_negotiate.dat", request.data, request.length); -#endif - - if (!msrpc_parse(&request, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - return NT_STATUS_INVALID_PARAMETER; - } - - SAFE_FREE(cliname); - SAFE_FREE(domname); - - debug_ntlmssp_flags(neg_flags); - - cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); - - data_blob_free(&ntlmssp_state->chal); - ntlmssp_state->chal = data_blob(cryptkey, 8); - - /* Give them the challenge. For now, ignore neg_flags and just - return the flags we want. Obviously this is not correct */ - - chal_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { - chal_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->unicode = True; - } else { - chal_flags |= NTLMSSP_NEGOTIATE_OEM; - } - - target_name = ntlmssp_target_name(ntlmssp_state, - neg_flags, &chal_flags); - - /* This should be a 'netbios domain -> DNS domain' mapping */ - dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); - strlower(dnsdomname); - - dnsname[0] = '\0'; - get_myfullname(dnsname); - strlower(dnsname); - - if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) - { - const char *target_name_dns = ""; - if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { - target_name_dns = dnsdomname; - } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { - target_name_dns = dnsname; - } - - /* the numbers here are the string type flags */ - msrpc_gen(&struct_blob, "aaaaa", - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, target_name_dns, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname, - ntlmssp_state->unicode, 0, ""); - } else { - struct_blob = data_blob(NULL, 0); - } - - { - const char *gen_string; - if (ntlmssp_state->unicode) { - gen_string = "CdUdbddB"; - } else { - gen_string = "CdAdbddB"; - } - - msrpc_gen(reply, gen_string, - "NTLMSSP", - NTLMSSP_CHALLENGE, - target_name, - chal_flags, - cryptkey, 8, - 0, 0, - struct_blob.data, struct_blob.length); - } - - data_blob_free(&struct_blob); - - ntlmssp_state->expected_state = NTLMSSP_AUTH; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -/** - * Next state function for the Authenticate packet - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) -{ - DATA_BLOB sess_key; - uint32 ntlmssp_command, neg_flags; - NTSTATUS nt_status; - - const char *parse_string; - - /* parse the NTLMSSP packet */ -#if 0 - file_save("ntlmssp_auth.dat", request.data, request.length); -#endif - - if (ntlmssp_state->unicode) { - parse_string = "CdBBUUUBd"; - } else { - parse_string = "CdBBAAABd"; - } - - data_blob_free(&ntlmssp_state->lm_resp); - data_blob_free(&ntlmssp_state->nt_resp); - - SAFE_FREE(ntlmssp_state->user); - SAFE_FREE(ntlmssp_state->domain); - SAFE_FREE(ntlmssp_state->workstation); - - /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&request, parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &ntlmssp_state->domain, - &ntlmssp_state->user, - &ntlmssp_state->workstation, - &sess_key, - &neg_flags)) { - return NT_STATUS_INVALID_PARAMETER; - } - - data_blob_free(&sess_key); - - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%d len2=%d\n", - ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length)); - -#if 0 - file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); - file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); -#endif - - nt_status = ntlmssp_state->check_password(ntlmssp_state); - - *reply = data_blob(NULL, 0); - - return nt_status; -} - -/** - * Create an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, allocated by this funciton - */ - -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - (*ntlmssp_state)->mem_ctx = mem_ctx; - (*ntlmssp_state)->get_challenge = get_challenge; - - (*ntlmssp_state)->get_global_myname = lp_netbios_name; - (*ntlmssp_state)->get_domain = lp_workgroup; - (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ - - (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; - - return NT_STATUS_OK; -} - -/** - * End an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, free()ed by this funciton - */ - -NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - - SAFE_FREE((*ntlmssp_state)->user); - SAFE_FREE((*ntlmssp_state)->domain); - SAFE_FREE((*ntlmssp_state)->workstation); - - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; - return NT_STATUS_OK; -} - -/** - * Next state function for the NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. - */ - -NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) -{ - uint32 ntlmssp_command; - *reply = data_blob(NULL, 0); - - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command != ntlmssp_state->expected_state) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command == NTLMSSP_NEGOTIATE) { - return ntlmssp_server_negotiate(ntlmssp_state, request, reply); - } else if (ntlmssp_command == NTLMSSP_AUTH) { - return ntlmssp_server_auth(ntlmssp_state, request, reply); - } else { - return NT_STATUS_INVALID_PARAMETER; - } -} - -/********************************************************************* - Client side NTLMSSP -*********************************************************************/ - -/** - * Next state function for the Initial packet - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, - DATA_BLOB reply, DATA_BLOB *next_request) -{ - if (ntlmssp_state->unicode) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - } - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(next_request, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - ntlmssp_state->neg_flags, - ntlmssp_state->get_domain(), - ntlmssp_state->get_global_myname()); - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -/** - * Next state function for the Challenge Packet. Generate an auth packet. - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, - const DATA_BLOB reply, DATA_BLOB *next_request) -{ - uint32 chal_flags, ntlmssp_command, unkn1, unkn2; - DATA_BLOB server_domain_blob; - DATA_BLOB challenge_blob; - DATA_BLOB struct_blob; - char *server_domain; - const char *chal_parse_string; - const char *auth_gen_string; - DATA_BLOB lm_response = data_blob(NULL, 0); - DATA_BLOB nt_response = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); - uint8 datagram_sess_key[16]; - - ZERO_STRUCT(datagram_sess_key); - - if (!msrpc_parse(&reply, "CdBd", - "NTLMSSP", - &ntlmssp_command, - &server_domain_blob, - &chal_flags)) { - DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - data_blob_free(&server_domain_blob); - - if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - chal_parse_string = "CdUdbddB"; - auth_gen_string = "CdBBUUUBd"; - ntlmssp_state->unicode = True; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; - } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { - chal_parse_string = "CdAdbddB"; - auth_gen_string = "CdBBAAABd"; - ntlmssp_state->unicode = False; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } else { - return NT_STATUS_INVALID_PARAMETER; - } - - if (!msrpc_parse(&reply, chal_parse_string, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { - DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - SAFE_FREE(server_domain); - data_blob_free(&struct_blob); - - if (challenge_blob.length != 8) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_state->use_ntlmv2) { - - /* TODO: if the remote server is standalone, then we should replace 'domain' - with the server name as supplied above */ - - if (!SMBNTLMv2encrypt(ntlmssp_state->user, - ntlmssp_state->domain, - ntlmssp_state->password, challenge_blob, - &lm_response, &nt_response, &session_key)) { - data_blob_free(&challenge_blob); - return NT_STATUS_NO_MEMORY; - } - } else { - uchar nt_hash[16]; - E_md4hash(ntlmssp_state->password, nt_hash); - - /* non encrypted password supplied. Ignore ntpass. */ - if (lp_client_lanman_auth()) { - lm_response = data_blob(NULL, 24); - SMBencrypt(ntlmssp_state->password,challenge_blob.data, - lm_response.data); - } - - nt_response = data_blob(NULL, 24); - SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, - nt_response.data); - session_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); - } - - data_blob_free(&challenge_blob); - - /* this generates the actual auth packet */ - if (!msrpc_gen(next_request, auth_gen_string, - "NTLMSSP", - NTLMSSP_AUTH, - lm_response.data, lm_response.length, - nt_response.data, nt_response.length, - ntlmssp_state->domain, - ntlmssp_state->user, - ntlmssp_state->get_global_myname(), - datagram_sess_key, 0, - ntlmssp_state->neg_flags)) { - - data_blob_free(&lm_response); - data_blob_free(&nt_response); - data_blob_free(&session_key); - return NT_STATUS_NO_MEMORY; - } - - data_blob_free(&lm_response); - data_blob_free(&nt_response); - - ntlmssp_state->session_key = session_key; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP Client context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - (*ntlmssp_state)->mem_ctx = mem_ctx; - - (*ntlmssp_state)->get_global_myname = lp_netbios_name; - (*ntlmssp_state)->get_domain = lp_workgroup; - - (*ntlmssp_state)->unicode = True; - - (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_REQUEST_TARGET; - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - data_blob_free(&(*ntlmssp_state)->session_key); - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, - DATA_BLOB reply, DATA_BLOB *next_request) -{ - uint32 ntlmssp_command; - *next_request = data_blob(NULL, 0); - - if (!reply.length) { - return ntlmssp_client_initial(ntlmssp_state, reply, next_request); - } - - if (!msrpc_parse(&reply, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command == NTLMSSP_CHALLENGE) { - return ntlmssp_client_challenge(ntlmssp_state, reply, next_request); - } - return NT_STATUS_INVALID_PARAMETER; -} - -NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) -{ - ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); - if (!ntlmssp_state->user) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) -{ - ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); - if (!ntlmssp_state->password) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) -{ - ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); - if (!ntlmssp_state->domain) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} diff --git a/source4/libcli/ntlmssp_parse.c b/source4/libcli/ntlmssp_parse.c deleted file mode 100644 index ac779a3906..0000000000 --- a/source4/libcli/ntlmssp_parse.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5/SPNEGO routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 - Copyright (C) Andrew Bartlett 2002-2003 - - 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" - -/* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_gen(DATA_BLOB *blob, - const char *format, ...) -{ - int i, n; - va_list ap; - char *s; - uint8 *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - BOOL unicode; - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_charnum(s) * 2; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } - break; - case 'B': - b = va_arg(ap, uint8 *); - head_size += 8; - data_size += va_arg(ap, int); - break; - case 'b': - b = va_arg(ap, uint8 *); - head_size += va_arg(ap, int); - break; - case 'd': - n = va_arg(ap, int); - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob(NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - if (unicode) { - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; - } - break; - - case 'B': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - memcpy(blob->data+data_ofs, b, n); - data_ofs += n; - break; - case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; - break; - case 'b': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); - head_ofs += n; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, - STR_ASCII|STR_TERMINATE); - break; - } - } - va_end(ap); - - return True; -} - - -/* a helpful macro to avoid running over the end of our blob */ -#define NEED_DATA(amount) \ -if ((head_ofs + amount) > blob->length) { \ - return False; \ -} - -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ - -BOOL msrpc_parse(const DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - char **ps, *s; - DATA_BLOB *b; - size_t head_ofs = 0; - uint16 len1, len2; - uint32 ptr; - uint32 *v; - pstring p; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - if (len1 & 1) { - /* if odd length and unicode */ - return False; - } - - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = smb_xstrdup(p); - } else { - (*ps) = smb_xstrdup(""); - } - break; - case 'A': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_ASCII|STR_NOALIGN); - (*ps) = smb_xstrdup(p); - } else { - (*ps) = smb_xstrdup(""); - } - break; - case 'B': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - b = (DATA_BLOB *)va_arg(ap, void *); - *b = data_blob(blob->data + ptr, len1); - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, unsigned); - /* make sure its in the right format - be strict */ - NEED_DATA(len1); - *b = data_blob(blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32 *); - NEED_DATA(4); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; - } - break; - } - } - va_end(ap); - - return True; -} - diff --git a/source4/libcli/util/ntlmssp_sign.c b/source4/libcli/util/ntlmssp_sign.c deleted file mode 100644 index bd6d64d842..0000000000 --- a/source4/libcli/util/ntlmssp_sign.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Version 3.0 - * NTLMSSP Signing routines - * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 - * Copyright (C) Andrew Bartlett 2003 - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "includes.h" - -#define CLI_SIGN "session key to client-to-server signing key magic constant" -#define CLI_SEAL "session key to client-to-server sealing key magic constant" -#define SRV_SIGN "session key to server-to-client signing key magic constant" -#define SRV_SEAL "session key to server-to-client sealing key magic constant" - -static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) -{ - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; - - for (ind = 0; ind < len; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - -static void calc_hash(unsigned char *hash, const char *k2, int k2l) -{ - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - hash[ind] = (unsigned char)ind; - } - - for (ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (hash[ind] + k2[ind%k2l]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - hash[256] = 0; - hash[257] = 0; -} - -static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], - const char encrypted_response[16], - const char *constant) -{ - struct MD5Context ctx3; - - MD5Init(&ctx3); - MD5Update(&ctx3, encrypted_response, 5); - MD5Update(&ctx3, constant, strlen(constant)); - MD5Final(digest, &ctx3); - - calc_hash(hash, digest, 16); -} - -enum ntlmssp_direction { - NTLMSSP_SEND, - NTLMSSP_RECEIVE -}; - -static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - enum ntlmssp_direction direction, - DATA_BLOB *sig) -{ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - HMACMD5Context ctx; - char seq_num[4]; - uchar digest[16]; - SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - - hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); - hmac_md5_update(seq_num, 4, &ctx); - hmac_md5_update(data, length, &ctx); - hmac_md5_final(digest, &ctx); - - if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; - } - switch (direction) { - case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length); - break; - case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data, sig->length); - break; - } - } else { - uint32 crc; - crc = crc32_buffer(data, length); - if (!msrpc_gen(sig, "ddd", 0, crc, ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; - } - - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data, sig->length); - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - DATA_BLOB *sig) -{ - ntlmssp_state->ntlmssp_seq_num++; - return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); -} - -/** - * Check the signature of an incoming packet - * @note caller *must* check that the signature is the size it expects - * - */ - -NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - const DATA_BLOB *sig) -{ - DATA_BLOB local_sig; - NTSTATUS nt_status; - - if (sig->length < 8) { - DEBUG(0, ("NTLMSSP packet check failed due to short signiture (%u bytes)!\n", - sig->length)); - } - - nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, - length, NTLMSSP_RECEIVE, &local_sig); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); - return nt_status; - } - - if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(5, ("BAD SIG: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); - - DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); - - DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); - return NT_STATUS_ACCESS_DENIED; - } -} - -/** - Initialise the state for NTLMSSP signing. -*/ -NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) -{ - unsigned char p24[24]; - unsigned char lm_hash[16]; - - if (!ntlmssp_state->lm_resp.data) { - /* can't sign or check signitures yet */ - return NT_STATUS_UNSUCCESSFUL; - } - - E_deshash(ntlmssp_state->password, lm_hash); - - NTLMSSPOWFencrypt(lm_hash, ntlmssp_state->lm_resp.data, p24); - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - { - calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, ntlmssp_state->cli_sign_const, p24, CLI_SIGN); - calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, ntlmssp_state->cli_seal_const, p24, CLI_SEAL); - calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, ntlmssp_state->srv_sign_const, p24, SRV_SIGN); - calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, ntlmssp_state->srv_seal_const, p24, SRV_SEAL); - } - else - { - char k2[8]; - memcpy(k2, p24, 5); - k2[5] = 0xe5; - k2[6] = 0x38; - k2[7] = 0xb0; - - calc_hash(ntlmssp_state->ntlmssp_hash, k2, 8); - } - - ntlmssp_state->ntlmssp_seq_num = 0; - - ZERO_STRUCT(lm_hash); - return NT_STATUS_OK; -} diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 00c2b58146..39f3803ade 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -76,13 +76,12 @@ void E_deshash(const char *passwd, uchar p16[16]) { fstring dospwd; ZERO_STRUCT(dospwd); - ZERO_STRUCTP(p16); /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - E_P16(dospwd, p16); + E_P16((const unsigned char *)dospwd, p16); ZERO_STRUCT(dospwd); } @@ -248,23 +247,23 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } -/* Does the md5 encryption from the NT hash for NTLMv2. */ +/* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], - const DATA_BLOB srv_chal, - const DATA_BLOB cli_chal, + const DATA_BLOB *srv_chal, + const DATA_BLOB *cli_chal, uchar resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); - hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); + hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); + hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal.data, srv_chal.length); - dump_data(100, cli_chal.data, cli_chal.length); + dump_data(100, srv_chal->data, srv_chal->length); + dump_data(100, cli_chal->data, cli_chal->length); dump_data(100, resp_buf, 16); #endif } @@ -272,6 +271,8 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], void SMBsesskeygen_ntv2(const uchar kr[16], const uchar * nt_resp, uint8 sess_key[16]) { + /* a very nice, 128 bit, variable session key */ + HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); @@ -287,6 +288,9 @@ void SMBsesskeygen_ntv2(const uchar kr[16], void SMBsesskeygen_ntv1(const uchar kr[16], const uchar * nt_resp, uint8 sess_key[16]) { + /* yes, this session key does not change - yes, this + is a problem - but it is 128 bits */ + mdfour((unsigned char *)sess_key, kr, 16); #ifdef DEBUG_PASSWORD @@ -295,36 +299,125 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], - DATA_BLOB server_chal, size_t client_chal_length) +void SMBsesskeygen_lmv1(const uchar lm_hash[16], + const uchar lm_resp[24], /* only uses 8 */ + uint8 sess_key[16]) +{ + /* Calculate the LM session key (effective length 40 bits, + but changes with each session) */ + + uchar p24[24]; + uchar partial_lm_hash[16]; + + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 8); + + SMBOWFencrypt(lm_hash, lm_resp, p24); + + memcpy(sess_key, p24, 16); + sess_key[5] = 0xe5; + sess_key[6] = 0x38; + sess_key[7] = 0xb0; + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_lmv1:\n")); + dump_data(100, sess_key, 16); +#endif +} + +DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, + const char *domain) +{ + DATA_BLOB names_blob = data_blob(NULL, 0); + + msrpc_gen(&names_blob, "aaa", + True, NTLMSSP_NAME_TYPE_DOMAIN, domain, + True, NTLMSSP_NAME_TYPE_SERVER, hostname, + True, 0, ""); + return names_blob; +} + +static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) +{ + uchar client_chal[8]; + DATA_BLOB response = data_blob(NULL, 0); + char long_date[8]; + + generate_random_buffer(client_chal, sizeof(client_chal), False); + + put_long_date(long_date, time(NULL)); + + /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ + + msrpc_gen(&response, "ddbbdb", + 0x00000101, /* Header */ + 0, /* 'Reserved' */ + long_date, 8, /* Timestamp */ + client_chal, 8, /* client challenge */ + 0, /* Unknown */ + names_blob->data, names_blob->length); /* End of name list */ + + return response; +} + +static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob) { uchar ntlmv2_response[16]; DATA_BLOB ntlmv2_client_data; DATA_BLOB final_response; /* NTLMv2 */ + /* generate some data to pass into the response function - including + the hostname and domain name of the server */ + ntlmv2_client_data = NTLMv2_generate_client_data(names_blob); - /* We also get to specify some random data */ - ntlmv2_client_data = data_blob(NULL, client_chal_length); - generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - /* put it into nt_response, for the code below to put into the packet */ - final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ - memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + + memcpy(final_response.data+sizeof(ntlmv2_response), + ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); return final_response; } +static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], + const DATA_BLOB *server_chal) +{ + uchar lmv2_response[16]; + DATA_BLOB lmv2_client_data = data_blob(NULL, 8); + DATA_BLOB final_response = data_blob(NULL, 24); + + /* LMv2 */ + /* client-supplied random data */ + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); + memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); + + /* after the first 16 bytes is the random data we generated above, + so the server can verify us with it */ + memcpy(final_response.data+sizeof(lmv2_response), + lmv2_client_data.data, lmv2_client_data.length); + + data_blob_free(&lmv2_client_data); + + return final_response; +} + BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB server_chal, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *session_key) + DATA_BLOB *nt_session_key) { uchar nt_hash[16]; uchar ntlm_v2_hash[16]; @@ -338,18 +431,24 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password return False; } - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + if (nt_response) { + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, + names_blob); + if (nt_session_key) { + *nt_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data); + } + } /* LMv2 */ - *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); - - *session_key = data_blob(NULL, 16); + if (lm_response) { + *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); + } - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data); - return True; } @@ -416,3 +515,4 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } + -- cgit From c123c8454142d17d2884ae9dd951b7f2a0b1a343 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Nov 2003 02:08:41 +0000 Subject: fixed some memory leaks in the dcerpc use of ntlmssp signing (This used to be commit abbc9993b8f7eb9f57e079db1d0b170d0b9aa443) --- source4/libcli/auth/ntlmssp_sign.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 11d63ec5f3..2f510b0f98 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -180,8 +180,10 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); return nt_status; } - - if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) { + + if (local_sig.length != sig->length || + memcmp(local_sig.data + local_sig.length - 8, + sig->data + sig->length - 8, 8) != 0) { DEBUG(5, ("BAD SIG: wanted signature of\n")); dump_data(5, (const char *)local_sig.data, local_sig.length); @@ -192,6 +194,8 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_ACCESS_DENIED; } + data_blob_free(&local_sig); + /* increment counter on recieive */ ntlmssp_state->ntlmssp_seq_num++; -- cgit From 3e0501082cc5e5715dd315f890560a5759331df3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Nov 2003 21:57:29 +0000 Subject: fixed default port handling pointed out by Tom Jansen (This used to be commit 8246e6ca0bd0eaa92de602db46a119d368e93391) --- source4/libcli/raw/clisocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 6ccdeef366..f596cba854 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -41,7 +41,7 @@ struct cli_socket *cli_sock_init(void) sock->mem_ctx = mem_ctx; sock->fd = -1; - sock->port = 445; + sock->port = 0; /* 20 second default timeout */ sock->timeout = 20000; -- cgit From 7602aa50fd591e63393def79d55302a22e77c387 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 00:17:30 +0000 Subject: * got rid of UNISTR2 and everything that depends on it * removed a bunch of code that needs to be rewritten using the new interfaces (This used to be commit 9b02b486ef5906516f8cad79dbff5e3dd54cde66) --- source4/libcli/auth/ntlmssp.h | 3 + source4/libcli/util/credentials.c | 194 -------------------------------------- 2 files changed, 3 insertions(+), 194 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 681d4071db..c57646ca31 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -68,6 +68,9 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 #define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04 + +#define NTLMSSP_SIGN_VERSION 0xa + typedef struct ntlmssp_state { TALLOC_CTX *mem_ctx; diff --git a/source4/libcli/util/credentials.c b/source4/libcli/util/credentials.c index 0d521bae8a..2c8f7e7423 100644 --- a/source4/libcli/util/credentials.c +++ b/source4/libcli/util/credentials.c @@ -19,197 +19,3 @@ */ #include "includes.h" - -/**************************************************************************** -represent a credential as a string -****************************************************************************/ -char *credstr(const uchar *cred) -{ - static fstring buf; - slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", - cred[0], cred[1], cred[2], cred[3], - cred[4], cred[5], cred[6], cred[7]); - return buf; -} - - -/**************************************************************************** - setup the session key. -Input: 8 byte challenge block - 8 byte server challenge block - 16 byte md4 encrypted password -Output: - 8 byte session key -****************************************************************************/ -void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass, - uchar session_key[8]) -{ - uint32 sum[2]; - unsigned char sum2[8]; - - sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); - sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); - - SIVAL(sum2,0,sum[0]); - SIVAL(sum2,4,sum[1]); - - cred_hash1(session_key, sum2, pass); - - /* debug output */ - DEBUG(4,("cred_session_key\n")); - - DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data))); - DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data))); - DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); - DEBUG(5,(" sess_key : %s\n", credstr(session_key))); -} - - -/**************************************************************************** -create a credential - -Input: - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - 8 byte credential -****************************************************************************/ -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred) -{ - DOM_CHAL time_cred; - - SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time); - SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); - - cred_hash2(cred->data, time_cred.data, session_key); - - /* debug output*/ - DEBUG(4,("cred_create\n")); - - DEBUG(5,(" sess_key : %s\n", credstr(session_key))); - DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); - DEBUG(5,(" timestamp: %x\n" , timestamp.time)); - DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); - DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); -} - - -/**************************************************************************** - check a supplied credential - -Input: - 8 byte received credential - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - returns 1 if computed credential matches received credential - returns 0 otherwise -****************************************************************************/ -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp) -{ - DOM_CHAL cred2; - - cred_create(session_key, stored_cred, timestamp, &cred2); - - /* debug output*/ - DEBUG(4,("cred_assert\n")); - - DEBUG(5,(" challenge : %s\n", credstr(cred->data))); - DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); - - if (memcmp(cred->data, cred2.data, 8) == 0) - { - DEBUG(5, ("credentials check ok\n")); - return True; - } - else - { - DEBUG(5, ("credentials check wrong\n")); - return False; - } -} - - -/**************************************************************************** - checks credentials; generates next step in the credential chain -****************************************************************************/ -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) -{ - UTIME new_clnt_time; - uint32 new_cred; - - DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); - - /* increment client time by one second */ - new_clnt_time.time = sto_clnt_cred->timestamp.time + 1; - - /* check that the received server credentials are valid */ - if (!cred_assert(&rcv_srv_cred->challenge, sess_key, - &sto_clnt_cred->challenge, new_clnt_time)) - { - return False; - } - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->challenge.data, 0); - new_cred += new_clnt_time.time; - - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); - - DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data))); - return True; -} - - -/**************************************************************************** - checks credentials; generates next step in the credential chain -****************************************************************************/ -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred) -{ - UTIME new_clnt_time; - uint32 new_cred; - - DEBUG(5,("deal_with_creds: %d\n", __LINE__)); - - /* check that the received client credentials are valid */ - if (!cred_assert(&rcv_clnt_cred->challenge, sess_key, - &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp)) - { - return False; - } - - /* increment client time by one second */ - new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->challenge.data, 0); - new_cred += new_clnt_time.time; - - DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); - - /* doesn't matter that server time is 0 */ - rtn_srv_cred->timestamp.time = 0; - - DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time)); - - /* create return credentials for inclusion in the reply */ - cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time, - &rtn_srv_cred->challenge); - - DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); - - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); - - return True; -} -- cgit From b4b0177fdb5f1704a7347552e48b2ab647a03d14 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 04:13:43 +0000 Subject: added netr_ServerAuthenticate() and test code I would like the netlogon test suite to eventually do a new domain join using a fake workstation name, then remove itself afterwards, but for now I'm assuming we are already joined to the domain when the testsuite runs. This means you need to use the Samba3 net command to do a join before running RPC-NETLOGON (This used to be commit 8c7a9446a0892a4f7722cced5019667f7a9fafdd) --- source4/libcli/auth/credentials.c | 213 ++++++++++++++++++++++++++++++++++++++ source4/libcli/util/credentials.c | 21 ---- 2 files changed, 213 insertions(+), 21 deletions(-) create mode 100644 source4/libcli/auth/credentials.c delete mode 100644 source4/libcli/util/credentials.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c new file mode 100644 index 0000000000..6df163bdfc --- /dev/null +++ b/source4/libcli/auth/credentials.c @@ -0,0 +1,213 @@ +/* + Unix SMB/CIFS implementation. + + code to manipulate domain credentials + + Copyright (C) Andrew Tridgell 1997-2003 + + 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" + +/**************************************************************************** +represent a credential as a string +****************************************************************************/ +char *credstr(const uchar *cred) +{ + static fstring buf; + slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", + cred[0], cred[1], cred[2], cred[3], + cred[4], cred[5], cred[6], cred[7]); + return buf; +} + + +/**************************************************************************** + setup the session key. +Input: 8 byte challenge block + 8 byte server challenge block + 16 byte md4 encrypted password +Output: + 8 byte session key +****************************************************************************/ +void cred_session_key(const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 md4_pass[16], + uint8 session_key[8]) +{ + uint32 sum[2]; + uint8 sum2[8]; + + sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); + sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); + + SIVAL(sum2,0,sum[0]); + SIVAL(sum2,4,sum[1]); + + cred_hash1(session_key, sum2, md4_pass); +} + + +/**************************************************************************** +create a credential + +Input: + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + 8 byte credential +****************************************************************************/ +void cred_create(uchar session_key[8], struct netr_Credential *stor_cred, time_t timestamp, + struct netr_Credential *cred) +{ + struct netr_Credential time_cred; + + SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp); + SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); + + cred_hash2(cred->data, time_cred.data, session_key); + + /* debug output*/ + DEBUG(4,("cred_create\n")); + + DEBUG(5,(" sess_key : %s\n", credstr(session_key))); + DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); + DEBUG(5,(" timestamp: %x\n", (unsigned)timestamp)); + DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); + DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); +} + + +/**************************************************************************** + check a supplied credential + +Input: + 8 byte received credential + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + returns 1 if computed credential matches received credential + returns 0 otherwise +****************************************************************************/ +int cred_assert(struct netr_Credential *cred, uchar session_key[8], + struct netr_Credential *stored_cred, + time_t timestamp) +{ + struct netr_Credential cred2; + + cred_create(session_key, stored_cred, timestamp, &cred2); + + /* debug output*/ + DEBUG(4,("cred_assert\n")); + + DEBUG(5,(" challenge : %s\n", credstr(cred->data))); + DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); + + if (memcmp(cred->data, cred2.data, 8) == 0) + { + DEBUG(5, ("credentials check ok\n")); + return True; + } + else + { + DEBUG(5, ("credentials check wrong\n")); + return False; + } +} + + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL clnt_deal_with_creds(uchar sess_key[8], + struct netr_Authenticator *sto_clnt_cred, + struct netr_Authenticator *rcv_srv_cred) +{ + time_t new_clnt_time; + uint32 new_cred; + + DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); + + /* increment client time by one second !?! */ + new_clnt_time = sto_clnt_cred->timestamp + 1; + + /* check that the received server credentials are valid */ + if (!cred_assert(&rcv_srv_cred->cred, sess_key, + &sto_clnt_cred->cred, new_clnt_time)) { + return False; + } + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->cred.data, 0); + new_cred += new_clnt_time; + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->cred.data, 0, new_cred); + + DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->cred.data))); + return True; +} + + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL deal_with_creds(uchar sess_key[8], + struct netr_Authenticator *sto_clnt_cred, + struct netr_Authenticator *rcv_clnt_cred, + struct netr_Authenticator *rtn_srv_cred) +{ + time_t new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* check that the received client credentials are valid */ + if (!cred_assert(&rcv_clnt_cred->cred, sess_key, + &sto_clnt_cred->cred, rcv_clnt_cred->timestamp)) + { + return False; + } + + /* increment client time by one second */ + new_clnt_time = rcv_clnt_cred->timestamp + 1; + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->cred.data, 0); + new_cred += new_clnt_time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); + + /* doesn't matter that server time is 0 */ + rtn_srv_cred->timestamp = 0; + + DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", (unsigned)new_clnt_time)); + + /* create return credentials for inclusion in the reply */ + cred_create(sess_key, &sto_clnt_cred->cred, new_clnt_time, + &rtn_srv_cred->cred); + + DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->cred.data))); + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->cred.data, 0, new_cred); + + return True; +} diff --git a/source4/libcli/util/credentials.c b/source4/libcli/util/credentials.c deleted file mode 100644 index 2c8f7e7423..0000000000 --- a/source4/libcli/util/credentials.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - Unix SMB/CIFS implementation. - code to manipulate domain credentials - Copyright (C) Andrew Tridgell 1997-1998 - - 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" -- cgit From a6cf6cada93640fe6a24a7d3c5403079aeb7b4de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 09:28:10 +0000 Subject: added netr_LogonSamLogon() and test code (This used to be commit 4fa3ad3ecbfd8f8663fcdfaba9a7db481e303f2b) --- source4/libcli/auth/credentials.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 6df163bdfc..72572d8f91 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -143,8 +143,6 @@ BOOL clnt_deal_with_creds(uchar sess_key[8], time_t new_clnt_time; uint32 new_cred; - DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); - /* increment client time by one second !?! */ new_clnt_time = sto_clnt_cred->timestamp + 1; @@ -161,7 +159,6 @@ BOOL clnt_deal_with_creds(uchar sess_key[8], /* store new seed in client credentials */ SIVAL(sto_clnt_cred->cred.data, 0, new_cred); - DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->cred.data))); return True; } -- cgit From 232d6480a73d2f08edb341c90df01e4e31f7eee8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 10:07:24 +0000 Subject: fixed NTLMSSP_SIGN_VERSION (which I broke earlier today) (This used to be commit c8ef04077413f44101ba071187554e65a8e1c8fc) --- source4/libcli/auth/ntlmssp.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index c57646ca31..8d2fcab320 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -68,8 +68,7 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 #define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04 - -#define NTLMSSP_SIGN_VERSION 0xa +#define NTLMSSP_SIGN_VERSION 1 typedef struct ntlmssp_state { -- cgit From f9e2a8af391f8ecb7cf6aa2d017898503d16985f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 12:41:54 +0000 Subject: neater credentials handling in netlogon client code (This used to be commit b7d748f499f79415b444e7cebe7d8de7186fbc94) --- source4/libcli/auth/credentials.c | 191 +++++++------------------------------- 1 file changed, 32 insertions(+), 159 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 72572d8f91..06ca416592 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -22,32 +22,15 @@ #include "includes.h" -/**************************************************************************** -represent a credential as a string -****************************************************************************/ -char *credstr(const uchar *cred) -{ - static fstring buf; - slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", - cred[0], cred[1], cred[2], cred[3], - cred[4], cred[5], cred[6], cred[7]); - return buf; -} - - -/**************************************************************************** - setup the session key. -Input: 8 byte challenge block - 8 byte server challenge block - 16 byte md4 encrypted password -Output: - 8 byte session key -****************************************************************************/ -void cred_session_key(const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const uint8 md4_pass[16], - uint8 session_key[8]) +/* + initialise the credentials state +*/ +void creds_init(struct netr_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16]) { + struct netr_Credential time_cred; uint32 sum[2]; uint8 sum2[8]; @@ -57,154 +40,44 @@ void cred_session_key(const struct netr_Credential *client_challenge, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(session_key, sum2, md4_pass); -} - - -/**************************************************************************** -create a credential + cred_hash1(creds->session_key, sum2, machine_password); -Input: - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - 8 byte credential -****************************************************************************/ -void cred_create(uchar session_key[8], struct netr_Credential *stor_cred, time_t timestamp, - struct netr_Credential *cred) -{ - struct netr_Credential time_cred; + creds->sequence = 0; - SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp); - SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); + SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(cred->data, time_cred.data, session_key); + cred_hash2(creds->client_cred.data, time_cred.data, creds->session_key); - /* debug output*/ - DEBUG(4,("cred_create\n")); - - DEBUG(5,(" sess_key : %s\n", credstr(session_key))); - DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); - DEBUG(5,(" timestamp: %x\n", (unsigned)timestamp)); - DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); - DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); + creds->server_cred = *server_challenge; } - -/**************************************************************************** - check a supplied credential - -Input: - 8 byte received credential - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - returns 1 if computed credential matches received credential - returns 0 otherwise -****************************************************************************/ -int cred_assert(struct netr_Credential *cred, uchar session_key[8], - struct netr_Credential *stored_cred, - time_t timestamp) +/* + check that the credentials reply is correct then generate the next + set of credentials +*/ +BOOL creds_next(struct netr_CredentialState *creds, + const struct netr_Credential *next) { struct netr_Credential cred2; + struct netr_Credential time_cred; - cred_create(session_key, stored_cred, timestamp, &cred2); - - /* debug output*/ - DEBUG(4,("cred_assert\n")); - - DEBUG(5,(" challenge : %s\n", credstr(cred->data))); - DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); - - if (memcmp(cred->data, cred2.data, 8) == 0) - { - DEBUG(5, ("credentials check ok\n")); - return True; - } - else - { - DEBUG(5, ("credentials check wrong\n")); - return False; - } -} - - -/**************************************************************************** - checks credentials; generates next step in the credential chain -****************************************************************************/ -BOOL clnt_deal_with_creds(uchar sess_key[8], - struct netr_Authenticator *sto_clnt_cred, - struct netr_Authenticator *rcv_srv_cred) -{ - time_t new_clnt_time; - uint32 new_cred; - - /* increment client time by one second !?! */ - new_clnt_time = sto_clnt_cred->timestamp + 1; - - /* check that the received server credentials are valid */ - if (!cred_assert(&rcv_srv_cred->cred, sess_key, - &sto_clnt_cred->cred, new_clnt_time)) { - return False; - } - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->cred.data, 0); - new_cred += new_clnt_time; - - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->cred.data, 0, new_cred); - - return True; -} - - -/**************************************************************************** - checks credentials; generates next step in the credential chain -****************************************************************************/ -BOOL deal_with_creds(uchar sess_key[8], - struct netr_Authenticator *sto_clnt_cred, - struct netr_Authenticator *rcv_clnt_cred, - struct netr_Authenticator *rtn_srv_cred) -{ - time_t new_clnt_time; - uint32 new_cred; - - DEBUG(5,("deal_with_creds: %d\n", __LINE__)); - - /* check that the received client credentials are valid */ - if (!cred_assert(&rcv_clnt_cred->cred, sess_key, - &sto_clnt_cred->cred, rcv_clnt_cred->timestamp)) - { + SIVAL(time_cred.data, 0, IVAL(creds->server_cred.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->server_cred.data, 4)); + cred_hash2(cred2.data, time_cred.data, creds->session_key); + if (memcmp(next->data, cred2.data, 8) != 0) { + DEBUG(2,("credentials check failed\n")); return False; } - /* increment client time by one second */ - new_clnt_time = rcv_clnt_cred->timestamp + 1; - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->cred.data, 0); - new_cred += new_clnt_time; - - DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); - - /* doesn't matter that server time is 0 */ - rtn_srv_cred->timestamp = 0; - - DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", (unsigned)new_clnt_time)); + creds->server_cred = creds->client_cred; - /* create return credentials for inclusion in the reply */ - cred_create(sess_key, &sto_clnt_cred->cred, new_clnt_time, - &rtn_srv_cred->cred); - - DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->cred.data))); + SIVAL(time_cred.data, 0, IVAL(creds->client_cred.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->client_cred.data, 4)); - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->cred.data, 0, new_cred); + cred_hash2(cred2.data, time_cred.data, creds->session_key); + creds->client_cred = cred2; + creds->sequence++; return True; } -- cgit From 8b30b0071cb7668f49b2ea5951d1180bf90371e3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 22:13:11 +0000 Subject: * another small API change in the credentials code * don't use static variables in the smbdes code (This used to be commit e6e09064646c347169852fa162c72fc0542c6d5c) --- source4/libcli/auth/credentials.c | 68 ++++++++++++++++++++++---------- source4/libcli/util/smbdes.c | 82 +++++++++++++++++++-------------------- 2 files changed, 88 insertions(+), 62 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 06ca416592..80ea2e9583 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,12 +23,16 @@ #include "includes.h" /* - initialise the credentials state + initialise the credentials state and return the initial credentials + to be sent as part of a netr_ServerAuthenticate*() call. + + this call is made after the netr_ServerReqChallenge call */ void creds_init(struct netr_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16]) + const uint8 machine_password[16], + struct netr_Credential *initial_creds) { struct netr_Credential time_cred; uint32 sum[2]; @@ -44,40 +48,64 @@ void creds_init(struct netr_CredentialState *creds, creds->sequence = 0; - SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0) + creds->sequence); + SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(creds->client_cred.data, time_cred.data, creds->session_key); + cred_hash2(creds->cred2.data, time_cred.data, creds->session_key); + + creds->cred1 = *server_challenge; - creds->server_cred = *server_challenge; + *initial_creds = creds->cred2; } + /* - check that the credentials reply is correct then generate the next - set of credentials + check that a credentials reply is correct */ -BOOL creds_next(struct netr_CredentialState *creds, - const struct netr_Credential *next) +BOOL creds_check(struct netr_CredentialState *creds, + const struct netr_Credential *received_credentials) { - struct netr_Credential cred2; - struct netr_Credential time_cred; + struct netr_Credential cred2, time_cred; + uint32 sequence = creds->sequence?creds->sequence+1:0; - SIVAL(time_cred.data, 0, IVAL(creds->server_cred.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->server_cred.data, 4)); + SIVAL(time_cred.data, 0, IVAL(creds->cred1.data, 0) + sequence); + SIVAL(time_cred.data, 4, IVAL(creds->cred1.data, 4)); cred_hash2(cred2.data, time_cred.data, creds->session_key); - if (memcmp(next->data, cred2.data, 8) != 0) { + if (memcmp(received_credentials->data, cred2.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); return False; } - creds->server_cred = creds->client_cred; + return True; +} - SIVAL(time_cred.data, 0, IVAL(creds->client_cred.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->client_cred.data, 4)); +/* + produce the next authenticator in the sequence ready to send to + the server +*/ +void creds_authenticator(struct netr_CredentialState *creds, + struct netr_Authenticator *next) +{ + struct netr_Credential cred2; + struct netr_Credential time_cred; + + if (creds->sequence == 0) { + creds->sequence = time(NULL); + } + + /* this step size is quite arbitrary - the client can choose + any sequence number it likes */ + creds->sequence += 2; + + creds->cred1 = creds->cred2; + + SIVAL(time_cred.data, 0, IVAL(creds->cred2.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->cred2.data, 4)); cred_hash2(cred2.data, time_cred.data, creds->session_key); - creds->client_cred = cred2; - creds->sequence++; - return True; + creds->cred2 = cred2; + + next->cred = creds->cred2; + next->timestamp = creds->sequence; } diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index cde77f94a3..e5c4c6f3f1 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -306,7 +306,7 @@ static void smbhash(unsigned char *out, const unsigned char *in, const unsigned void E_P16(const unsigned char *p14,unsigned char *p16) { - unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + unsigned const char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; smbhash(p16, sp8, p14, 1); smbhash(p16+8, sp8, p14+7, 1); } @@ -341,8 +341,8 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) { unsigned char buf[8]; - static unsigned char key2[8]; - + unsigned char key2[8]; + ZERO_STRUCT(key2); smbhash(buf, in, key, 1); key2[0] = key[7]; smbhash(out, buf, key2, 1); @@ -350,8 +350,8 @@ void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) { - static unsigned char key2[8]; - + unsigned char key2[8]; + ZERO_STRUCT(key2); smbhash(out, in, key, forw); key2[0] = key[7]; smbhash(out + 8, in + 8, key2, forw); @@ -359,48 +359,46 @@ void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, void SamOEMhash( unsigned char *data, const unsigned char *key, int val) { - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (s_box[ind] + key[ind%16]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - for( ind = 0; ind < val; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; - - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; - - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (s_box[ind] + key[ind%16]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + + for (ind = 0; ind < val; ind++){ + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } } + /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ - void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw) { uchar s[14]; -- cgit From 06ae42483582ee76c3f6848697cf61cc142dd86a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 00:31:54 +0000 Subject: * netr_ServerPasswordSet() now works - the test suite changes the machine account password. * neater handling on value() options in IDL. The auto-print code will now display the right value so you don't need to initialise it in your C code (This used to be commit 3dd978b12bb5571fba4e1839c0f7ee60cf729aa2) --- source4/libcli/auth/credentials.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 80ea2e9583..1749037e8f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -109,3 +109,14 @@ void creds_authenticator(struct netr_CredentialState *creds, next->cred = creds->cred2; next->timestamp = creds->sequence; } + + +/* + encrypt a 16 byte password buffer using the session key +*/ +void creds_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 1); + *pass = tmp; +} -- cgit From 2e70035f87ebcdfbdc3cf8d05cd89d4eeeebc16c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 02:15:33 +0000 Subject: another big improvement in the credentials API. I think it now actually makes sense, and as a nice side effect it matches the debug output of the w2k3 netlogon.log (This used to be commit 3c7287c24e5970e5b7447ad042848505537c7d3b) --- source4/libcli/auth/credentials.c | 111 +++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 42 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 1749037e8f..5814053d5f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -28,11 +28,10 @@ this call is made after the netr_ServerReqChallenge call */ -void creds_init(struct netr_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const uint8 machine_password[16], - struct netr_Credential *initial_creds) +static void creds_init(struct netr_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16]) { struct netr_Credential time_cred; uint32 sum[2]; @@ -46,36 +45,82 @@ void creds_init(struct netr_CredentialState *creds, cred_hash1(creds->session_key, sum2, machine_password); - creds->sequence = 0; + creds->sequence = time(NULL); SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); + cred_hash2(creds->client.data, time_cred.data, creds->session_key); - cred_hash2(creds->cred2.data, time_cred.data, creds->session_key); + SIVAL(time_cred.data, 0, IVAL(server_challenge->data, 0)); + SIVAL(time_cred.data, 4, IVAL(server_challenge->data, 4)); + cred_hash2(creds->server.data, time_cred.data, creds->session_key); - creds->cred1 = *server_challenge; + creds->seed = creds->client; +} + + +/* + step the credentials to the next element in the chain +*/ +static void creds_step(struct netr_CredentialState *creds) +{ + struct netr_Credential time_cred; + + creds->sequence += 2; + + DEBUG(5,("\tseed %08x:%08x\n", + IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4))); + + SIVAL(time_cred.data, 0, IVAL(creds->seed.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4)); + + DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); + + cred_hash2(creds->client.data, time_cred.data, creds->session_key); + + DEBUG(5,("\tCLIENT %08x:%08x\n", + IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); + + SIVAL(time_cred.data, 0, IVAL(creds->seed.data, 0) + creds->sequence + 1); + SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4)); + + DEBUG(5,("\tseed+time+1 %08x:%08x\n", + IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); + + cred_hash2(creds->server.data, time_cred.data, creds->session_key); - *initial_creds = creds->cred2; + DEBUG(5,("\tSERVER %08x:%08x\n", + IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); + + creds->seed = time_cred; } /* - check that a credentials reply is correct + initialise the credentials chain and return the first client + credentials */ -BOOL creds_check(struct netr_CredentialState *creds, - const struct netr_Credential *received_credentials) +void creds_client_init(struct netr_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16], + struct netr_Credential *initial_credential) { - struct netr_Credential cred2, time_cred; - uint32 sequence = creds->sequence?creds->sequence+1:0; + creds_init(creds, client_challenge, server_challenge, machine_password); + + *initial_credential = creds->client; +} - SIVAL(time_cred.data, 0, IVAL(creds->cred1.data, 0) + sequence); - SIVAL(time_cred.data, 4, IVAL(creds->cred1.data, 4)); - cred_hash2(cred2.data, time_cred.data, creds->session_key); - if (memcmp(received_credentials->data, cred2.data, 8) != 0) { +/* + check that a credentials reply from a server is correct +*/ +BOOL creds_client_check(struct netr_CredentialState *creds, + const struct netr_Credential *received_credentials) +{ + if (memcmp(received_credentials->data, creds->server.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); return False; } - return True; } @@ -83,30 +128,12 @@ BOOL creds_check(struct netr_CredentialState *creds, produce the next authenticator in the sequence ready to send to the server */ -void creds_authenticator(struct netr_CredentialState *creds, - struct netr_Authenticator *next) +void creds_client_authenticator(struct netr_CredentialState *creds, + struct netr_Authenticator *next) { - struct netr_Credential cred2; - struct netr_Credential time_cred; - - if (creds->sequence == 0) { - creds->sequence = time(NULL); - } - - /* this step size is quite arbitrary - the client can choose - any sequence number it likes */ - creds->sequence += 2; - - creds->cred1 = creds->cred2; - - SIVAL(time_cred.data, 0, IVAL(creds->cred2.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->cred2.data, 4)); - - cred_hash2(cred2.data, time_cred.data, creds->session_key); - - creds->cred2 = cred2; + creds_step(creds); - next->cred = creds->cred2; + next->cred = creds->client; next->timestamp = creds->sequence; } @@ -114,7 +141,7 @@ void creds_authenticator(struct netr_CredentialState *creds, /* encrypt a 16 byte password buffer using the session key */ -void creds_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) +void creds_client_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) { struct netr_Password tmp; cred_hash3(tmp.data, pass->data, creds->session_key, 1); -- cgit From d65f0095c9acc11e9512c546a99af720d7dd5036 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 03:06:21 +0000 Subject: added netr_DatabaseSync(). It doesn't work as I haven't done schannel yet, but at least the request is understood by w2k3 Also modified pidl to allow multiple branches in a union to have the same element. This is used in netlogon. (This used to be commit 983c0e9683fa9666a6e055d1776ebeef8cd2e700) --- source4/libcli/auth/credentials.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 5814053d5f..acc083d57f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,8 +23,7 @@ #include "includes.h" /* - initialise the credentials state and return the initial credentials - to be sent as part of a netr_ServerAuthenticate*() call. + initialise the credentials state this call is made after the netr_ServerReqChallenge call */ @@ -60,7 +59,8 @@ static void creds_init(struct netr_CredentialState *creds, /* - step the credentials to the next element in the chain + step the credentials to the next element in the chain, updating the + current client and server credentials and the seed */ static void creds_step(struct netr_CredentialState *creds) { @@ -96,6 +96,12 @@ static void creds_step(struct netr_CredentialState *creds) } + +/***************************************************************** +The above functions are common to the client and server interface +next comes the client specific functions +******************************************************************/ + /* initialise the credentials chain and return the first client credentials -- cgit From 926240428c0646aabb13539745940b61a7cf44a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Dec 2003 02:03:06 +0000 Subject: * patch based on work by Jim Myers to unify the ioctl handling to be more like the other major SMB functions * added SMBntrename code (This used to be commit f2d3dc9893fa0e089c407fa16ce9ff13587e70cd) --- source4/libcli/raw/rawioctl.c | 105 ++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 34 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 506bddd497..2ea2cabb89 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client file operations Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 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 @@ -26,16 +27,17 @@ } while (0) /* - send a raw ioctl - async send + send a raw smb ioctl - async send */ -struct cli_request *smb_raw_ioctl_send(struct cli_tree *tree, struct smb_ioctl *parms) +static struct cli_request *smb_raw_smbioctl_send(struct cli_tree *tree, + union smb_ioctl *parms) { struct cli_request *req; SETUP_REQUEST(SMBioctl, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->in.fnum); - SIVAL(req->out.vwv, VWV(1), parms->in.request); + SSVAL(req->out.vwv, VWV(0), parms->ioctl.in.fnum); + SIVAL(req->out.vwv, VWV(1), parms->ioctl.in.request); if (!cli_request_send(req)) { cli_request_destroy(req); @@ -46,36 +48,28 @@ struct cli_request *smb_raw_ioctl_send(struct cli_tree *tree, struct smb_ioctl * } /* - send a raw ioctl - async recv + send a raw smb ioctl - async recv */ -NTSTATUS smb_raw_ioctl_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, struct smb_ioctl *parms) +static NTSTATUS smb_raw_smbioctl_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + union smb_ioctl *parms) { if (!cli_request_receive(req) || cli_request_is_error(req)) { return cli_request_destroy(req); } - parms->out.blob = cli_req_pull_blob(req, mem_ctx, req->in.data, -1); + parms->ioctl.out.blob = cli_req_pull_blob(req, mem_ctx, req->in.data, -1); return cli_request_destroy(req); } -/* - send a raw ioctl - sync interface -*/ -NTSTATUS smb_raw_ioctl(struct cli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_ioctl *parms) -{ - struct cli_request *req = smb_raw_ioctl_send(tree, parms); - return smb_raw_ioctl_recv(req, mem_ctx, parms); -} - - /**************************************************************************** NT ioctl (async send) ****************************************************************************/ -struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, - struct smb_ntioctl *parms) +static struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, + union smb_ioctl *parms) { struct smb_nttrans nt; uint16 setup[4]; @@ -85,10 +79,10 @@ struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, nt.in.max_data = 0; nt.in.setup_count = 4; nt.in.setup = setup; - SIVAL(setup, 0, parms->in.function); - SSVAL(setup, 4, parms->in.fnum); - SCVAL(setup, 6, parms->in.fsctl); - SCVAL(setup, 7, parms->in.filter); + SIVAL(setup, 0, parms->ntioctl.in.function); + SSVAL(setup, 4, parms->ntioctl.in.fnum); + SCVAL(setup, 6, parms->ntioctl.in.fsctl); + SCVAL(setup, 7, parms->ntioctl.in.filter); nt.in.function = NT_TRANSACT_IOCTL; nt.in.params = data_blob(NULL, 0); nt.in.data = data_blob(NULL, 0); @@ -99,20 +93,63 @@ struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, /**************************************************************************** NT ioctl (async recv) ****************************************************************************/ -NTSTATUS smb_raw_ntioctl_recv(struct cli_request *req, - struct smb_ntioctl *parms) +static NTSTATUS smb_raw_ntioctl_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, + union smb_ioctl *parms) { - struct smb_nttrans nt; + if (!cli_request_receive(req) || + cli_request_is_error(req)) { + return cli_request_destroy(req); + } - return smb_raw_nttrans_recv(req, req->mem_ctx, &nt); + parms->ntioctl.out.blob = cli_req_pull_blob(req, mem_ctx, req->in.data, -1); + return cli_request_destroy(req); } -/**************************************************************************** -NT ioctl (sync interface) -****************************************************************************/ -NTSTATUS smb_raw_ntioctl(struct cli_tree *tree, - struct smb_ntioctl *parms) + +/* + send a raw ioctl - async send +*/ +struct cli_request *smb_raw_ioctl_send(struct cli_tree *tree, union smb_ioctl *parms) +{ + struct cli_request *req = NULL; + + switch (parms->generic.level) { + case RAW_IOCTL_IOCTL: + req = smb_raw_smbioctl_send(tree, parms); + break; + + case RAW_IOCTL_NTIOCTL: + req = smb_raw_ntioctl_send(tree, parms); + break; + } + + return req; +} + +/* + recv a raw ioctl - async recv +*/ +NTSTATUS smb_raw_ioctl_recv(struct cli_request *req, + TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { - struct cli_request *req = smb_raw_ntioctl_send(tree, parms); - return smb_raw_ntioctl_recv(req, parms); + switch (parms->generic.level) { + case RAW_IOCTL_IOCTL: + return smb_raw_smbioctl_recv(req, mem_ctx, parms); + + case RAW_IOCTL_NTIOCTL: + return smb_raw_ntioctl_recv(req, mem_ctx, parms); + } + return NT_STATUS_INVALID_LEVEL; +} + +/* + send a raw ioctl - sync interface +*/ +NTSTATUS smb_raw_ioctl(struct cli_tree *tree, + TALLOC_CTX *mem_ctx, union smb_ioctl *parms) +{ + struct cli_request *req; + req = smb_raw_ioctl_send(tree, parms); + return smb_raw_ioctl_recv(req, mem_ctx, parms); } -- cgit From fcc4efd1ea637c810eed8444080b87d7f92c837a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Dec 2003 09:07:45 +0000 Subject: the next step in the dcerpc server code. Added the link between the IPC IO routines and the dcerpc endpoint servers. (This used to be commit 4929c53bc8dddda8a763fdfbcf81a79776d01113) --- source4/libcli/raw/rawtrans.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index f31b1eaf7e..f7a3b4aa43 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -233,6 +233,11 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, /* make sure we don't leak data via the padding */ memset(req->out.data, 0, padding); + if (command == SMBtrans && parms->in.trans_name) { + namelen = cli_req_append_string(req, parms->in.trans_name, + STR_TERMINATE); + } + /* primary request */ SSVAL(req->out.vwv,VWV(0),parms->in.params.length); SSVAL(req->out.vwv,VWV(1),parms->in.data.length); @@ -243,9 +248,6 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, SIVAL(req->out.vwv,VWV(6),parms->in.timeout); SSVAL(req->out.vwv,VWV(8),0); /* reserved */ SSVAL(req->out.vwv,VWV(9),parms->in.params.length); - if (command == SMBtrans && parms->in.trans_name) - namelen = cli_req_append_string(req, parms->in.trans_name, - STR_TERMINATE); SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)+namelen); SSVAL(req->out.vwv,VWV(11),parms->in.data.length); SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)+namelen); -- cgit From 6a3ef87d3ee58c9704f60fe7ae0897036fec9b29 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Dec 2003 08:59:25 +0000 Subject: make sure we allow clients to negotiate ntlmssp seal if they want it (This used to be commit a1275c1e89462f0a3cce73066777055c3c970b76) --- source4/libcli/auth/ntlmssp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 9ee71a2d28..5fd3938a7d 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -743,7 +743,8 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_NTLM | // NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | - NTLMSSP_NEGOTIATE_SIGN; + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_SEAL; return NT_STATUS_OK; } -- cgit From 24c22aef90d8534ee2d016b37b2b302f1367d106 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Dec 2003 09:02:58 +0000 Subject: a fairly large commit! This adds support for bigendian rpc in the client. I have installed SUN pcnetlink locally and am using it to test the samba4 rpc code. This allows us to easily find places where we have stuffed up the types (such as 2 uint16 versus a uint32), as testing both big-endian and little-endian easily shows which is correct. I have now used this to fix several bugs like that in the samba4 IDL. In order to make this work I also had to redefine a GUID as a true structure, not a blob. From the pcnetlink wire it is clear that it is indeed defined as a structure (the byte order changes). This required changing lots of Samba code to use a GUID as a structure. I also had to fix the if_version code in dcerpc syntax IDs, as it turns out they are a single uint32 not two uint16s. The big-endian support is a bit ugly at the moment, and breaks the layering in some places. More work is needed, especially on the server side. (This used to be commit bb1af644a5a7b188290ce36232f255da0e5d66d2) --- source4/libcli/raw/rawfsinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 362063bfc5..85daf654d3 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -259,7 +259,8 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req, case RAW_QFS_OBJECTID_INFORMATION: QFS_CHECK_SIZE(64); - memcpy(fsinfo->objectid_information.out.guid.info, blob.data, GUID_SIZE); + status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); for (i=0;i<6;i++) { fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8); } -- cgit From 7db3bbc0482789efd68cd043459a1822a439f4da Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 2 Jan 2004 01:04:59 +0000 Subject: Autodetect service_type in cli_tree_full_connection() if the caller passes in NULL. (This used to be commit b63ebaa770940a276ab63583a13d8cc349b6efe6) --- source4/libcli/raw/clitree.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 1e9104308e..1114c8a9c5 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -268,6 +268,12 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, tcon.tconx.in.flags = 0; tcon.tconx.in.password = data_blob(NULL, 0); asprintf(&tcon.tconx.in.path, "\\\\%s\\%s", dest_host, service); + if (!service_type) { + if (strequal(service, "IPC$")) + service_type = "IPC"; + else + service_type = "?????"; + } tcon.tconx.in.device = service_type; status = smb_tree_connect(tree, mem_ctx, &tcon); -- cgit From ff4a1461684bcf57da70067e4d40b0c5e183eed7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 Jan 2004 23:19:07 +0000 Subject: * fixed a segv when -U is not used in smbtorture. * fixed the handling of anonymous logins (This used to be commit 7cbc4ad8710ad33387145bfc9974d0ed4b0fb231) --- source4/libcli/raw/clisession.c | 12 +++++++++--- source4/libcli/raw/clitree.c | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 9d154e10cd..c5d4888089 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -272,7 +272,10 @@ static NTSTATUS smb_raw_session_setup_generic_old(struct cli_session *session, s2.old.in.os = "Unix"; s2.old.in.lanman = "Samba"; - if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + if (!parms->generic.in.password) { + s2.old.in.password = data_blob(NULL, 0); + } else if (session->transport->negotiate.sec_mode & + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { s2.old.in.password = lanman_blob(parms->generic.in.password, session->transport->negotiate.secblob); } else { @@ -318,8 +321,11 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, s2.nt1.in.os = "Unix"; s2.nt1.in.lanman = "Samba"; - if (s2.nt1.in.user[0] && - (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) { + if (!parms->generic.in.password) { + s2.nt1.in.password1 = data_blob(NULL, 0); + s2.nt1.in.password2 = data_blob(NULL, 0); + } else if (session->transport->negotiate.sec_mode & + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { s2.nt1.in.password1 = lanman_blob(parms->generic.in.password, session->transport->negotiate.secblob); s2.nt1.in.password2 = nt_blob(parms->generic.in.password, diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 1114c8a9c5..b35bf67c94 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -238,9 +238,15 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, setup.generic.in.capabilities = CAP_UNICODE | CAP_STATUS32 | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | CAP_W2K_SMBS | CAP_LARGE_READX | CAP_LARGE_WRITEX; - setup.generic.in.password = password; - setup.generic.in.user = user; - setup.generic.in.domain = domain; + if (!user || !user[0]) { + setup.generic.in.password = NULL; + setup.generic.in.user = ""; + setup.generic.in.domain = ""; + } else { + setup.generic.in.password = password; + setup.generic.in.user = user; + setup.generic.in.domain = domain; + } mem_ctx = talloc_init("tcon"); if (!mem_ctx) { -- cgit From 670ccc7d643b8e04743542b4336f6830ac065463 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 1 Feb 2004 11:26:25 +0000 Subject: merge: ldap and krb5 configure tests libads/*.c and libcli/raw/clikrb5.c from 3.0 metze (This used to be commit 64b5bfcd73d7626d6f687a641b11e64821144df7) --- source4/libcli/raw/clikrb5.c | 96 ++++++++++++++++++++++++++---------------- source4/libcli/raw/clispnego.c | 20 ++++++--- 2 files changed, 72 insertions(+), 44 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c index 24da1455de..1d9c02f7f4 100644 --- a/source4/libcli/raw/clikrb5.c +++ b/source4/libcli/raw/clikrb5.c @@ -97,7 +97,9 @@ return ret; } krb5_use_enctype(context, &eblock, enctype); - return krb5_string_to_key(context, &eblock, key, password, &salt); + ret = krb5_string_to_key(context, &eblock, key, password, &salt); + SAFE_FREE(salt.data); + return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) int create_kerberos_key_from_string(krb5_context context, @@ -235,12 +237,12 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -static krb5_error_code krb5_mk_req2(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf) +static krb5_error_code ads_krb5_mk_req(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf) { krb5_error_code retval; krb5_principal server; @@ -255,7 +257,7 @@ static krb5_error_code krb5_mk_req2(krb5_context context, } /* obtain ticket & session key */ - memset((char *)&creds, 0, sizeof(creds)); + ZERO_STRUCT(creds); if ((retval = krb5_copy_principal(context, server, &creds.server))) { DEBUG(1,("krb5_copy_principal failed (%s)\n", error_message(retval))); @@ -305,14 +307,14 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) { krb5_error_code retval; krb5_data packet; krb5_ccache ccdef; krb5_context context; krb5_auth_context auth_context = NULL; - DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, @@ -344,56 +346,76 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) goto failed; } - if ((retval = krb5_mk_req2(context, - &auth_context, - 0, - principal, - ccdef, &packet))) { + if ((retval = ads_krb5_mk_req(context, + &auth_context, + AP_OPTS_USE_SUBKEY, + principal, + ccdef, &packet))) { goto failed; } - ret = data_blob(packet.data, packet.length); + get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); + + *ticket = data_blob(packet.data, packet.length); + /* Hmm, heimdal dooesn't have this - what's the correct call? */ -/* krb5_free_data_contents(context, &packet); */ - krb5_free_context(context); - return ret; +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(context, &packet); +#endif failed: if ( context ) krb5_free_context(context); - return data_blob(NULL, 0); + return retval; } - BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) { -#ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; -#endif + krb5_error_code err; BOOL ret = False; memset(session_key, 0, 16); -#ifdef ENCTYPE_ARCFOUR_HMAC - if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { - if (KRB5_KEY_TYPE(skey) == - ENCTYPE_ARCFOUR_HMAC - && KRB5_KEY_LENGTH(skey) == 16) { - memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - ret = True; - } + if (remote) + err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); + else + err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); + if (err == 0 && skey != NULL) { + DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); + *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + ret = True; + krb5_free_keyblock(context, skey); + } else { + DEBUG(10, ("KRB5 error getting session key %d\n", err)); } -#endif /* ENCTYPE_ARCFOUR_HMAC */ return ret; } + + +#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) + const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) +{ + static krb5_data kdata; + + kdata.data = krb5_principal_get_comp_string(context, principal, i); + kdata.length = strlen(kdata.data); + return &kdata; +} +#endif + #else /* HAVE_KRB5 */ - /* this saves a few linking headaches */ -DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) - { +/* this saves a few linking headaches */ +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) +{ DEBUG(0,("NO KERBEROS SUPPORT\n")); - return data_blob(NULL, 0); - } + return 1; +} #endif diff --git a/source4/libcli/raw/clispnego.c b/source4/libcli/raw/clispnego.c index 53f7eb6e7d..e6cadc466c 100644 --- a/source4/libcli/raw/clispnego.c +++ b/source4/libcli/raw/clispnego.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify @@ -323,24 +323,30 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) +int spnego_gen_negTokenTarg(const char *principal, int time_offset, + DATA_BLOB *targ, + DATA_BLOB *session_key_krb5) { - DATA_BLOB tkt, tkt_wrapped, targ; + int retval; + DATA_BLOB tkt, tkt_wrapped; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal, time_offset); + /* get a kerberos ticket for the service and extract the session key */ + retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); + + if (retval) + return retval; /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ - targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); data_blob_free(&tkt_wrapped); data_blob_free(&tkt); - return targ; + return retval; } -- cgit From 4639eb5a58f8c0906afdc8e8f8f67f82e9547f75 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 8 Feb 2004 00:51:07 +0000 Subject: Convert libcli routines to use cli_tree instead of cli_state. Port smbtorture to use the new interface. Part 2 will be to eliminate cli_state from smbtorture as this is now the only place where it is used. (This used to be commit db1cc96af62ea42837d60592877fc3f93cef143b) --- source4/libcli/clideltree.c | 38 +++++------ source4/libcli/clifile.c | 141 ++++++++++++++++++++++------------------- source4/libcli/clilist.c | 41 ++++++------ source4/libcli/climessage.c | 20 +++--- source4/libcli/clireadwrite.c | 20 +++--- source4/libcli/clisecdesc.c | 8 +-- source4/libcli/clitrans2.c | 22 +++---- source4/libcli/util/clierror.c | 30 +++++---- 8 files changed, 168 insertions(+), 152 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 8769b8dfa7..d28950f136 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -21,7 +21,7 @@ #include "includes.h" struct delete_state { - struct cli_state *cli; + struct cli_tree *tree; int total_deleted; BOOL failed; }; @@ -41,30 +41,30 @@ static void delete_fn(file_info *finfo, const char *name, void *state) asprintf(&s, "%s%s", n, finfo->name); if (finfo->mode & FILE_ATTRIBUTE_READONLY) { - if (!cli_setatr(dstate->cli, s, 0, 0)) { + if (!cli_setatr(dstate->tree, s, 0, 0)) { DEBUG(2,("Failed to remove READONLY on %s - %s\n", - s, cli_errstr(dstate->cli))); + s, cli_errstr(dstate->tree))); } } if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { char *s2; asprintf(&s2, "%s\\*", s); - cli_unlink(dstate->cli, s2); - cli_list(dstate->cli, s2, + cli_unlink(dstate->tree, s2); + cli_list(dstate->tree, s2, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, state); free(s2); - if (!cli_rmdir(dstate->cli, s)) { + if (!cli_rmdir(dstate->tree, s)) { DEBUG(2,("Failed to delete %s - %s\n", - s, cli_errstr(dstate->cli))); + s, cli_errstr(dstate->tree))); dstate->failed = True; } dstate->total_deleted++; } else { - if (!cli_unlink(dstate->cli, s)) { + if (!cli_unlink(dstate->tree, s)) { DEBUG(2,("Failed to delete %s - %s\n", - s, cli_errstr(dstate->cli))); + s, cli_errstr(dstate->tree))); dstate->failed = True; } dstate->total_deleted++; @@ -77,34 +77,34 @@ static void delete_fn(file_info *finfo, const char *name, void *state) recursively descend a tree deleting all files returns the number of files deleted, or -1 on error */ -int cli_deltree(struct cli_state *cli, const char *dname) +int cli_deltree(struct cli_tree *tree, const char *dname) { char *mask; struct delete_state dstate; - dstate.cli = cli; + dstate.tree = tree; dstate.total_deleted = 0; dstate.failed = False; /* it might be a file */ - if (cli_unlink(cli, dname)) { + if (cli_unlink(tree, dname)) { return 1; } - if (NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_OBJECT_NAME_NOT_FOUND) || - NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_OBJECT_PATH_NOT_FOUND) || - NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_NO_SUCH_FILE)) { + if (NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) || + NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) || + NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) { return 0; } asprintf(&mask, "%s\\*", dname); - cli_unlink(cli, mask); - cli_list(dstate.cli, mask, + cli_unlink(dstate.tree, mask); + cli_list(dstate.tree, mask, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, &dstate); free(mask); - if (!cli_rmdir(dstate.cli, dname)) { + if (!cli_rmdir(dstate.tree, dname)) { DEBUG(2,("Failed to delete %s - %s\n", - dname, cli_errstr(dstate.cli))); + dname, cli_errstr(dstate.tree))); return -1; } dstate.total_deleted++; diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 27ead40740..6606455e49 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -26,7 +26,7 @@ Hard/Symlink a file (UNIX extensions). ****************************************************************************/ -static BOOL cli_link_internal(struct cli_state *cli, +static BOOL cli_link_internal(struct cli_tree *tree, const char *fname_src, const char *fname_dst, BOOL hard_link) { @@ -43,7 +43,7 @@ static BOOL cli_link_internal(struct cli_state *cli, parms.unix_link.in.link_dest = fname_dst; } - status = smb_raw_setpathinfo(cli->tree, &parms); + status = smb_raw_setpathinfo(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -79,24 +79,27 @@ static uint32 unix_perms_to_wire(mode_t perms) /**************************************************************************** Symlink a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +BOOL cli_unix_symlink(struct cli_tree *tree, const char *fname_src, + const char *fname_dst) { - return cli_link_internal(cli, fname_src, fname_dst, False); + return cli_link_internal(tree, fname_src, fname_dst, False); } /**************************************************************************** Hard a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +BOOL cli_unix_hardlink(struct cli_tree *tree, const char *fname_src, + const char *fname_dst) { - return cli_link_internal(cli, fname_src, fname_dst, True); + return cli_link_internal(tree, fname_src, fname_dst, True); } /**************************************************************************** Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ -static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, +static BOOL cli_unix_chmod_chown_internal(struct cli_tree *tree, + const char *fname, uint32 mode, uint32 uid, uint32 gid) { union smb_setfileinfo parms; @@ -108,7 +111,7 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna parms.unix_basic.in.gid = gid; parms.unix_basic.in.mode = mode; - status = smb_raw_setpathinfo(cli->tree, &parms); + status = smb_raw_setpathinfo(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -117,25 +120,30 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna chmod a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) +BOOL cli_unix_chmod(struct cli_tree *tree, const char *fname, mode_t mode) { - return cli_unix_chmod_chown_internal(cli, fname, - unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); + return cli_unix_chmod_chown_internal(tree, fname, + unix_perms_to_wire(mode), + SMB_UID_NO_CHANGE, + SMB_GID_NO_CHANGE); } /**************************************************************************** chown a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) +BOOL cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, + gid_t gid) { - return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); + return cli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE, + (uint32)uid, (uint32)gid); } /**************************************************************************** Rename a file. ****************************************************************************/ -BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) +BOOL cli_rename(struct cli_tree *tree, const char *fname_src, + const char *fname_dst) { union smb_rename parms; @@ -143,14 +151,14 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ parms.rename.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; parms.rename.in.pattern1 = fname_src; parms.rename.in.pattern2 = fname_dst; - return NT_STATUS_IS_OK(smb_raw_rename(cli->tree, &parms)); + return NT_STATUS_IS_OK(smb_raw_rename(tree, &parms)); } /**************************************************************************** Delete a file. ****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, const char *fname) +BOOL cli_unlink(struct cli_tree *tree, const char *fname) { struct smb_unlink parms; @@ -160,39 +168,39 @@ BOOL cli_unlink(struct cli_state *cli, const char *fname) } else { parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; } - return NT_STATUS_IS_OK(smb_raw_unlink(cli->tree, &parms)); + return NT_STATUS_IS_OK(smb_raw_unlink(tree, &parms)); } /**************************************************************************** Create a directory. ****************************************************************************/ -BOOL cli_mkdir(struct cli_state *cli, const char *dname) +BOOL cli_mkdir(struct cli_tree *tree, const char *dname) { union smb_mkdir parms; parms.mkdir.level = RAW_MKDIR_MKDIR; parms.mkdir.in.path = dname; - return NT_STATUS_IS_OK(smb_raw_mkdir(cli->tree, &parms)); + return NT_STATUS_IS_OK(smb_raw_mkdir(tree, &parms)); } /**************************************************************************** Remove a directory. ****************************************************************************/ -BOOL cli_rmdir(struct cli_state *cli, const char *dname) +BOOL cli_rmdir(struct cli_tree *tree, const char *dname) { struct smb_rmdir parms; parms.in.path = dname; - return NT_STATUS_IS_OK(smb_raw_rmdir(cli->tree, &parms)); + return NT_STATUS_IS_OK(smb_raw_rmdir(tree, &parms)); } /**************************************************************************** Set or clear the delete on close flag. ****************************************************************************/ -BOOL cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) +BOOL cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) { union smb_setfileinfo parms; NTSTATUS status; @@ -201,7 +209,7 @@ BOOL cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) parms.disposition_info.file.fnum = fnum; parms.disposition_info.in.delete_on_close = flag; - status = smb_raw_setfileinfo(cli->tree, &parms); + status = smb_raw_setfileinfo(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -211,11 +219,11 @@ BOOL cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) Create/open a file - exposing the full horror of the NT API :-). Used in CIFS-on-CIFS NTVFS. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, const char *fname, - uint32 CreatFlags, uint32 DesiredAccess, - uint32 FileAttributes, uint32 ShareAccess, - uint32 CreateDisposition, uint32 CreateOptions, - uint8 SecurityFlags) +int cli_nt_create_full(struct cli_tree *tree, const char *fname, + uint32 CreatFlags, uint32 DesiredAccess, + uint32 FileAttributes, uint32 ShareAccess, + uint32 CreateDisposition, uint32 CreateOptions, + uint8 SecurityFlags) { union smb_open open_parms; TALLOC_CTX *mem_ctx; @@ -237,7 +245,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, open_parms.ntcreatex.in.security_flags = SecurityFlags; open_parms.ntcreatex.in.fname = fname; - status = smb_raw_open(cli->tree, mem_ctx, &open_parms); + status = smb_raw_open(tree, mem_ctx, &open_parms); talloc_destroy(mem_ctx); if (NT_STATUS_IS_OK(status)) { @@ -252,7 +260,8 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, Open a file (using SMBopenx) WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ -int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) +int cli_open(struct cli_tree *tree, const char *fname, int flags, + int share_mode) { union smb_open open_parms; unsigned openfn=0; @@ -303,7 +312,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode open_parms.openx.in.timeout = 0; open_parms.openx.in.fname = fname; - status = smb_raw_open(cli->tree, mem_ctx, &open_parms); + status = smb_raw_open(tree, mem_ctx, &open_parms); talloc_destroy(mem_ctx); if (NT_STATUS_IS_OK(status)) { @@ -317,7 +326,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode /**************************************************************************** Close a file. ****************************************************************************/ -BOOL cli_close(struct cli_state *cli, int fnum) +BOOL cli_close(struct cli_tree *tree, int fnum) { union smb_close close_parms; NTSTATUS status; @@ -325,7 +334,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) close_parms.close.level = RAW_CLOSE_CLOSE; close_parms.close.in.fnum = fnum; close_parms.close.in.write_time = 0; - status = smb_raw_close(cli->tree, &close_parms); + status = smb_raw_close(tree, &close_parms); return NT_STATUS_IS_OK(status); } @@ -333,7 +342,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ -NTSTATUS cli_locktype(struct cli_state *cli, int fnum, +NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, uint32 offset, uint32 len, int timeout, unsigned char locktype) { union smb_lock parms; @@ -346,12 +355,12 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; parms.lockx.in.lock_cnt = 1; - lock[0].pid = cli->session->pid; + lock[0].pid = tree->session->pid; lock[0].offset = offset; lock[0].count = len; parms.lockx.in.locks = &lock[0]; - status = smb_raw_lock(cli->tree, &parms); + status = smb_raw_lock(tree, &parms); return status; } @@ -360,7 +369,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, /**************************************************************************** Lock a file. ****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, +BOOL cli_lock(struct cli_tree *tree, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { union smb_lock parms; @@ -373,12 +382,12 @@ BOOL cli_lock(struct cli_state *cli, int fnum, parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; parms.lockx.in.lock_cnt = 1; - lock[0].pid = cli->session->pid; + lock[0].pid = tree->session->pid; lock[0].offset = offset; lock[0].count = len; parms.lockx.in.locks = &lock[0]; - status = smb_raw_lock(cli->tree, &parms); + status = smb_raw_lock(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -387,7 +396,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, /**************************************************************************** Unlock a file. ****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) +BOOL cli_unlock(struct cli_tree *tree, int fnum, uint32 offset, uint32 len) { union smb_lock parms; struct smb_lock_entry lock[1]; @@ -399,12 +408,12 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) parms.lockx.in.timeout = 0; parms.lockx.in.ulock_cnt = 1; parms.lockx.in.lock_cnt = 0; - lock[0].pid = cli->session->pid; + lock[0].pid = tree->session->pid; lock[0].offset = offset; lock[0].count = len; parms.lockx.in.locks = &lock[0]; - status = smb_raw_lock(cli->tree, &parms); + status = smb_raw_lock(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -412,7 +421,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) /**************************************************************************** Lock a file with 64 bit offsets. ****************************************************************************/ -BOOL cli_lock64(struct cli_state *cli, int fnum, +BOOL cli_lock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, SMB_OFF_T len, int timeout, enum brl_type lock_type) { union smb_lock parms; @@ -420,8 +429,8 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, struct smb_lock_entry lock[1]; NTSTATUS status; - if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { - return cli_lock(cli, fnum, offset, len, timeout, lock_type); + if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) { + return cli_lock(tree, fnum, offset, len, timeout, lock_type); } parms.lockx.level = RAW_LOCK_LOCKX; @@ -433,12 +442,12 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; parms.lockx.in.lock_cnt = 1; - lock[0].pid = cli->session->pid; + lock[0].pid = tree->session->pid; lock[0].offset = offset; lock[0].count = len; parms.lockx.in.locks = &lock[0]; - status = smb_raw_lock(cli->tree, &parms); + status = smb_raw_lock(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -447,14 +456,14 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, /**************************************************************************** Unlock a file with 64 bit offsets. ****************************************************************************/ -BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_OFF_T offset, SMB_OFF_T len) +BOOL cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, SMB_OFF_T len) { union smb_lock parms; struct smb_lock_entry lock[1]; NTSTATUS status; - if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { - return cli_unlock(cli, fnum, offset, len); + if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) { + return cli_unlock(tree, fnum, offset, len); } parms.lockx.level = RAW_LOCK_LOCKX; @@ -463,12 +472,12 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_OFF_T offset, SMB_OFF_T l parms.lockx.in.timeout = 0; parms.lockx.in.ulock_cnt = 1; parms.lockx.in.lock_cnt = 0; - lock[0].pid = cli->session->pid; + lock[0].pid = tree->session->pid; lock[0].offset = offset; lock[0].count = len; parms.lockx.in.locks = &lock[0]; - status = smb_raw_lock(cli->tree, &parms); + status = smb_raw_lock(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -477,9 +486,9 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_OFF_T offset, SMB_OFF_T l /**************************************************************************** Do a SMBgetattrE call. ****************************************************************************/ -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) +BOOL cli_getattrE(struct cli_tree *tree, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time) { union smb_fileinfo parms; NTSTATUS status; @@ -487,7 +496,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, parms.getattre.level = RAW_FILEINFO_GETATTRE; parms.getattre.in.fnum = fd; - status = smb_raw_fileinfo(cli->tree, NULL, &parms); + status = smb_raw_fileinfo(tree, NULL, &parms); if (!NT_STATUS_IS_OK(status)) return False; @@ -518,7 +527,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, /**************************************************************************** Do a SMBgetatr call ****************************************************************************/ -BOOL cli_getatr(struct cli_state *cli, const char *fname, +BOOL cli_getatr(struct cli_tree *tree, const char *fname, uint16 *attr, size_t *size, time_t *t) { union smb_fileinfo parms; @@ -527,7 +536,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, parms.getattr.level = RAW_FILEINFO_GETATTR; parms.getattr.in.fname = fname; - status = smb_raw_pathinfo(cli->tree, NULL, &parms); + status = smb_raw_pathinfo(tree, NULL, &parms); if (!NT_STATUS_IS_OK(status)) { return False; @@ -552,7 +561,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, /**************************************************************************** Do a SMBsetatr call. ****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 mode, time_t t) +BOOL cli_setatr(struct cli_tree *tree, const char *fname, uint16 mode, time_t t) { union smb_setfileinfo parms; NTSTATUS status; @@ -562,7 +571,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 mode, time_t t) parms.setattr.in.write_time = t; parms.setattr.file.fname = fname; - status = smb_raw_setpathinfo(cli->tree, &parms); + status = smb_raw_setpathinfo(tree, &parms); return NT_STATUS_IS_OK(status); } @@ -571,7 +580,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 mode, time_t t) /**************************************************************************** Check for existence of a dir. ****************************************************************************/ -BOOL cli_chkpath(struct cli_state *cli, const char *path) +BOOL cli_chkpath(struct cli_tree *tree, const char *path) { struct smb_chkpath parms; char *path2; @@ -586,7 +595,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) parms.in.path = path2; - status = smb_raw_chkpath(cli->tree, &parms); + status = smb_raw_chkpath(tree, &parms); free(path2); @@ -597,7 +606,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) /**************************************************************************** Query disk space. ****************************************************************************/ -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) +BOOL cli_dskattr(struct cli_tree *tree, int *bsize, int *total, int *avail) { union smb_fsinfo fsinfo_parms; TALLOC_CTX *mem_ctx; @@ -606,7 +615,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) mem_ctx = talloc_init("cli_dskattr"); fsinfo_parms.dskattr.level = RAW_QFS_DSKATTR; - status = smb_raw_fsinfo(cli->tree, mem_ctx, &fsinfo_parms); + status = smb_raw_fsinfo(tree, mem_ctx, &fsinfo_parms); if (NT_STATUS_IS_OK(status)) { *bsize = fsinfo_parms.dskattr.out.block_size; *total = fsinfo_parms.dskattr.out.units_total; @@ -622,7 +631,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) /**************************************************************************** Create and open a temporary file. ****************************************************************************/ -int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) +int cli_ctemp(struct cli_tree *tree, const char *path, char **tmp_path) { union smb_open open_parms; TALLOC_CTX *mem_ctx; @@ -635,7 +644,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) open_parms.ctemp.in.attrib = 0; open_parms.ctemp.in.directory = path; - status = smb_raw_open(cli->tree, mem_ctx, &open_parms); + status = smb_raw_open(tree, mem_ctx, &open_parms); if (tmp_path) { *tmp_path = strdup(open_parms.ctemp.out.name); } diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 425a6002cc..ee0357579c 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -81,8 +81,9 @@ static BOOL cli_list_new_callback(void *private, union smb_search_data *file) return True; } -int cli_list_new(struct cli_state *cli, const char *Mask, uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *caller_state) +int cli_list_new(struct cli_tree *tree, const char *Mask, uint16 attribute, + void (*fn)(file_info *, const char *, void *), + void *caller_state) { union smb_search_first first_parms; union smb_search_next next_parms; @@ -104,7 +105,7 @@ int cli_list_new(struct cli_state *cli, const char *Mask, uint16 attribute, mask = talloc_strdup(state.mem_ctx, Mask); - if (cli->transport->negotiate.capabilities & CAP_NT_SMBS) { + if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) { level = RAW_SEARCH_BOTH_DIRECTORY_INFO; } else { level = RAW_SEARCH_STANDARD; @@ -122,7 +123,7 @@ int cli_list_new(struct cli_state *cli, const char *Mask, uint16 attribute, first_parms.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE_IF_END; first_parms.t2ffirst.in.storage_type = 0; - status = smb_raw_search_first(cli->tree, + status = smb_raw_search_first(tree, state.mem_ctx, &first_parms, (void*)&state, cli_list_new_callback); if (!NT_STATUS_IS_OK(status)) { @@ -148,7 +149,7 @@ int cli_list_new(struct cli_state *cli, const char *Mask, uint16 attribute, next_parms.t2fnext.in.resume_key = 0; next_parms.t2fnext.in.flags = FLAG_TRANS2_FIND_CONTINUE | FLAG_TRANS2_FIND_CLOSE_IF_END; - status = smb_raw_search_next(cli->tree, + status = smb_raw_search_next(tree, state.mem_ctx, &next_parms, (void*)&state, @@ -223,8 +224,9 @@ static BOOL cli_list_old_callback(void *private, union smb_search_data *file) return True; } -int cli_list_old(struct cli_state *cli, const char *Mask, uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *caller_state) +int cli_list_old(struct cli_tree *tree, const char *Mask, uint16 attribute, + void (*fn)(file_info *, const char *, void *), + void *caller_state) { union smb_search_first first_parms; union smb_search_next next_parms; @@ -254,10 +256,11 @@ int cli_list_old(struct cli_state *cli, const char *Mask, uint16 attribute, first_parms.search_first.in.search_attrib = attribute; first_parms.search_first.in.pattern = mask; - status = smb_raw_search_first(cli->tree, state.mem_ctx, - &first_parms, - (void*)&state, - cli_list_old_callback); + status = smb_raw_search_first(tree, state.mem_ctx, + &first_parms, + (void*)&state, + cli_list_old_callback); + if (!NT_STATUS_IS_OK(status)) { talloc_destroy(state.mem_ctx); return -1; @@ -274,10 +277,10 @@ int cli_list_old(struct cli_state *cli, const char *Mask, uint16 attribute, next_parms.search_next.in.search_attrib = attribute; next_parms.search_next.in.search_id = state.status; - status = smb_raw_search_next(cli->tree, state.mem_ctx, - &next_parms, - (void*)&state, - cli_list_old_callback); + status = smb_raw_search_next(tree, state.mem_ctx, + &next_parms, + (void*)&state, + cli_list_old_callback); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(state.mem_ctx); @@ -304,10 +307,10 @@ int cli_list_old(struct cli_state *cli, const char *Mask, uint16 attribute, This auto-switches between old and new style. ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list(struct cli_tree *tree, const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - if (cli->transport->negotiate.protocol <= PROTOCOL_LANMAN1) - return cli_list_old(cli, Mask, attribute, fn, state); - return cli_list_new(cli, Mask, attribute, fn, state); + if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) + return cli_list_old(tree, Mask, attribute, fn, state); + return cli_list_new(tree, Mask, attribute, fn, state); } diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index ad5d41545b..6470f4c154 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -25,17 +25,17 @@ /**************************************************************************** start a message sequence ****************************************************************************/ -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp) +BOOL cli_message_start(struct cli_tree *tree, char *host, char *username, + int *grp) { struct cli_request *req; - req = cli_request_setup(cli->tree, SMBsendstrt, 0, 0); + req = cli_request_setup(tree, SMBsendstrt, 0, 0); cli_req_append_string(req, username, STR_TERMINATE); cli_req_append_string(req, host, STR_TERMINATE); if (!cli_request_send(req) || !cli_request_receive(req) || - cli_is_error(cli)) { + cli_is_error(tree)) { cli_request_destroy(req); return False; } @@ -50,18 +50,18 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, /**************************************************************************** send a message ****************************************************************************/ -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +BOOL cli_message_text(struct cli_tree *tree, char *msg, int len, int grp) { struct cli_request *req; - req = cli_request_setup(cli->tree, SMBsendtxt, 1, 0); + req = cli_request_setup(tree, SMBsendtxt, 1, 0); SSVAL(req->out.vwv, VWV(0), grp); cli_req_append_bytes(req, msg, len); if (!cli_request_send(req) || !cli_request_receive(req) || - cli_is_error(cli)) { + cli_is_error(tree)) { cli_request_destroy(req); return False; } @@ -73,16 +73,16 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) /**************************************************************************** end a message ****************************************************************************/ -BOOL cli_message_end(struct cli_state *cli, int grp) +BOOL cli_message_end(struct cli_tree *tree, int grp) { struct cli_request *req; - req = cli_request_setup(cli->tree, SMBsendend, 1, 0); + req = cli_request_setup(tree, SMBsendend, 1, 0); SSVAL(req->out.vwv, VWV(0), grp); if (!cli_request_send(req) || !cli_request_receive(req) || - cli_is_error(cli)) { + cli_is_error(tree)) { cli_request_destroy(req); return False; } diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 1e6c0fc064..7b47281e2c 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -24,7 +24,8 @@ /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ -ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +ssize_t cli_read(struct cli_tree *tree, int fnum, char *buf, off_t offset, + size_t size) { union smb_read parms; int readsize; @@ -41,7 +42,8 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ * Set readsize to the maximum size we can handle in one readX, * rounded down to a multiple of 1024. */ - readsize = (cli->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; + readsize = (tree->session->transport->negotiate.max_xmit - + (MIN_SMB_SIZE+32)) & ~1023; if (readsize > 0xFFFF) readsize = 0xFFFF; while (total < size) { @@ -55,7 +57,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ parms.readx.in.remaining = size - total; parms.readx.out.data = buf + total; - status = smb_raw_read(cli->tree, &parms); + status = smb_raw_read(tree, &parms); if (!NT_STATUS_IS_OK(status)) { return -1; @@ -80,12 +82,12 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ 0x0004 use raw named pipe protocol 0x0008 start of message mode named pipe protocol ****************************************************************************/ -ssize_t cli_write(struct cli_state *cli, +ssize_t cli_write(struct cli_tree *tree, int fnum, uint16 write_mode, const char *buf, off_t offset, size_t size) { union smb_write parms; - int block = (cli->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; + int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; ssize_t total = 0; if (size == 0) { @@ -109,7 +111,7 @@ ssize_t cli_write(struct cli_state *cli, parms.writex.in.count = block; parms.writex.in.data = buf; - status = smb_raw_write(cli->tree, &parms); + status = smb_raw_write(tree, &parms); if (!NT_STATUS_IS_OK(status)) { return -1; @@ -126,7 +128,7 @@ ssize_t cli_write(struct cli_state *cli, /**************************************************************************** write to a file using a SMBwrite and not bypassing 0 byte writes ****************************************************************************/ -ssize_t cli_smbwrite(struct cli_state *cli, +ssize_t cli_smbwrite(struct cli_tree *tree, int fnum, char *buf, off_t offset, size_t size1) { union smb_write parms; @@ -136,7 +138,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, parms.write.in.remaining = 0; do { - size_t size = MIN(size1, cli->transport->negotiate.max_xmit - 48); + size_t size = MIN(size1, tree->session->transport->negotiate.max_xmit - 48); if (size > 0xFFFF) size = 0xFFFF; parms.write.in.fnum = fnum; @@ -144,7 +146,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, parms.write.in.count = size; parms.write.in.data = buf + total; - if (NT_STATUS_IS_ERR(smb_raw_write(cli->tree, &parms))) + if (NT_STATUS_IS_ERR(smb_raw_write(tree, &parms))) return -1; size = parms.write.out.nwritten; diff --git a/source4/libcli/clisecdesc.c b/source4/libcli/clisecdesc.c index 66272251ec..7f3ec0f6bf 100644 --- a/source4/libcli/clisecdesc.c +++ b/source4/libcli/clisecdesc.c @@ -24,7 +24,7 @@ /**************************************************************************** query the security descriptor for a open file ****************************************************************************/ -SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, +SEC_DESC *cli_query_secdesc(struct cli_tree *tree, int fnum, TALLOC_CTX *mem_ctx) { struct smb_nttrans parms; @@ -48,7 +48,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, parms.in.params = param_blob; parms.in.data = data_blob(NULL, 0); - status = smb_raw_nttrans(cli->tree, mem_ctx, &parms); + status = smb_raw_nttrans(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); @@ -72,7 +72,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, /**************************************************************************** set the security descriptor for a open file ****************************************************************************/ -BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) +BOOL cli_set_secdesc(struct cli_tree *tree, int fnum, SEC_DESC *sd) { struct smb_nttrans parms; char param[8]; @@ -106,7 +106,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) parms.in.params = param_blob; parms.in.data = data_blob(NULL, 0); - status = smb_raw_nttrans(cli->tree, mem_ctx, &parms); + status = smb_raw_nttrans(tree, mem_ctx, &parms); if (NT_STATUS_IS_ERR(status)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 0ceac925f7..c8f7db5a9d 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -23,7 +23,7 @@ /**************************************************************************** send a qpathinfo call ****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, +BOOL cli_qpathinfo(struct cli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16 *mode) { @@ -37,7 +37,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, parms.standard.level = RAW_FILEINFO_STANDARD; parms.standard.in.fname = fname; - status = smb_raw_pathinfo(cli->tree, mem_ctx, &parms); + status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_destroy(mem_ctx); if (!NT_STATUS_IS_OK(status)) { return False; @@ -65,7 +65,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, +BOOL cli_qpathinfo2(struct cli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) @@ -80,7 +80,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, parms.all_info.level = RAW_FILEINFO_ALL_INFO; parms.all_info.in.fname = fname; - status = smb_raw_pathinfo(cli->tree, mem_ctx, &parms); + status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_destroy(mem_ctx); if (!NT_STATUS_IS_OK(status)) { return False; @@ -112,7 +112,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, /**************************************************************************** send a qfileinfo QUERY_FILE_NAME_INFO call ****************************************************************************/ -BOOL cli_qfilename(struct cli_state *cli, int fnum, +BOOL cli_qfilename(struct cli_tree *tree, int fnum, const char **name) { union smb_fileinfo parms; @@ -125,7 +125,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, parms.name_info.level = RAW_FILEINFO_NAME_INFO; parms.name_info.in.fnum = fnum; - status = smb_raw_fileinfo(cli->tree, mem_ctx, &parms); + status = smb_raw_fileinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); *name = NULL; @@ -143,7 +143,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, /**************************************************************************** send a qfileinfo call ****************************************************************************/ -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, +BOOL cli_qfileinfo(struct cli_tree *tree, int fnum, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) @@ -158,7 +158,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, parms.all_info.level = RAW_FILEINFO_ALL_INFO; parms.all_info.in.fnum = fnum; - status = smb_raw_fileinfo(cli->tree, mem_ctx, &parms); + status = smb_raw_fileinfo(tree, mem_ctx, &parms); talloc_destroy(mem_ctx); if (!NT_STATUS_IS_OK(status)) { return False; @@ -193,7 +193,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, /**************************************************************************** send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call ****************************************************************************/ -NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, +NTSTATUS cli_qpathinfo_alt_name(struct cli_tree *tree, const char *fname, const char **alt_name) { union smb_fileinfo parms; @@ -206,11 +206,11 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, mem_ctx = talloc_init("cli_qpathinfo_alt_name"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; - status = smb_raw_pathinfo(cli->tree, mem_ctx, &parms); + status = smb_raw_pathinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); *alt_name = NULL; - return cli_nt_error(cli); + return cli_nt_error(tree); } if (!parms.alt_name_info.out.fname.s) { diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index 4fa1daa3be..97436d2106 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -25,14 +25,15 @@ /*************************************************************************** Return an error message from the last response ****************************************************************************/ -const char *cli_errstr(struct cli_state *cli) +const char *cli_errstr(struct cli_tree *tree) { - switch (cli->transport->error.etype) { + switch (tree->session->transport->error.etype) { case ETYPE_DOS: - return dos_errstr(cli->transport->error.e.dos.eclass, - cli->transport->error.e.dos.ecode); + return dos_errstr( + tree->session->transport->error.e.dos.eclass, + tree->session->transport->error.e.dos.ecode); case ETYPE_NT: - return nt_errstr(cli->transport->error.e.nt_status); + return nt_errstr(tree->session->transport->error.e.nt_status); case ETYPE_SOCKET: return "socket_error"; @@ -48,15 +49,16 @@ const char *cli_errstr(struct cli_state *cli) /* Return the 32-bit NT status code from the last packet */ -NTSTATUS cli_nt_error(struct cli_state *cli) +NTSTATUS cli_nt_error(struct cli_tree *tree) { - switch (cli->transport->error.etype) { + switch (tree->session->transport->error.etype) { case ETYPE_NT: - return cli->transport->error.e.nt_status; + return tree->session->transport->error.e.nt_status; case ETYPE_DOS: - return dos_to_ntstatus(cli->transport->error.e.dos.eclass, - cli->transport->error.e.dos.ecode); + return dos_to_ntstatus( + tree->session->transport->error.e.dos.eclass, + tree->session->transport->error.e.dos.ecode); case ETYPE_SOCKET: return NT_STATUS_UNSUCCESSFUL; @@ -87,13 +89,13 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) /* Return true if the last packet was an error */ -BOOL cli_is_error(struct cli_state *cli) +BOOL cli_is_error(struct cli_tree *tree) { - return NT_STATUS_IS_ERR(cli_nt_error(cli)); + return NT_STATUS_IS_ERR(cli_nt_error(tree)); } /* Return true if the last error was a DOS error */ -BOOL cli_is_dos_error(struct cli_state *cli) +BOOL cli_is_dos_error(struct cli_tree *tree) { - return cli->transport->error.etype == ETYPE_DOS; + return tree->session->transport->error.etype == ETYPE_DOS; } -- cgit From 078cced5ec1026432f5df275a7023db70a62693e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Feb 2004 10:22:12 +0000 Subject: - modified the dcerpc client security code to be generic, so ntlmssp and schannel are both instances of possible security modules - added schannel sign and sign/seal support to the dcerpc client code. You select it with binding options of "schannel,sign" or "schannel,seal". (This used to be commit 05db0b9d942cad8f1dd574dc35b759e5e79d4195) --- source4/libcli/auth/schannel.c | 309 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/auth/schannel.h | 35 +++++ 2 files changed, 344 insertions(+) create mode 100644 source4/libcli/auth/schannel.c create mode 100644 source4/libcli/auth/schannel.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c new file mode 100644 index 0000000000..e5a786ff24 --- /dev/null +++ b/source4/libcli/auth/schannel.c @@ -0,0 +1,309 @@ +/* + Unix SMB/CIFS implementation. + + schannel library code + + Copyright (C) Andrew Tridgell 2004 + + 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" + +/******************************************************************* + Encode or Decode the sequence number (which is symmetric) + ********************************************************************/ +static void netsec_deal_with_seq_num(struct schannel_state *state, + const uchar packet_digest[8], + uchar seq_num[8]) +{ + static const uchar zeros[4]; + uchar sequence_key[16]; + uchar digest1[16]; + + hmac_md5(state->session_key, zeros, sizeof(zeros), digest1); + hmac_md5(digest1, packet_digest, 8, sequence_key); + SamOEMhash(seq_num, sequence_key, 8); + + state->seq_num++; +} + + +/******************************************************************* + Calculate the key with which to encode the data payload + ********************************************************************/ +static void netsec_get_sealing_key(const uchar session_key[16], + const uchar seq_num[8], + uchar sealing_key[16]) +{ + static const uchar zeros[4]; + uchar digest2[16]; + uchar sess_kf0[16]; + int i; + + for (i = 0; i < 16; i++) { + sess_kf0[i] = session_key[i] ^ 0xf0; + } + + hmac_md5(sess_kf0, zeros, 4, digest2); + hmac_md5(digest2, seq_num, 8, sealing_key); +} + + +/******************************************************************* + Create a digest over the entire packet (including the data), and + MD5 it with the session key. + ********************************************************************/ +static void schannel_digest(const uchar sess_key[16], + const uchar netsec_sig[8], + const uchar *confounder, + const uchar *data, size_t data_len, + uchar digest_final[16]) +{ + uchar packet_digest[16]; + static const uchar zeros[4]; + struct MD5Context ctx; + + MD5Init(&ctx); + MD5Update(&ctx, zeros, 4); + MD5Update(&ctx, netsec_sig, 8); + if (confounder) { + MD5Update(&ctx, confounder, 8); + } + MD5Update(&ctx, data, data_len); + MD5Final(packet_digest, &ctx); + + hmac_md5(sess_key, packet_digest, sizeof(packet_digest), digest_final); +} + + +/* + unseal a packet +*/ +NTSTATUS schannel_unseal_packet(struct schannel_state *state, + uchar *data, size_t length, + DATA_BLOB *sig) +{ + uchar digest_final[16]; + uchar confounder[8]; + uchar seq_num[8]; + uchar sealing_key[16]; + static const uchar netsec_sig[8] = NETSEC_SEAL_SIGNATURE; + + if (sig->length != 32) { + return NT_STATUS_ACCESS_DENIED; + } + + memcpy(confounder, sig->data+24, 8); + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0:0x80); + + netsec_get_sealing_key(state->session_key, seq_num, sealing_key); + SamOEMhash(confounder, sealing_key, 8); + SamOEMhash(data, sealing_key, length); + + schannel_digest(state->session_key, + netsec_sig, confounder, + data, length, digest_final); + + if (memcmp(digest_final, sig->data+16, 8) != 0) { + dump_data_pw("calc digest:", digest_final, 8); + dump_data_pw("wire digest:", sig->data+16, 8); + return NT_STATUS_ACCESS_DENIED; + } + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + if (memcmp(seq_num, sig->data+8, 8) != 0) { + dump_data_pw("calc seq num:", seq_num, 8); + dump_data_pw("wire seq num:", sig->data+8, 8); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + +/* + check the signature on a packet +*/ +NTSTATUS schannel_check_packet(struct schannel_state *state, + const uchar *data, size_t length, + const DATA_BLOB *sig) +{ + uchar digest_final[16]; + uchar seq_num[8]; + static const uchar netsec_sig[8] = NETSEC_SIGN_SIGNATURE; + + if (sig->length != 32) { + return NT_STATUS_ACCESS_DENIED; + } + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0:0x80); + + dump_data_pw("seq_num:\n", seq_num, 8); + dump_data_pw("sess_key:\n", state->session_key, 16); + + schannel_digest(state->session_key, + netsec_sig, NULL, + data, length, digest_final); + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + if (memcmp(seq_num, sig->data+8, 8) != 0) { + dump_data_pw("calc seq num:", seq_num, 8); + dump_data_pw("wire seq num:", sig->data+8, 8); + return NT_STATUS_ACCESS_DENIED; + } + + if (memcmp(digest_final, sig->data+16, 8) != 0) { + dump_data_pw("calc digest:", digest_final, 8); + dump_data_pw("wire digest:", sig->data+16, 8); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + + +/* + seal a packet +*/ +NTSTATUS schannel_seal_packet(struct schannel_state *state, + uchar *data, size_t length, + DATA_BLOB *sig) +{ + uchar digest_final[16]; + uchar confounder[8]; + uchar seq_num[8]; + uchar sealing_key[16]; + static const uchar netsec_sig[8] = NETSEC_SEAL_SIGNATURE; + + generate_random_buffer(confounder, 8, False); + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0x80:0); + + schannel_digest(state->session_key, + netsec_sig, confounder, + data, length, digest_final); + + netsec_get_sealing_key(state->session_key, seq_num, sealing_key); + SamOEMhash(confounder, sealing_key, 8); + SamOEMhash(data, sealing_key, length); + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + if (!state->signature.data) { + state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); + if (!state->signature.data) { + return NT_STATUS_NO_MEMORY; + } + } + (*sig) = state->signature; + + memcpy(sig->data, netsec_sig, 8); + memcpy(sig->data+8, seq_num, 8); + memcpy(sig->data+16, digest_final, 8); + memcpy(sig->data+24, confounder, 8); + + dump_data_pw("signature:", sig->data+ 0, 8); + dump_data_pw("seq_num :", sig->data+ 8, 8); + dump_data_pw("digest :", sig->data+16, 8); + dump_data_pw("confound :", sig->data+24, 8); + + return NT_STATUS_OK; +} + + +/* + sign a packet +*/ +NTSTATUS schannel_sign_packet(struct schannel_state *state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + uchar digest_final[16]; + uchar seq_num[8]; + static const uchar netsec_sig[8] = NETSEC_SIGN_SIGNATURE; + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0x80:0); + + schannel_digest(state->session_key, + netsec_sig, NULL, + data, length, digest_final); + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + if (!state->signature.data) { + state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); + if (!state->signature.data) { + return NT_STATUS_NO_MEMORY; + } + } + (*sig) = state->signature; + + memcpy(sig->data, netsec_sig, 8); + memcpy(sig->data+8, seq_num, 8); + memcpy(sig->data+16, digest_final, 8); + memset(sig->data+24, 0, 8); + + dump_data_pw("signature:", sig->data+ 0, 8); + dump_data_pw("seq_num :", sig->data+ 8, 8); + dump_data_pw("digest :", sig->data+16, 8); + dump_data_pw("confound :", sig->data+24, 8); + + return NT_STATUS_OK; +} + +/* + destroy an schannel context + */ +void schannel_end(struct schannel_state **state) +{ + talloc_destroy((*state)->mem_ctx); + (*state) = NULL; +} + +/* + create an schannel context state +*/ +NTSTATUS schannel_start(struct schannel_state **state, + uint8 session_key[16], + BOOL initiator) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("schannel_state"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + (*state) = talloc_p(mem_ctx, struct schannel_state); + if (!(*state)) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*state)->mem_ctx = mem_ctx; + memcpy((*state)->session_key, session_key, 16); + (*state)->initiator = initiator; + (*state)->signature = data_blob(NULL, 0); + (*state)->seq_num = 0; + + return NT_STATUS_OK; +} diff --git a/source4/libcli/auth/schannel.h b/source4/libcli/auth/schannel.h new file mode 100644 index 0000000000..7b710d7cb9 --- /dev/null +++ b/source4/libcli/auth/schannel.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + schannel library code + + Copyright (C) Andrew Tridgell 2004 + + 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" + +struct schannel_state { + TALLOC_CTX *mem_ctx; + uint8 session_key[16]; + uint32 seq_num; + BOOL initiator; + DATA_BLOB signature; +}; + +#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } + -- cgit From 9a6388179b9c4e13238ed91aebaca9b15e02408f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 10 Feb 2004 11:33:35 +0000 Subject: Convert libcli routines to return NTSTATUS instead of BOOL. Again, the only users are smbclient and smbtorture. (This used to be commit 54cb508c78e5c1faa3ade46b46b165983c880d10) --- source4/libcli/cliconnect.c | 39 +++++++------- source4/libcli/clideltree.c | 10 ++-- source4/libcli/clifile.c | 120 +++++++++++++++++++++++--------------------- source4/libcli/clitrans2.c | 56 ++++++++++----------- 4 files changed, 113 insertions(+), 112 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 4fdffa6287..e2d9665792 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -53,28 +53,26 @@ BOOL cli_transport_establish(struct cli_state *cli, } /* wrapper around smb_raw_negotiate() */ -BOOL cli_negprot(struct cli_state *cli) +NTSTATUS cli_negprot(struct cli_state *cli) { - NTSTATUS status; - status = smb_raw_negotiate(cli->transport); - return NT_STATUS_IS_OK(status); + return smb_raw_negotiate(cli->transport); } /* wrapper around smb_raw_session_setup() */ -BOOL cli_session_setup(struct cli_state *cli, - const char *user, - const char *password, - const char *domain) +NTSTATUS cli_session_setup(struct cli_state *cli, + const char *user, + const char *password, + const char *domain) { union smb_sesssetup setup; NTSTATUS status; TALLOC_CTX *mem_ctx; cli->session = cli_session_init(cli->transport); - if (!cli->session) return False; + if (!cli->session) return NT_STATUS_UNSUCCESSFUL; mem_ctx = talloc_init("cli_session_setup"); - if (!mem_ctx) return False; + if (!mem_ctx) return NT_STATUS_NO_MEMORY; setup.generic.level = RAW_SESSSETUP_GENERIC; setup.generic.in.sesskey = cli->transport->negotiate.sesskey; @@ -91,19 +89,19 @@ BOOL cli_session_setup(struct cli_state *cli, talloc_destroy(mem_ctx); - return NT_STATUS_IS_OK(status); + return status; } /* wrapper around smb_tree_connect() */ -BOOL cli_send_tconX(struct cli_state *cli, const char *sharename, const char *devtype, - const char *password) +NTSTATUS cli_send_tconX(struct cli_state *cli, const char *sharename, + const char *devtype, const char *password) { union smb_tcon tcon; TALLOC_CTX *mem_ctx; NTSTATUS status; cli->tree = cli_tree_init(cli->session); - if (!cli->tree) return False; + if (!cli->tree) return NT_STATUS_UNSUCCESSFUL; cli->tree->reference_count++; @@ -115,9 +113,8 @@ BOOL cli_send_tconX(struct cli_state *cli, const char *sharename, const char *de tcon.tconx.in.device = devtype; mem_ctx = talloc_init("tcon"); - if (!mem_ctx) { - return False; - } + if (!mem_ctx) + return NT_STATUS_NO_MEMORY; status = smb_tree_connect(cli->tree, mem_ctx, &tcon); @@ -125,7 +122,7 @@ BOOL cli_send_tconX(struct cli_state *cli, const char *sharename, const char *de talloc_destroy(mem_ctx); - return NT_STATUS_IS_OK(status); + return status; } @@ -182,11 +179,9 @@ done: /* disconnect the tree */ -BOOL cli_tdis(struct cli_state *cli) +NTSTATUS cli_tdis(struct cli_state *cli) { - NTSTATUS status; - status = smb_tree_disconnect(cli->tree); - return NT_STATUS_IS_OK(status); + return smb_tree_disconnect(cli->tree); } /**************************************************************************** diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index d28950f136..2bbfd9bd22 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -41,7 +41,7 @@ static void delete_fn(file_info *finfo, const char *name, void *state) asprintf(&s, "%s%s", n, finfo->name); if (finfo->mode & FILE_ATTRIBUTE_READONLY) { - if (!cli_setatr(dstate->tree, s, 0, 0)) { + if (NT_STATUS_IS_ERR(cli_setatr(dstate->tree, s, 0, 0))) { DEBUG(2,("Failed to remove READONLY on %s - %s\n", s, cli_errstr(dstate->tree))); } @@ -55,14 +55,14 @@ static void delete_fn(file_info *finfo, const char *name, void *state) FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, state); free(s2); - if (!cli_rmdir(dstate->tree, s)) { + if (NT_STATUS_IS_ERR(cli_rmdir(dstate->tree, s))) { DEBUG(2,("Failed to delete %s - %s\n", s, cli_errstr(dstate->tree))); dstate->failed = True; } dstate->total_deleted++; } else { - if (!cli_unlink(dstate->tree, s)) { + if (NT_STATUS_IS_ERR(cli_unlink(dstate->tree, s))) { DEBUG(2,("Failed to delete %s - %s\n", s, cli_errstr(dstate->tree))); dstate->failed = True; @@ -87,7 +87,7 @@ int cli_deltree(struct cli_tree *tree, const char *dname) dstate.failed = False; /* it might be a file */ - if (cli_unlink(tree, dname)) { + if (NT_STATUS_IS_OK(cli_unlink(tree, dname))) { return 1; } if (NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) || @@ -102,7 +102,7 @@ int cli_deltree(struct cli_tree *tree, const char *dname) FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, &dstate); free(mask); - if (!cli_rmdir(dstate.tree, dname)) { + if (NT_STATUS_IS_ERR(cli_rmdir(dstate.tree, dname))) { DEBUG(2,("Failed to delete %s - %s\n", dname, cli_errstr(dstate.tree))); return -1; diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 6606455e49..5432834522 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -26,9 +26,9 @@ Hard/Symlink a file (UNIX extensions). ****************************************************************************/ -static BOOL cli_link_internal(struct cli_tree *tree, - const char *fname_src, - const char *fname_dst, BOOL hard_link) +static NTSTATUS cli_link_internal(struct cli_tree *tree, + const char *fname_src, + const char *fname_dst, BOOL hard_link) { union smb_setfileinfo parms; NTSTATUS status; @@ -45,13 +45,13 @@ static BOOL cli_link_internal(struct cli_tree *tree, status = smb_raw_setpathinfo(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Map standard UNIX permissions onto wire representations. ****************************************************************************/ -static uint32 unix_perms_to_wire(mode_t perms) +static uint32 unix_perms_to_wire(mode_t perms) { unsigned int ret = 0; @@ -79,8 +79,8 @@ static uint32 unix_perms_to_wire(mode_t perms) /**************************************************************************** Symlink a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_symlink(struct cli_tree *tree, const char *fname_src, - const char *fname_dst) +NTSTATUS cli_unix_symlink(struct cli_tree *tree, const char *fname_src, + const char *fname_dst) { return cli_link_internal(tree, fname_src, fname_dst, False); } @@ -88,8 +88,8 @@ BOOL cli_unix_symlink(struct cli_tree *tree, const char *fname_src, /**************************************************************************** Hard a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_hardlink(struct cli_tree *tree, const char *fname_src, - const char *fname_dst) +NTSTATUS cli_unix_hardlink(struct cli_tree *tree, const char *fname_src, + const char *fname_dst) { return cli_link_internal(tree, fname_src, fname_dst, True); } @@ -98,9 +98,10 @@ BOOL cli_unix_hardlink(struct cli_tree *tree, const char *fname_src, /**************************************************************************** Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ -static BOOL cli_unix_chmod_chown_internal(struct cli_tree *tree, - const char *fname, - uint32 mode, uint32 uid, uint32 gid) +static NTSTATUS cli_unix_chmod_chown_internal(struct cli_tree *tree, + const char *fname, + uint32 mode, uint32 uid, + uint32 gid) { union smb_setfileinfo parms; NTSTATUS status; @@ -113,14 +114,14 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_tree *tree, status = smb_raw_setpathinfo(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** chmod a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_chmod(struct cli_tree *tree, const char *fname, mode_t mode) +NTSTATUS cli_unix_chmod(struct cli_tree *tree, const char *fname, mode_t mode) { return cli_unix_chmod_chown_internal(tree, fname, unix_perms_to_wire(mode), @@ -131,8 +132,8 @@ BOOL cli_unix_chmod(struct cli_tree *tree, const char *fname, mode_t mode) /**************************************************************************** chown a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, - gid_t gid) +NTSTATUS cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, + gid_t gid) { return cli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); @@ -142,8 +143,8 @@ BOOL cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, /**************************************************************************** Rename a file. ****************************************************************************/ -BOOL cli_rename(struct cli_tree *tree, const char *fname_src, - const char *fname_dst) +NTSTATUS cli_rename(struct cli_tree *tree, const char *fname_src, + const char *fname_dst) { union smb_rename parms; @@ -151,14 +152,15 @@ BOOL cli_rename(struct cli_tree *tree, const char *fname_src, parms.rename.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; parms.rename.in.pattern1 = fname_src; parms.rename.in.pattern2 = fname_dst; - return NT_STATUS_IS_OK(smb_raw_rename(tree, &parms)); + + return smb_raw_rename(tree, &parms); } /**************************************************************************** Delete a file. ****************************************************************************/ -BOOL cli_unlink(struct cli_tree *tree, const char *fname) +NTSTATUS cli_unlink(struct cli_tree *tree, const char *fname) { struct smb_unlink parms; @@ -168,39 +170,41 @@ BOOL cli_unlink(struct cli_tree *tree, const char *fname) } else { parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; } - return NT_STATUS_IS_OK(smb_raw_unlink(tree, &parms)); + + return smb_raw_unlink(tree, &parms); } /**************************************************************************** Create a directory. ****************************************************************************/ -BOOL cli_mkdir(struct cli_tree *tree, const char *dname) +NTSTATUS cli_mkdir(struct cli_tree *tree, const char *dname) { union smb_mkdir parms; parms.mkdir.level = RAW_MKDIR_MKDIR; parms.mkdir.in.path = dname; - return NT_STATUS_IS_OK(smb_raw_mkdir(tree, &parms)); + return smb_raw_mkdir(tree, &parms); } /**************************************************************************** Remove a directory. ****************************************************************************/ -BOOL cli_rmdir(struct cli_tree *tree, const char *dname) +NTSTATUS cli_rmdir(struct cli_tree *tree, const char *dname) { struct smb_rmdir parms; parms.in.path = dname; - return NT_STATUS_IS_OK(smb_raw_rmdir(tree, &parms)); + + return smb_raw_rmdir(tree, &parms); } /**************************************************************************** Set or clear the delete on close flag. ****************************************************************************/ -BOOL cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) +NTSTATUS cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) { union smb_setfileinfo parms; NTSTATUS status; @@ -211,7 +215,7 @@ BOOL cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) status = smb_raw_setfileinfo(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } @@ -326,7 +330,7 @@ int cli_open(struct cli_tree *tree, const char *fname, int flags, /**************************************************************************** Close a file. ****************************************************************************/ -BOOL cli_close(struct cli_tree *tree, int fnum) +NTSTATUS cli_close(struct cli_tree *tree, int fnum) { union smb_close close_parms; NTSTATUS status; @@ -335,7 +339,7 @@ BOOL cli_close(struct cli_tree *tree, int fnum) close_parms.close.in.fnum = fnum; close_parms.close.in.write_time = 0; status = smb_raw_close(tree, &close_parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** @@ -343,7 +347,8 @@ BOOL cli_close(struct cli_tree *tree, int fnum) this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, - uint32 offset, uint32 len, int timeout, unsigned char locktype) + uint32 offset, uint32 len, int timeout, + unsigned char locktype) { union smb_lock parms; struct smb_lock_entry lock[1]; @@ -369,8 +374,9 @@ NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, /**************************************************************************** Lock a file. ****************************************************************************/ -BOOL cli_lock(struct cli_tree *tree, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type) +NTSTATUS cli_lock(struct cli_tree *tree, int fnum, + uint32 offset, uint32 len, int timeout, + enum brl_type lock_type) { union smb_lock parms; struct smb_lock_entry lock[1]; @@ -389,14 +395,14 @@ BOOL cli_lock(struct cli_tree *tree, int fnum, status = smb_raw_lock(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Unlock a file. ****************************************************************************/ -BOOL cli_unlock(struct cli_tree *tree, int fnum, uint32 offset, uint32 len) +NTSTATUS cli_unlock(struct cli_tree *tree, int fnum, uint32 offset, uint32 len) { union smb_lock parms; struct smb_lock_entry lock[1]; @@ -414,15 +420,16 @@ BOOL cli_unlock(struct cli_tree *tree, int fnum, uint32 offset, uint32 len) parms.lockx.in.locks = &lock[0]; status = smb_raw_lock(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Lock a file with 64 bit offsets. ****************************************************************************/ -BOOL cli_lock64(struct cli_tree *tree, int fnum, - SMB_OFF_T offset, SMB_OFF_T len, int timeout, enum brl_type lock_type) +NTSTATUS cli_lock64(struct cli_tree *tree, int fnum, + SMB_OFF_T offset, SMB_OFF_T len, int timeout, + enum brl_type lock_type) { union smb_lock parms; int ltype; @@ -449,14 +456,15 @@ BOOL cli_lock64(struct cli_tree *tree, int fnum, status = smb_raw_lock(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Unlock a file with 64 bit offsets. ****************************************************************************/ -BOOL cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, SMB_OFF_T len) +NTSTATUS cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, + SMB_OFF_T len) { union smb_lock parms; struct smb_lock_entry lock[1]; @@ -479,16 +487,16 @@ BOOL cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, SMB_OFF_T l status = smb_raw_lock(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Do a SMBgetattrE call. ****************************************************************************/ -BOOL cli_getattrE(struct cli_tree *tree, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) +NTSTATUS cli_getattrE(struct cli_tree *tree, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time) { union smb_fileinfo parms; NTSTATUS status; @@ -499,7 +507,7 @@ BOOL cli_getattrE(struct cli_tree *tree, int fd, status = smb_raw_fileinfo(tree, NULL, &parms); if (!NT_STATUS_IS_OK(status)) - return False; + return status; if (size) { *size = parms.getattre.out.size; @@ -521,14 +529,14 @@ BOOL cli_getattrE(struct cli_tree *tree, int fd, *m_time = parms.getattre.out.write_time; } - return True; + return status; } /**************************************************************************** Do a SMBgetatr call ****************************************************************************/ -BOOL cli_getatr(struct cli_tree *tree, const char *fname, - uint16 *attr, size_t *size, time_t *t) +NTSTATUS cli_getatr(struct cli_tree *tree, const char *fname, + uint16 *attr, size_t *size, time_t *t) { union smb_fileinfo parms; NTSTATUS status; @@ -539,7 +547,7 @@ BOOL cli_getatr(struct cli_tree *tree, const char *fname, status = smb_raw_pathinfo(tree, NULL, &parms); if (!NT_STATUS_IS_OK(status)) { - return False; + return status; } if (size) { @@ -554,14 +562,15 @@ BOOL cli_getatr(struct cli_tree *tree, const char *fname, *attr = parms.getattr.out.attrib; } - return True; + return status; } /**************************************************************************** Do a SMBsetatr call. ****************************************************************************/ -BOOL cli_setatr(struct cli_tree *tree, const char *fname, uint16 mode, time_t t) +NTSTATUS cli_setatr(struct cli_tree *tree, const char *fname, uint16 mode, + time_t t) { union smb_setfileinfo parms; NTSTATUS status; @@ -573,14 +582,14 @@ BOOL cli_setatr(struct cli_tree *tree, const char *fname, uint16 mode, time_t t) status = smb_raw_setpathinfo(tree, &parms); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Check for existence of a dir. ****************************************************************************/ -BOOL cli_chkpath(struct cli_tree *tree, const char *path) +NTSTATUS cli_chkpath(struct cli_tree *tree, const char *path) { struct smb_chkpath parms; char *path2; @@ -599,14 +608,14 @@ BOOL cli_chkpath(struct cli_tree *tree, const char *path) free(path2); - return NT_STATUS_IS_OK(status); + return status; } /**************************************************************************** Query disk space. ****************************************************************************/ -BOOL cli_dskattr(struct cli_tree *tree, int *bsize, int *total, int *avail) +NTSTATUS cli_dskattr(struct cli_tree *tree, int *bsize, int *total, int *avail) { union smb_fsinfo fsinfo_parms; TALLOC_CTX *mem_ctx; @@ -624,7 +633,7 @@ BOOL cli_dskattr(struct cli_tree *tree, int *bsize, int *total, int *avail) talloc_destroy(mem_ctx); - return NT_STATUS_IS_OK(status); + return status; } @@ -654,4 +663,3 @@ int cli_ctemp(struct cli_tree *tree, const char *path, char **tmp_path) } return -1; } - diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index c8f7db5a9d..777150a257 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -23,25 +23,24 @@ /**************************************************************************** send a qpathinfo call ****************************************************************************/ -BOOL cli_qpathinfo(struct cli_tree *tree, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) +NTSTATUS cli_qpathinfo(struct cli_tree *tree, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; NTSTATUS status; mem_ctx = talloc_init("cli_qpathinfo"); - if (!mem_ctx) return False; + if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.standard.level = RAW_FILEINFO_STANDARD; parms.standard.in.fname = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_destroy(mem_ctx); - if (!NT_STATUS_IS_OK(status)) { - return False; - } + if (!NT_STATUS_IS_OK(status)) + return status; if (c_time) { *c_time = parms.standard.out.create_time; @@ -59,32 +58,31 @@ BOOL cli_qpathinfo(struct cli_tree *tree, const char *fname, *mode = parms.standard.out.attrib; } - return True; + return status; } /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_tree *tree, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino) +NTSTATUS cli_qpathinfo2(struct cli_tree *tree, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; NTSTATUS status; mem_ctx = talloc_init("cli_qfilename"); - if (!mem_ctx) return False; + if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; parms.all_info.in.fname = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_destroy(mem_ctx); - if (!NT_STATUS_IS_OK(status)) { - return False; - } + if (!NT_STATUS_IS_OK(status)) + return status; if (c_time) { *c_time = nt_time_to_unix(&parms.all_info.out.create_time); @@ -105,22 +103,21 @@ BOOL cli_qpathinfo2(struct cli_tree *tree, const char *fname, *mode = parms.all_info.out.attrib; } - return True; + return status; } /**************************************************************************** send a qfileinfo QUERY_FILE_NAME_INFO call ****************************************************************************/ -BOOL cli_qfilename(struct cli_tree *tree, int fnum, - const char **name) +NTSTATUS cli_qfilename(struct cli_tree *tree, int fnum, const char **name) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; NTSTATUS status; mem_ctx = talloc_init("cli_qfilename"); - if (!mem_ctx) return False; + if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.name_info.level = RAW_FILEINFO_NAME_INFO; parms.name_info.in.fnum = fnum; @@ -129,31 +126,32 @@ BOOL cli_qfilename(struct cli_tree *tree, int fnum, if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); *name = NULL; - return False; + return status; } *name = strdup(parms.name_info.out.fname.s); talloc_destroy(mem_ctx); - return True; + return status; } /**************************************************************************** send a qfileinfo call ****************************************************************************/ -BOOL cli_qfileinfo(struct cli_tree *tree, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino) +NTSTATUS cli_qfileinfo(struct cli_tree *tree, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; NTSTATUS status; mem_ctx = talloc_init("cli_qfileinfo"); - if (!mem_ctx) return False; + if (!mem_ctx) + return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; parms.all_info.in.fnum = fnum; @@ -161,7 +159,7 @@ BOOL cli_qfileinfo(struct cli_tree *tree, int fnum, status = smb_raw_fileinfo(tree, mem_ctx, &parms); talloc_destroy(mem_ctx); if (!NT_STATUS_IS_OK(status)) { - return False; + return status; } if (c_time) { @@ -186,7 +184,7 @@ BOOL cli_qfileinfo(struct cli_tree *tree, int fnum, *ino = 0; } - return True; + return status; } -- cgit From 45e446248d36087dd53c341051424beb058bd99d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Feb 2004 06:02:32 +0000 Subject: move more code to the config.m4 scheme LIBBASIC, LIBSMB are the new global subsystems metze (This used to be commit a25c167b3f13031ba992b2d3f74387bdfffbf5b0) --- source4/libcli/config.m4 | 37 +++++++++++++++++++++++++++++++++++++ source4/libcli/libsmb.m4 | 8 ++++++++ 2 files changed, 45 insertions(+) create mode 100644 source4/libcli/config.m4 create mode 100644 source4/libcli/libsmb.m4 (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 new file mode 100644 index 0000000000..7176f83ebc --- /dev/null +++ b/source4/libcli/config.m4 @@ -0,0 +1,37 @@ +dnl # LIBCLI subsystem + +SMB_SUBSYSTEM(LIBCLI_RAW,[], + [libcli/raw/rawfile.o libcli/raw/smb_signing.o \ + libcli/raw/clisocket.o libcli/raw/clitransport.o \ + libcli/raw/clisession.o libcli/raw/clitree.o \ + libcli/raw/clikrb5.o libcli/raw/clispnego.o libcli/raw/rawrequest.o \ + libcli/raw/rawreadwrite.o libcli/raw/rawsearch.o \ + libcli/raw/rawsetfileinfo.o libcli/raw/raweas.o \ + libcli/raw/rawtrans.o libcli/raw/clioplock.o \ + libcli/raw/rawnegotiate.o libcli/raw/rawfsinfo.o \ + libcli/raw/rawfileinfo.o libcli/raw/rawnotify.o \ + libcli/raw/rawioctl.o libcli/raw/rawacl.o], + libcli/raw/libcli_raw_public_proto.h) + +SMB_SUBSYSTEM(LIBCLI_UTILS,[], + [libcli/util/asn1.o \ + libcli/util/smberr.o \ + libcli/util/doserr.o libcli/util/errormap.o \ + libcli/util/pwd_cache.o libcli/util/clierror.o libcli/util/cliutil.o \ + libcli/util/nterr.o libcli/util/smbdes.o libcli/util/smbencrypt.o], + libcli/util/libcli_utils_public_proto.h) + +SMB_SUBSYSTEM(LIBCLI_AUTH,[], + [libcli/auth/ntlmssp.o libcli/auth/ntlmssp_parse.o \ + libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o \ + libcli/auth/credentials.o], + libcli/auth/libcli_auth_public_proto.h) + +SMB_SUBSYSTEM(LIBCLI_NMB,[], + [libcli/unexpected.o libcli/namecache.o libcli/nmblib.o \ + libcli/namequery.o], + libcli/libcli_nmb_public_proto.h) + +SMB_SUBSYSTEM(LIBCLI,[], + [\$(LIBCLI_RAW_OBJS) \$(LIBCLI_UTILS_OBJS) \$(LIBCLI_AUTH_OBJS) \$(LIBCLI_NMB_OBJS)], + librpc/libcli_public_proto.h) diff --git a/source4/libcli/libsmb.m4 b/source4/libcli/libsmb.m4 new file mode 100644 index 0000000000..e34c171e48 --- /dev/null +++ b/source4/libcli/libsmb.m4 @@ -0,0 +1,8 @@ +dnl # LIBSMB subsystem + +SMB_SUBSYSTEM(LIBSMB,[], + [libcli/clireadwrite.o libcli/cliconnect.o \ + libcli/clifile.o libcli/clilist.o libcli/clitrans2.o \ + libcli/climessage.o libcli/clideltree.o \ + \$(LIBCLI_OBJS) \$(LIBRPC_OBJS)], + libcli/libsmb_public_proto.h) -- cgit From 6c7e231773ec83c0ec31df51866ad5765e593100 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Feb 2004 04:02:00 +0000 Subject: fixed a problem with the smb client code spinning when the connection is lost. We now close the cli_transport when there is a socket io error (This used to be commit 138cb5f2f5f8ce1479ac687d18e6a0e355e55b7f) --- source4/libcli/raw/rawrequest.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 4191d3775e..2b84345abb 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -309,7 +309,11 @@ BOOL cli_request_receive(struct cli_request *req) return False; } - cli_request_receive_next(req->transport); + if (!cli_request_receive_next(req->transport)) { + cli_transport_close(req->transport); + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + return False; + } } return True; -- cgit From 4282138ebbf2b2f708903cdfe713786a8c3e6960 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 21 Feb 2004 11:23:51 +0000 Subject: The file descriptor argument to cli_getattrE() is a fnum not a fd. (This used to be commit f172b6f1d08b7de040cde4a7d88708e5af29a3a4) --- source4/libcli/clifile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 5432834522..d1dd0b4ff2 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -494,7 +494,7 @@ NTSTATUS cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, /**************************************************************************** Do a SMBgetattrE call. ****************************************************************************/ -NTSTATUS cli_getattrE(struct cli_tree *tree, int fd, +NTSTATUS cli_getattrE(struct cli_tree *tree, int fnum, uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { @@ -502,7 +502,7 @@ NTSTATUS cli_getattrE(struct cli_tree *tree, int fd, NTSTATUS status; parms.getattre.level = RAW_FILEINFO_GETATTRE; - parms.getattre.in.fnum = fd; + parms.getattre.in.fnum = fnum; status = smb_raw_fileinfo(tree, NULL, &parms); -- cgit From 14591dc0eaa8751e8eb982d4157862e8ab8f2841 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Mar 2004 07:11:13 +0000 Subject: fixed two writex client bugs - always use the 14 word writex varient even for small transfers as long as large offsets are negotiated (this matches windows behaviour) - make sure we fill in the top 16 bits of the count for large writex calls (This used to be commit 9ea20d0c9a1cb4800f3f54195cbbe70c98c8e423) --- source4/libcli/raw/rawreadwrite.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 84c7e3c00f..3aa95c35aa 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -40,7 +40,7 @@ struct cli_request *smb_raw_read_send(struct cli_tree *tree, union smb_read *par return NULL; case RAW_READ_READBRAW: - if (parms->readbraw.in.offset >= 0x80000000) { + if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = True; } SETUP_REQUEST(SMBreadbraw, bigoffset? 10:8, 0); @@ -72,7 +72,7 @@ struct cli_request *smb_raw_read_send(struct cli_tree *tree, union smb_read *par break; case RAW_READ_READX: - if (parms->readx.in.offset >= 0x80000000) { + if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = True; } SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); @@ -232,7 +232,7 @@ struct cli_request *smb_raw_write_send(struct cli_tree *tree, union smb_write *p break; case RAW_WRITE_WRITEX: - if (parms->writex.in.offset >= 0x80000000) { + if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = True; } SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); @@ -243,7 +243,7 @@ struct cli_request *smb_raw_write_send(struct cli_tree *tree, union smb_write *p SIVAL(req->out.vwv, VWV(5), 0); /* reserved */ SSVAL(req->out.vwv, VWV(7), parms->writex.in.wmode); SSVAL(req->out.vwv, VWV(8), parms->writex.in.remaining); - SSVAL(req->out.vwv, VWV(9), 0); /* reserved */ + SSVAL(req->out.vwv, VWV(9), parms->writex.in.count>>16); SSVAL(req->out.vwv, VWV(10), parms->writex.in.count); SSVAL(req->out.vwv, VWV(11), PTR_DIFF(req->out.data, req->out.hdr)); if (bigoffset) { -- cgit From f169d83a8b707d6d480c456bf4e4ca7c85dadbae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 25 Mar 2004 02:41:19 +0000 Subject: fixed the handling of level II oplocks in samba4, especially when acting as a cifs redirectory (using the cifs backend) (This used to be commit 06a8100e6a2f3f079af5b6ec32d87d1d25f56c3c) --- source4/libcli/raw/clioplock.c | 3 ++- source4/libcli/raw/rawrequest.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index 8f69716bda..f27bf937ce 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -33,7 +33,8 @@ BOOL cli_oplock_ack(struct cli_tree *tree, uint16 fnum, uint16 ack_level) SSVAL(req->out.vwv,VWV(0),0xFF); SSVAL(req->out.vwv,VWV(1),0); SSVAL(req->out.vwv,VWV(2),fnum); - SSVAL(req->out.vwv,VWV(3),ack_level); + SCVAL(req->out.vwv,VWV(3),LOCKING_ANDX_OPLOCK_RELEASE); + SCVAL(req->out.vwv,VWV(3)+1,ack_level); SIVAL(req->out.vwv,VWV(4),0); SSVAL(req->out.vwv,VWV(6),0); SSVAL(req->out.vwv,VWV(7),0); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 2b84345abb..f03cc5cf16 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -340,7 +340,7 @@ static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, con if (transport->oplock.handler) { uint16 tid = SVAL(hdr, HDR_TID); uint16 fnum = SVAL(vwv,VWV(2)); - uint8 level = CVAL(vwv,VWV(3)); + uint8 level = CVAL(vwv,VWV(3)+1); transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private); } -- cgit From b087ed482115520a6c18e9a1c02accce0014d80f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Apr 2004 08:44:08 +0000 Subject: r23: get rid of def_finfo (This used to be commit 25b7ec390aec3e324c4c7ad8edbc90fc8896b230) --- source4/libcli/util/cliutil.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/cliutil.c b/source4/libcli/util/cliutil.c index 13b3dad0bf..56dee7381a 100644 --- a/source4/libcli/util/cliutil.c +++ b/source4/libcli/util/cliutil.c @@ -24,9 +24,6 @@ Functions nicked from lib/util.c needed by client. *******************************************************************/ -/* a default finfo structure to ensure all fields are sensible */ -file_info def_finfo = {-1,0,0,0,0,0,0,"",""}; - /******************************************************************* A wrapper that handles case sensitivity and the special handling of the ".." name. -- cgit From 381a903d00ccbc3e80e8eca533d304fed6c13870 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 5 Apr 2004 12:26:23 +0000 Subject: r42: importing .cvsignore files (This used to be commit 11717ae912449bde596ff6cf7d8fddcc86548f15) --- source4/libcli/.cvsignore | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 source4/libcli/.cvsignore (limited to 'source4/libcli') diff --git a/source4/libcli/.cvsignore b/source4/libcli/.cvsignore deleted file mode 100644 index 2588860f65..0000000000 --- a/source4/libcli/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.po -*.po32 - -- cgit From a8a42e7f53c67b09954ea2232830c07c6e011aa0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Apr 2004 07:18:37 +0000 Subject: r100: remember the user session key during session setup so it can be used in various crypto routines (This used to be commit f6cf9020c8899e784385ea0e14fa465685441ee6) --- source4/libcli/raw/clisession.c | 2 ++ source4/libcli/raw/clitransport.c | 9 +++++++++ 2 files changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index c5d4888089..1c0af77d11 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -247,6 +247,8 @@ static void setup_nt1_signing(struct cli_transport *transport, const char *passw SMBsesskeygen_ntv1(nt_hash, NULL, session_key); nt_response = nt_blob(password, transport->negotiate.secblob); + cli_transport_set_session_key(transport, session_key); + cli_transport_simple_set_signing(transport, session_key, nt_response); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 2d614cc3bd..62152bbe4d 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -222,3 +222,12 @@ BOOL cli_transport_select(struct cli_transport *transport) return True; } + +/* + store the user session key for a transport +*/ +void cli_transport_set_session_key(struct cli_transport *transport, + const uint8 session_key[16]) +{ + memcpy(transport->negotiate.user_session_key, session_key, 16); +} -- cgit From 984bfce2d9de9eb73e09887b720d219566242398 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Apr 2004 07:20:53 +0000 Subject: r101: added lsa_SetSecret() and lsa_QuerySecret() this required some crypto infrastructure and some sid utilities (This used to be commit 37d0efa9c2af8532536bea88412f0dd3ed39ecfc) --- source4/libcli/auth/session.c | 133 ++++++++++++++++++++++++++++++++++++++++++ source4/libcli/config.m4 | 5 +- source4/libcli/util/dom_sid.c | 90 ++++++++++++++++++++++++++++ source4/libcli/util/smbdes.c | 2 +- 4 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 source4/libcli/auth/session.c create mode 100644 source4/libcli/util/dom_sid.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c new file mode 100644 index 0000000000..946b0fe62f --- /dev/null +++ b/source4/libcli/auth/session.c @@ -0,0 +1,133 @@ +/* + Unix SMB/CIFS implementation. + + code to encrypt/decrypt data using the user session key + + Copyright (C) Andrew Tridgell 2004 + + 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" + +/* + encrypt or decrypt a blob of data using the user session key + as used in lsa_SetSecret + + before calling, the out blob must be initialised to be the same size + as the in blob +*/ +void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const uint8 session_key[16], + BOOL forward) +{ + int i, k; + + for (i=0,k=0; + ilength; + i += 8, k += 7) { + uint8 bin[8], bout[8], key[7]; + + memset(bin, 0, 8); + memcpy(bin, &in->data[i], MIN(8, in->length-i)); + + if (k + 7 > 16) { + k = (16 - k); + } + memcpy(key, &session_key[k], 7); + + smbhash(bout, bin, key, forward?1:0); + + memcpy(&out->data[i], bout, MIN(8, in->length-i)); + } +} + + +/* + a convenient wrapper around sess_crypt_blob() for strings, using the LSA convention + + note that we round the length to a multiple of 8. This seems to be needed for + compatibility with windows + + caller should free using data_blob_free() +*/ +DATA_BLOB sess_encrypt_string(const char *str, const uint8 session_key[16]) +{ + DATA_BLOB ret, src; + int slen = strlen(str); + int dlen = (slen+7) & ~7; + + src = data_blob(NULL, 8+dlen); + if (!src.data) { + return data_blob(NULL, 0); + } + + ret = data_blob(NULL, 8+dlen); + if (!ret.data) { + data_blob_free(&src); + return data_blob(NULL, 0); + } + + SIVAL(src.data, 0, slen); + SIVAL(src.data, 4, 1); + memset(src.data+8, 0, dlen); + memcpy(src.data+8, str, slen); + + sess_crypt_blob(&ret, &src, session_key, True); + + data_blob_free(&src); + + return ret; +} + +/* + a convenient wrapper around sess_crypt_blob() for strings, using the LSA convention + + caller should free the returned string +*/ +char *sess_decrypt_string(DATA_BLOB *blob, const uint8 session_key[16]) +{ + DATA_BLOB out; + int slen; + char *ret; + + if (blob->length < 8) { + return NULL; + } + + out = data_blob(NULL, blob->length); + if (!out.data) { + return NULL; + } + + sess_crypt_blob(&out, blob, session_key, False); + + slen = IVAL(out.data, 0); + if (slen > blob->length - 8) { + DEBUG(0,("Invalid crypt length %d\n", slen)); + return NULL; + } + + if (IVAL(out.data, 4) != 1) { + DEBUG(0,("Unexpected revision number %d in session crypted string\n", + IVAL(out.data, 4))); + return NULL; + } + + ret = strndup(out.data+8, slen); + + data_blob_free(&out); + + return ret; +} diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 7176f83ebc..ac8e7cbabb 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -18,13 +18,14 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], libcli/util/smberr.o \ libcli/util/doserr.o libcli/util/errormap.o \ libcli/util/pwd_cache.o libcli/util/clierror.o libcli/util/cliutil.o \ - libcli/util/nterr.o libcli/util/smbdes.o libcli/util/smbencrypt.o], + libcli/util/nterr.o libcli/util/smbdes.o libcli/util/smbencrypt.o \ + libcli/util/dom_sid.o], libcli/util/libcli_utils_public_proto.h) SMB_SUBSYSTEM(LIBCLI_AUTH,[], [libcli/auth/ntlmssp.o libcli/auth/ntlmssp_parse.o \ libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o \ - libcli/auth/credentials.o], + libcli/auth/credentials.o libcli/auth/session.o], libcli/auth/libcli_auth_public_proto.h) SMB_SUBSYSTEM(LIBCLI_NMB,[], diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c new file mode 100644 index 0000000000..652f17a6b6 --- /dev/null +++ b/source4/libcli/util/dom_sid.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + routines to manipulate a "struct dom_sid" + + Copyright (C) Andrew Tridgell 2004 + + 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" + +/* + convert a string to a dom_sid, returning a talloc'd dom_sid +*/ +struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) +{ + struct dom_sid *ret; + unsigned int rev, ia, num_sub_auths, i; + char *p; + + if (strncasecmp(sidstr, "S-", 2)) { + return NULL; + } + + sidstr += 2; + + rev = strtol(sidstr, &p, 10); + if (*p != '-') { + return NULL; + } + sidstr = p+1; + + ia = strtol(sidstr, &p, 10); + if (*p != '-') { + return NULL; + } + sidstr = p+1; + + num_sub_auths = 0; + for (i=0;sidstr[i];i++) { + if (sidstr[i] == '-') num_sub_auths++; + } + + ret = talloc_p(mem_ctx, struct dom_sid); + if (!ret) { + return NULL; + } + + ret->sub_auths = talloc_array_p(mem_ctx, uint32, num_sub_auths); + if (!ret->sub_auths) { + return NULL; + } + + ret->sid_rev_num = rev; + ret->id_auth[0] = 0; + ret->id_auth[0] = 0; + ret->id_auth[1] = 0; + ret->id_auth[2] = ia >> 24; + ret->id_auth[3] = ia >> 16; + ret->id_auth[4] = ia >> 8; + ret->id_auth[5] = ia; + ret->num_auths = num_sub_auths; + + for (i=0;isub_auths[i] = strtol(sidstr, &p, 10); + if (p == sidstr) { + return NULL; + } + if (*p != '-' && i < num_sub_auths-1) { + return NULL; + } + sidstr = p+1; + } + + return ret; +} + diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index e5c4c6f3f1..d282b0135a 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -276,7 +276,7 @@ static void str_to_key(const unsigned char *str,unsigned char *key) } -static void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) +void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { int i; char outb[64]; -- cgit From ac193579e7db00c7a2ea0aadaaf0d34c10dcf1a5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 10 Apr 2004 20:18:22 +0000 Subject: r152: a quick airport commit .... added ldbedit, a _really_ useful command added ldbadd, ldbdel, ldbsearch and ldbmodify to build solved lots of timezone issues, we now pass the torture tests with client and server in different zones fixed several build issues I know this breaks the no-LDAP build. Wait till I arrive in San Jose for that fix. (This used to be commit af34710d4da1841653624fe304b1c8d812c0fdd9) --- source4/libcli/config.m4 | 3 +- source4/libcli/raw/rawdate.c | 81 +++++++++++++++++++++++++++++++++++++ source4/libcli/raw/rawfile.c | 27 ++++++++----- source4/libcli/raw/rawfileinfo.c | 30 +++++++++----- source4/libcli/raw/rawnegotiate.c | 7 ++-- source4/libcli/raw/rawreadwrite.c | 3 +- source4/libcli/raw/rawsearch.c | 21 ++++++---- source4/libcli/raw/rawsetfileinfo.c | 21 ++++++---- source4/libcli/util/smbencrypt.c | 5 ++- 9 files changed, 159 insertions(+), 39 deletions(-) create mode 100644 source4/libcli/raw/rawdate.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index ac8e7cbabb..b5273b9bb2 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -10,7 +10,8 @@ SMB_SUBSYSTEM(LIBCLI_RAW,[], libcli/raw/rawtrans.o libcli/raw/clioplock.o \ libcli/raw/rawnegotiate.o libcli/raw/rawfsinfo.o \ libcli/raw/rawfileinfo.o libcli/raw/rawnotify.o \ - libcli/raw/rawioctl.o libcli/raw/rawacl.o], + libcli/raw/rawioctl.o libcli/raw/rawacl.o \ + libcli/raw/rawdate.o ], libcli/raw/libcli_raw_public_proto.h) SMB_SUBSYSTEM(LIBCLI_UTILS,[], diff --git a/source4/libcli/raw/rawdate.c b/source4/libcli/raw/rawdate.c new file mode 100644 index 0000000000..e80c376bf7 --- /dev/null +++ b/source4/libcli/raw/rawdate.c @@ -0,0 +1,81 @@ +/* + Unix SMB/CIFS implementation. + + raw date handling functions + + Copyright (C) Andrew Tridgell 2004 + + 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" + +/******************************************************************* +put a dos date into a buffer (time/date format) +This takes GMT time and puts local time for zone_offset in the buffer +********************************************************************/ +void raw_push_dos_date(struct cli_transport *transport, + uint8 *buf, int offset, time_t unixdate) +{ + push_dos_date(buf, offset, unixdate, transport->negotiate.server_zone); +} + +/******************************************************************* +put a dos date into a buffer (date/time format) +This takes GMT time and puts local time in the buffer +********************************************************************/ +void raw_push_dos_date2(struct cli_transport *transport, + char *buf, int offset, time_t unixdate) +{ + push_dos_date2(buf, offset, unixdate, transport->negotiate.server_zone); +} + +/******************************************************************* +put a dos 32 bit "unix like" date into a buffer. This routine takes +GMT and converts it to LOCAL time in zone_offset before putting it +********************************************************************/ +void raw_push_dos_date3(struct cli_transport *transport, + char *buf, int offset, time_t unixdate) +{ + push_dos_date3(buf, offset, unixdate, transport->negotiate.server_zone); +} + +/******************************************************************* +convert a dos date +********************************************************************/ +time_t raw_pull_dos_date(struct cli_transport *transport, + const uint8 *date_ptr) +{ + return pull_dos_date(date_ptr, transport->negotiate.server_zone); +} + +/******************************************************************* +like raw_pull_dos_date() but the words are reversed +********************************************************************/ +time_t raw_pull_dos_date2(struct cli_transport *transport, + const uint8 *date_ptr) +{ + return pull_dos_date2(date_ptr, transport->negotiate.server_zone); +} + +/******************************************************************* + create a unix GMT date from a dos date in 32 bit "unix like" format + these arrive in server zone, with corresponding DST + ******************************************************************/ +time_t raw_pull_dos_date3(struct cli_transport *transport, + const uint8 *date_ptr) +{ + return pull_dos_date3(date_ptr, transport->negotiate.server_zone); +} diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 0dc2a15c11..d1a665ab14 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -240,7 +240,8 @@ static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode); SSVAL(t2.in.params.data, VWV(2), 0); /* reserved */ SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs); - put_dos_date(t2.in.params.data, VWV(4), parms->t2open.in.write_time); + raw_push_dos_date(tree->session->transport, + t2.in.params.data, VWV(4), parms->t2open.in.write_time); SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func); SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size); SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout); @@ -278,7 +279,8 @@ static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx parms->t2open.out.fnum = SVAL(t2.out.params.data, VWV(0)); parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1)); - parms->t2open.out.write_time = make_unix_date3(t2.out.params.data + VWV(2)); + parms->t2open.out.write_time = raw_pull_dos_date3(req->transport, + t2.out.params.data + VWV(2)); parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4)); parms->t2open.out.access = SVAL(t2.out.params.data, VWV(6)); parms->t2open.out.ftype = SVAL(t2.out.params.data, VWV(7)); @@ -316,7 +318,8 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode); SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs); SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs); - put_dos_date3(req->out.vwv, VWV(6), parms->openx.in.write_time); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(6), parms->openx.in.write_time); SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func); SIVAL(req->out.vwv, VWV(9), parms->openx.in.size); SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout); @@ -327,21 +330,24 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par case RAW_OPEN_MKNEW: SETUP_REQUEST(SMBmknew, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib); - put_dos_date3(req->out.vwv, VWV(1), parms->mknew.in.write_time); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(1), parms->mknew.in.write_time); cli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE); break; case RAW_OPEN_CREATE: SETUP_REQUEST(SMBcreate, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib); - put_dos_date3(req->out.vwv, VWV(1), parms->create.in.write_time); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(1), parms->create.in.write_time); cli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE); break; case RAW_OPEN_CTEMP: SETUP_REQUEST(SMBctemp, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib); - put_dos_date3(req->out.vwv, VWV(1), parms->ctemp.in.write_time); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(1), parms->ctemp.in.write_time); cli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE); break; @@ -398,7 +404,8 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s CLI_CHECK_WCT(req, 7); parms->open.out.fnum = SVAL(req->in.vwv, VWV(0)); parms->open.out.attrib = SVAL(req->in.vwv, VWV(1)); - parms->open.out.write_time = make_unix_date3(req->in.vwv + VWV(2)); + parms->open.out.write_time = raw_pull_dos_date3(req->transport, + req->in.vwv + VWV(2)); parms->open.out.size = IVAL(req->in.vwv, VWV(4)); parms->open.out.rmode = SVAL(req->in.vwv, VWV(6)); break; @@ -407,7 +414,8 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s CLI_CHECK_MIN_WCT(req, 15); parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2)); parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3)); - parms->openx.out.write_time = make_unix_date3(req->in.vwv + VWV(4)); + parms->openx.out.write_time = raw_pull_dos_date3(req->transport, + req->in.vwv + VWV(4)); parms->openx.out.size = IVAL(req->in.vwv, VWV(6)); parms->openx.out.access = SVAL(req->in.vwv, VWV(8)); parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9)); @@ -491,7 +499,8 @@ struct cli_request *smb_raw_close_send(struct cli_tree *tree, union smb_close *p case RAW_CLOSE_CLOSE: SETUP_REQUEST(SMBclose, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum); - put_dos_date3(req->out.vwv, VWV(1), parms->close.in.write_time); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(1), parms->close.in.write_time); break; case RAW_CLOSE_SPLCLOSE: diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index fd66080057..9d715e6104 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -52,9 +52,12 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, case RAW_FILEINFO_STANDARD: FINFO_CHECK_SIZE(22); - parms->standard.out.create_time = make_unix_date2(blob->data + 0); - parms->standard.out.access_time = make_unix_date2(blob->data + 4); - parms->standard.out.write_time = make_unix_date2(blob->data + 8); + parms->standard.out.create_time = raw_pull_dos_date2(session->transport, + blob->data + 0); + parms->standard.out.access_time = raw_pull_dos_date2(session->transport, + blob->data + 4); + parms->standard.out.write_time = raw_pull_dos_date2(session->transport, + blob->data + 8); parms->standard.out.size = IVAL(blob->data, 12); parms->standard.out.alloc_size = IVAL(blob->data, 16); parms->standard.out.attrib = SVAL(blob->data, 20); @@ -62,9 +65,12 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, case RAW_FILEINFO_EA_SIZE: FINFO_CHECK_SIZE(26); - parms->ea_size.out.create_time = make_unix_date2(blob->data + 0); - parms->ea_size.out.access_time = make_unix_date2(blob->data + 4); - parms->ea_size.out.write_time = make_unix_date2(blob->data + 8); + parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport, + blob->data + 0); + parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport, + blob->data + 4); + parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport, + blob->data + 8); parms->ea_size.out.size = IVAL(blob->data, 12); parms->ea_size.out.alloc_size = IVAL(blob->data, 16); parms->ea_size.out.attrib = SVAL(blob->data, 20); @@ -376,7 +382,8 @@ static NTSTATUS smb_raw_getattr_recv(struct cli_request *req, CLI_CHECK_WCT(req, 10); parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0)); - parms->getattr.out.write_time = make_unix_date3(req->in.vwv + VWV(1)); + parms->getattr.out.write_time = raw_pull_dos_date3(req->transport, + req->in.vwv + VWV(1)); parms->getattr.out.size = IVAL(req->in.vwv, VWV(3)); failed: @@ -416,9 +423,12 @@ static NTSTATUS smb_raw_getattrE_recv(struct cli_request *req, } CLI_CHECK_WCT(req, 11); - parms->getattre.out.create_time = make_unix_date2(req->in.vwv + VWV(0)); - parms->getattre.out.access_time = make_unix_date2(req->in.vwv + VWV(2)); - parms->getattre.out.write_time = make_unix_date2(req->in.vwv + VWV(4)); + parms->getattre.out.create_time = raw_pull_dos_date2(req->transport, + req->in.vwv + VWV(0)); + parms->getattre.out.access_time = raw_pull_dos_date2(req->transport, + req->in.vwv + VWV(2)); + parms->getattre.out.write_time = raw_pull_dos_date2(req->transport, + req->in.vwv + VWV(4)); parms->getattre.out.size = IVAL(req->in.vwv, VWV(6)); parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8)); parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10)); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 04941f6118..587050bef8 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -129,8 +129,9 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(6)); transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(10)) * 60; - /* this time is converted to GMT by make_unix_date */ - transport->negotiate.server_time = make_unix_date(req->in.vwv+VWV(8)); + /* this time is converted to GMT by raw_pull_dos_date */ + transport->negotiate.server_time = raw_pull_dos_date(transport, + req->in.vwv+VWV(8)); if ((SVAL(req->in.vwv,VWV(5)) & 0x1)) { transport->negotiate.readbraw_supported = 1; } @@ -144,7 +145,7 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) transport->negotiate.sec_mode = 0; transport->negotiate.server_time = time(NULL); transport->negotiate.max_xmit = ~0; - transport->negotiate.server_zone = TimeDiff(time(NULL)); + transport->negotiate.server_zone = get_time_zone(transport->negotiate.server_time); } /* a way to force ascii SMB */ diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 3aa95c35aa..3e3b29d252 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -223,7 +223,8 @@ struct cli_request *smb_raw_write_send(struct cli_tree *tree, union smb_write *p SSVAL(req->out.vwv, VWV(0), parms->writeclose.in.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeclose.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeclose.in.offset); - put_dos_date3(req->out.vwv, VWV(4), parms->writeclose.in.mtime); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(4), parms->writeclose.in.mtime); SCVAL(req->out.data, 0, 0); if (parms->writeclose.in.count > 0) { memcpy(req->out.data+1, parms->writeclose.in.data, diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 4c7da6ec4d..a4236d2dbe 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -44,7 +44,8 @@ static void smb_raw_search_backend(struct cli_request *req, for (i=0; i < count; i++) { search_data.search.search_id = cli_req_pull_blob(req, mem_ctx, p, 21); search_data.search.attrib = CVAL(p, 21); - search_data.search.write_time = make_unix_date(p + 22); + search_data.search.write_time = raw_pull_dos_date(req->transport, + p + 22); search_data.search.size = IVAL(p, 26); cli_req_pull_ascii(req, mem_ctx, &search_data.search.name, p+30, 13, STR_ASCII); if (!callback(private, &search_data)) { @@ -255,9 +256,12 @@ static int parse_trans2_search(struct cli_tree *tree, blob->length -= 4; } if (blob->length < 24) return -1; - data->standard.create_time = make_unix_date2(blob->data + 0); - data->standard.access_time = make_unix_date2(blob->data + 4); - data->standard.write_time = make_unix_date2(blob->data + 8); + data->standard.create_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 0); + data->standard.access_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 4); + data->standard.write_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 8); data->standard.size = IVAL(blob->data, 12); data->standard.alloc_size = IVAL(blob->data, 16); data->standard.attrib = SVAL(blob->data, 20); @@ -274,9 +278,12 @@ static int parse_trans2_search(struct cli_tree *tree, blob->length -= 4; } if (blob->length < 28) return -1; - data->ea_size.create_time = make_unix_date2(blob->data + 0); - data->ea_size.access_time = make_unix_date2(blob->data + 4); - data->ea_size.write_time = make_unix_date2(blob->data + 8); + data->ea_size.create_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 0); + data->ea_size.access_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 4); + data->ea_size.write_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 8); data->ea_size.size = IVAL(blob->data, 12); data->ea_size.alloc_size = IVAL(blob->data, 16); data->ea_size.attrib = SVAL(blob->data, 20); diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index b82c20176b..9da94f161c 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -45,9 +45,12 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, case RAW_SFILEINFO_STANDARD: NEED_BLOB(12); - put_dos_date2(blob->data, 0, parms->standard.in.create_time); - put_dos_date2(blob->data, 4, parms->standard.in.access_time); - put_dos_date2(blob->data, 8, parms->standard.in.write_time); + raw_push_dos_date2(tree->session->transport, + blob->data, 0, parms->standard.in.create_time); + raw_push_dos_date2(tree->session->transport, + blob->data, 4, parms->standard.in.access_time); + raw_push_dos_date2(tree->session->transport, + blob->data, 8, parms->standard.in.write_time); return True; case RAW_SFILEINFO_EA_SET: @@ -204,7 +207,8 @@ static struct cli_request *smb_raw_setattr_send(struct cli_tree *tree, if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), parms->setattr.in.attrib); - put_dos_date3(req->out.vwv, VWV(1), parms->setattr.in.write_time); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(1), parms->setattr.in.write_time); memset(req->out.vwv + VWV(3), 0, 10); /* reserved */ cli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE); cli_req_append_ascii4(req, "", STR_TERMINATE); @@ -229,9 +233,12 @@ static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree, if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), parms->setattre.file.fnum); - put_dos_date2(req->out.vwv, VWV(1), parms->setattre.in.create_time); - put_dos_date2(req->out.vwv, VWV(3), parms->setattre.in.access_time); - put_dos_date2(req->out.vwv, VWV(5), parms->setattre.in.write_time); + raw_push_dos_date2(tree->session->transport, + req->out.vwv, VWV(1), parms->setattre.in.create_time); + raw_push_dos_date2(tree->session->transport, + req->out.vwv, VWV(3), parms->setattre.in.access_time); + raw_push_dos_date2(tree->session->transport, + req->out.vwv, VWV(5), parms->setattre.in.write_time); if (!cli_request_send(req)) { cli_request_destroy(req); diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 39f3803ade..fc3449d767 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -342,10 +342,13 @@ static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) uchar client_chal[8]; DATA_BLOB response = data_blob(NULL, 0); char long_date[8]; + NTTIME nttime; + + unix_to_nt_time(&nttime, time(NULL)); generate_random_buffer(client_chal, sizeof(client_chal), False); - put_long_date(long_date, time(NULL)); + push_nttime(long_date, 0, &nttime); /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ -- cgit From 00cedc0c0448b3520678c7959ea9269d6e5c10f1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Apr 2004 21:17:58 +0000 Subject: r189: Added UNIX search into tests - added client library parse code. Jeremy. (This used to be commit a25ae9addbb362abf67a0cbd6e62bf4cbe06d8b7) --- source4/libcli/raw/rawsearch.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index a4236d2dbe..ef854679dc 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -413,8 +413,34 @@ static int parse_trans2_search(struct cli_tree *tree, return -1; } return ofs; - } + case RAW_SEARCH_UNIX_INFO: + if (blob->length < 105) return -1; + ofs = IVAL(blob->data, 0); + data->unix_info.file_index = IVAL(blob->data, 4); + data->unix_info.size = BVAL(blob->data, 8); + data->unix_info.alloc_size = BVAL(blob->data, 16); + data->unix_info.status_change_time = cli_pull_nttime(blob->data, 24); + data->unix_info.access_time = cli_pull_nttime(blob->data, 32); + data->unix_info.change_time = cli_pull_nttime(blob->data, 40); + data->unix_info.uid = IVAL(blob->data, 48); + data->unix_info.gid = IVAL(blob->data, 56); + data->unix_info.file_type = IVAL(blob->data, 64); + data->unix_info.dev_major = BVAL(blob->data, 68); + data->unix_info.dev_minor = BVAL(blob->data, 76); + data->unix_info.unique_id = BVAL(blob->data, 84); + data->unix_info.permissions = IVAL(blob->data, 92); + data->unix_info.nlink = IVAL(blob->data, 100); + /* There is no length field for this name but we know it's null terminated. */ + len = cli_blob_pull_string(tree->session, mem_ctx, blob, + &data->unix_info.name, + 0, 104, 0); + if (ofs != 0 && ofs < 104+len) { + return -1; + } + return ofs; + + } /* invalid level */ return -1; } -- cgit From 763c4bc9acc0e9162bcb7c8e487522fa62aedae6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Apr 2004 01:09:41 +0000 Subject: r204: Turns out that the string in the SEARCH unix_info level is that rare thing, a non-length string (ie. not a WIRE_STRING) but a null terminated char string. There wasn't a good interface to pull that out of a blob (all the string interfaces assumed WIRE_STRINGS). Added a new one, only used for this call. Sucks, I know - but the alternatives suck more. Added tests for some of the unix info returned. Jeremy. (This used to be commit 4d0ed04c54b105789ffd32334c3b0e544f02418c) --- source4/libcli/raw/rawrequest.c | 46 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/raw/rawsearch.c | 9 ++++---- 2 files changed, 50 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index f03cc5cf16..321d43f220 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -1007,6 +1007,52 @@ size_t cli_blob_pull_string(struct cli_session *session, blob->data+str_offset, dest->private_length, flags); } +/* + pull a string from a blob, returning a talloced char * + + Currently only used by the UNIX search info level. + + the string length is limited by 2 things: + - the data size in the blob + - the end of string (null termination) + + on failure zero is returned and dest->s is set to NULL, otherwise the number + of bytes consumed in the blob is returned +*/ +size_t cli_blob_pull_unix_string(struct cli_session *session, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, + const char **dest, + uint16 str_offset, + unsigned flags) +{ + int extra = 0; + *dest = NULL; + + if (!(flags & STR_ASCII) && + ((flags & STR_UNICODE) || + (session->transport->negotiate.capabilities & CAP_UNICODE))) { + int align = 0; + if ((str_offset&1) && !(flags & STR_NOALIGN)) { + align = 1; + } + if (flags & STR_LEN_NOTERM) { + extra = 2; + } + return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, dest, + blob->data+str_offset+align, + -1, flags); + } + + if (flags & STR_LEN_NOTERM) { + extra = 1; + } + + return extra + cli_blob_pull_ascii(mem_ctx, blob, dest, + blob->data+str_offset, -1, flags); +} + + /* append a string into a blob */ diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index ef854679dc..8b60633fe8 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -415,7 +415,7 @@ static int parse_trans2_search(struct cli_tree *tree, return ofs; case RAW_SEARCH_UNIX_INFO: - if (blob->length < 105) return -1; + if (blob->length < 109) return -1; ofs = IVAL(blob->data, 0); data->unix_info.file_index = IVAL(blob->data, 4); data->unix_info.size = BVAL(blob->data, 8); @@ -432,10 +432,9 @@ static int parse_trans2_search(struct cli_tree *tree, data->unix_info.permissions = IVAL(blob->data, 92); data->unix_info.nlink = IVAL(blob->data, 100); /* There is no length field for this name but we know it's null terminated. */ - len = cli_blob_pull_string(tree->session, mem_ctx, blob, - &data->unix_info.name, - 0, 104, 0); - if (ofs != 0 && ofs < 104+len) { + len = cli_blob_pull_unix_string(tree->session, mem_ctx, blob, + &data->unix_info.name, 108, 0); + if (ofs != 0 && ofs < 108+len) { return -1; } return ofs; -- cgit From b9411f8aca7d3619551adaa09cd632cb507a6c7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 18 Apr 2004 03:57:09 +0000 Subject: r265: fixed a bug in the string to sid conversion code (This used to be commit 117aa5cab7783ea741d4840ea5ced00cf34868a3) --- source4/libcli/util/dom_sid.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index 652f17a6b6..dbc9c20155 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -44,10 +44,10 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) sidstr = p+1; ia = strtol(sidstr, &p, 10); - if (*p != '-') { + if (p == sidstr) { return NULL; } - sidstr = p+1; + sidstr = p; num_sub_auths = 0; for (i=0;sidstr[i];i++) { @@ -75,14 +75,15 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) ret->num_auths = num_sub_auths; for (i=0;isub_auths[i] = strtol(sidstr, &p, 10); - if (p == sidstr) { + if (sidstr[0] != '-') { return NULL; } - if (*p != '-' && i < num_sub_auths-1) { + sidstr++; + ret->sub_auths[i] = strtol(sidstr, &p, 10); + if (p == sidstr) { return NULL; } - sidstr = p+1; + sidstr = p; } return ret; -- cgit From 8fce9e3c549bcf1433119333ddbbf0a3dc4af8d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Apr 2004 05:48:03 +0000 Subject: r275: added IDL and test code for samr_QueryDisplayInfo3(), samr_AddMultipleMembersToAlias(), samr_RemoveMultipleMembersFromAlias(), samr_OemChangePasswordUser2(), and samr_ChangePasswordUser2() The password change functions don't actually work yet (but should soon). At this stage I have just completed the IDL for them. Next step is to get the hash verifiers right and the torture test should be able to do password changes. (This used to be commit 849d0d314a2add80f2b2be6b503fea05973f998e) --- source4/libcli/util/smbencrypt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index fc3449d767..13d56e1e78 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -217,7 +217,9 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) +BOOL make_oem_passwd_hash(char data[516], const char *passwd, + const uchar old_pw_hash[16], + BOOL unicode) { int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); @@ -242,7 +244,9 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); + SamOEMhash((unsigned char *)data, + (const unsigned char *)old_pw_hash, + 516); return True; } -- cgit From 5f545543f0bfb9d97d6401576906c0ba9e596cd1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Apr 2004 05:01:31 +0000 Subject: r305: - added IDL and test code for samr_RidToSid() - completed the IDL and test code for the various set user password mechanisms in samr. Three password mechanisms are now working, the UserInfo24 method, the OemChangePasswordUser2() method (which only sets the LM password) and the ChangePasswordUser2() method which sets both the LM and NT passwords. - updated some crypto routines to support the password change tests (This used to be commit 051efa2abf9d1fbbf783df411c02f2714027f813) --- source4/libcli/util/smbdes.c | 30 ++++++++++++++++++++++-------- source4/libcli/util/smbencrypt.c | 21 ++++++++++++++------- 2 files changed, 36 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index d282b0135a..80b938b460 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -357,7 +357,8 @@ void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, smbhash(out + 8, in + 8, key2, forw); } -void SamOEMhash( unsigned char *data, const unsigned char *key, int val) + +void SamOEMhashBlob(unsigned char *data, int len, const DATA_BLOB *key) { unsigned char s_box[256]; unsigned char index_i = 0; @@ -369,23 +370,22 @@ void SamOEMhash( unsigned char *data, const unsigned char *key, int val) s_box[ind] = (unsigned char)ind; } - for( ind = 0; ind < 256; ind++) { + for (ind = 0; ind < 256; ind++) { unsigned char tc; - - j += (s_box[ind] + key[ind%16]); - + + j += (s_box[ind] + key->data[ind%key->length]); + tc = s_box[ind]; s_box[ind] = s_box[j]; s_box[j] = tc; } - - for (ind = 0; ind < val; ind++){ + for (ind = 0; ind < len; ind++) { unsigned char tc; unsigned char t; index_i++; index_j += s_box[index_i]; - + tc = s_box[index_i]; s_box[index_i] = s_box[index_j]; s_box[index_j] = tc; @@ -395,6 +395,20 @@ void SamOEMhash( unsigned char *data, const unsigned char *key, int val) } } +/* + a varient that assumes a 16 byte key. This should be removed + when the last user is gone +*/ +void SamOEMhash(unsigned char *data, const unsigned char keystr[16], int len) +{ + DATA_BLOB key; + + key.length = 16; + key.data = keystr; + + SamOEMhashBlob(data, len, &key); +} + /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 13d56e1e78..a1c026a27d 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -460,21 +460,28 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password } /*********************************************************** - encode a password buffer. The caller gets to figure out - what to put in it. + encode a password buffer with a unicode password. The buffer + is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length) +BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) { - generate_random_buffer((unsigned char *)buffer, 516, True); + uchar new_pw[512]; + size_t new_pw_len; - memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length); + new_pw_len = push_string(NULL, new_pw, + password, + sizeof(new_pw), string_flags); + + memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); + + generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True); /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - SIVAL(buffer, 512, new_pw_length); - + SIVAL(buffer, 512, new_pw_len); + ZERO_STRUCT(new_pw); return True; } -- cgit From 2b9fb9618ad8b2b468b0f9961f35a2b0db9d53b5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Apr 2004 06:18:40 +0000 Subject: r324: - don't reseed on every password generate - check for overflow (very unlikely) in random buffer generation (This used to be commit 548ec1efefa6f337a362cbadae74f177774e9e29) --- source4/libcli/util/smbencrypt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index a1c026a27d..a091805345 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -471,10 +471,13 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) new_pw_len = push_string(NULL, new_pw, password, sizeof(new_pw), string_flags); + if (new_pw_len > 512) { + return False; + } memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True); + generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, False); /* * The length of the new password is in the last 4 bytes of @@ -485,6 +488,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) return True; } + /*********************************************************** decode a password buffer *new_pw_len is the length in bytes of the possibly mulitbyte -- cgit From 493a37ba663686b7bee3f7093d6650a24250f101 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 Apr 2004 04:21:22 +0000 Subject: r335: added much better handling of servers that die unexpectedly during a request (a dead socket). I discovered this when testing against Sun's PC-NetLink. cleaned up the naming of some of the samr requests add IDL and test code for samr_QueryGroupMember(), samr_SetMemberAttributesOfGroup() and samr_Shutdown(). (actually, I didn't leave the samr_Shutdown() test in, as its fatal to windows servers due to doing exactly what it says it does). (This used to be commit 925bc2622c105dee4ffff809c6c35cd209a839f8) --- source4/libcli/raw/clisocket.c | 26 +++++++++++++++++++++++--- source4/libcli/raw/clitransport.c | 8 ++++++++ source4/libcli/raw/rawrequest.c | 11 +++++++---- source4/libcli/raw/rawtrans.c | 1 - 4 files changed, 38 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index f596cba854..4dae7d517d 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -74,15 +74,25 @@ BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) } +/**************************************************************************** + mark the socket as dead +****************************************************************************/ +void cli_sock_dead(struct cli_socket *sock) +{ + if (sock->fd != -1) { + close(sock->fd); + sock->fd = -1; + } +} + /**************************************************************************** reduce socket reference count - if it becomes zero then close ****************************************************************************/ void cli_sock_close(struct cli_socket *sock) { sock->reference_count--; - if (sock->reference_count <= 0 && sock->fd != -1) { - close(sock->fd); - sock->fd = -1; + if (sock->reference_count <= 0) { + cli_sock_dead(sock); } } @@ -99,6 +109,11 @@ void cli_sock_set_options(struct cli_socket *sock, const char *options) ****************************************************************************/ ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) { + if (sock->fd == -1) { + errno = EIO; + return -1; + } + return write_data(sock->fd, data, len); } @@ -108,6 +123,11 @@ ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) ****************************************************************************/ ssize_t cli_sock_read(struct cli_socket *sock, char *data, size_t len) { + if (sock->fd == -1) { + errno = EIO; + return -1; + } + return read_data(sock->fd, data, len); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 62152bbe4d..b8eef65c7f 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -60,6 +60,14 @@ void cli_transport_close(struct cli_transport *transport) } } +/* + mark the transport as dead +*/ +void cli_transport_dead(struct cli_transport *transport) +{ + cli_sock_dead(transport->socket); +} + /**************************************************************************** diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 321d43f220..35a2d363df 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -40,9 +40,11 @@ NTSTATUS cli_request_destroy(struct cli_request *req) _send() call fails completely */ if (!req) return NT_STATUS_UNSUCCESSFUL; - /* remove it from the list of pending requests (a null op if - its not in the list) */ - DLIST_REMOVE(req->transport->pending_requests, req); + if (req->transport) { + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_requests, req); + } /* ahh, its so nice to destroy a complex structure in such a simple way! */ @@ -306,11 +308,12 @@ BOOL cli_request_receive(struct cli_request *req) /* keep receiving packets until this one is replied to */ while (!req->in.buffer) { if (!cli_transport_select(req->transport)) { + req->status = NT_STATUS_UNSUCCESSFUL; return False; } if (!cli_request_receive_next(req->transport)) { - cli_transport_close(req->transport); + cli_transport_dead(req->transport); req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; return False; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index f7a3b4aa43..1fd91b29d7 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -64,7 +64,6 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, parms->out.params.data = NULL; if (!cli_request_receive(req)) { - req->status = NT_STATUS_UNSUCCESSFUL; return cli_request_destroy(req); } -- cgit From 9f084101dd392ceb85f141f55ee56bed344626ef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 2 May 2004 08:45:00 +0000 Subject: r443: Update Samba4 to the auth and NTLMSSP code from Samba3. Not all the auth code is merged - only those parts that are actually being used in Samba4. There is a lot more work to do in the NTLMSSP area, and I hope to develop that work here. There is a start on this here - splitting NTLMSSP into two parts that my operate in an async fashion (before and after the actual authentication) Andrew Bartlett (This used to be commit 5876c78806e6a6c44613a1354e8d564b427d0c9f) --- source4/libcli/auth/ntlm_check.c | 445 ++++++++++++++++++++++++++++++++++++ source4/libcli/auth/ntlmssp.c | 246 ++++++++++++++------ source4/libcli/auth/ntlmssp.h | 7 + source4/libcli/auth/ntlmssp_parse.c | 20 +- source4/libcli/auth/ntlmssp_sign.c | 67 ++++-- source4/libcli/config.m4 | 3 +- source4/libcli/util/smbencrypt.c | 121 +++++----- 7 files changed, 753 insertions(+), 156 deletions(-) create mode 100644 source4/libcli/auth/ntlm_check.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c new file mode 100644 index 0000000000..a7764f9e98 --- /dev/null +++ b/source4/libcli/auth/ntlm_check.c @@ -0,0 +1,445 @@ +/* + Unix SMB/CIFS implementation. + Password and authentication handling + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Gerald Carter 2003 + + 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" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/**************************************************************************** + Core of smb password checking routine. +****************************************************************************/ + +static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, + const uchar *part_passwd, + const DATA_BLOB *sec_blob, + DATA_BLOB *user_sess_key) +{ + /* Finish the encryption of part_passwd. */ + uchar p24[24]; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); + /* No password set - always false ! */ + return False; + } + + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", + (unsigned long)sec_blob->length)); + return False; + } + + if (nt_response->length != 24) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", + (unsigned long)nt_response->length)); + return False; + } + + SMBOWFencrypt(part_passwd, sec_blob->data, p24); + if (user_sess_key != NULL) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); + } + + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); + dump_data(100, part_passwd, 16); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, nt_response->data, nt_response->length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); + dump_data(100, p24, 24); +#endif + return (memcmp(p24, nt_response->data, 24) == 0); +} + +/**************************************************************************** + Core of smb password checking routine. (NTLMv2, LMv2) + Note: The same code works with both NTLMv2 and LMv2. +****************************************************************************/ + +static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, + const uchar *part_passwd, + const DATA_BLOB *sec_blob, + const char *user, const char *domain, + BOOL upper_case_domain, /* should the domain be transformed into upper case? */ + DATA_BLOB *user_sess_key) +{ + /* Finish the encryption of part_passwd. */ + uchar kr[16]; + uchar value_from_encryption[16]; + uchar client_response[16]; + DATA_BLOB client_key_data; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); + /* No password set - always False */ + return False; + } + + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", + (unsigned long)sec_blob->length)); + return False; + } + + if (ntv2_response->length < 24) { + /* We MUST have more than 16 bytes, or the stuff below will go + crazy. No known implementation sends less than the 24 bytes + for LMv2, let alone NTLMv2. */ + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", + (unsigned long)ntv2_response->length)); + return False; + } + + client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); + /* + todo: should we be checking this for anything? We can't for LMv2, + but for NTLMv2 it is meant to contain the current time etc. + */ + + memcpy(client_response, ntv2_response->data, sizeof(client_response)); + + if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { + return False; + } + + SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); + if (user_sess_key != NULL) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); + } + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); + dump_data(100, part_passwd, 16); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, ntv2_response->data, ntv2_response->length); + DEBUGADD(100,("Variable data from client was |\n")); + dump_data(100, client_key_data.data, client_key_data.length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); + dump_data(100, value_from_encryption, 16); +#endif + data_blob_clear_free(&client_key_data); + return (memcmp(value_from_encryption, client_response, 16) == 0); +} + +/** + * Check a challenge-response password against the value of the NT or + * LM password hash. + * + * @param mem_ctx talloc context + * @param challenge 8-byte challenge. If all zero, forces plaintext comparison + * @param nt_response 'unicode' NT response to the challenge, or unicode password + * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page + * @param username internal Samba username, for log messages + * @param client_username username the client used + * @param client_domain domain name the client used (may be mapped) + * @param nt_pw MD4 unicode password from our passdb or similar + * @param lm_pw LANMAN ASCII password from our passdb or similar + * @param user_sess_key User session key + * @param lm_sess_key LM session key (first 8 bytes of the LM hash) + */ + +NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, + const DATA_BLOB *challenge, + const DATA_BLOB *lm_response, + const DATA_BLOB *nt_response, + const DATA_BLOB *lm_interactive_pwd, + const DATA_BLOB *nt_interactive_pwd, + const char *username, + const char *client_username, + const char *client_domain, + const uint8 *lm_pw, const uint8 *nt_pw, + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) +{ + static const unsigned char zeros[8]; + if (nt_pw == NULL) { + DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", + username)); + } + + if (nt_interactive_pwd && nt_interactive_pwd->length && nt_pw) { + if (nt_interactive_pwd->length != 16) { + DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_pwd->length, + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) { + if (user_sess_key) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data); + } + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (lm_interactive_pwd && lm_interactive_pwd->length && lm_pw) { + if (lm_interactive_pwd->length != 16) { + DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_pwd->length, + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (memcmp(lm_interactive_pwd->data, lm_pw, 16) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } + + /* Check for cleartext netlogon. Used by Exchange 5.5. */ + if (challenge->length == sizeof(zeros) && + (memcmp(challenge->data, zeros, challenge->length) == 0 )) { + + DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", + username)); + if (nt_pw && nt_response->length) { + unsigned char pwhash[16]; + mdfour(pwhash, nt_response->data, nt_response->length); + if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NT (Unicode) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", + username)); + + } else if (lm_pw && lm_response->length) { + uchar dospwd[14]; + uchar p16[16]; + ZERO_STRUCT(dospwd); + + memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + + /* we *might* need to upper-case the string here */ + E_P16((const unsigned char *)dospwd, p16); + + if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: LANMAN (ASCII) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); + return NT_STATUS_WRONG_PASSWORD; + } + } + + if (nt_response->length != 0 && nt_response->length < 24) { + DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + } + + if (nt_response->length >= 24 && nt_pw) { + if (nt_response->length > 24) { + /* We have the NT MD4 hash challenge available - see if we can + use it + */ + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + client_domain, + False, + user_sess_key)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain)); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + client_domain, + True, + user_sess_key)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + "", + False, + user_sess_key)) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } + + if (lp_ntlm_auth()) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n")); + if (smb_pwd_check_ntlmv1(nt_response, + nt_pw, challenge, + user_sess_key)) { + /* The LM session key for this response is not very secure, + so use it only if we otherwise allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n", + username)); + /* no return, becouse we might pick up LMv2 in the LM field */ + } + } + + if (lm_response->length == 0) { + DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (lm_response->length < 24) { + DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", + username)); + } else if (!lm_pw) { + DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n", + username)); + } else { + DEBUG(4,("ntlm_password_check: Checking LM password\n")); + if (smb_pwd_check_ntlmv1(lm_response, + lm_pw, challenge, + NULL)) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + return NT_STATUS_OK; + } + } + + if (!nt_pw) { + DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username)); + return NT_STATUS_WRONG_PASSWORD; + } + + /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. + - related to Win9X, legacy NAS pass-though authentication + */ + DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + client_domain, + False, + NULL)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain)); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + client_domain, + True, + NULL)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + "", + False, + NULL)) { + return NT_STATUS_OK; + } + + /* Apparently NT accepts NT responses in the LM field + - I think this is related to Win9X pass-though authentication + */ + DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); + if (lp_ntlm_auth()) { + if (smb_pwd_check_ntlmv1(lm_response, + nt_pw, challenge, + NULL)) { + /* The session key for this response is still very odd. + It not very secure, so use it only if we otherwise + allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } + return NT_STATUS_OK; + } + DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); + } else { + DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); + } + return NT_STATUS_WRONG_PASSWORD; +} + diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 5fd3938a7d..00cf4d380a 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -282,7 +282,7 @@ void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) data_blob_free(&(*ntlmssp_state)->chal); data_blob_free(&(*ntlmssp_state)->lm_resp); data_blob_free(&(*ntlmssp_state)->nt_resp); - + data_blob_free(&(*ntlmssp_state)->encrypted_session_key); talloc_destroy(mem_ctx); } @@ -330,7 +330,7 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = False; } - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) { + if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) { /* other end forcing us to use LM */ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; ntlmssp_state->use_ntlmv2 = False; @@ -338,9 +338,12 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + } + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { @@ -403,13 +406,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); - chal_flags = ntlmssp_state->neg_flags; - - target_name = ntlmssp_target_name(ntlmssp_state, - neg_flags, &chal_flags); - if (target_name == NULL) - return NT_STATUS_INVALID_PARAMETER; - /* Ask our caller what challenge they would like in the packet */ cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); @@ -418,9 +414,21 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } + /* The flags we send back are not just the negotiated flags, + * they are also 'what is in this packet'. Therfore, we + * operate on 'chal_flags' from here on + */ + + chal_flags = ntlmssp_state->neg_flags; + + /* get the right name to fill in as 'target' */ + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + if (target_name == NULL) + return NT_STATUS_INVALID_PARAMETER; + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); - /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; @@ -429,7 +437,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, dnsname[0] = '\0'; get_myfullname(dnsname); - strlower_m(dnsname); /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) @@ -486,20 +493,12 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, * @return Errors or NT_STATUS_OK. */ -static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) +static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request) { - DATA_BLOB encrypted_session_key = data_blob(NULL, 0); - DATA_BLOB nt_session_key = data_blob(NULL, 0); - DATA_BLOB lm_session_key = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); uint32 ntlmssp_command, auth_flags; NTSTATUS nt_status; - /* used by NTLM2 */ - BOOL doing_ntlm2 = False; - - uchar session_nonce[16]; uchar session_nonce_hash[16]; const char *parse_string; @@ -507,9 +506,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, char *user = NULL; char *workstation = NULL; - /* parse the NTLMSSP packet */ - *reply = data_blob(NULL, 0); - #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); #endif @@ -536,14 +532,14 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &domain, &user, &workstation, - &encrypted_session_key, + &ntlmssp_state->encrypted_session_key, &auth_flags)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)request.data, request.length); SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->encrypted_session_key); auth_flags = 0; /* Try again with a shorter string (Win9X truncates this packet) */ @@ -572,11 +568,14 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } } + if (auth_flags) + ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth()); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } @@ -584,7 +583,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } @@ -592,7 +591,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } @@ -618,13 +617,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, struct MD5Context md5_session_nonce_ctx; SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8); - doing_ntlm2 = True; + ntlmssp_state->doing_ntlm2 = True; - memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8); - memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8); + memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8); + memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8); MD5Init(&md5_session_nonce_ctx); - MD5Update(&md5_session_nonce_ctx, session_nonce, 16); + MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8); @@ -634,69 +633,117 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /* We changed the effective challenge - set it */ if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) { - data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } } } + return NT_STATUS_OK; +} - /* Finally, actually ask if the password is OK */ - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { - data_blob_free(&encrypted_session_key); - return nt_status; - } +/** + * Next state function for the Authenticate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param reply The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB *user_session_key, + DATA_BLOB *lm_session_key, + DATA_BLOB *reply) +{ + NTSTATUS nt_status; + DATA_BLOB session_key = data_blob(NULL, 0); + + /* parse the NTLMSSP packet */ + *reply = data_blob(NULL, 0); + + if (user_session_key) + dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length); - dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length); - dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length); + if (lm_session_key) + dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length); /* Handle the different session key derivation for NTLM2 */ - if (doing_ntlm2) { - if (nt_session_key.data && nt_session_key.length == 16) { + if (ntlmssp_state->doing_ntlm2) { + if (user_session_key && user_session_key->data && user_session_key->length == 16) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - hmac_md5(nt_session_key.data, session_nonce, - sizeof(session_nonce), session_key.data); + hmac_md5(user_session_key->data, ntlmssp_state->session_nonce, + sizeof(ntlmssp_state->session_nonce), session_key.data); + DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - + + } else { + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); + session_key = data_blob(NULL, 0); } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (lm_session_key.data && lm_session_key.length >= 8 && - ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, - session_key.data); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); + if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) { + if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data, + session_key.data); + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } else { + /* use the key unmodified - it's + * probably a NULL key from the guest + * login */ + session_key = *lm_session_key; + } + } else { + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); + session_key = data_blob(NULL, 0); } - } else if (nt_session_key.data) { - session_key = nt_session_key; + } else if (user_session_key && user_session_key->data) { + session_key = *user_session_key; + DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } else if (lm_session_key && lm_session_key->data) { + session_key = *lm_session_key; + DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); + dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } else { + DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); + session_key = data_blob(NULL, 0); } /* With KEY_EXCH, the client supplies the proposed session key, but encrypts it with the long-term key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - if (!encrypted_session_key.data || encrypted_session_key.length != 16) { - data_blob_free(&encrypted_session_key); + if (!ntlmssp_state->encrypted_session_key.data + || ntlmssp_state->encrypted_session_key.length != 16) { + data_blob_free(&ntlmssp_state->encrypted_session_key); DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", - encrypted_session_key.length)); + ntlmssp_state->encrypted_session_key.length)); return NT_STATUS_INVALID_PARAMETER; } else if (!session_key.data || session_key.length != 16) { DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", session_key.length)); + ntlmssp_state->session_key = session_key; } else { - dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, + dump_data_pw("KEY_EXCH session key (enc):\n", + ntlmssp_state->encrypted_session_key.data, + ntlmssp_state->encrypted_session_key.length); + SamOEMhash(ntlmssp_state->encrypted_session_key.data, session_key.data, - encrypted_session_key.length); + ntlmssp_state->encrypted_session_key.length); ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, - encrypted_session_key.data, - encrypted_session_key.length); - dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length); + ntlmssp_state->encrypted_session_key.data, + ntlmssp_state->encrypted_session_key.length); + dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data, + ntlmssp_state->encrypted_session_key.length); } } else { ntlmssp_state->session_key = session_key; } - data_blob_free(&encrypted_session_key); + nt_status = ntlmssp_sign_init(ntlmssp_state); + + data_blob_free(&ntlmssp_state->encrypted_session_key); /* allow arbitarily many authentications */ ntlmssp_state->expected_state = NTLMSSP_AUTH; @@ -704,6 +751,47 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, return nt_status; } + +/** + * Next state function for the Authenticate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param reply The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB user_session_key = data_blob(NULL, 0); + DATA_BLOB lm_session_key = data_blob(NULL, 0); + NTSTATUS nt_status; + + /* parse the NTLMSSP packet */ + *reply = data_blob(NULL, 0); + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, request))) { + return nt_status; + } + + /* + * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth + * is required (by "ntlm auth = no" and "lm auth = no" being set in the + * smb.conf file) and no NTLMv2 response was sent then the password check + * will fail here. JRA. + */ + + /* Finally, actually ask if the password is OK */ + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, + &user_session_key, &lm_session_key))) { + return nt_status; + } + + return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key, reply); +} + /** * Create an NTLMSSP state machine * @@ -874,7 +962,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } if (!ntlmssp_state->password) { + static const uchar zeros[16]; /* do nothing - blobs are zero length */ + + /* session key is all zeros */ + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); + + /* not doing NLTM2 without a password */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { if (!struct_blob.length) { @@ -900,7 +995,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, uchar nt_hash[16]; uchar session_nonce[16]; uchar session_nonce_hash[16]; - uchar nt_session_key[16]; + uchar user_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); @@ -917,7 +1012,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); - dump_data(5, session_nonce_hash, 8); + dump_data(5, (const char *)session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password, @@ -926,8 +1021,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); - hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); + SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); + hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { @@ -964,16 +1059,19 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* Key exchange encryptes a new client-generated session key with the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + /* Make up a new session key */ uint8 client_session_key[16]; - - generate_random_buffer(client_session_key, sizeof(client_session_key), False); + generate_random_buffer(client_session_key, sizeof(client_session_key), False); + + /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + + /* Mark the new session key as the 'real' session key */ data_blob_free(&session_key); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); - dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); } /* this generates the actual auth packet */ @@ -1018,7 +1116,7 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 8d2fcab320..d678e26e21 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -94,6 +94,13 @@ typedef struct ntlmssp_state DATA_BLOB session_key; uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + + /* internal variables used by NTLM2 */ + BOOL doing_ntlm2; + uchar session_nonce[16]; + + /* internal variables used by KEY_EXCH (client-supplied user session key */ + DATA_BLOB encrypted_session_key; void *auth_context; diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 3444db0306..4b3043aec8 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -216,7 +216,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, /* if odd length and unicode */ return False; } - + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + if (0 < len1) { pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, @@ -241,7 +243,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } - + + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + if (0 < len1) { pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, @@ -266,6 +271,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } + + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + *b = data_blob(blob->data + ptr, len1); } break; @@ -274,6 +283,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, len1 = va_arg(ap, unsigned); /* make sure its in the right format - be strict */ NEED_DATA(len1); + if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + return False; + *b = data_blob(blob->data + head_ofs, len1); head_ofs += len1; break; @@ -284,6 +296,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); + + if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + return False; + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 2f510b0f98..5039a842bc 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -53,7 +53,7 @@ static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) hash[257] = index_j; } -static void calc_hash(unsigned char *hash, const char *k2, int k2l) +static void calc_hash(unsigned char hash[258], const char *k2, int k2l) { unsigned char j = 0; int ind; @@ -78,7 +78,7 @@ static void calc_hash(unsigned char *hash, const char *k2, int k2l) hash[257] = 0; } -static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], +static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16], DATA_BLOB session_key, const char *constant) { @@ -91,8 +91,8 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)); - MD5Final((unsigned char *)digest, &ctx3); + MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1); + MD5Final(digest, &ctx3); calc_hash(hash, digest, 16); } @@ -109,12 +109,12 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - char seq_num[4]; + uchar seq_num[4]; uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); - hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); + hmac_md5_update(seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -122,13 +122,16 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, , ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } - switch (direction) { - case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); - break; - case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); - break; + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); + break; + } } } else { uint32 crc; @@ -145,10 +148,16 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, } NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, - const uchar *data, size_t length, - DATA_BLOB *sig) + const uchar *data, size_t length, + DATA_BLOB *sig) { - NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot check sign packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; @@ -168,6 +177,11 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, DATA_BLOB local_sig; NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot check packet signature\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + if (sig->length < 8) { DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", (unsigned long)sig->length)); @@ -194,8 +208,6 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_ACCESS_DENIED; } - data_blob_free(&local_sig); - /* increment counter on recieive */ ntlmssp_state->ntlmssp_seq_num++; @@ -212,6 +224,11 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot seal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -274,6 +291,11 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot unseal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + DEBUG(10,("ntlmssp__unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -299,6 +321,11 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot intialise signing\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { const char *send_sign_const; @@ -337,14 +364,14 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, ntlmssp_state->recv_sign_const, - ntlmssp_state->session_key, send_sign_const); + ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP receive sign hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, ntlmssp_state->recv_seal_const, - ntlmssp_state->session_key, send_seal_const); + ntlmssp_state->session_key, recv_seal_const); dump_data_pw("NTLMSSP receive seal hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index b5273b9bb2..7fdbe17349 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -26,7 +26,8 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], SMB_SUBSYSTEM(LIBCLI_AUTH,[], [libcli/auth/ntlmssp.o libcli/auth/ntlmssp_parse.o \ libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o \ - libcli/auth/credentials.o libcli/auth/session.o], + libcli/auth/credentials.o libcli/auth/session.o \ + libcli/auth/ntlm_check.o], libcli/auth/libcli_auth_public_proto.h) SMB_SUBSYSTEM(LIBCLI_NMB,[], diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index a091805345..4b2c753637 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -28,13 +28,17 @@ /* This implements the X/Open SMB password encryption It takes a password ('unix' string), a 8 byte "crypt key" - and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) + and puts 24 bytes of encrypted password into p24 + + Returns False if password must have been truncated to create LM hash +*/ +BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) { + BOOL ret; uchar p21[21]; memset(p21,'\0',21); - E_deshash(passwd, p21); + ret = E_deshash(passwd, p21); SMBOWFencrypt(p21, c8, p24); @@ -44,6 +48,8 @@ void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) dump_data(100, (const char *)c8, 8); dump_data(100, (char *)p24, 24); #endif + + return ret; } /** @@ -70,20 +76,29 @@ void E_md4hash(const char *passwd, uchar p16[16]) * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. * @param p16 return password hashed with DES, caller allocated 16 byte buffer + * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True + * @note p16 is filled in regardless */ -void E_deshash(const char *passwd, uchar p16[16]) +BOOL E_deshash(const char *passwd, uchar p16[16]) { + BOOL ret = True; fstring dospwd; ZERO_STRUCT(dospwd); /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const unsigned char *)dospwd, p16); + if (strlen(dospwd) > 14) { + ret = False; + } + ZERO_STRUCT(dospwd); + + return ret; } /** @@ -118,7 +133,9 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) /* Does both the NTLMv2 owfs of a user's password */ BOOL ntv2_owf_gen(const uchar owf[16], - const char *user_in, const char *domain_in, uchar kr_buf[16]) + const char *user_in, const char *domain_in, + BOOL upper_case_domain, /* Transform the domain into UPPER case */ + uchar kr_buf[16]) { smb_ucs2_t *user; smb_ucs2_t *domain; @@ -141,7 +158,9 @@ BOOL ntv2_owf_gen(const uchar owf[16], } strupper_w(user); - strupper_w(domain); + + if (upper_case_domain) + strupper_w(domain); SMB_ASSERT(user_byte_len >= 2); SMB_ASSERT(domain_byte_len >= 2); @@ -217,40 +236,6 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], const char *passwd, - const uchar old_pw_hash[16], - BOOL unicode) -{ - int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); - - if (new_pw_len > 512) - { - DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); - return False; - } - - /* - * Now setup the data area. - * We need to generate a random fill - * for this area to make it harder to - * decrypt. JRA. - */ - generate_random_buffer((unsigned char *)data, 516, False); - push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len, - STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII)); - SIVAL(data, 512, new_pw_len); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("make_oem_passwd_hash\n")); - dump_data(100, data, 516); -#endif - SamOEMhash((unsigned char *)data, - (const unsigned char *)old_pw_hash, - 516); - - return True; -} - /* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB *srv_chal, @@ -329,15 +314,35 @@ void SMBsesskeygen_lmv1(const uchar lm_hash[16], #endif } +void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], + const uchar lm_resp[24], /* only uses 8 */ + uint8 sess_key[16]) +{ + uchar p24[24]; + uchar partial_lm_hash[16]; + + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 8); + + SMBOWFencrypt(partial_lm_hash, lm_resp, p24); + + memcpy(sess_key, p24, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); + dump_data(100, sess_key, 16); +#endif +} + DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, const char *domain) { DATA_BLOB names_blob = data_blob(NULL, 0); msrpc_gen(&names_blob, "aaa", - True, NTLMSSP_NAME_TYPE_DOMAIN, domain, - True, NTLMSSP_NAME_TYPE_SERVER, hostname, - True, 0, ""); + NTLMSSP_NAME_TYPE_DOMAIN, domain, + NTLMSSP_NAME_TYPE_SERVER, hostname, + 0, ""); return names_blob; } @@ -424,7 +429,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *nt_session_key) + DATA_BLOB *user_session_key) { uchar nt_hash[16]; uchar ntlm_v2_hash[16]; @@ -434,19 +439,19 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password the username and domain. This prevents username swapping during the auth exchange */ - if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) { + if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { return False; } if (nt_response) { *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, names_blob); - if (nt_session_key) { - *nt_session_key = data_blob(NULL, 16); + if (user_session_key) { + *user_session_key = data_blob(NULL, 16); /* The NTLMv2 calculations also provide a session key, for signing etc later */ /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data); + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); } } @@ -471,9 +476,6 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) new_pw_len = push_string(NULL, new_pw, password, sizeof(new_pw), string_flags); - if (new_pw_len > 512) { - return False; - } memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); @@ -495,13 +497,14 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) returned password including termination. ************************************************************/ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) + int new_pwrd_size, uint32 *new_pw_len, + int string_flags) { int byte_len=0; /* Warning !!! : This function is called from some rpc call. - The password IN the buffer is a UNICODE string. + The password IN the buffer may be a UNICODE string. The password IN new_pwrd is an ASCII string If you reuse that code somewhere else check first. */ @@ -514,15 +517,16 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, dump_data(100, in_buffer, 516); #endif - /* Password cannot be longer than 128 characters */ - if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + /* Password cannot be longer than the size of the password buffer */ + if ( (byte_len < 0) || (byte_len > 512)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); return False; } - /* decode into the return buffer. Buffer must be a pstring */ - *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE); + /* decode into the return buffer. Buffer length supplied */ + *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + byte_len, string_flags); #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); @@ -533,4 +537,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -- cgit From d8bb3d81a6396c4051be00de0808c60839b6945e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 2 May 2004 12:42:01 +0000 Subject: r451: More NTLMSSP work. The work here is trying to get the LM_KEY option for NLTMSSP operating, however until that functions properly, it is now controlled by some new smb.conf options, defaulting off. Andrew Bartlett (This used to be commit c63eb35b45c6db6e4c5302d1832bb5cef49a14f6) --- source4/libcli/auth/ntlmssp.c | 190 +++++++++++++++++++++++++++++++-------- source4/libcli/auth/ntlmssp.h | 5 +- source4/libcli/util/smbencrypt.c | 62 +++---------- 3 files changed, 167 insertions(+), 90 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 00cf4d380a..161a15023a 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -330,10 +330,10 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = False; } - if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) { + if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) { /* other end forcing us to use LM */ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; - ntlmssp_state->use_ntlmv2 = False; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } @@ -348,6 +348,13 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; + if (neg_flags & NTLMSSP_NEGOTIATE_56) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; + } + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56; } if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { @@ -360,6 +367,32 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, } +/** + Weaken NTLMSSP keys to cope with down-level clients and servers. + + We probably should have some parameters to control this, but as + it only occours for LM_KEY connections, and this is controlled + by the client lanman auth/lanman auth parameters, it isn't too bad. +*/ + +static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) { + /* Key weakening not performed on the master key for NTLM2 + and does not occour for NTLM1. Therefore we only need + to do this for the LM_KEY. + */ + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { + + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + ntlmssp_state->session_key.data[7] = 0xa0; + } else { /* forty bits */ + ntlmssp_state->session_key.data[5] = 0xe5; + ntlmssp_state->session_key.data[6] = 0x38; + ntlmssp_state->session_key.data[7] = 0xb0; + } + } +} /** * Next state function for the Negotiate packet @@ -404,7 +437,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, debug_ntlmssp_flags(neg_flags); } - ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); + ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key); /* Ask our caller what challenge they would like in the packet */ cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); @@ -534,8 +567,8 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, &workstation, &ntlmssp_state->encrypted_session_key, &auth_flags)) { - DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); - dump_data(2, (const char *)request.data, request.length); + DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); + dump_data(10, (const char *)request.data, request.length); SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); @@ -569,7 +602,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, } if (auth_flags) - ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth()); + ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { SAFE_FREE(domain); @@ -636,6 +669,9 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } + + /* LM Key is incompatible... */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } } return NT_STATUS_OK; @@ -680,7 +716,10 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); session_key = data_blob(NULL, 0); } - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + /* Ensure we can never get here on NTLMv2 */ + && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) { + if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) { if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); @@ -688,27 +727,47 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); dump_data_pw("LM session key:\n", session_key.data, session_key.length); - } else { - /* use the key unmodified - it's - * probably a NULL key from the guest - * login */ - session_key = *lm_session_key; + } else { + + /* When there is no LM response, just use zeros */ + static const uchar zeros[24]; + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lm_sess_key(zeros, zeros, + session_key.data); + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); } } else { + /* LM Key not selected */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); } + } else if (user_session_key && user_session_key->data) { session_key = *user_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + + /* LM Key not selected */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } else if (lm_session_key && lm_session_key->data) { + /* Very weird to have LM key, but no user session key, but anyway.. */ session_key = *lm_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + + /* LM Key not selected */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } else { DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); session_key = data_blob(NULL, 0); + + /* LM Key not selected */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } /* With KEY_EXCH, the client supplies the proposed session key, @@ -741,6 +800,9 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; } + /* The server might need us to use a partial-strength session key */ + ntlmssp_weaken_keys(ntlmssp_state); + nt_status = ntlmssp_sign_init(ntlmssp_state); data_blob_free(&ntlmssp_state->encrypted_session_key); @@ -824,6 +886,9 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; + (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() + && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False)); + (*ntlmssp_state)->ref_count = 1; (*ntlmssp_state)->neg_flags = @@ -895,9 +960,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, char *server_domain; const char *chal_parse_string; const char *auth_gen_string; + uchar lm_hash[16]; DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB lm_session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; @@ -917,7 +984,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); + ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key); if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { @@ -967,7 +1034,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* session key is all zeros */ session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); - + lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); + /* not doing NLTM2 without a password */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { @@ -990,6 +1058,10 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } + + /* LM Key is incompatible... */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { struct MD5Context md5_session_nonce_ctx; uchar nt_hash[16]; @@ -1024,38 +1096,69 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + + /* LM Key is incompatible... */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } else { - - - uchar lm_hash[16]; uchar nt_hash[16]; - E_deshash(ntlmssp_state->password, lm_hash); - E_md4hash(ntlmssp_state->password, nt_hash); - + + if (ntlmssp_state->use_nt_response) { + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, + nt_response.data); + E_md4hash(ntlmssp_state->password, nt_hash); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + dump_data_pw("NT session key:\n", session_key.data, session_key.length); + } + /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - SMBencrypt(ntlmssp_state->password,challenge_blob.data, - lm_response.data); + if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data, + lm_response.data)) { + /* If the LM password was too long (and therefore the LM hash being + of the first 14 chars only), don't send it */ + data_blob_free(&lm_response); + + /* LM Key is incompatible with 'long' passwords */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } else { + E_deshash(ntlmssp_state->password, lm_hash); + lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + memcpy(lm_session_key.data, lm_hash, 8); + memset(&lm_session_key.data[8], '\0', 8); + + if (!ntlmssp_state->use_nt_response) { + session_key = lm_session_key; + } + } + } else { + /* LM Key is incompatible... */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, - nt_response.data); - - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lp_client_lanman_auth()) { - SMBsesskeygen_lmv1(lm_hash, lm_response.data, - session_key.data); - dump_data_pw("LM session key\n", session_key.data, session_key.length); + } + + if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + && lp_client_lanman_auth() && lm_session_key.length == 16) { + DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + if (lm_response.length == 24) { + SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, + new_session_key.data); } else { - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); - dump_data_pw("NT session key:\n", session_key.data, session_key.length); + static const uchar zeros[24]; + SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros, + new_session_key.data); } + new_session_key.length = 16; + session_key = new_session_key; + dump_data_pw("LM session key\n", session_key.data, session_key.length); } + data_blob_free(&struct_blob); + /* Key exchange encryptes a new client-generated session key with the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { @@ -1093,10 +1196,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, data_blob_free(&ntlmssp_state->chal); + ntlmssp_state->session_key = session_key; + + /* The client might be using 56 or 40 bit weakened keys */ + ntlmssp_weaken_keys(ntlmssp_state); + ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; - ntlmssp_state->session_key = session_key; ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; @@ -1128,7 +1235,12 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->get_global_myname = global_myname; (*ntlmssp_state)->get_domain = lp_workgroup; - (*ntlmssp_state)->unicode = True; + (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True); + + (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True); + + (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() + && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False)); (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); @@ -1145,7 +1257,11 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) * We need to set this to allow a later SetPassword * via the SAMR pipe to succeed. Strange.... We could * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - * */ + * + * Without this, Windows will not create the master key + * that it thinks is only used for NTLMSSP signing and + * sealing. (It is actually pulled out and used directly) + */ NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index d678e26e21..a5e0951fa8 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -61,7 +61,7 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_CHAL_TARGET_INFO 0x00800000 #define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */ #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 -#define NTLMSSP_NEGOTIATE_080000000 0x80000000 +#define NTLMSSP_NEGOTIATE_56 0x80000000 #define NTLMSSP_NAME_TYPE_SERVER 0x01 #define NTLMSSP_NAME_TYPE_DOMAIN 0x02 @@ -80,6 +80,9 @@ typedef struct ntlmssp_state BOOL unicode; BOOL use_ntlmv2; + BOOL use_nt_response; /* Set to 'NO' to debug what happens when the NT response is omited */ + BOOL allow_lm_key; /* The LM_KEY code is not functional at this point, and it's not + very secure anyway */ char *user; char *domain; char *workstation; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 4b2c753637..cefd01bf1c 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -198,25 +198,6 @@ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) E_P24(p21, c8, p24); } -/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24]) -{ - uchar p21[21]; - - memset(p21,'\0',21); - memcpy(p21, passwd, 8); - memset(p21 + 8, 0xbd, 8); - - E_P24(p21, ntlmchalresp, p24); -#ifdef DEBUG_PASSWORD - DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); - dump_data(100, (char *)p21, 21); - dump_data(100, (const char *)ntlmchalresp, 8); - dump_data(100, (char *)p24, 24); -#endif -} - - /* Does the NT MD4 hash then des encryption. */ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) @@ -288,48 +269,25 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -void SMBsesskeygen_lmv1(const uchar lm_hash[16], - const uchar lm_resp[24], /* only uses 8 */ - uint8 sess_key[16]) +void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], + const uchar lm_resp[24], /* only uses 8 */ + uint8 sess_key[16]) { /* Calculate the LM session key (effective length 40 bits, but changes with each session) */ - uchar p24[24]; - uchar partial_lm_hash[16]; - - memcpy(partial_lm_hash, lm_hash, 8); - memset(partial_lm_hash + 8, 0xbd, 8); - - SMBOWFencrypt(lm_hash, lm_resp, p24); - - memcpy(sess_key, p24, 16); - sess_key[5] = 0xe5; - sess_key[6] = 0x38; - sess_key[7] = 0xb0; - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_lmv1:\n")); - dump_data(100, sess_key, 16); -#endif -} + uchar p21[21]; + + memset(p21,'\0',21); + memcpy(p21, lm_hash, 8); + memset(p21 + 8, 0xbd, 8); -void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], - const uchar lm_resp[24], /* only uses 8 */ - uint8 sess_key[16]) -{ - uchar p24[24]; - uchar partial_lm_hash[16]; - - memcpy(partial_lm_hash, lm_hash, 8); - memset(partial_lm_hash + 8, 0xbd, 8); + E_P24(p21, lm_resp, p24); - SMBOWFencrypt(partial_lm_hash, lm_resp, p24); - memcpy(sess_key, p24, 16); #ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); + DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n")); dump_data(100, sess_key, 16); #endif } -- cgit From dce84ffd379012812170f68f7de8aab73123f0b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 May 2004 12:42:18 +0000 Subject: r610: - Merge the Samba3 'ntlm_auth --diagnostics' testsuite to Samba4. - This required using NETLOGON_NEG_AUTH2_FLAGS for the SetupCredentials2 negotiation flags, which is what Samba3 does, because otherwise the server uses different crypto. - This tests the returned session keys, which we decrypt. - Update the Samba4 notion of a 'session key' to be a DATA_BLOB in most places. - Fix session key code to return NT_STATUS_NO_SESSION_KEY if none is available. - Remove a useless argument to SMBsesskeygen_ntv1 - move netr_CredentialState from the .idl to the new credentials.h Andrew Bartlett (This used to be commit 44f8b5b53e6abd4de8a676f78d729988fadff320) --- source4/libcli/auth/credentials.c | 50 +++++++++++++++++++++++++-------------- source4/libcli/auth/credentials.h | 29 +++++++++++++++++++++++ source4/libcli/auth/ntlm_check.c | 4 ++-- source4/libcli/auth/ntlmssp.c | 4 ++-- source4/libcli/raw/clisession.c | 29 ++++++++++++++++------- source4/libcli/raw/clitransport.c | 8 ------- source4/libcli/raw/smb_signing.c | 12 ++++++---- source4/libcli/util/smbdes.c | 13 +++++----- source4/libcli/util/smbencrypt.c | 3 +-- 9 files changed, 101 insertions(+), 51 deletions(-) create mode 100644 source4/libcli/auth/credentials.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index acc083d57f..638bff7e8b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -27,7 +27,7 @@ this call is made after the netr_ServerReqChallenge call */ -static void creds_init(struct netr_CredentialState *creds, +static void creds_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8 machine_password[16]) @@ -48,11 +48,11 @@ static void creds_init(struct netr_CredentialState *creds, SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(creds->client.data, time_cred.data, creds->session_key); + cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); SIVAL(time_cred.data, 0, IVAL(server_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(server_challenge->data, 4)); - cred_hash2(creds->server.data, time_cred.data, creds->session_key); + cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); creds->seed = creds->client; } @@ -62,7 +62,7 @@ static void creds_init(struct netr_CredentialState *creds, step the credentials to the next element in the chain, updating the current client and server credentials and the seed */ -static void creds_step(struct netr_CredentialState *creds) +static void creds_step(struct creds_CredentialState *creds) { struct netr_Credential time_cred; @@ -76,7 +76,7 @@ static void creds_step(struct netr_CredentialState *creds) DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->client.data, time_cred.data, creds->session_key); + cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tCLIENT %08x:%08x\n", IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); @@ -87,7 +87,7 @@ static void creds_step(struct netr_CredentialState *creds) DEBUG(5,("\tseed+time+1 %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->server.data, time_cred.data, creds->session_key); + cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tSERVER %08x:%08x\n", IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); @@ -95,7 +95,30 @@ static void creds_step(struct netr_CredentialState *creds) creds->seed = time_cred; } +/* + DES encrypt a 16 byte password buffer using the session key +*/ +void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 1); + *pass = tmp; +} + +/* + ARCFOUR encrypt/decrypt a password buffer using the session key +*/ +void creds_arcfour_crypt(struct creds_CredentialState *creds, char *data, size_t len) +{ + DATA_BLOB session_key = data_blob(NULL, 16); + + memcpy(&session_key.data[0], creds->session_key, 8); + memset(&session_key.data[8], '\0', 8); + + SamOEMhashBlob(data, len, &session_key); + data_blob_free(&session_key); +} /***************************************************************** The above functions are common to the client and server interface @@ -106,7 +129,7 @@ next comes the client specific functions initialise the credentials chain and return the first client credentials */ -void creds_client_init(struct netr_CredentialState *creds, +void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8 machine_password[16], @@ -120,7 +143,7 @@ void creds_client_init(struct netr_CredentialState *creds, /* check that a credentials reply from a server is correct */ -BOOL creds_client_check(struct netr_CredentialState *creds, +BOOL creds_client_check(struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { if (memcmp(received_credentials->data, creds->server.data, 8) != 0) { @@ -134,7 +157,7 @@ BOOL creds_client_check(struct netr_CredentialState *creds, produce the next authenticator in the sequence ready to send to the server */ -void creds_client_authenticator(struct netr_CredentialState *creds, +void creds_client_authenticator(struct creds_CredentialState *creds, struct netr_Authenticator *next) { creds_step(creds); @@ -144,12 +167,3 @@ void creds_client_authenticator(struct netr_CredentialState *creds, } -/* - encrypt a 16 byte password buffer using the session key -*/ -void creds_client_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) -{ - struct netr_Password tmp; - cred_hash3(tmp.data, pass->data, creds->session_key, 1); - *pass = tmp; -} diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h new file mode 100644 index 0000000000..7a7a34ced2 --- /dev/null +++ b/source4/libcli/auth/credentials.h @@ -0,0 +1,29 @@ +/* + Unix SMB/CIFS implementation. + + code to manipulate domain credentials + + Copyright (C) Andrew Tridgell 2004 + + 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. +*/ + +struct creds_CredentialState { + uint8 session_key[8]; + uint32 sequence; + struct netr_Credential seed; + struct netr_Credential client; + struct netr_Credential server; +}; diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index a7764f9e98..32a7507c1f 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -59,7 +59,7 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, SMBOWFencrypt(part_passwd, sec_blob->data, p24); if (user_sess_key != NULL) { *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); + SMBsesskeygen_ntv1(part_passwd, user_sess_key->data); } @@ -195,7 +195,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) { if (user_sess_key) { *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data); + SMBsesskeygen_ntv1(nt_pw, user_sess_key->data); } return NT_STATUS_OK; } else { diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 161a15023a..9513d5a138 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -1093,7 +1093,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); + SMBsesskeygen_ntv1(nt_hash, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); @@ -1108,7 +1108,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, nt_response.data); E_md4hash(ntlmssp_state->password, nt_hash); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + SMBsesskeygen_ntv1(nt_hash, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 1c0af77d11..fe64565597 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -234,22 +234,34 @@ static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) return blob; } +/* + store the user session key for a transport +*/ +void cli_session_set_user_session_key(struct cli_session *session, + const DATA_BLOB *session_key) +{ + session->user_session_key = data_blob_talloc(session->mem_ctx, + session_key->data, + session_key->length); +} + /* setup signing for a NT1 style session setup */ -static void setup_nt1_signing(struct cli_transport *transport, const char *password) +static void use_nt1_session_keys(struct cli_session *session, + const char *password, const DATA_BLOB *nt_response) { + struct cli_transport *transport = session->transport; uchar nt_hash[16]; - uchar session_key[16]; - DATA_BLOB nt_response; + DATA_BLOB session_key = data_blob(NULL, 16); E_md4hash(password, nt_hash); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key); - nt_response = nt_blob(password, transport->negotiate.secblob); + SMBsesskeygen_ntv1(nt_hash, session_key.data); - cli_transport_set_session_key(transport, session_key); + cli_transport_simple_set_signing(transport, session_key, *nt_response); - cli_transport_simple_set_signing(transport, session_key, nt_response); + cli_session_set_user_session_key(session, &session_key); + data_blob_free(&session_key); } /**************************************************************************** @@ -332,7 +344,8 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, session->transport->negotiate.secblob); s2.nt1.in.password2 = nt_blob(parms->generic.in.password, session->transport->negotiate.secblob); - setup_nt1_signing(session->transport, parms->generic.in.password); + use_nt1_session_keys(session, parms->generic.in.password, &s2.nt1.in.password2); + } else { s2.nt1.in.password1 = data_blob(parms->generic.in.password, strlen(parms->generic.in.password)); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index b8eef65c7f..72cad2e925 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -231,11 +231,3 @@ BOOL cli_transport_select(struct cli_transport *transport) return True; } -/* - store the user session key for a transport -*/ -void cli_transport_set_session_key(struct cli_transport *transport, - const uint8 session_key[16]) -{ - memcpy(transport->negotiate.user_session_key, session_key, 16); -} diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 2ab61aa001..5f47a5e42a 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -220,7 +220,8 @@ static void cli_transport_simple_free_signing_context(struct cli_transport *tran SMB signing - Simple implementation - setup the MAC key. ************************************************************/ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, - const uchar user_transport_key[16], const DATA_BLOB response) + const DATA_BLOB user_session_key, + const DATA_BLOB response) { struct smb_basic_signing_context *data; @@ -235,10 +236,13 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, data = smb_xmalloc(sizeof(*data)); transport->negotiate.sign_info.signing_context = data; - data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_transport_key, 16); - memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); + + if (response.length) { + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + } /* Initialise the sequence number */ data->next_seq_num = 0; diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 80b938b460..22bafcb449 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -338,14 +338,14 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char smbhash(out, buf, key+9, 1); } -void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) +void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { unsigned char buf[8]; unsigned char key2[8]; ZERO_STRUCT(key2); - smbhash(buf, in, key, 1); + smbhash(buf, in, key, forw); key2[0] = key[7]; - smbhash(out, buf, key2, 1); + smbhash(out, buf, key2, forw); } void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) @@ -401,12 +401,11 @@ void SamOEMhashBlob(unsigned char *data, int len, const DATA_BLOB *key) */ void SamOEMhash(unsigned char *data, const unsigned char keystr[16], int len) { - DATA_BLOB key; - - key.length = 16; - key.data = keystr; + DATA_BLOB key = data_blob(keystr, 16); SamOEMhashBlob(data, len, &key); + + data_blob_free(&key); } diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index cefd01bf1c..5468bdbebe 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -255,8 +255,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], #endif } -void SMBsesskeygen_ntv1(const uchar kr[16], - const uchar * nt_resp, uint8 sess_key[16]) +void SMBsesskeygen_ntv1(const uchar kr[16], uint8 sess_key[16]) { /* yes, this session key does not change - yes, this is a problem - but it is 128 bits */ -- cgit From 59c8f48f0dfc0e4d42623fe1595cd9773ac5d15f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 May 2004 13:07:23 +0000 Subject: r611: Fix breakage from my last commit: Now that all session keys are DATA_BLOBs, fix the callers. This assumes some things about the behaviour of certain crypto algorithms, without the ability to test it on session keys != 16 bytes in length. We will just need to retest when we get the KRB5 support in (DES keys are 8 bytes). Andrew Bartlett (This used to be commit e4355a7ec1eba92bdecef8cc478272897276dbae) --- source4/libcli/auth/session.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 946b0fe62f..77eb1a6527 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -29,7 +29,7 @@ before calling, the out blob must be initialised to be the same size as the in blob */ -void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const uint8 session_key[16], +void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, BOOL forward) { int i, k; @@ -42,10 +42,10 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const uint8 session_ke memset(bin, 0, 8); memcpy(bin, &in->data[i], MIN(8, in->length-i)); - if (k + 7 > 16) { - k = (16 - k); + if (k + 7 > session_key->length) { + k = (session_key->length - k); } - memcpy(key, &session_key[k], 7); + memcpy(key, &session_key->data[k], 7); smbhash(bout, bin, key, forward?1:0); @@ -62,7 +62,7 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const uint8 session_ke caller should free using data_blob_free() */ -DATA_BLOB sess_encrypt_string(const char *str, const uint8 session_key[16]) +DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key) { DATA_BLOB ret, src; int slen = strlen(str); @@ -96,7 +96,7 @@ DATA_BLOB sess_encrypt_string(const char *str, const uint8 session_key[16]) caller should free the returned string */ -char *sess_decrypt_string(DATA_BLOB *blob, const uint8 session_key[16]) +char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) { DATA_BLOB out; int slen; -- cgit From f236700ef67d4f93ec56ec7808584552e94e0dfe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 10:20:53 +0000 Subject: r665: merge over the new build system from my tmp branch to the main SAMBA_4_0 tree. NOTE: that it's not completely ready, but it's functional:-) metze (This used to be commit c78a2ddb28ec50d6570a83b1f66f18a5c3621731) --- source4/libcli/config.m4 | 76 +++++++++++++++++++++++++++++------------------- source4/libcli/libsmb.m4 | 14 +++++---- 2 files changed, 55 insertions(+), 35 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 7fdbe17349..788d7e3a0c 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -1,40 +1,56 @@ dnl # LIBCLI subsystem SMB_SUBSYSTEM(LIBCLI_RAW,[], - [libcli/raw/rawfile.o libcli/raw/smb_signing.o \ - libcli/raw/clisocket.o libcli/raw/clitransport.o \ - libcli/raw/clisession.o libcli/raw/clitree.o \ - libcli/raw/clikrb5.o libcli/raw/clispnego.o libcli/raw/rawrequest.o \ - libcli/raw/rawreadwrite.o libcli/raw/rawsearch.o \ - libcli/raw/rawsetfileinfo.o libcli/raw/raweas.o \ - libcli/raw/rawtrans.o libcli/raw/clioplock.o \ - libcli/raw/rawnegotiate.o libcli/raw/rawfsinfo.o \ - libcli/raw/rawfileinfo.o libcli/raw/rawnotify.o \ - libcli/raw/rawioctl.o libcli/raw/rawacl.o \ - libcli/raw/rawdate.o ], - libcli/raw/libcli_raw_public_proto.h) + [libcli/raw/rawfile.o + libcli/raw/smb_signing.o + libcli/raw/clisocket.o + libcli/raw/clitransport.o + libcli/raw/clisession.o + libcli/raw/clitree.o + libcli/raw/clikrb5.o + libcli/raw/clispnego.o + libcli/raw/rawrequest.o + libcli/raw/rawreadwrite.o + libcli/raw/rawsearch.o + libcli/raw/rawsetfileinfo.o + libcli/raw/raweas.o + libcli/raw/rawtrans.o + libcli/raw/clioplock.o + libcli/raw/rawnegotiate.o + libcli/raw/rawfsinfo.o + libcli/raw/rawfileinfo.o + libcli/raw/rawnotify.o + libcli/raw/rawioctl.o + libcli/raw/rawacl.o + libcli/raw/rawdate.o]) SMB_SUBSYSTEM(LIBCLI_UTILS,[], - [libcli/util/asn1.o \ - libcli/util/smberr.o \ - libcli/util/doserr.o libcli/util/errormap.o \ - libcli/util/pwd_cache.o libcli/util/clierror.o libcli/util/cliutil.o \ - libcli/util/nterr.o libcli/util/smbdes.o libcli/util/smbencrypt.o \ - libcli/util/dom_sid.o], - libcli/util/libcli_utils_public_proto.h) + [libcli/util/asn1.o + libcli/util/smberr.o + libcli/util/doserr.o + libcli/util/errormap.o + libcli/util/pwd_cache.o + libcli/util/clierror.o + libcli/util/cliutil.o + libcli/util/nterr.o + libcli/util/smbdes.o + libcli/util/smbencrypt.o + libcli/util/dom_sid.o]) SMB_SUBSYSTEM(LIBCLI_AUTH,[], - [libcli/auth/ntlmssp.o libcli/auth/ntlmssp_parse.o \ - libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o \ - libcli/auth/credentials.o libcli/auth/session.o \ - libcli/auth/ntlm_check.o], - libcli/auth/libcli_auth_public_proto.h) + [libcli/auth/ntlmssp.o + libcli/auth/ntlmssp_parse.o + libcli/auth/ntlmssp_sign.o + libcli/auth/schannel.o + libcli/auth/credentials.o + libcli/auth/session.o + libcli/auth/ntlm_check.o]) SMB_SUBSYSTEM(LIBCLI_NMB,[], - [libcli/unexpected.o libcli/namecache.o libcli/nmblib.o \ - libcli/namequery.o], - libcli/libcli_nmb_public_proto.h) + [libcli/unexpected.o + libcli/namecache.o + libcli/nmblib.o + libcli/namequery.o]) -SMB_SUBSYSTEM(LIBCLI,[], - [\$(LIBCLI_RAW_OBJS) \$(LIBCLI_UTILS_OBJS) \$(LIBCLI_AUTH_OBJS) \$(LIBCLI_NMB_OBJS)], - librpc/libcli_public_proto.h) +SMB_SUBSYSTEM(LIBCLI,[],[],[], + [LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB]) diff --git a/source4/libcli/libsmb.m4 b/source4/libcli/libsmb.m4 index e34c171e48..fe2a5b17ba 100644 --- a/source4/libcli/libsmb.m4 +++ b/source4/libcli/libsmb.m4 @@ -1,8 +1,12 @@ dnl # LIBSMB subsystem SMB_SUBSYSTEM(LIBSMB,[], - [libcli/clireadwrite.o libcli/cliconnect.o \ - libcli/clifile.o libcli/clilist.o libcli/clitrans2.o \ - libcli/climessage.o libcli/clideltree.o \ - \$(LIBCLI_OBJS) \$(LIBRPC_OBJS)], - libcli/libsmb_public_proto.h) + [libcli/clireadwrite.o + libcli/cliconnect.o + libcli/clifile.o + libcli/clilist.o + libcli/clitrans2.o + libcli/climessage.o + libcli/clideltree.o], + [], + [LIBCLI LIBRPC]) -- cgit From ace1c1f816afe2104f830c9a0f76048e8ea2b0c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 18:06:45 +0000 Subject: r697: make use of SMB_EXT_LIB for LDAP and KRB5 metze (This used to be commit b054f7d4906d1d2b96b352af09c6bdcf96553c2a) --- source4/libcli/config.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 788d7e3a0c..7331223487 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -22,7 +22,8 @@ SMB_SUBSYSTEM(LIBCLI_RAW,[], libcli/raw/rawnotify.o libcli/raw/rawioctl.o libcli/raw/rawacl.o - libcli/raw/rawdate.o]) + libcli/raw/rawdate.o], + [KRB5]) SMB_SUBSYSTEM(LIBCLI_UTILS,[], [libcli/util/asn1.o -- cgit From 90cde0acd1544b544a1e5f3fb396ae8c3229b23d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 20:14:05 +0000 Subject: r702: fix krb5 linking metze (This used to be commit d0145cec9f757d8867d54b1019a3060995a95072) --- source4/libcli/config.m4 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 7331223487..e24fd1ba9e 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -1,5 +1,10 @@ dnl # LIBCLI subsystem +LIBCLI_RAW_LIBS= +if test x"$with_ads_support" = x"yes"; then + LIBCLI_RAW_LIBS="KRB5" +fi + SMB_SUBSYSTEM(LIBCLI_RAW,[], [libcli/raw/rawfile.o libcli/raw/smb_signing.o @@ -23,7 +28,7 @@ SMB_SUBSYSTEM(LIBCLI_RAW,[], libcli/raw/rawioctl.o libcli/raw/rawacl.o libcli/raw/rawdate.o], - [KRB5]) + [${LIBCLI_RAW_LIBS}]) SMB_SUBSYSTEM(LIBCLI_UTILS,[], [libcli/util/asn1.o -- cgit From c727f2ec5e8c978224ecd0640c6180dbe0a44455 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 May 2004 23:16:33 +0000 Subject: r708: Clean up copyright headers, to reflect code that has come and gone over time. Andrew Bartlett (This used to be commit 1a53e5c8296a7c09563abde1eb4a66ce9cf45473) --- source4/libcli/auth/ntlm_check.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index 32a7507c1f..96aa352542 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -1,10 +1,9 @@ /* Unix SMB/CIFS implementation. Password and authentication handling - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Andrew Bartlett 2001-2003 - Copyright (C) Gerald Carter 2003 + Copyright (C) Andrew Bartlett 2001-2004 + Copyright (C) Gerald Carter 2003 + Copyright (C) Luke Kenneth Casson Leighton 1996-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 -- cgit From 5767c107735f83bd564a30abf8f374b326667966 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 May 2004 04:02:22 +0000 Subject: r718: removed some more unused code, and two source files (This used to be commit a9768c25fd32e76514c837f343f2b52bf0f0824d) --- source4/libcli/config.m4 | 1 - source4/libcli/util/pwd_cache.c | 72 ----------------------------------------- 2 files changed, 73 deletions(-) delete mode 100644 source4/libcli/util/pwd_cache.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index e24fd1ba9e..82f629b280 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -35,7 +35,6 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], libcli/util/smberr.o libcli/util/doserr.o libcli/util/errormap.o - libcli/util/pwd_cache.o libcli/util/clierror.o libcli/util/cliutil.o libcli/util/nterr.o diff --git a/source4/libcli/util/pwd_cache.c b/source4/libcli/util/pwd_cache.c deleted file mode 100644 index 0d84f04ee3..0000000000 --- a/source4/libcli/util/pwd_cache.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password cacheing. obfuscation is planned - Copyright (C) Luke Kenneth Casson Leighton 1996-1998 - - 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" - -/**************************************************************************** - Initialises a password structure. -****************************************************************************/ - -static void pwd_init(struct pwd_info *pwd) -{ - memset((char *)pwd->password , '\0', sizeof(pwd->password )); - memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); - memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd)); - memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf)); - memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf)); - - pwd->null_pwd = True; /* safest option... */ - pwd->cleartext = False; - pwd->crypted = False; -} - -/**************************************************************************** - Makes lm and nt hashed passwords. -****************************************************************************/ - -static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) -{ - pstring dos_passwd; - - pwd_init(pwd); - - push_ascii_pstring(dos_passwd, clr); - - nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ - -void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) -{ - pwd_init(pwd); - push_ascii_fstring(pwd->password, clr); - pwd->cleartext = True; - pwd->null_pwd = False; - pwd->crypted = False; - pwd_make_lm_nt_16(pwd, clr); -} - - -- cgit From 6b921d1d2175f3b6267cb6e89b463cff852880cc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 14 May 2004 05:41:21 +0000 Subject: r719: Follow the trend - remove more unused functions. Andrew Bartlett (This used to be commit 62eef851fd79b2739b93b4ed7829514a3dcbf1d0) --- source4/libcli/raw/clirewrite.c | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 source4/libcli/raw/clirewrite.c (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clirewrite.c b/source4/libcli/raw/clirewrite.c deleted file mode 100644 index 2d2e2e3feb..0000000000 --- a/source4/libcli/raw/clirewrite.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "includes.h" - -/* - - this is a set of temporary stub functions used during the libsmb rewrite. - This file will need to go away before the rewrite is complete. -*/ - -void become_root(void) -{} - -void unbecome_root(void) -{} - -BOOL become_user_permanently(uid_t uid, gid_t gid) -{ return True; } - -void set_effective_uid(uid_t uid) -{} - -uid_t sec_initial_uid(void) -{ return 0; } -- cgit From 064e7447bebd715c8351d9a0ee31f648990f2336 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 May 2004 07:51:38 +0000 Subject: r743: Start on a NETLOGON server in Samba4. Currently this only authentiates the machine, not real users. As a consequence of running the Samba4 NETLOGON test against Samba4, I found a number of issues in the SAMR server, which I have addressed. There are more templates in the provison.ldif for this reason. I also added some debug to our credentials code, and fixed some bugs in the auth_sam module. The static buffer in generate_random_string() bit me badly, so I removed it in favor of a talloc based system. Andrew Bartlett (This used to be commit 94624e519b66def97758b8a48a01ffe9029176f0) --- source4/libcli/auth/credentials.c | 46 ++++++++++++++++++++++++++++++++++++--- source4/libcli/auth/credentials.h | 9 ++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 638bff7e8b..7d56f26b11 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -4,6 +4,7 @@ code to manipulate domain credentials Copyright (C) Andrew Tridgell 1997-2003 + Copyright (C) Andrew Bartlett 2004 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 @@ -36,6 +37,10 @@ static void creds_init(struct creds_CredentialState *creds, uint32 sum[2]; uint8 sum2[8]; + dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); + dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); + dump_data_pw("Machine Pass", machine_password, 16); + sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); @@ -44,8 +49,6 @@ static void creds_init(struct creds_CredentialState *creds, cred_hash1(creds->session_key, sum2, machine_password); - creds->sequence = time(NULL); - SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); @@ -136,6 +139,7 @@ void creds_client_init(struct creds_CredentialState *creds, struct netr_Credential *initial_credential) { creds_init(creds, client_challenge, server_challenge, machine_password); + creds->sequence = time(NULL); *initial_credential = creds->client; } @@ -146,7 +150,8 @@ void creds_client_init(struct creds_CredentialState *creds, BOOL creds_client_check(struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { - if (memcmp(received_credentials->data, creds->server.data, 8) != 0) { + if (!received_credentials || + memcmp(received_credentials->data, creds->server.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); return False; } @@ -167,3 +172,38 @@ void creds_client_authenticator(struct creds_CredentialState *creds, } +/***************************************************************** +The above functions are common to the client and server interface +next comes the server specific functions +******************************************************************/ + +/* + initialise the credentials chain and return the first server + credentials +*/ +void creds_server_init(struct creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16], + struct netr_Credential *initial_credential) +{ + creds_init(creds, client_challenge, server_challenge, machine_password); + + *initial_credential = creds->server; +} + +/* + check that a credentials reply from a server is correct +*/ +BOOL creds_server_check(const struct creds_CredentialState *creds, + const struct netr_Credential *received_credentials) +{ + if (memcmp(received_credentials->data, creds->client.data, 8) != 0) { + DEBUG(2,("credentials check failed\n")); + dump_data_pw("client creds", creds->client.data, 8); + dump_data_pw("calc creds", received_credentials->data, 8); + return False; + } + return True; +} + diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 7a7a34ced2..a7e81d43af 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -27,3 +27,12 @@ struct creds_CredentialState { struct netr_Credential client; struct netr_Credential server; }; + + +/* for the timebeing, use the same neg flags as Samba3. */ +/* The 7 here seems to be required to get Win2k not to downgrade us + to NT4. Actually, anything other than 1ff would seem to do... */ +#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff + +#define NETLOGON_NEG_SCHANNEL 0x40000000 + -- cgit From 92dd542aa01f2c3b64ca104696c731919f4d7ec7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 May 2004 21:30:48 +0000 Subject: r754: Implement the SetPassword operation on the netlogon pipe. This involves allowing the password set code in samdb to take an already hashed password, and some fixes to our torture code. Andrew Bartlett (This used to be commit f9f581b5804a20785df06cde157b23c952edc2ce) --- source4/libcli/auth/credentials.c | 61 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 7d56f26b11..5fa9d5ac4a 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -69,8 +69,6 @@ static void creds_step(struct creds_CredentialState *creds) { struct netr_Credential time_cred; - creds->sequence += 2; - DEBUG(5,("\tseed %08x:%08x\n", IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4))); @@ -98,6 +96,7 @@ static void creds_step(struct creds_CredentialState *creds) creds->seed = time_cred; } + /* DES encrypt a 16 byte password buffer using the session key */ @@ -108,6 +107,16 @@ void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass = tmp; } +/* + DES decrypt a 16 byte password buffer using the session key +*/ +void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 0); + *pass = tmp; +} + /* ARCFOUR encrypt/decrypt a password buffer using the session key */ @@ -138,12 +147,29 @@ void creds_client_init(struct creds_CredentialState *creds, const uint8 machine_password[16], struct netr_Credential *initial_credential) { - creds_init(creds, client_challenge, server_challenge, machine_password); creds->sequence = time(NULL); + creds_init(creds, client_challenge, server_challenge, machine_password); *initial_credential = creds->client; } +/* + step the credentials to the next element in the chain, updating the + current client and server credentials and the seed + + produce the next authenticator in the sequence ready to send to + the server +*/ +void creds_client_authenticator(struct creds_CredentialState *creds, + struct netr_Authenticator *next) +{ + creds->sequence += 2; + creds_step(creds); + + next->cred = creds->client; + next->timestamp = creds->sequence; +} + /* check that a credentials reply from a server is correct */ @@ -158,19 +184,6 @@ BOOL creds_client_check(struct creds_CredentialState *creds, return True; } -/* - produce the next authenticator in the sequence ready to send to - the server -*/ -void creds_client_authenticator(struct creds_CredentialState *creds, - struct netr_Authenticator *next) -{ - creds_step(creds); - - next->cred = creds->client; - next->timestamp = creds->sequence; -} - /***************************************************************** The above functions are common to the client and server interface @@ -207,3 +220,19 @@ BOOL creds_server_check(const struct creds_CredentialState *creds, return True; } +BOOL creds_server_step_check(struct creds_CredentialState *creds, + struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator) +{ + /* Should we check that this is increasing? */ + creds->sequence = received_authenticator->timestamp; + creds_step(creds); + if (creds_server_check(creds, &received_authenticator->cred)) { + return_authenticator->cred = creds->server; + return_authenticator->timestamp = creds->sequence; + return True; + } else { + ZERO_STRUCTP(return_authenticator); + return False; + } +} -- cgit From 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 May 2004 13:57:39 +0000 Subject: r873: converted samba4 to use real 64 bit integers instead of structures. This was suggested by metze recently. I checked on the build farm and all the machines we have support 64 bit ints, and support the LL suffix for 64 bit constants. I suspect some won't support strtoll() and related functions, so we will probably need replacements for those. (This used to be commit 9a9244a1c66654c12abe4379661cba83a73c4c21) --- source4/libcli/clilist.c | 6 +++--- source4/libcli/clitrans2.c | 16 ++++++++-------- source4/libcli/raw/clispnego.c | 12 ++++++------ source4/libcli/raw/rawnegotiate.c | 2 +- source4/libcli/raw/rawrequest.c | 10 +++------- source4/libcli/raw/rawsetfileinfo.c | 14 +++++++------- source4/libcli/util/asn1.c | 12 ++++++------ source4/libcli/util/smbencrypt.c | 2 +- 8 files changed, 35 insertions(+), 39 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index ee0357579c..ca4b6acdc7 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -45,9 +45,9 @@ static BOOL interpret_long_filename(int level, ZERO_STRUCTP(finfo); finfo->size = info->both_directory_info.size; - finfo->ctime = nt_time_to_unix(&info->both_directory_info.create_time); - finfo->atime = nt_time_to_unix(&info->both_directory_info.access_time); - finfo->mtime = nt_time_to_unix(&info->both_directory_info.write_time); + finfo->ctime = nt_time_to_unix(info->both_directory_info.create_time); + finfo->atime = nt_time_to_unix(info->both_directory_info.access_time); + finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time); finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */ if (info->both_directory_info.short_name.s) { strncpy(finfo->short_name, info->both_directory_info.short_name.s, diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 777150a257..dc8c2cdfec 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -85,16 +85,16 @@ NTSTATUS cli_qpathinfo2(struct cli_tree *tree, const char *fname, return status; if (c_time) { - *c_time = nt_time_to_unix(&parms.all_info.out.create_time); + *c_time = nt_time_to_unix(parms.all_info.out.create_time); } if (a_time) { - *a_time = nt_time_to_unix(&parms.all_info.out.access_time); + *a_time = nt_time_to_unix(parms.all_info.out.access_time); } if (m_time) { - *m_time = nt_time_to_unix(&parms.all_info.out.change_time); + *m_time = nt_time_to_unix(parms.all_info.out.change_time); } if (w_time) { - *w_time = nt_time_to_unix(&parms.all_info.out.write_time); + *w_time = nt_time_to_unix(parms.all_info.out.write_time); } if (size) { *size = parms.all_info.out.size; @@ -163,16 +163,16 @@ NTSTATUS cli_qfileinfo(struct cli_tree *tree, int fnum, } if (c_time) { - *c_time = nt_time_to_unix(&parms.all_info.out.create_time); + *c_time = nt_time_to_unix(parms.all_info.out.create_time); } if (a_time) { - *a_time = nt_time_to_unix(&parms.all_info.out.access_time); + *a_time = nt_time_to_unix(parms.all_info.out.access_time); } if (m_time) { - *m_time = nt_time_to_unix(&parms.all_info.out.change_time); + *m_time = nt_time_to_unix(parms.all_info.out.change_time); } if (w_time) { - *w_time = nt_time_to_unix(&parms.all_info.out.write_time); + *w_time = nt_time_to_unix(parms.all_info.out.write_time); } if (mode) { *mode = parms.all_info.out.attrib; diff --git a/source4/libcli/raw/clispnego.c b/source4/libcli/raw/clispnego.c index e6cadc466c..7ad6be1006 100644 --- a/source4/libcli/raw/clispnego.c +++ b/source4/libcli/raw/clispnego.c @@ -141,9 +141,9 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data,ASN1_CONTEXT(0)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; + char *aoid = NULL; + asn1_read_OID(&data,&aoid); + OIDs[i] = aoid; } OIDs[i] = NULL; asn1_end_tag(&data); @@ -230,9 +230,9 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; + char *aoid = NULL; + asn1_read_OID(&data,&aoid); + OIDs[i] = aoid; } OIDs[i] = NULL; asn1_end_tag(&data); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 587050bef8..5b94ef63d8 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -106,7 +106,7 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) /* this time arrives in real GMT */ ntt = cli_pull_nttime(req->in.vwv, VWV(11)+1); - transport->negotiate.server_time = nt_time_to_unix(&ntt); + transport->negotiate.server_time = nt_time_to_unix(ntt); transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, req->in.data_size); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 35a2d363df..085b445fba 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -831,11 +831,9 @@ BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char * /* put a NTTIME into a packet */ - -void cli_push_nttime(void *base, uint16 offset, NTTIME *t) +void cli_push_nttime(void *base, uint16 offset, NTTIME t) { - SIVAL(base, offset, t->low); - SIVAL(base, offset+4, t->high); + SBVAL(base, offset, t); } /* @@ -843,9 +841,7 @@ void cli_push_nttime(void *base, uint16 offset, NTTIME *t) */ NTTIME cli_pull_nttime(void *base, uint16 offset) { - NTTIME ret; - ret.low = IVAL(base, offset); - ret.high = IVAL(base, offset+4); + NTTIME ret = BVAL(base, offset); return ret; } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 9da94f161c..d8fc78972d 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -61,10 +61,10 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: NEED_BLOB(40); - cli_push_nttime(blob->data, 0, &parms->basic_info.in.create_time); - cli_push_nttime(blob->data, 8, &parms->basic_info.in.access_time); - cli_push_nttime(blob->data, 16, &parms->basic_info.in.write_time); - cli_push_nttime(blob->data, 24, &parms->basic_info.in.change_time); + cli_push_nttime(blob->data, 0, parms->basic_info.in.create_time); + cli_push_nttime(blob->data, 8, parms->basic_info.in.access_time); + cli_push_nttime(blob->data, 16, parms->basic_info.in.write_time); + cli_push_nttime(blob->data, 24, parms->basic_info.in.change_time); SIVAL(blob->data, 32, parms->basic_info.in.attrib); SIVAL(blob->data, 36, 0); /* padding */ return True; @@ -73,9 +73,9 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, NEED_BLOB(92); SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file); SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes); - cli_push_nttime(blob->data, 16, &parms->unix_basic.in.status_change_time); - cli_push_nttime(blob->data, 24, &parms->unix_basic.in.access_time); - cli_push_nttime(blob->data, 32, &parms->unix_basic.in.change_time); + cli_push_nttime(blob->data, 16, parms->unix_basic.in.status_change_time); + cli_push_nttime(blob->data, 24, parms->unix_basic.in.access_time); + cli_push_nttime(blob->data, 32, parms->unix_basic.in.change_time); SBVAL(blob->data, 40, parms->unix_basic.in.uid); SBVAL(blob->data, 48, parms->unix_basic.in.gid); SIVAL(blob->data, 56, parms->unix_basic.in.file_type); diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 09d4fbb6c9..07c692f700 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -315,17 +315,17 @@ int asn1_tag_remaining(ASN1_DATA *data) BOOL asn1_read_OID(ASN1_DATA *data, char **OID) { uint8 b; - pstring oid; + pstring aoid; fstring el; if (!asn1_start_tag(data, ASN1_OID)) return False; asn1_read_uint8(data, &b); - oid[0] = 0; + aoid[0] = 0; snprintf(el, sizeof(el), "%u", b/40); - pstrcat(oid, el); + pstrcat(aoid, el); snprintf(el, sizeof(el), " %u", b%40); - pstrcat(oid, el); + pstrcat(aoid, el); while (asn1_tag_remaining(data) > 0) { unsigned v = 0; @@ -334,12 +334,12 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); snprintf(el, sizeof(el), " %u", v); - pstrcat(oid, el); + pstrcat(aoid, el); } asn1_end_tag(data); - *OID = strdup(oid); + *OID = strdup(aoid); return !data->has_error; } diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 5468bdbebe..013f00d5fa 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -314,7 +314,7 @@ static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) generate_random_buffer(client_chal, sizeof(client_chal), False); - push_nttime(long_date, 0, &nttime); + push_nttime(long_date, 0, nttime); /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ -- cgit From 5b0ab386cb0fb74d78e6c68abe1b047ab515b7b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 May 2004 14:06:28 +0000 Subject: r874: This patch is a pile of work on NTLMSSP: Samba's NTLMSSP code is now fully talloc based, which should go a long way to cleaning up the memory leaks in this code. This also avoids a lot of extra copies of data, as we now allocate the 'return' blobs on a caller-supplied context. I have also been doing a lot of work towards NTLM2 signing and sealing. I have this working for sealing, but not for the verifier (MD5 integrity check on the stream) which is still incorrect. (I can aim a rpcecho sinkdata from a Win2k3 box to my server, and the data arrives intact, but the signature check fails. It does however match the test values I have...). The new torture test is cludged in - when we get a unit test suite back, I'll happliy put it in the 'right' place.... Andrew Bartlett (This used to be commit 399e2e2b1149b8d1c070aa7f0d5131c0b577d2b9) --- source4/libcli/auth/ntlmssp.c | 209 ++++++++++++++++++++---------------- source4/libcli/auth/ntlmssp.h | 19 ++-- source4/libcli/auth/ntlmssp_parse.c | 32 +++--- source4/libcli/auth/ntlmssp_sign.c | 205 ++++++++++++++++++++++------------- source4/libcli/auth/schannel.c | 7 +- source4/libcli/util/smbencrypt.c | 21 ++-- 6 files changed, 294 insertions(+), 199 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 9513d5a138..3773c8e590 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -24,13 +24,17 @@ #include "includes.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB reply, DATA_BLOB *next_request); + TALLOC_CTX *out_mem_ctx, + DATA_BLOB in, DATA_BLOB *out); static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out); static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB reply, DATA_BLOB *next_request); + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out); static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply); + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out); /** * Callbacks for NTLMSSP - for both client and server operating modes @@ -41,6 +45,7 @@ static const struct ntlmssp_callbacks { enum NTLMSSP_ROLE role; enum NTLM_MESSAGE_TYPE ntlmssp_command; NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, + TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out); } ntlmssp_callbacks[] = { {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial}, @@ -205,12 +210,15 @@ NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, * Next state function for the NTLMSSP state machine * * @param ntlmssp_state NTLMSSP State - * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB - * @param out The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. */ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, + TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { DATA_BLOB input; @@ -219,6 +227,16 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, *out = data_blob(NULL, 0); + if (ntlmssp_state->expected_state == NTLMSSP_DONE) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!out_mem_ctx) { + /* if the caller doesn't want to manage/own the memory, + we can put it on our context */ + out_mem_ctx = ntlmssp_state->mem_ctx; + } + if (!in.length && ntlmssp_state->stored_response.length) { input = ntlmssp_state->stored_response; @@ -239,7 +257,8 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, break; } } else { - if (!msrpc_parse(&input, "Cd", + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &input, "Cd", "NTLMSSP", &ntlmssp_command)) { DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); @@ -255,8 +274,9 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, for (i=0; ntlmssp_callbacks[i].fn; i++) { if (ntlmssp_callbacks[i].role == ntlmssp_state->role - && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { - return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out); + && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command + && ntlmssp_callbacks[i].fn) { + return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out); } } @@ -279,10 +299,6 @@ void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->ref_count--; if ((*ntlmssp_state)->ref_count == 0) { - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - data_blob_free(&(*ntlmssp_state)->encrypted_session_key); talloc_destroy(mem_ctx); } @@ -391,6 +407,7 @@ static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) { ntlmssp_state->session_key.data[6] = 0x38; ntlmssp_state->session_key.data[7] = 0xb0; } + ntlmssp_state->session_key.length = 8; } } @@ -398,13 +415,15 @@ static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) { * Next state function for the Negotiate packet * * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. */ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; @@ -419,21 +438,19 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif - if (request.length) { - if (!msrpc_parse(&request, "CddAA", + if (in.length) { + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &in, "CddAA", "NTLMSSP", &ntlmssp_command, &neg_flags, &cliname, &domname)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); - dump_data(2, (const char *)request.data, request.length); + dump_data(2, (const char *)in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } - SAFE_FREE(cliname); - SAFE_FREE(domname); - debug_ntlmssp_flags(neg_flags); } @@ -481,7 +498,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, target_name_dns = dnsname; } - msrpc_gen(&struct_blob, "aaaaa", + msrpc_gen(out_mem_ctx, + &struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, @@ -500,7 +518,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, gen_string = "CdAdbddB"; } - msrpc_gen(reply, gen_string, + msrpc_gen(out_mem_ctx, + out, gen_string, "NTLMSSP", NTLMSSP_CHALLENGE, target_name, @@ -510,8 +529,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, struct_blob.data, struct_blob.length); } - data_blob_free(&struct_blob); - ntlmssp_state->expected_state = NTLMSSP_AUTH; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -522,7 +539,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, * * @param ntlmssp_state NTLMSSP State * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. * @return Errors or NT_STATUS_OK. */ @@ -549,6 +565,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, parse_string = "CdBBAAABd"; } + /* zero these out */ data_blob_free(&ntlmssp_state->lm_resp); data_blob_free(&ntlmssp_state->nt_resp); @@ -557,7 +574,8 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&request, parse_string, + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, @@ -569,9 +587,8 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, &auth_flags)) { DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); dump_data(10, (const char *)request.data, request.length); - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); + + /* zero this out */ data_blob_free(&ntlmssp_state->encrypted_session_key); auth_flags = 0; @@ -583,7 +600,8 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, } /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&request, parse_string, + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, @@ -593,9 +611,6 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, &workstation)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)request.data, request.length); - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); return NT_STATUS_INVALID_PARAMETER; } @@ -605,33 +620,23 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); + /* zero this out */ data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); + /* zero this out */ data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); + /* zero this out */ data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); @@ -648,7 +653,8 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) { struct MD5Context md5_session_nonce_ctx; - SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8); + SMB_ASSERT(ntlmssp_state->internal_chal.data + && ntlmssp_state->internal_chal.length == 8); ntlmssp_state->doing_ntlm2 = True; @@ -659,13 +665,17 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); - ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8); + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, + session_nonce_hash, 8); - /* LM response is no longer useful */ + /* LM response is no longer useful, zero it out */ data_blob_free(&ntlmssp_state->lm_resp); /* We changed the effective challenge - set it */ - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) { + if (!NT_STATUS_IS_OK(nt_status = + ntlmssp_state->set_challenge(ntlmssp_state, + &ntlmssp_state->chal))) { + /* zero this out */ data_blob_free(&ntlmssp_state->encrypted_session_key); return nt_status; } @@ -678,25 +688,20 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, } /** - * Next state function for the Authenticate packet + * Next state function for the Authenticate packet + * (after authentication - figures out the session keys etc) * * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param reply The reply, as an allocated DATA_BLOB, caller to free. * @return Errors or NT_STATUS_OK. */ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, - DATA_BLOB *lm_session_key, - DATA_BLOB *reply) + DATA_BLOB *lm_session_key) { NTSTATUS nt_status; DATA_BLOB session_key = data_blob(NULL, 0); - /* parse the NTLMSSP packet */ - *reply = data_blob(NULL, 0); - if (user_session_key) dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length); @@ -807,8 +812,15 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&ntlmssp_state->encrypted_session_key); - /* allow arbitarily many authentications */ - ntlmssp_state->expected_state = NTLMSSP_AUTH; + /* allow arbitarily many authentications, but watch that this will cause a + memory leak, until the ntlmssp_state is shutdown + */ + + if (ntlmssp_state->server_multiple_authentications) { + ntlmssp_state->expected_state = NTLMSSP_AUTH; + } else { + ntlmssp_state->expected_state = NTLMSSP_DONE; + } return nt_status; } @@ -818,22 +830,23 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, * Next state function for the Authenticate packet * * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param reply The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. + * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB + * @param out The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. */ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) { DATA_BLOB user_session_key = data_blob(NULL, 0); DATA_BLOB lm_session_key = data_blob(NULL, 0); NTSTATUS nt_status; - /* parse the NTLMSSP packet */ - *reply = data_blob(NULL, 0); + /* zero the outbound NTLMSSP packet */ + *out = data_blob_talloc(out_mem_ctx, NULL, 0); - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, request))) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) { return nt_status; } @@ -851,7 +864,12 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, return nt_status; } - return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key, reply); + if (ntlmssp_state->server_use_session_keys) { + return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key); + } else { + ntlmssp_state->session_key = data_blob(NULL, 0); + return NT_STATUS_OK; + } } /** @@ -889,6 +907,9 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False)); + (*ntlmssp_state)->server_use_session_keys = True; + (*ntlmssp_state)->server_multiple_authentications = False; + (*ntlmssp_state)->ref_count = 1; (*ntlmssp_state)->neg_flags = @@ -910,13 +931,15 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) * Next state function for the Initial packet * * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context + * @param in The request, as a DATA_BLOB. reply.data must be NULL + * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx * @return Errors or NT_STATUS_OK. */ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB reply, DATA_BLOB *next_request) + TALLOC_CTX *out_mem_ctx, + DATA_BLOB in, DATA_BLOB *out) { if (ntlmssp_state->unicode) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; @@ -929,7 +952,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, } /* generate the ntlmssp negotiate packet */ - msrpc_gen(next_request, "CddAA", + msrpc_gen(out_mem_ctx, + out, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, @@ -951,7 +975,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, */ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB reply, DATA_BLOB *next_request) + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) { uint32 chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; @@ -968,13 +993,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; - if (!msrpc_parse(&reply, "CdBd", + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &in, "CdBd", "NTLMSSP", &ntlmssp_command, &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, (const char *)reply.data, reply.length); + dump_data(2, (const char *)in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -1006,7 +1032,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (!msrpc_parse(&reply, chal_parse_string, + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &in, chal_parse_string, "NTLMSSP", &ntlmssp_command, &server_domain, @@ -1015,16 +1042,13 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, &unkn1, &unkn2, &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - dump_data(2, (const char *)reply.data, reply.length); + dump_data(2, (const char *)in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } - ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx, - server_domain); + ntlmssp_state->server_domain = server_domain; - SAFE_FREE(server_domain); if (challenge_blob.length != 8) { - data_blob_free(&struct_blob); return NT_STATUS_INVALID_PARAMETER; } @@ -1137,7 +1161,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* LM Key is incompatible... */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - } if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) @@ -1156,8 +1179,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, dump_data_pw("LM session key\n", session_key.data, session_key.length); } - data_blob_free(&struct_blob); - /* Key exchange encryptes a new client-generated session key with the password-derived key */ @@ -1167,18 +1188,19 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, generate_random_buffer(client_session_key, sizeof(client_session_key), False); /* Encrypt the new session key with the old one */ - encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); + encrypted_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ - data_blob_free(&session_key); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); } /* this generates the actual auth packet */ - if (!msrpc_gen(next_request, auth_gen_string, + if (!msrpc_gen(out_mem_ctx, + out, auth_gen_string, "NTLMSSP", NTLMSSP_AUTH, lm_response.data, lm_response.length, @@ -1192,10 +1214,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_NO_MEMORY; } - data_blob_free(&encrypted_session_key); - - data_blob_free(&ntlmssp_state->chal); - ntlmssp_state->session_key = session_key; /* The client might be using 56 or 40 bit weakened keys */ @@ -1205,10 +1223,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; - ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + ntlmssp_state->expected_state = NTLMSSP_DONE; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { - DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); + DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", + nt_errstr(nt_status))); return nt_status; } diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index a5e0951fa8..d3d39e8465 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -34,7 +34,8 @@ enum NTLM_MESSAGE_TYPE NTLMSSP_NEGOTIATE = 1, NTLMSSP_CHALLENGE = 2, NTLMSSP_AUTH = 3, - NTLMSSP_UNKNOWN = 4 + NTLMSSP_UNKNOWN = 4, + NTLMSSP_DONE = 5 /* samba final state */ }; /* NTLMSSP negotiation flags */ @@ -80,9 +81,15 @@ typedef struct ntlmssp_state BOOL unicode; BOOL use_ntlmv2; - BOOL use_nt_response; /* Set to 'NO' to debug what happens when the NT response is omited */ + BOOL use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ BOOL allow_lm_key; /* The LM_KEY code is not functional at this point, and it's not very secure anyway */ + + BOOL server_use_session_keys; /* Set to 'False' for authentication only, + that will never return a session key */ + BOOL server_multiple_authentications; /* Set to 'True' to allow squid 2.5 + style 'challenge caching' */ + char *user; char *domain; char *workstation; @@ -159,10 +166,10 @@ typedef struct ntlmssp_state uint32 ntlmssp_seq_num; /* ntlmv2 */ - char send_sign_const[16]; - char send_seal_const[16]; - char recv_sign_const[16]; - char recv_seal_const[16]; + char send_sign_key[16]; + char send_seal_key[16]; + char recv_sign_key[16]; + char recv_seal_key[16]; unsigned char send_sign_hash[258]; unsigned char send_seal_hash[258]; diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 4b3043aec8..6ddaeebb06 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -40,7 +40,7 @@ d = word (4 bytes) C = constant ascii string */ -BOOL msrpc_gen(DATA_BLOB *blob, +BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *format, ...) { int i, n; @@ -91,7 +91,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, va_end(ap); /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob(NULL, head_size + data_size); + *blob = data_blob_talloc(mem_ctx, NULL, head_size + data_size); head_ofs = 0; data_ofs = head_size; @@ -182,12 +182,12 @@ if ((head_ofs + amount) > blob->length) { \ C = constant ascii string */ -BOOL msrpc_parse(const DATA_BLOB *blob, +BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const char *format, ...) { int i; va_list ap; - char **ps, *s; + const char **ps, *s; DATA_BLOB *b; size_t head_ofs = 0; uint16 len1, len2; @@ -206,7 +206,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, ps = va_arg(ap, char **); if (len1 == 0 && len2 == 0) { - *ps = smb_xstrdup(""); + *ps = ""; } else { /* make sure its in the right format - be strict */ if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { @@ -223,9 +223,12 @@ BOOL msrpc_parse(const DATA_BLOB *blob, pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, STR_UNICODE|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + (*ps) = talloc_strdup(mem_ctx, p); + if (!(*ps)) { + return False; + } } else { - (*ps) = smb_xstrdup(""); + (*ps) = ""; } } break; @@ -238,7 +241,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, ps = va_arg(ap, char **); /* make sure its in the right format - be strict */ if (len1 == 0 && len2 == 0) { - *ps = smb_xstrdup(""); + *ps = ""; } else { if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; @@ -251,9 +254,12 @@ BOOL msrpc_parse(const DATA_BLOB *blob, pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, STR_ASCII|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + (*ps) = talloc_strdup(mem_ctx, p); + if (!(*ps)) { + return False; + } } else { - (*ps) = smb_xstrdup(""); + (*ps) = ""; } } break; @@ -265,7 +271,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, b = (DATA_BLOB *)va_arg(ap, void *); if (len1 == 0 && len2 == 0) { - *b = data_blob(NULL, 0); + *b = data_blob_talloc(mem_ctx, NULL, 0); } else { /* make sure its in the right format - be strict */ if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { @@ -275,7 +281,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) return False; - *b = data_blob(blob->data + ptr, len1); + *b = data_blob_talloc(mem_ctx, blob->data + ptr, len1); } break; case 'b': @@ -286,7 +292,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) return False; - *b = data_blob(blob->data + head_ofs, len1); + *b = data_blob_talloc(mem_ctx, blob->data + head_ofs, len1); head_ofs += len1; break; case 'd': diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 5039a842bc..6abec7e8b6 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -53,7 +53,7 @@ static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) hash[257] = index_j; } -static void calc_hash(unsigned char hash[258], const char *k2, int k2l) +static void calc_hash(unsigned char hash[258], const char *key, size_t key_len) { unsigned char j = 0; int ind; @@ -67,7 +67,7 @@ static void calc_hash(unsigned char hash[258], const char *k2, int k2l) { unsigned char tc; - j += (hash[ind] + k2[ind%k2l]); + j += (hash[ind] + key[ind%key_len]); tc = hash[ind]; hash[ind] = hash[j]; @@ -78,23 +78,37 @@ static void calc_hash(unsigned char hash[258], const char *k2, int k2l) hash[257] = 0; } -static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16], +/** + * Some notes on then NTLM2 code: + * + * This code works correctly for the sealing part of the problem. If + * we disable the check for valid client signatures, then we see that + * the output of a rpcecho 'sinkdata' at smbd is correct. We get the + * valid data, and it is validly decrypted. + * + * This means that the quantity of data passing though the RC4 sealing + * pad is correct. + * + * This code also correctly matches test values that I have obtained, + * claiming to be the correct output of NTLM2 signature generation. + * + */ + + + + +static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char subkey[16], DATA_BLOB session_key, const char *constant) { struct MD5Context ctx3; - /* NOTE: This code is currently complate fantasy - it's - got more in common with reality than the previous code - (the LM session key is not the right thing to use) but - it still needs work */ - MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1); - MD5Final(digest, &ctx3); + MD5Update(&ctx3, constant, strlen(constant)+1); + MD5Final(subkey, &ctx3); - calc_hash(hash, digest, 16); + calc_hash(hash, subkey, 16); } enum ntlmssp_direction { @@ -103,40 +117,51 @@ enum ntlmssp_direction { }; static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, + TALLOC_CTX *sig_mem_ctx, const uchar *data, size_t length, enum ntlmssp_direction direction, DATA_BLOB *sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; uchar seq_num[4]; uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); + switch (direction) { + case NTLMSSP_SEND: + hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, + sizeof(ntlmssp_state->send_sign_key), &ctx); + break; + case NTLMSSP_RECEIVE: + hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, + sizeof(ntlmssp_state->recv_sign_key), &ctx); + break; + } hmac_md5_update(seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); - if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ - , ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; - } - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { switch (direction) { case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, digest, 8); break; case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); + NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, digest, 8); break; } } + *sig = data_blob_talloc(sig_mem_ctx, NULL, 16); + SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); + memcpy(sig->data + 4, digest, 8); + memcpy(sig->data + 12, seq_num, 4); + } else { uint32 crc; crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } @@ -148,16 +173,19 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, } NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, - const uchar *data, size_t length, - DATA_BLOB *sig) + TALLOC_CTX *sig_mem_ctx, + const uchar *data, size_t length, + DATA_BLOB *sig) { NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot check sign packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; } - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, + data, length, NTLMSSP_SEND, sig); /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; @@ -166,11 +194,11 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, /** * Check the signature of an incoming packet - * @note caller *must* check that the signature is the size it expects * */ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, + TALLOC_CTX *sig_mem_ctx, const uchar *data, size_t length, const DATA_BLOB *sig) { @@ -187,7 +215,7 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, (unsigned long)sig->length)); } - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, data, length, NTLMSSP_RECEIVE, &local_sig); if (!NT_STATUS_IS_OK(nt_status)) { @@ -195,22 +223,37 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, return nt_status; } - if (local_sig.length != sig->length || - memcmp(local_sig.data + local_sig.length - 8, - sig->data + sig->length - 8, 8) != 0) { - DEBUG(5, ("BAD SIG: wanted signature of\n")); - dump_data(5, (const char *)local_sig.data, local_sig.length); - - DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, (const char *)(sig->data), sig->length); + /* increment counter on recv */ + ntlmssp_state->ntlmssp_seq_num++; - DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n")); - return NT_STATUS_ACCESS_DENIED; + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + if (local_sig.length != sig->length || + memcmp(local_sig.data, + sig->data, sig->length) != 0) { + DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); + + DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); + return NT_STATUS_ACCESS_DENIED; + } + } else { + if (local_sig.length != sig->length || + memcmp(local_sig.data + 8, + sig->data + 8, sig->length - 8) != 0) { + DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n")); + dump_data(5, (const char *)local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, (const char *)(sig->data), sig->length); + + DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n")); + return NT_STATUS_ACCESS_DENIED; + } } - /* increment counter on recieive */ - ntlmssp_state->ntlmssp_seq_num++; - return NT_STATUS_OK; } @@ -221,6 +264,7 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, */ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, + TALLOC_CTX *sig_mem_ctx, uchar *data, size_t length, DATA_BLOB *sig) { @@ -233,32 +277,34 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - char seq_num[4]; + uchar seq_num[4]; uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); - hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); + hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, + sizeof(ntlmssp_state->send_sign_key), &ctx); + hmac_md5_update(seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); - if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ - , ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; + /* The order of these two operations matters - we must first seal the packet, + then seal the sequence number - this is becouse the send_seal_hash is not + constant, but is is rather updated with each iteration */ + + NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, digest, 8); } - dump_data_pw("ntlmssp client sealing hash:\n", - ntlmssp_state->send_seal_hash, - sizeof(ntlmssp_state->send_seal_hash)); - NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); - dump_data_pw("ntlmssp client signing hash:\n", - ntlmssp_state->send_sign_hash, - sizeof(ntlmssp_state->send_sign_hash)); - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + *sig = data_blob_talloc(sig_mem_ctx, NULL, 16); + SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); + memcpy(sig->data + 4, digest, 8); + memcpy(sig->data + 12, seq_num, 4); } else { uint32 crc; crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } @@ -288,8 +334,9 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, */ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, - uchar *data, size_t length, - DATA_BLOB *sig) + TALLOC_CTX *sig_mem_ctx, + uchar *data, size_t length, + DATA_BLOB *sig) { if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot unseal packet\n")); @@ -307,7 +354,10 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, } dump_data_pw("ntlmssp clear data\n", data, length); - return ntlmssp_check_packet(ntlmssp_state, data, length, sig); + return ntlmssp_check_packet(ntlmssp_state, sig_mem_ctx, data, length, sig); + + /* increment counter on recv */ + ntlmssp_state->ntlmssp_seq_num++; } /** @@ -348,57 +398,60 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) break; } + /* SEND */ calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, - ntlmssp_state->send_sign_const, + ntlmssp_state->send_sign_key, ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP send sign key:\n", + ntlmssp_state->send_sign_key, + sizeof(ntlmssp_state->send_sign_key)); + dump_data_pw("NTLMSSP send sign hash:\n", ntlmssp_state->send_sign_hash, sizeof(ntlmssp_state->send_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, - ntlmssp_state->send_seal_const, + ntlmssp_state->send_seal_key, ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP send seal key:\n", + ntlmssp_state->send_seal_key, + sizeof(ntlmssp_state->send_seal_key)); + dump_data_pw("NTLMSSP send sesl hash:\n", ntlmssp_state->send_seal_hash, sizeof(ntlmssp_state->send_seal_hash)); + /* RECV */ calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, - ntlmssp_state->recv_sign_const, + ntlmssp_state->recv_sign_key, ntlmssp_state->session_key, recv_sign_const); + dump_data_pw("NTLMSSP recv sign key:\n", + ntlmssp_state->recv_sign_key, + sizeof(ntlmssp_state->recv_sign_key)); dump_data_pw("NTLMSSP receive sign hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, - ntlmssp_state->recv_seal_const, + ntlmssp_state->recv_seal_key, ntlmssp_state->session_key, recv_seal_const); + dump_data_pw("NTLMSSP recv seal key:\n", + ntlmssp_state->recv_sign_key, + sizeof(ntlmssp_state->recv_seal_key)); dump_data_pw("NTLMSSP receive seal hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); - } - else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { - /* can't sign or check signatures yet */ - DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); - - calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8); - dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); } else { - if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { + if (!ntlmssp_state->session_key.data) { /* can't sign or check signatures yet */ - DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); + DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY\n")); return NT_STATUS_UNSUCCESSFUL; } DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); + calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), ntlmssp_state->session_key.length); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index e5a786ff24..59d0c4aa7d 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -93,6 +93,7 @@ static void schannel_digest(const uchar sess_key[16], unseal a packet */ NTSTATUS schannel_unseal_packet(struct schannel_state *state, + TALLOC_CTX *mem_ctx, uchar *data, size_t length, DATA_BLOB *sig) { @@ -183,6 +184,7 @@ NTSTATUS schannel_check_packet(struct schannel_state *state, seal a packet */ NTSTATUS schannel_seal_packet(struct schannel_state *state, + TALLOC_CTX *mem_ctx, uchar *data, size_t length, DATA_BLOB *sig) { @@ -208,7 +210,7 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); if (!state->signature.data) { - state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); + state->signature = data_blob_talloc(mem_ctx, NULL, 32); if (!state->signature.data) { return NT_STATUS_NO_MEMORY; } @@ -233,6 +235,7 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, sign a packet */ NTSTATUS schannel_sign_packet(struct schannel_state *state, + TALLOC_CTX *mem_ctx, const uchar *data, size_t length, DATA_BLOB *sig) { @@ -250,7 +253,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); if (!state->signature.data) { - state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); + state->signature = data_blob_talloc(mem_ctx, NULL, 32); if (!state->signature.data) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 013f00d5fa..edf1526d2e 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -291,19 +291,20 @@ void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], #endif } -DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, +DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, + const char *hostname, const char *domain) { - DATA_BLOB names_blob = data_blob(NULL, 0); + DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - msrpc_gen(&names_blob, "aaa", + msrpc_gen(mem_ctx, &names_blob, "aaa", NTLMSSP_NAME_TYPE_DOMAIN, domain, NTLMSSP_NAME_TYPE_SERVER, hostname, 0, ""); return names_blob; } -static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) +static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) { uchar client_chal[8]; DATA_BLOB response = data_blob(NULL, 0); @@ -318,7 +319,7 @@ static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - msrpc_gen(&response, "ddbbdb", + msrpc_gen(mem_ctx, &response, "ddbbdb", 0x00000101, /* Header */ 0, /* 'Reserved' */ long_date, 8, /* Timestamp */ @@ -337,10 +338,16 @@ static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], DATA_BLOB ntlmv2_client_data; DATA_BLOB final_response; + TALLOC_CTX *mem_ctx = talloc_init("NTLMv2_generate_response internal context"); + + if (!mem_ctx) { + return data_blob(NULL, 0); + } + /* NTLMv2 */ /* generate some data to pass into the response function - including the hostname and domain name of the server */ - ntlmv2_client_data = NTLMv2_generate_client_data(names_blob); + ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); @@ -352,7 +359,7 @@ static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], memcpy(final_response.data+sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); - data_blob_free(&ntlmv2_client_data); + talloc_destroy(mem_ctx); return final_response; } -- cgit From f9d8f8843dc0ab8c9d59abde7222e0f118b86b5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 16:24:13 +0000 Subject: r884: convert samba4 to use [u]int32_t instead of [u]int32 metze (This used to be commit 0e5517d937a2eb7cf707991d1c7498c1ab456095) --- source4/libcli/auth/credentials.c | 2 +- source4/libcli/auth/credentials.h | 2 +- source4/libcli/auth/ntlmssp.c | 16 ++++++++-------- source4/libcli/auth/ntlmssp.h | 6 +++--- source4/libcli/auth/ntlmssp_parse.c | 6 +++--- source4/libcli/auth/ntlmssp_sign.c | 4 ++-- source4/libcli/auth/schannel.h | 2 +- source4/libcli/clifile.c | 20 ++++++++++---------- source4/libcli/raw/clikrb5.c | 4 ++-- source4/libcli/raw/raweas.c | 4 ++-- source4/libcli/raw/rawnotify.c | 4 ++-- source4/libcli/raw/rawrequest.c | 4 ++-- source4/libcli/raw/rawtrans.c | 10 +++++----- source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/util/clierror.c | 2 +- source4/libcli/util/dom_sid.c | 2 +- source4/libcli/util/errormap.c | 8 ++++---- source4/libcli/util/smbencrypt.c | 2 +- 18 files changed, 50 insertions(+), 50 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 5fa9d5ac4a..139b17d5b3 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -34,7 +34,7 @@ static void creds_init(struct creds_CredentialState *creds, const uint8 machine_password[16]) { struct netr_Credential time_cred; - uint32 sum[2]; + uint32_t sum[2]; uint8 sum2[8]; dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index a7e81d43af..85efd54bc1 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -22,7 +22,7 @@ struct creds_CredentialState { uint8 session_key[8]; - uint32 sequence; + uint32_t sequence; struct netr_Credential seed; struct netr_Credential client; struct netr_Credential server; diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 3773c8e590..54b219f879 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -62,7 +62,7 @@ static const struct ntlmssp_callbacks { * @param neg_flags The flags from the packet */ -void debug_ntlmssp_flags(uint32 neg_flags) +void debug_ntlmssp_flags(uint32_t neg_flags) { DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); @@ -222,7 +222,7 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, const DATA_BLOB in, DATA_BLOB *out) { DATA_BLOB input; - uint32 ntlmssp_command; + uint32_t ntlmssp_command; int i; *out = data_blob(NULL, 0); @@ -317,7 +317,7 @@ void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) */ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, - uint32 neg_flags, uint32 *chal_flags) + uint32_t neg_flags, uint32_t *chal_flags) { if (neg_flags & NTLMSSP_REQUEST_TARGET) { *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; @@ -335,7 +335,7 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, } static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32 neg_flags, BOOL allow_lm) { + uint32_t neg_flags, BOOL allow_lm) { if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; @@ -427,8 +427,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; - uint32 neg_flags = 0; - uint32 ntlmssp_command, chal_flags; + uint32_t neg_flags = 0; + uint32_t ntlmssp_command, chal_flags; char *cliname=NULL, *domname=NULL; const uint8 *cryptkey; const char *target_name; @@ -545,7 +545,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request) { - uint32 ntlmssp_command, auth_flags; + uint32_t ntlmssp_command, auth_flags; NTSTATUS nt_status; uchar session_nonce_hash[16]; @@ -978,7 +978,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - uint32 chal_flags, ntlmssp_command, unkn1, unkn2; + uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; DATA_BLOB challenge_blob; DATA_BLOB struct_blob = data_blob(NULL, 0); diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index d3d39e8465..95713de6c5 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -77,7 +77,7 @@ typedef struct ntlmssp_state unsigned int ref_count; enum NTLMSSP_ROLE role; enum server_types server_role; - uint32 expected_state; + uint32_t expected_state; BOOL unicode; BOOL use_ntlmv2; @@ -103,7 +103,7 @@ typedef struct ntlmssp_state DATA_BLOB nt_resp; DATA_BLOB session_key; - uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ /* internal variables used by NTLM2 */ BOOL doing_ntlm2; @@ -163,7 +163,7 @@ typedef struct ntlmssp_state /* SMB Signing */ - uint32 ntlmssp_seq_num; + uint32_t ntlmssp_seq_num; /* ntlmv2 */ char send_sign_key[16]; diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 6ddaeebb06..6d0d644a89 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -191,8 +191,8 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *b; size_t head_ofs = 0; uint16 len1, len2; - uint32 ptr; - uint32 *v; + uint32_t ptr; + uint32_t *v; pstring p; va_start(ap, format); @@ -296,7 +296,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, head_ofs += len1; break; case 'd': - v = va_arg(ap, uint32 *); + v = va_arg(ap, uint32_t *); NEED_DATA(4); *v = IVAL(blob->data, head_ofs); head_ofs += 4; break; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 6abec7e8b6..df7bddcd38 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -159,7 +159,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, memcpy(sig->data + 12, seq_num, 4); } else { - uint32 crc; + uint32_t crc; crc = crc32_calc_buffer((const char *)data, length); if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; @@ -302,7 +302,7 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, memcpy(sig->data + 4, digest, 8); memcpy(sig->data + 12, seq_num, 4); } else { - uint32 crc; + uint32_t crc; crc = crc32_calc_buffer((const char *)data, length); if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/auth/schannel.h b/source4/libcli/auth/schannel.h index 7b710d7cb9..74507c547d 100644 --- a/source4/libcli/auth/schannel.h +++ b/source4/libcli/auth/schannel.h @@ -25,7 +25,7 @@ struct schannel_state { TALLOC_CTX *mem_ctx; uint8 session_key[16]; - uint32 seq_num; + uint32_t seq_num; BOOL initiator; DATA_BLOB signature; }; diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index d1dd0b4ff2..803e27699f 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -51,7 +51,7 @@ static NTSTATUS cli_link_internal(struct cli_tree *tree, /**************************************************************************** Map standard UNIX permissions onto wire representations. ****************************************************************************/ -static uint32 unix_perms_to_wire(mode_t perms) +static uint32_t unix_perms_to_wire(mode_t perms) { unsigned int ret = 0; @@ -100,8 +100,8 @@ NTSTATUS cli_unix_hardlink(struct cli_tree *tree, const char *fname_src, ****************************************************************************/ static NTSTATUS cli_unix_chmod_chown_internal(struct cli_tree *tree, const char *fname, - uint32 mode, uint32 uid, - uint32 gid) + uint32_t mode, uint32_t uid, + uint32_t gid) { union smb_setfileinfo parms; NTSTATUS status; @@ -136,7 +136,7 @@ NTSTATUS cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, gid_t gid) { return cli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE, - (uint32)uid, (uint32)gid); + (uint32_t)uid, (uint32_t)gid); } @@ -224,9 +224,9 @@ NTSTATUS cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) Used in CIFS-on-CIFS NTVFS. ****************************************************************************/ int cli_nt_create_full(struct cli_tree *tree, const char *fname, - uint32 CreatFlags, uint32 DesiredAccess, - uint32 FileAttributes, uint32 ShareAccess, - uint32 CreateDisposition, uint32 CreateOptions, + uint32_t CreatFlags, uint32_t DesiredAccess, + uint32_t FileAttributes, uint32_t ShareAccess, + uint32_t CreateDisposition, uint32_t CreateOptions, uint8 SecurityFlags) { union smb_open open_parms; @@ -347,7 +347,7 @@ NTSTATUS cli_close(struct cli_tree *tree, int fnum) this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, - uint32 offset, uint32 len, int timeout, + uint32_t offset, uint32_t len, int timeout, unsigned char locktype) { union smb_lock parms; @@ -375,7 +375,7 @@ NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, Lock a file. ****************************************************************************/ NTSTATUS cli_lock(struct cli_tree *tree, int fnum, - uint32 offset, uint32 len, int timeout, + uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type) { union smb_lock parms; @@ -402,7 +402,7 @@ NTSTATUS cli_lock(struct cli_tree *tree, int fnum, /**************************************************************************** Unlock a file. ****************************************************************************/ -NTSTATUS cli_unlock(struct cli_tree *tree, int fnum, uint32 offset, uint32 len) +NTSTATUS cli_unlock(struct cli_tree *tree, int fnum, uint32_t offset, uint32_t len) { union smb_lock parms; struct smb_lock_entry lock[1]; diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c index 1d9c02f7f4..0d4fade295 100644 --- a/source4/libcli/raw/clikrb5.c +++ b/source4/libcli/raw/clikrb5.c @@ -37,10 +37,10 @@ /* * This function is not in the Heimdal mainline. */ - krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) + krb5_error_code krb5_set_real_time(krb5_context context, int32_t_t seconds, int32_t_t microseconds) { krb5_error_code ret; - int32_t sec, usec; + int32_t_t sec, usec; ret = krb5_us_timeofday(context, &sec, &usec); if (ret) diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index ce0368c304..f265c8281d 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -42,7 +42,7 @@ uint_t ea_list_size(uint_t num_eas, struct ea_struct *eas) void ea_put_list(char *data, uint_t num_eas, struct ea_struct *eas) { int i; - uint32 ea_size; + uint32_t ea_size; ea_size = ea_list_size(num_eas, eas); @@ -105,7 +105,7 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, uint_t *num_eas, struct ea_struct **eas) { int n; - uint32 ea_size, ofs; + uint32_t ea_size, ofs; if (blob->length < 4) { return NT_STATUS_INFO_LENGTH_MISMATCH; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 7d635da0dc..1030a61704 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -51,7 +51,7 @@ NTSTATUS smb_raw_changenotify_recv(struct cli_request *req, { struct smb_nttrans nt; NTSTATUS status; - uint32 ofs, i; + uint32_t ofs, i; struct cli_session *session = req?req->session:NULL; status = smb_raw_nttrans_recv(req, mem_ctx, &nt); @@ -64,7 +64,7 @@ NTSTATUS smb_raw_changenotify_recv(struct cli_request *req, /* count them */ for (ofs=0; nt.out.params.length - ofs > 12; ) { - uint32 next = IVAL(nt.out.params.data, ofs); + uint32_t next = IVAL(nt.out.params.data, ofs); parms->out.num_changes++; if (next == 0 || ofs + next >= nt.out.params.length) break; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 085b445fba..d8e4d80b39 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -153,7 +153,7 @@ struct cli_request *cli_request_setup_session(struct cli_session *session, { struct cli_request *req; uint16 flags2; - uint32 capabilities; + uint32_t capabilities; req = cli_request_setup_transport(session->transport, command, wct, buflen); @@ -798,7 +798,7 @@ DATA_BLOB cli_req_pull_blob(struct cli_request *req, TALLOC_CTX *mem_ctx, const /* check that a lump of data in a request is within the bounds of the data section of the packet */ -static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32 count) +static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32_t count) { /* be careful with wraparound! */ if (ptr < req->in.data || diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 1fd91b29d7..d13a1227dd 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -320,8 +320,8 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, struct smb_nttrans *parms) { - uint32 total_data, recvd_data=0; - uint32 total_param, recvd_param=0; + uint32_t total_data, recvd_data=0; + uint32_t total_param, recvd_param=0; if (!cli_request_receive(req) || cli_request_is_error(req)) { @@ -369,9 +369,9 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, while (recvd_data < total_data || recvd_param < total_param) { - uint32 param_count, param_ofs, param_disp; - uint32 data_count, data_ofs, data_disp; - uint32 total_data2, total_param2; + uint32_t param_count, param_ofs, param_disp; + uint32_t data_count, data_ofs, data_disp; + uint32_t total_data2, total_param2; /* parse out the total lengths again - they can shrink! */ total_param2 = IVAL(req->in.vwv, 3); diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 5f47a5e42a..bb295ee991 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -24,7 +24,7 @@ struct smb_basic_signing_context { DATA_BLOB mac_key; - uint32 next_seq_num; + uint32_t next_seq_num; }; /*********************************************************** diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index 97436d2106..7b78d191dd 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -75,7 +75,7 @@ NTSTATUS cli_nt_error(struct cli_tree *tree) /* Return the DOS error from the last packet - an error class and an error code. */ -void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) +void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32_t *ecode) { if (cli->transport->error.etype == ETYPE_DOS) { ntstatus_to_dos(cli->transport->error.e.nt_status, diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index dbc9c20155..88ece25a8e 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -59,7 +59,7 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) return NULL; } - ret->sub_auths = talloc_array_p(mem_ctx, uint32, num_sub_auths); + ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, num_sub_auths); if (!ret->sub_auths) { return NULL; } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index a257c2d0ea..11a07d45c7 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -47,7 +47,7 @@ /* NT status -> dos error map */ static const struct { uint8 dos_class; - uint32 dos_code; + uint32_t dos_code; NTSTATUS ntstatus; } ntstatus_to_dos_map[] = { {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, @@ -613,7 +613,7 @@ static const struct { /* dos -> nt status error map */ static const struct { uint8 dos_class; - uint32 dos_code; + uint32_t dos_code; NTSTATUS ntstatus; } dos_to_ntstatus_map[] = { {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, @@ -1410,7 +1410,7 @@ static const struct { /***************************************************************************** convert a dos eclas/ecode to a NT status32 code *****************************************************************************/ -NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode) +NTSTATUS dos_to_ntstatus(uint8 eclass, uint32_t ecode) { int i; if (eclass == 0 && ecode == 0) return NT_STATUS_OK; @@ -1427,7 +1427,7 @@ NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode) /***************************************************************************** convert a NT status code to a dos class/code *****************************************************************************/ -void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) +void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32_t *ecode) { int i; if (NT_STATUS_IS_OK(ntstatus)) { diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index edf1526d2e..b31f62c727 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -461,7 +461,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) returned password including termination. ************************************************************/ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len, + int new_pwrd_size, uint32_t *new_pw_len, int string_flags) { int byte_len=0; -- cgit From f88bf54c7f6d1c2ef833047eb8327953c304b5ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:24:24 +0000 Subject: r889: convert samba4 to use [u]int16_t instead of [u]int16 metze (This used to be commit af6f1f8a01bebbecd99bc8c066519e89966e65e3) --- source4/libcli/auth/ntlmssp_parse.c | 2 +- source4/libcli/clidfs.c | 4 ++-- source4/libcli/clifile.c | 6 +++--- source4/libcli/clilist.c | 6 +++--- source4/libcli/clireadwrite.c | 2 +- source4/libcli/clitrans2.c | 6 +++--- source4/libcli/nmblib.c | 2 +- source4/libcli/raw/clioplock.c | 2 +- source4/libcli/raw/clisession.c | 4 ++-- source4/libcli/raw/clitransport.c | 4 ++-- source4/libcli/raw/raweas.c | 2 +- source4/libcli/raw/rawfile.c | 8 ++++---- source4/libcli/raw/rawfileinfo.c | 8 ++++---- source4/libcli/raw/rawfsinfo.c | 8 ++++---- source4/libcli/raw/rawioctl.c | 2 +- source4/libcli/raw/rawnotify.c | 2 +- source4/libcli/raw/rawrequest.c | 18 +++++++++--------- source4/libcli/raw/rawsearch.c | 24 ++++++++++++------------ source4/libcli/raw/rawsetfileinfo.c | 10 +++++----- source4/libcli/raw/rawtrans.c | 6 +++--- source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/util/smbencrypt.c | 2 +- source4/libcli/util/smberr.c | 2 +- 23 files changed, 66 insertions(+), 66 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 6d0d644a89..91596e7bdb 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -190,7 +190,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const char **ps, *s; DATA_BLOB *b; size_t head_ofs = 0; - uint16 len1, len2; + uint16_t len1, len2; uint32_t ptr; uint32_t *v; pstring p; diff --git a/source4/libcli/clidfs.c b/source4/libcli/clidfs.c index fc24cccf54..ae7a8dc6eb 100644 --- a/source4/libcli/clidfs.c +++ b/source4/libcli/clidfs.c @@ -113,7 +113,7 @@ int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinf int i; char *rparam=NULL, *rdata=NULL; int param_len, data_len; - uint16 setup; + uint16_t setup; pstring param; DATA_BLOB trans_param, trans_data; @@ -381,7 +381,7 @@ int cli_dfs_open(struct cli_client* cluster, int *server, ****************************************************************************/ NTSTATUS cli_nt_unlink(struct cli_client* cluster, int *server, - char *fname_src, uint16 FileAttributes) + char *fname_src, uint16_t FileAttributes) { int referral_number; dfs_info dinfo; diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 803e27699f..a417ae621c 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -495,7 +495,7 @@ NTSTATUS cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, Do a SMBgetattrE call. ****************************************************************************/ NTSTATUS cli_getattrE(struct cli_tree *tree, int fnum, - uint16 *attr, size_t *size, + uint16_t *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { union smb_fileinfo parms; @@ -536,7 +536,7 @@ NTSTATUS cli_getattrE(struct cli_tree *tree, int fnum, Do a SMBgetatr call ****************************************************************************/ NTSTATUS cli_getatr(struct cli_tree *tree, const char *fname, - uint16 *attr, size_t *size, time_t *t) + uint16_t *attr, size_t *size, time_t *t) { union smb_fileinfo parms; NTSTATUS status; @@ -569,7 +569,7 @@ NTSTATUS cli_getatr(struct cli_tree *tree, const char *fname, /**************************************************************************** Do a SMBsetatr call. ****************************************************************************/ -NTSTATUS cli_setatr(struct cli_tree *tree, const char *fname, uint16 mode, +NTSTATUS cli_setatr(struct cli_tree *tree, const char *fname, uint16_t mode, time_t t) { union smb_setfileinfo parms; diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index ca4b6acdc7..09d536a710 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -81,7 +81,7 @@ static BOOL cli_list_new_callback(void *private, union smb_search_data *file) return True; } -int cli_list_new(struct cli_tree *tree, const char *Mask, uint16 attribute, +int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, void (*fn)(file_info *, const char *, void *), void *caller_state) { @@ -224,7 +224,7 @@ static BOOL cli_list_old_callback(void *private, union smb_search_data *file) return True; } -int cli_list_old(struct cli_tree *tree, const char *Mask, uint16 attribute, +int cli_list_old(struct cli_tree *tree, const char *Mask, uint16_t attribute, void (*fn)(file_info *, const char *, void *), void *caller_state) { @@ -307,7 +307,7 @@ int cli_list_old(struct cli_tree *tree, const char *Mask, uint16 attribute, This auto-switches between old and new style. ****************************************************************************/ -int cli_list(struct cli_tree *tree, const char *Mask,uint16 attribute, +int cli_list(struct cli_tree *tree, const char *Mask,uint16_t attribute, void (*fn)(file_info *, const char *, void *), void *state) { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 7b47281e2c..e9c8b80c4f 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -83,7 +83,7 @@ ssize_t cli_read(struct cli_tree *tree, int fnum, char *buf, off_t offset, 0x0008 start of message mode named pipe protocol ****************************************************************************/ ssize_t cli_write(struct cli_tree *tree, - int fnum, uint16 write_mode, + int fnum, uint16_t write_mode, const char *buf, off_t offset, size_t size) { union smb_write parms; diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index dc8c2cdfec..a83660685b 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -25,7 +25,7 @@ send a qpathinfo call ****************************************************************************/ NTSTATUS cli_qpathinfo(struct cli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) + size_t *size, uint16_t *mode) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; @@ -66,7 +66,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ NTSTATUS cli_qpathinfo2(struct cli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, + time_t *w_time, size_t *size, uint16_t *mode, SMB_INO_T *ino) { union smb_fileinfo parms; @@ -141,7 +141,7 @@ NTSTATUS cli_qfilename(struct cli_tree *tree, int fnum, const char **name) send a qfileinfo call ****************************************************************************/ NTSTATUS cli_qfileinfo(struct cli_tree *tree, int fnum, - uint16 *mode, size_t *size, + uint16_t *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index a875f4652e..0fe9ee2453 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -1244,7 +1244,7 @@ static char *name_ptr(char *buf,int ofs) if ((c & 0xC0) == 0xC0) { - uint16 l = RSVAL(buf, ofs) & 0x3FFF; + uint16_t l = RSVAL(buf, ofs) & 0x3FFF; DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); return(buf + l); } diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index f27bf937ce..eacfd411a0 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -23,7 +23,7 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ -BOOL cli_oplock_ack(struct cli_tree *tree, uint16 fnum, uint16 ack_level) +BOOL cli_oplock_ack(struct cli_tree *tree, uint16_t fnum, uint16_t ack_level) { BOOL ret; struct cli_request *req; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index fe64565597..b3876f2490 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -45,7 +45,7 @@ struct cli_session *cli_session_init(struct cli_transport *transport) session->mem_ctx = mem_ctx; session->transport = transport; - session->pid = (uint16)getpid(); + session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; session->transport->reference_count++; @@ -144,7 +144,7 @@ NTSTATUS smb_raw_session_setup_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { - uint16 len; + uint16_t len; char *p; if (!cli_request_receive(req)) { diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 72cad2e925..1e9032459f 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -127,9 +127,9 @@ BOOL cli_transport_connect(struct cli_transport *transport, /**************************************************************************** get next mid in sequence ****************************************************************************/ -uint16 cli_transport_next_mid(struct cli_transport *transport) +uint16_t cli_transport_next_mid(struct cli_transport *transport) { - uint16 mid; + uint16_t mid; struct cli_request *req; mid = transport->next_mid; diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index f265c8281d..ae58790baa 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -69,7 +69,7 @@ uint_t ea_pull_struct(const DATA_BLOB *blob, struct ea_struct *ea) { uint8 nlen; - uint16 vlen; + uint16_t vlen; if (blob->length < 6) { return 0; diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index d1a665ab14..5128ba96ce 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -111,10 +111,10 @@ static struct cli_request *smb_raw_t2mkdir_send(struct cli_tree *tree, union smb_mkdir *parms) { struct smb_trans2 t2; - uint16 setup = TRANSACT2_MKDIR; + uint16_t setup = TRANSACT2_MKDIR; TALLOC_CTX *mem_ctx; struct cli_request *req; - uint16 data_total; + uint16_t data_total; mem_ctx = talloc_init("t2mkdir"); @@ -219,10 +219,10 @@ static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, union smb_open *parms) { struct smb_trans2 t2; - uint16 setup = TRANSACT2_OPEN; + uint16_t setup = TRANSACT2_OPEN; TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open"); struct cli_request *req; - uint16 list_size; + uint16_t list_size; list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas); diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 9d715e6104..f27a0d7281 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -261,10 +261,10 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, Very raw query file info - returns param/data blobs - (async send) ****************************************************************************/ static struct cli_request *smb_raw_fileinfo_blob_send(struct cli_tree *tree, - uint16 fnum, uint16 info_level) + uint16_t fnum, uint16_t info_level) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_QFILEINFO; + uint16_t setup = TRANSACT2_QFILEINFO; struct cli_request *req; TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo"); @@ -314,10 +314,10 @@ static NTSTATUS smb_raw_fileinfo_blob_recv(struct cli_request *req, ****************************************************************************/ static struct cli_request *smb_raw_pathinfo_blob_send(struct cli_tree *tree, const char *fname, - uint16 info_level) + uint16_t info_level) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_QPATHINFO; + uint16_t setup = TRANSACT2_QPATHINFO; struct cli_request *req; TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo"); diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 85daf654d3..faf375deb0 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -67,10 +67,10 @@ failed: ****************************************************************************/ static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree, TALLOC_CTX *mem_ctx, - uint16 info_level) + uint16_t info_level) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_QFSINFO; + uint16_t setup = TRANSACT2_QFSINFO; tp.in.max_setup = 0; tp.in.flags = 0; @@ -133,7 +133,7 @@ struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo) { - uint16 info_level; + uint16_t info_level; /* handle the only non-trans2 call separately */ if (fsinfo->generic.level == RAW_QFS_DSKATTR) { @@ -144,7 +144,7 @@ struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree, } /* the headers map the trans2 levels direct to info levels */ - info_level = (uint16)fsinfo->generic.level; + info_level = (uint16_t)fsinfo->generic.level; return smb_raw_qfsinfo_send(tree, mem_ctx, info_level); } diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 2ea2cabb89..271758c65c 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -72,7 +72,7 @@ static struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, union smb_ioctl *parms) { struct smb_nttrans nt; - uint16 setup[4]; + uint16_t setup[4]; nt.in.max_setup = 0; nt.in.max_param = 0; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 1030a61704..b8efa2fcd6 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -26,7 +26,7 @@ change notify (async send) struct cli_request *smb_raw_changenotify_send(struct cli_tree *tree, struct smb_notify *parms) { struct smb_nttrans nt; - uint16 setup[4]; + uint16_t setup[4]; nt.in.max_setup = 0; nt.in.max_param = parms->in.buffer_size; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index d8e4d80b39..d7085ea3d2 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -152,7 +152,7 @@ struct cli_request *cli_request_setup_session(struct cli_session *session, uint8 command, unsigned wct, unsigned buflen) { struct cli_request *req; - uint16 flags2; + uint16_t flags2; uint32_t capabilities; req = cli_request_setup_transport(session->transport, command, wct, buflen); @@ -341,8 +341,8 @@ static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, con } if (transport->oplock.handler) { - uint16 tid = SVAL(hdr, HDR_TID); - uint16 fnum = SVAL(vwv,VWV(2)); + uint16_t tid = SVAL(hdr, HDR_TID); + uint16_t fnum = SVAL(vwv,VWV(2)); uint8 level = CVAL(vwv,VWV(3)+1); transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private); } @@ -370,7 +370,7 @@ BOOL cli_request_receive_next(struct cli_transport *transport) char *buffer, *hdr, *vwv; TALLOC_CTX *mem_ctx; struct cli_request *req; - uint16 wct, mid = 0; + uint16_t wct, mid = 0; len = cli_sock_read(transport->socket, header, 4); if (len != 4) { @@ -635,7 +635,7 @@ size_t cli_req_append_bytes(struct cli_request *req, const uint8 *bytes, size_t append variable block (type 5 buffer) into the data portion of the request packet return the number of bytes added */ -size_t cli_req_append_var_block(struct cli_request *req, const uint8 *bytes, uint16 byte_len) +size_t cli_req_append_var_block(struct cli_request *req, const uint8 *bytes, uint16_t byte_len) { cli_req_grow_allocation(req, byte_len + 3 + req->out.data_size); SCVAL(req->out.data + req->out.data_size, 0, 5); @@ -831,7 +831,7 @@ BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char * /* put a NTTIME into a packet */ -void cli_push_nttime(void *base, uint16 offset, NTTIME t) +void cli_push_nttime(void *base, uint16_t offset, NTTIME t) { SBVAL(base, offset, t); } @@ -839,7 +839,7 @@ void cli_push_nttime(void *base, uint16 offset, NTTIME t) /* pull a NTTIME from a packet */ -NTTIME cli_pull_nttime(void *base, uint16 offset) +NTTIME cli_pull_nttime(void *base, uint16_t offset) { NTTIME ret = BVAL(base, offset); return ret; @@ -967,7 +967,7 @@ size_t cli_blob_pull_string(struct cli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, WIRE_STRING *dest, - uint16 len_offset, uint16 str_offset, + uint16_t len_offset, uint16_t str_offset, unsigned flags) { int extra; @@ -1022,7 +1022,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **dest, - uint16 str_offset, + uint16_t str_offset, unsigned flags) { int extra = 0; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 8b60633fe8..bdb57aa6c4 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -25,7 +25,7 @@ ****************************************************************************/ static void smb_raw_search_backend(struct cli_request *req, TALLOC_CTX *mem_ctx, - uint16 count, + uint16_t count, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) @@ -129,12 +129,12 @@ static NTSTATUS smb_raw_search_next_old(struct cli_tree *tree, static NTSTATUS smb_raw_search_first_blob(struct cli_tree *tree, TALLOC_CTX *mem_ctx, /* used to allocate output blobs */ union smb_search_first *io, - uint16 info_level, + uint16_t info_level, DATA_BLOB *out_param_blob, DATA_BLOB *out_data_blob) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_FINDFIRST; + uint16_t setup = TRANSACT2_FINDFIRST; NTSTATUS status; tp.in.max_setup = 0; @@ -181,12 +181,12 @@ static NTSTATUS smb_raw_search_first_blob(struct cli_tree *tree, static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, - uint16 info_level, + uint16_t info_level, DATA_BLOB *out_param_blob, DATA_BLOB *out_data_blob) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_FINDNEXT; + uint16_t setup = TRANSACT2_FINDNEXT; NTSTATUS status; tp.in.max_setup = 0; @@ -236,7 +236,7 @@ static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, static int parse_trans2_search(struct cli_tree *tree, TALLOC_CTX *mem_ctx, enum search_level level, - uint16 flags, + uint16_t flags, DATA_BLOB *blob, union smb_search_data *data) { @@ -450,8 +450,8 @@ static int parse_trans2_search(struct cli_tree *tree, static NTSTATUS smb_raw_t2search_backend(struct cli_tree *tree, TALLOC_CTX *mem_ctx, enum search_level level, - uint16 flags, - int16 count, + uint16_t flags, + int16_t count, DATA_BLOB *blob, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) @@ -495,7 +495,7 @@ NTSTATUS smb_raw_search_first(struct cli_tree *tree, union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { - uint16 info_level = 0; + uint16_t info_level = 0; DATA_BLOB p_blob, d_blob; NTSTATUS status; @@ -505,7 +505,7 @@ NTSTATUS smb_raw_search_first(struct cli_tree *tree, if (io->generic.level >= RAW_SEARCH_GENERIC) { return NT_STATUS_INVALID_LEVEL; } - info_level = (uint16)io->generic.level; + info_level = (uint16_t)io->generic.level; status = smb_raw_search_first_blob(tree, mem_ctx, io, info_level, &p_blob, &d_blob); @@ -539,7 +539,7 @@ NTSTATUS smb_raw_search_next(struct cli_tree *tree, union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { - uint16 info_level = 0; + uint16_t info_level = 0; DATA_BLOB p_blob, d_blob; NTSTATUS status; @@ -549,7 +549,7 @@ NTSTATUS smb_raw_search_next(struct cli_tree *tree, if (io->generic.level >= RAW_SEARCH_GENERIC) { return NT_STATUS_INVALID_LEVEL; } - info_level = (uint16)io->generic.level; + info_level = (uint16_t)io->generic.level; status = smb_raw_search_next_blob(tree, mem_ctx, io, info_level, &p_blob, &d_blob); diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index d8fc78972d..3dcda401f5 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -132,12 +132,12 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, ****************************************************************************/ static struct cli_request *smb_raw_setfileinfo_blob_send(struct cli_tree *tree, TALLOC_CTX *mem_ctx, - uint16 fnum, - uint16 info_level, + uint16_t fnum, + uint16_t info_level, DATA_BLOB *blob) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_SETFILEINFO; + uint16_t setup = TRANSACT2_SETFILEINFO; tp.in.max_setup = 0; tp.in.flags = 0; @@ -166,11 +166,11 @@ static struct cli_request *smb_raw_setfileinfo_blob_send(struct cli_tree *tree, static struct cli_request *smb_raw_setpathinfo_blob_send(struct cli_tree *tree, TALLOC_CTX *mem_ctx, const char *fname, - uint16 info_level, + uint16_t info_level, DATA_BLOB *blob) { struct smb_trans2 tp; - uint16 setup = TRANSACT2_SETPATHINFO; + uint16_t setup = TRANSACT2_SETPATHINFO; tp.in.max_setup = 0; tp.in.flags = 0; diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index d13a1227dd..04dbcdc87d 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -119,9 +119,9 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, } while (1) { - uint16 param_count, param_ofs, param_disp; - uint16 data_count, data_ofs, data_disp; - uint16 total_data2, total_param2; + uint16_t param_count, param_ofs, param_disp; + uint16_t data_count, data_ofs, data_disp; + uint16_t total_data2, total_param2; /* parse out the total lengths again - they can shrink! */ total_data2 = SVAL(req->in.vwv, VWV(1)); diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index bb295ee991..989b5527aa 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -68,7 +68,7 @@ static BOOL set_smb_signing_real_common(struct cli_transport *transport) static void mark_packet_signed(struct cli_request *req) { - uint16 flags2; + uint16_t flags2; flags2 = SVAL(req->out.hdr, HDR_FLG2); flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(req->out.hdr, HDR_FLG2, flags2); diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index b31f62c727..fa29059585 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -66,7 +66,7 @@ void E_md4hash(const char *passwd, uchar p16[16]) /* Password must be converted to NT unicode - null terminated. */ push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); /* Calculate length in bytes */ - len = strlen_w(wpwd) * sizeof(int16); + len = strlen_w(wpwd) * sizeof(int16_t); mdfour(p16, (unsigned char *)wpwd, len); ZERO_STRUCT(wpwd); diff --git a/source4/libcli/util/smberr.c b/source4/libcli/util/smberr.c index d6eabcfbce..577308a7c0 100644 --- a/source4/libcli/util/smberr.c +++ b/source4/libcli/util/smberr.c @@ -145,7 +145,7 @@ static const struct { /* return a dos error string given a error class and error code */ -const char *dos_errstr(uint8 class, uint16 code) +const char *dos_errstr(uint8 class, uint16_t code) { static char *msg; int i, j; -- cgit From fcd718c7d8a6850ae8719f23ed044b06b57501cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:50:17 +0000 Subject: r890: convert samba4 to use [u]int8_t instead of [u]int8 metze (This used to be commit 2986c5f08c8f0c26a2ea7b6ce20aae025183109f) --- source4/libcli/auth/credentials.c | 8 ++++---- source4/libcli/auth/credentials.h | 2 +- source4/libcli/auth/ntlm_check.c | 8 ++++---- source4/libcli/auth/ntlmssp.c | 6 +++--- source4/libcli/auth/ntlmssp.h | 2 +- source4/libcli/auth/ntlmssp_parse.c | 20 ++++++++++---------- source4/libcli/auth/schannel.c | 2 +- source4/libcli/auth/schannel.h | 2 +- source4/libcli/auth/session.c | 2 +- source4/libcli/clifile.c | 2 +- source4/libcli/raw/clispnego.c | 10 +++++----- source4/libcli/raw/rawacl.c | 4 ++-- source4/libcli/raw/rawdate.c | 8 ++++---- source4/libcli/raw/raweas.c | 2 +- source4/libcli/raw/rawrequest.c | 14 +++++++------- source4/libcli/raw/rawtrans.c | 2 +- source4/libcli/util/asn1.c | 26 +++++++++++++------------- source4/libcli/util/clierror.c | 2 +- source4/libcli/util/errormap.c | 8 ++++---- source4/libcli/util/smbencrypt.c | 6 +++--- source4/libcli/util/smberr.c | 4 ++-- 21 files changed, 70 insertions(+), 70 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 139b17d5b3..cf6d0cca62 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -31,11 +31,11 @@ static void creds_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16]) + const uint8_t machine_password[16]) { struct netr_Credential time_cred; uint32_t sum[2]; - uint8 sum2[8]; + uint8_t sum2[8]; dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); @@ -144,7 +144,7 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16], + const uint8_t machine_password[16], struct netr_Credential *initial_credential) { creds->sequence = time(NULL); @@ -197,7 +197,7 @@ next comes the server specific functions void creds_server_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16], + const uint8_t machine_password[16], struct netr_Credential *initial_credential) { creds_init(creds, client_challenge, server_challenge, machine_password); diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 85efd54bc1..84787bd778 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -21,7 +21,7 @@ */ struct creds_CredentialState { - uint8 session_key[8]; + uint8_t session_key[8]; uint32_t sequence; struct netr_Credential seed; struct netr_Credential client; diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index 96aa352542..a3b92752aa 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -174,7 +174,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, const char *username, const char *client_username, const char *client_domain, - const uint8 *lm_pw, const uint8 *nt_pw, + const uint8_t *lm_pw, const uint8_t *nt_pw, DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { @@ -326,7 +326,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, so use it only if we otherwise allow LM authentication */ if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; + uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); *lm_sess_key = data_blob(first_8_lm_hash, 16); @@ -367,7 +367,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, if (smb_pwd_check_ntlmv1(lm_response, lm_pw, challenge, NULL)) { - uint8 first_8_lm_hash[16]; + uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); *user_sess_key = data_blob(first_8_lm_hash, 16); @@ -427,7 +427,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, allow LM authentication */ if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; + uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); *user_sess_key = data_blob(first_8_lm_hash, 16); diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 54b219f879..4f6c6d02c9 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -105,7 +105,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) * */ -static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) +static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; generate_random_buffer(chal, sizeof(chal), False); @@ -430,7 +430,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, uint32_t neg_flags = 0; uint32_t ntlmssp_command, chal_flags; char *cliname=NULL, *domname=NULL; - const uint8 *cryptkey; + const uint8_t *cryptkey; const char *target_name; /* parse the NTLMSSP packet */ @@ -1184,7 +1184,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { /* Make up a new session key */ - uint8 client_session_key[16]; + uint8_t client_session_key[16]; generate_random_buffer(client_session_key, sizeof(client_session_key), False); /* Encrypt the new session key with the old one */ diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 95713de6c5..28487c1ab5 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -121,7 +121,7 @@ typedef struct ntlmssp_state * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication * */ - const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); + const uint8_t *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); /** * Callback to find if the challenge used by NTLM authentication may be modified diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 91596e7bdb..aa4fc6b98f 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -46,7 +46,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, int i, n; va_list ap; char *s; - uint8 *b; + uint8_t *b; int head_size=0, data_size=0; int head_ofs, data_ofs; @@ -70,12 +70,12 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, data_size += (str_charnum(s) * 2) + 4; break; case 'B': - b = va_arg(ap, uint8 *); + b = va_arg(ap, uint8_t *); head_size += 8; data_size += va_arg(ap, int); break; case 'b': - b = va_arg(ap, uint8 *); + b = va_arg(ap, uint8_t *); head_size += va_arg(ap, int); break; case 'd': @@ -131,7 +131,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, break; case 'B': - b = va_arg(ap, uint8 *); + b = va_arg(ap, uint8_t *); n = va_arg(ap, int); SSVAL(blob->data, head_ofs, n); head_ofs += 2; SSVAL(blob->data, head_ofs, n); head_ofs += 2; @@ -145,7 +145,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, SIVAL(blob->data, head_ofs, n); head_ofs += 4; break; case 'b': - b = va_arg(ap, uint8 *); + b = va_arg(ap, uint8_t *); n = va_arg(ap, int); memcpy(blob->data + head_ofs, b, n); head_ofs += n; @@ -216,7 +216,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, /* if odd length and unicode */ return False; } - if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) return False; if (0 < len1) { @@ -247,7 +247,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, return False; } - if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) return False; if (0 < len1) { @@ -278,7 +278,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, return False; } - if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) return False; *b = data_blob_talloc(mem_ctx, blob->data + ptr, len1); @@ -289,7 +289,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, len1 = va_arg(ap, unsigned); /* make sure its in the right format - be strict */ NEED_DATA(len1); - if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) return False; *b = data_blob_talloc(mem_ctx, blob->data + head_ofs, len1); @@ -303,7 +303,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, case 'C': s = va_arg(ap, char *); - if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) return False; head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 59d0c4aa7d..0a26db3037 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -286,7 +286,7 @@ void schannel_end(struct schannel_state **state) create an schannel context state */ NTSTATUS schannel_start(struct schannel_state **state, - uint8 session_key[16], + uint8_t session_key[16], BOOL initiator) { TALLOC_CTX *mem_ctx; diff --git a/source4/libcli/auth/schannel.h b/source4/libcli/auth/schannel.h index 74507c547d..b074b104fb 100644 --- a/source4/libcli/auth/schannel.h +++ b/source4/libcli/auth/schannel.h @@ -24,7 +24,7 @@ struct schannel_state { TALLOC_CTX *mem_ctx; - uint8 session_key[16]; + uint8_t session_key[16]; uint32_t seq_num; BOOL initiator; DATA_BLOB signature; diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 77eb1a6527..1176d7fd0d 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -37,7 +37,7 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi for (i=0,k=0; ilength; i += 8, k += 7) { - uint8 bin[8], bout[8], key[7]; + uint8_t bin[8], bout[8], key[7]; memset(bin, 0, 8); memcpy(bin, &in->data[i], MIN(8, in->length-i)); diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index a417ae621c..d1f9145e44 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -227,7 +227,7 @@ int cli_nt_create_full(struct cli_tree *tree, const char *fname, uint32_t CreatFlags, uint32_t DesiredAccess, uint32_t FileAttributes, uint32_t ShareAccess, uint32_t CreateDisposition, uint32_t CreateOptions, - uint8 SecurityFlags) + uint8_t SecurityFlags) { union smb_open open_parms; TALLOC_CTX *mem_ctx; diff --git a/source4/libcli/raw/clispnego.c b/source4/libcli/raw/clispnego.c index 7ad6be1006..ff7d45c8c1 100644 --- a/source4/libcli/raw/clispnego.c +++ b/source4/libcli/raw/clispnego.c @@ -26,7 +26,7 @@ generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ -DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], +DATA_BLOB spnego_gen_negTokenInit(uint8_t guid[16], const char *OIDs[], const char *principal) { @@ -260,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8_t tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; @@ -288,7 +288,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8_t tok_id[2]) { BOOL ret; ASN1_DATA data; @@ -453,7 +453,7 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, { ASN1_DATA data; DATA_BLOB ret; - uint8 negResult; + uint8_t negResult; if (NT_STATUS_IS_OK(nt_status)) { negResult = SPNEGO_NEG_RESULT_ACCEPT; @@ -496,7 +496,7 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, DATA_BLOB *auth) { ASN1_DATA data; - uint8 negResult; + uint8_t negResult; if (NT_STATUS_IS_OK(nt_status)) { negResult = SPNEGO_NEG_RESULT_ACCEPT; diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index cfc086c7ce..ca93591597 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -27,7 +27,7 @@ struct cli_request *smb_raw_query_secdesc_send(struct cli_tree *tree, struct smb_query_secdesc *query) { struct smb_nttrans nt; - uint8 params[8]; + uint8_t params[8]; nt.in.max_setup = 0; nt.in.max_param = 4; @@ -108,7 +108,7 @@ struct cli_request *smb_raw_set_secdesc_send(struct cli_tree *tree, struct smb_set_secdesc *set) { struct smb_nttrans nt; - uint8 params[8]; + uint8_t params[8]; struct ndr_push *ndr; struct cli_request *req; NTSTATUS status; diff --git a/source4/libcli/raw/rawdate.c b/source4/libcli/raw/rawdate.c index e80c376bf7..3b731d653b 100644 --- a/source4/libcli/raw/rawdate.c +++ b/source4/libcli/raw/rawdate.c @@ -27,7 +27,7 @@ put a dos date into a buffer (time/date format) This takes GMT time and puts local time for zone_offset in the buffer ********************************************************************/ void raw_push_dos_date(struct cli_transport *transport, - uint8 *buf, int offset, time_t unixdate) + uint8_t *buf, int offset, time_t unixdate) { push_dos_date(buf, offset, unixdate, transport->negotiate.server_zone); } @@ -56,7 +56,7 @@ void raw_push_dos_date3(struct cli_transport *transport, convert a dos date ********************************************************************/ time_t raw_pull_dos_date(struct cli_transport *transport, - const uint8 *date_ptr) + const uint8_t *date_ptr) { return pull_dos_date(date_ptr, transport->negotiate.server_zone); } @@ -65,7 +65,7 @@ time_t raw_pull_dos_date(struct cli_transport *transport, like raw_pull_dos_date() but the words are reversed ********************************************************************/ time_t raw_pull_dos_date2(struct cli_transport *transport, - const uint8 *date_ptr) + const uint8_t *date_ptr) { return pull_dos_date2(date_ptr, transport->negotiate.server_zone); } @@ -75,7 +75,7 @@ time_t raw_pull_dos_date2(struct cli_transport *transport, these arrive in server zone, with corresponding DST ******************************************************************/ time_t raw_pull_dos_date3(struct cli_transport *transport, - const uint8 *date_ptr) + const uint8_t *date_ptr) { return pull_dos_date3(date_ptr, transport->negotiate.server_zone); } diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index ae58790baa..e07fbcd288 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -68,7 +68,7 @@ uint_t ea_pull_struct(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct ea_struct *ea) { - uint8 nlen; + uint8_t nlen; uint16_t vlen; if (blob->length < 6) { diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index d7085ea3d2..fd2d85cc65 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -103,7 +103,7 @@ struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, ui setup a SMB packet at transport level */ struct cli_request *cli_request_setup_transport(struct cli_transport *transport, - uint8 command, unsigned wct, unsigned buflen) + uint8_t command, unsigned wct, unsigned buflen) { struct cli_request *req; @@ -149,7 +149,7 @@ struct cli_request *cli_request_setup_transport(struct cli_transport *transport, way. This interface is used before a session is setup. */ struct cli_request *cli_request_setup_session(struct cli_session *session, - uint8 command, unsigned wct, unsigned buflen) + uint8_t command, unsigned wct, unsigned buflen) { struct cli_request *req; uint16_t flags2; @@ -189,7 +189,7 @@ struct cli_request *cli_request_setup_session(struct cli_session *session, setup a request for tree based commands */ struct cli_request *cli_request_setup(struct cli_tree *tree, - uint8 command, + uint8_t command, unsigned wct, unsigned buflen) { struct cli_request *req; @@ -343,7 +343,7 @@ static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, con if (transport->oplock.handler) { uint16_t tid = SVAL(hdr, HDR_TID); uint16_t fnum = SVAL(vwv,VWV(2)); - uint8 level = CVAL(vwv,VWV(3)+1); + uint8_t level = CVAL(vwv,VWV(3)+1); transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private); } @@ -599,7 +599,7 @@ size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsig size_t cli_req_append_ascii4(struct cli_request *req, const char *str, unsigned flags) { size_t size; - cli_req_append_bytes(req, (const uint8 *)"\4", 1); + cli_req_append_bytes(req, (const uint8_t *)"\4", 1); size = cli_req_append_string(req, str, flags); return size + 1; } @@ -623,7 +623,7 @@ size_t cli_req_append_blob(struct cli_request *req, const DATA_BLOB *blob) append raw bytes into the data portion of the request packet return the number of bytes added */ -size_t cli_req_append_bytes(struct cli_request *req, const uint8 *bytes, size_t byte_len) +size_t cli_req_append_bytes(struct cli_request *req, const uint8_t *bytes, size_t byte_len) { cli_req_grow_allocation(req, byte_len + req->out.data_size); memcpy(req->out.data + req->out.data_size, bytes, byte_len); @@ -635,7 +635,7 @@ size_t cli_req_append_bytes(struct cli_request *req, const uint8 *bytes, size_t append variable block (type 5 buffer) into the data portion of the request packet return the number of bytes added */ -size_t cli_req_append_var_block(struct cli_request *req, const uint8 *bytes, uint16_t byte_len) +size_t cli_req_append_var_block(struct cli_request *req, const uint8_t *bytes, uint16_t byte_len) { cli_req_grow_allocation(req, byte_len + 3 + req->out.data_size); SCVAL(req->out.data + req->out.data_size, 0, 5); diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 04dbcdc87d..fb2abf3e2d 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -206,7 +206,7 @@ NTSTATUS smb_raw_trans_recv(struct cli_request *req, ****************************************************************************/ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, struct smb_trans2 *parms, - uint8 command) + uint8_t command) { int wct = 14 + parms->in.setup_count; struct cli_request *req; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 07c692f700..b44c62bc50 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -31,7 +31,7 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { - uint8 *newp; + uint8_t *newp; newp = Realloc(data->data, data->ofs+len); if (!newp) { SAFE_FREE(data->data); @@ -46,14 +46,14 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) return True; } -/* useful fn for writing a uint8 */ -BOOL asn1_write_uint8(ASN1_DATA *data, uint8 v) +/* useful fn for writing a uint8_t */ +BOOL asn1_write_uint8(ASN1_DATA *data, uint8_t v) { return asn1_write(data, &v, 1); } /* push a tag onto the asn1 data buffer. Used for nested structures */ -BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) +BOOL asn1_push_tag(ASN1_DATA *data, uint8_t tag) { struct nesting *nesting; @@ -187,7 +187,7 @@ BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) /* check a BOOLEAN */ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) { - uint8 b = 0; + uint8_t b = 0; asn1_read_uint8(data, &b); if (b != ASN1_BOOLEAN) { @@ -228,16 +228,16 @@ BOOL asn1_read(ASN1_DATA *data, void *p, int len) return True; } -/* read a uint8 from a ASN1 buffer */ -BOOL asn1_read_uint8(ASN1_DATA *data, uint8 *v) +/* read a uint8_t from a ASN1 buffer */ +BOOL asn1_read_uint8(ASN1_DATA *data, uint8_t *v) { return asn1_read(data, v, 1); } /* start reading a nested asn1 structure */ -BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) +BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) { - uint8 b; + uint8_t b; struct nesting *nesting; if (!asn1_read_uint8(data, &b)) @@ -314,7 +314,7 @@ int asn1_tag_remaining(ASN1_DATA *data) /* read an object ID from a ASN1 buffer */ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) { - uint8 b; + uint8_t b; pstring aoid; fstring el; @@ -392,7 +392,7 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) /* read an interger */ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) { - uint8 b; + uint8_t b; *i = 0; if (!asn1_start_tag(data, ASN1_INTEGER)) return False; @@ -407,7 +407,7 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) /* check a enumarted value is correct */ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) { - uint8 b; + uint8_t b; if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; asn1_read_uint8(data, &b); asn1_end_tag(data); @@ -419,7 +419,7 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) } /* write an enumarted value to the stream */ -BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v) +BOOL asn1_write_enumerated(ASN1_DATA *data, uint8_t v) { if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; asn1_write_uint8(data, v); diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index 7b78d191dd..d852cd0d21 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -75,7 +75,7 @@ NTSTATUS cli_nt_error(struct cli_tree *tree) /* Return the DOS error from the last packet - an error class and an error code. */ -void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32_t *ecode) +void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode) { if (cli->transport->error.etype == ETYPE_DOS) { ntstatus_to_dos(cli->transport->error.e.nt_status, diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 11a07d45c7..46290baa7c 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -46,7 +46,7 @@ /* NT status -> dos error map */ static const struct { - uint8 dos_class; + uint8_t dos_class; uint32_t dos_code; NTSTATUS ntstatus; } ntstatus_to_dos_map[] = { @@ -612,7 +612,7 @@ static const struct { /* dos -> nt status error map */ static const struct { - uint8 dos_class; + uint8_t dos_class; uint32_t dos_code; NTSTATUS ntstatus; } dos_to_ntstatus_map[] = { @@ -1410,7 +1410,7 @@ static const struct { /***************************************************************************** convert a dos eclas/ecode to a NT status32 code *****************************************************************************/ -NTSTATUS dos_to_ntstatus(uint8 eclass, uint32_t ecode) +NTSTATUS dos_to_ntstatus(uint8_t eclass, uint32_t ecode) { int i; if (eclass == 0 && ecode == 0) return NT_STATUS_OK; @@ -1427,7 +1427,7 @@ NTSTATUS dos_to_ntstatus(uint8 eclass, uint32_t ecode) /***************************************************************************** convert a NT status code to a dos class/code *****************************************************************************/ -void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32_t *ecode) +void ntstatus_to_dos(NTSTATUS ntstatus, uint8_t *eclass, uint32_t *ecode) { int i; if (NT_STATUS_IS_OK(ntstatus)) { diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index fa29059585..5b210394c1 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -239,7 +239,7 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], } void SMBsesskeygen_ntv2(const uchar kr[16], - const uchar * nt_resp, uint8 sess_key[16]) + const uchar * nt_resp, uint8_t sess_key[16]) { /* a very nice, 128 bit, variable session key */ @@ -255,7 +255,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], #endif } -void SMBsesskeygen_ntv1(const uchar kr[16], uint8 sess_key[16]) +void SMBsesskeygen_ntv1(const uchar kr[16], uint8_t sess_key[16]) { /* yes, this session key does not change - yes, this is a problem - but it is 128 bits */ @@ -270,7 +270,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], uint8 sess_key[16]) void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], const uchar lm_resp[24], /* only uses 8 */ - uint8 sess_key[16]) + uint8_t sess_key[16]) { /* Calculate the LM session key (effective length 40 bits, but changes with each session) */ diff --git a/source4/libcli/util/smberr.c b/source4/libcli/util/smberr.c index 577308a7c0..87cc601b8d 100644 --- a/source4/libcli/util/smberr.c +++ b/source4/libcli/util/smberr.c @@ -128,7 +128,7 @@ static const struct err_code_struct hard_msgs[] = { static const struct { - uint8 class; + uint8_t class; const char *class_name; const struct err_code_struct *err_msgs; } err_classes[] = { @@ -145,7 +145,7 @@ static const struct { /* return a dos error string given a error class and error code */ -const char *dos_errstr(uint8 class, uint16_t code) +const char *dos_errstr(uint8_t class, uint16_t code) { static char *msg; int i, j; -- cgit From e80dad7561edbf65605e9c94ef8801e4416ba002 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 25 May 2004 18:12:55 +0000 Subject: r891: fix compile (This used to be commit 8b6c048a02b4be0ba9c67ed82973041dccdd5c51) --- source4/libcli/raw/clikrb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c index 0d4fade295..1d9c02f7f4 100644 --- a/source4/libcli/raw/clikrb5.c +++ b/source4/libcli/raw/clikrb5.c @@ -37,10 +37,10 @@ /* * This function is not in the Heimdal mainline. */ - krb5_error_code krb5_set_real_time(krb5_context context, int32_t_t seconds, int32_t_t microseconds) + krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) { krb5_error_code ret; - int32_t_t sec, usec; + int32_t sec, usec; ret = krb5_us_timeofday(context, &sec, &usec); if (ret) -- cgit From 47864891ffd6309764fdc3a5227ec2e83c6f7107 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 May 2004 01:13:12 +0000 Subject: r893: a few more _t conversions (This used to be commit 66eb46dbb1486c5916194bf6b303cf16373a272a) --- source4/libcli/raw/clioplock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index eacfd411a0..0cd6adb41f 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -50,7 +50,7 @@ BOOL cli_oplock_ack(struct cli_tree *tree, uint16_t fnum, uint16_t ack_level) set the oplock handler for a connection ****************************************************************************/ void cli_oplock_handler(struct cli_transport *transport, - BOOL (*handler)(struct cli_transport *, uint16, uint16, uint8, void *), + BOOL (*handler)(struct cli_transport *, uint16_t, uint16_t, uint8_t, void *), void *private) { transport->oplock.handler = handler; -- cgit From 8b3f08cefcd41e6f8005de84a2cc865c1011194d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 May 2004 05:40:33 +0000 Subject: r898: - remove some unused macros - remove unused lib/smbpasswd.c - don't set the pkt size twice when doing SMB signing (This used to be commit 69a2942f7987647a32d43c71f41ac1a82a82ccda) --- source4/libcli/util/errormap.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 46290baa7c..e2aeded65d 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1486,6 +1486,13 @@ WERROR ntstatus_to_werror(NTSTATUS error) /* Mapping between Unix, DOS and NT error numbers */ +struct unix_error_map { + int unix_error; + int dos_class; + int dos_code; + NTSTATUS nt_error; +}; + const struct unix_error_map unix_dos_nt_errmap[] = { { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, -- cgit From db3c011977e9aad535be298d64fa63af61c0669c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 May 2004 04:13:58 +0000 Subject: r917: - added the start of a LSA server to samba4. - added start of QueryDomainInfo in samr server "net rpc info" from samba3 now works against a samba4 server. I suspect join will work fairly soon. (This used to be commit 0a2c6a1062d0e364356853001f5f39bdb542f453) --- source4/libcli/auth/ntlmssp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 28487c1ab5..a5565888f1 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -76,7 +76,7 @@ typedef struct ntlmssp_state TALLOC_CTX *mem_ctx; unsigned int ref_count; enum NTLMSSP_ROLE role; - enum server_types server_role; + enum samr_Role server_role; uint32_t expected_state; BOOL unicode; -- cgit From 45e93c19ef95978f908f5b14962770510634cd3b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 29 May 2004 08:11:46 +0000 Subject: r943: change samba4 to use 'uint8_t' instead of 'unsigned char' metze (This used to be commit b5378803fdcb3b3afe7c2932a38828e83470f61a) --- source4/libcli/auth/ntlm_check.c | 6 ++--- source4/libcli/auth/ntlmssp.h | 10 ++++---- source4/libcli/auth/ntlmssp_sign.c | 22 ++++++++--------- source4/libcli/clifile.c | 2 +- source4/libcli/raw/smb_signing.c | 8 +++---- source4/libcli/util/smbdes.c | 48 +++++++++++++++++++------------------- source4/libcli/util/smbencrypt.c | 14 +++++------ 7 files changed, 55 insertions(+), 55 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index a3b92752aa..cdb092d1b5 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -178,7 +178,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { - static const unsigned char zeros[8]; + static const uint8_t zeros[8]; if (nt_pw == NULL) { DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", username)); @@ -232,7 +232,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", username)); if (nt_pw && nt_response->length) { - unsigned char pwhash[16]; + uint8_t pwhash[16]; mdfour(pwhash, nt_response->data, nt_response->length); if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { return NT_STATUS_OK; @@ -255,7 +255,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, /* Only the fisrt 14 chars are considered, password need not be null terminated. */ /* we *might* need to upper-case the string here */ - E_P16((const unsigned char *)dospwd, p16); + E_P16((const uint8_t *)dospwd, p16); if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { return NT_STATUS_OK; diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index a5565888f1..968911fef5 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -171,13 +171,13 @@ typedef struct ntlmssp_state char recv_sign_key[16]; char recv_seal_key[16]; - unsigned char send_sign_hash[258]; - unsigned char send_seal_hash[258]; - unsigned char recv_sign_hash[258]; - unsigned char recv_seal_hash[258]; + uint8_t send_sign_hash[258]; + uint8_t send_seal_hash[258]; + uint8_t recv_sign_hash[258]; + uint8_t recv_seal_hash[258]; /* ntlmv1 */ - unsigned char ntlmssp_hash[258]; + uint8_t ntlmssp_hash[258]; /* it turns out that we don't always get the response in at the time we want to process it. diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index df7bddcd38..22aa877b63 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -27,16 +27,16 @@ #define SRV_SIGN "session key to server-to-client signing key magic constant" #define SRV_SEAL "session key to server-to-client sealing key magic constant" -static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) +static void NTLMSSPcalc_ap( uint8_t *hash, uint8_t *data, int len) { - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; + uint8_t index_i = hash[256]; + uint8_t index_j = hash[257]; int ind; for (ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; + uint8_t tc; + uint8_t t; index_i++; index_j += hash[index_i]; @@ -53,19 +53,19 @@ static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) hash[257] = index_j; } -static void calc_hash(unsigned char hash[258], const char *key, size_t key_len) +static void calc_hash(uint8_t hash[258], const char *key, size_t key_len) { - unsigned char j = 0; + uint8_t j = 0; int ind; for (ind = 0; ind < 256; ind++) { - hash[ind] = (unsigned char)ind; + hash[ind] = (uint8_t)ind; } for (ind = 0; ind < 256; ind++) { - unsigned char tc; + uint8_t tc; j += (hash[ind] + key[ind%key_len]); @@ -97,7 +97,7 @@ static void calc_hash(unsigned char hash[258], const char *key, size_t key_len) -static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char subkey[16], +static void calc_ntlmv2_hash(uint8_t hash[258], uint8_t subkey[16], DATA_BLOB session_key, const char *constant) { @@ -365,7 +365,7 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, */ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) { - unsigned char p24[24]; + uint8_t p24[24]; ZERO_STRUCT(p24); DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index d1f9145e44..23f3cdc4a4 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -348,7 +348,7 @@ NTSTATUS cli_close(struct cli_tree *tree, int fnum) ****************************************************************************/ NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, uint32_t offset, uint32_t len, int timeout, - unsigned char locktype) + uint8_t locktype) { union smb_lock parms; struct smb_lock_entry lock[1]; diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 989b5527aa..c82946ac53 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -98,7 +98,7 @@ static BOOL signing_good(struct cli_request *req, BOOL good) ************************************************************/ static void cli_request_simple_sign_outgoing_message(struct cli_request *req) { - unsigned char calc_md5_mac[16]; + uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; @@ -150,9 +150,9 @@ static void cli_request_simple_sign_outgoing_message(struct cli_request *req) static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) { BOOL good; - unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - unsigned char sequence_buf[8]; + uint8_t calc_md5_mac[16]; + uint8_t server_sent_mac[8]; + uint8_t sequence_buf[8]; struct MD5Context md5_ctx; struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; const size_t offset_end_of_sig = (HDR_SS_FIELD + 8); diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 22bafcb449..b0efdec157 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -258,7 +258,7 @@ static void dohash(char *out, char *in, char *key, int forw) permute(out, rl, perm6, 64); } -static void str_to_key(const unsigned char *str,unsigned char *key) +static void str_to_key(const uint8_t *str,uint8_t *key) { int i; @@ -276,13 +276,13 @@ static void str_to_key(const unsigned char *str,unsigned char *key) } -void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) +void smbhash(uint8_t *out, const uint8_t *in, const uint8_t *key, int forw) { int i; char outb[64]; char inb[64]; char keyb[64]; - unsigned char key2[8]; + uint8_t key2[8]; str_to_key(key, key2); @@ -304,53 +304,53 @@ void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *k } } -void E_P16(const unsigned char *p14,unsigned char *p16) +void E_P16(const uint8_t *p14,uint8_t *p16) { unsigned const char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; smbhash(p16, sp8, p14, 1); smbhash(p16+8, sp8, p14+7, 1); } -void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24) +void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) { smbhash(p24, c8, p21, 1); smbhash(p24+8, c8, p21+7, 1); smbhash(p24+16, c8, p21+14, 1); } -void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out) +void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out) { smbhash(out, in, p14, 0); smbhash(out+8, in+8, p14+7, 0); } -void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out) +void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) { smbhash(out, in, p14, 1); smbhash(out+8, in+8, p14+7, 1); } -void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key) +void cred_hash1(uint8_t *out, const uint8_t *in, const uint8_t *key) { - unsigned char buf[8]; + uint8_t buf[8]; smbhash(buf, in, key, 1); smbhash(out, buf, key+9, 1); } -void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) +void cred_hash2(uint8_t *out, const uint8_t *in, const uint8_t *key, int forw) { - unsigned char buf[8]; - unsigned char key2[8]; + uint8_t buf[8]; + uint8_t key2[8]; ZERO_STRUCT(key2); smbhash(buf, in, key, forw); key2[0] = key[7]; smbhash(out, buf, key2, forw); } -void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) +void cred_hash3(uint8_t *out, uint8_t *in, const uint8_t *key, int forw) { - unsigned char key2[8]; + uint8_t key2[8]; ZERO_STRUCT(key2); smbhash(out, in, key, forw); key2[0] = key[7]; @@ -358,20 +358,20 @@ void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, } -void SamOEMhashBlob(unsigned char *data, int len, const DATA_BLOB *key) +void SamOEMhashBlob(uint8_t *data, int len, const DATA_BLOB *key) { - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; + uint8_t s_box[256]; + uint8_t index_i = 0; + uint8_t index_j = 0; + uint8_t j = 0; int ind; for (ind = 0; ind < 256; ind++) { - s_box[ind] = (unsigned char)ind; + s_box[ind] = (uint8_t)ind; } for (ind = 0; ind < 256; ind++) { - unsigned char tc; + uint8_t tc; j += (s_box[ind] + key->data[ind%key->length]); @@ -380,8 +380,8 @@ void SamOEMhashBlob(unsigned char *data, int len, const DATA_BLOB *key) s_box[j] = tc; } for (ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; + uint8_t tc; + uint8_t t; index_i++; index_j += s_box[index_i]; @@ -399,7 +399,7 @@ void SamOEMhashBlob(unsigned char *data, int len, const DATA_BLOB *key) a varient that assumes a 16 byte key. This should be removed when the last user is gone */ -void SamOEMhash(unsigned char *data, const unsigned char keystr[16], int len) +void SamOEMhash(uint8_t *data, const uint8_t keystr[16], int len) { DATA_BLOB key = data_blob(keystr, 16); diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 5b210394c1..d52d24e1e1 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -68,7 +68,7 @@ void E_md4hash(const char *passwd, uchar p16[16]) /* Calculate length in bytes */ len = strlen_w(wpwd) * sizeof(int16_t); - mdfour(p16, (unsigned char *)wpwd, len); + mdfour(p16, (uint8_t *)wpwd, len); ZERO_STRUCT(wpwd); } @@ -90,7 +90,7 @@ BOOL E_deshash(const char *passwd, uchar p16[16]) push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - E_P16((const unsigned char *)dospwd, p16); + E_P16((const uint8_t *)dospwd, p16); if (strlen(dospwd) > 14) { ret = False; @@ -170,8 +170,8 @@ BOOL ntv2_owf_gen(const uchar owf[16], domain_byte_len = domain_byte_len - 2; hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); - hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); + hmac_md5_update((const uint8_t *)user, user_byte_len, &ctx); + hmac_md5_update((const uint8_t *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD @@ -247,7 +247,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(nt_resp, 16, &ctx); - hmac_md5_final((unsigned char *)sess_key, &ctx); + hmac_md5_final((uint8_t *)sess_key, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv2:\n")); @@ -260,7 +260,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], uint8_t sess_key[16]) /* yes, this session key does not change - yes, this is a problem - but it is 128 bits */ - mdfour((unsigned char *)sess_key, kr, 16); + mdfour((uint8_t *)sess_key, kr, 16); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv1:\n")); @@ -443,7 +443,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, False); + generate_random_buffer((uint8_t *)buffer, 512 - new_pw_len, False); /* * The length of the new password is in the last 4 bytes of -- cgit From 6a0ce94d025d4288c87080c0f4d6e3013559794c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 May 2004 13:15:15 +0000 Subject: r950: - added netr_ServerAuthenticate3(). This is used by WinXP clients who try to login to Samba4, as WinXP sees us as an ADS server. Unfortunately WinXP also uses a set of negotiate_flags that we don't support yet. Some crypto work needed. (This used to be commit 2d740b65706fb5b4ebc138587472a885d680517f) --- source4/libcli/auth/credentials.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 84787bd778..20eed73cc0 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -34,5 +34,8 @@ struct creds_CredentialState { to NT4. Actually, anything other than 1ff would seem to do... */ #define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff +/* these are the flags that ADS clients use */ +#define NETLOGON_NEG_AUTH2_ADS_FLAGS 0x600fffff + #define NETLOGON_NEG_SCHANNEL 0x40000000 -- cgit From fa2e9ec311b99dee2fbff5ee5fa2c743298dacad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Jun 2004 08:12:45 +0000 Subject: r960: convert 'unsigned int' to uint_t in the most places metze (This used to be commit 18062d2ed9fc9224c43143c10efbf2f6f1f5bbe0) --- source4/libcli/auth/ntlmssp.h | 2 +- source4/libcli/clifile.c | 2 +- source4/libcli/namequery.c | 6 +++--- source4/libcli/nmblib.c | 2 +- source4/libcli/util/dom_sid.c | 2 +- source4/libcli/util/smbdes.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 968911fef5..aa7aa7e02b 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -74,7 +74,7 @@ enum NTLM_MESSAGE_TYPE typedef struct ntlmssp_state { TALLOC_CTX *mem_ctx; - unsigned int ref_count; + uint_t ref_count; enum NTLMSSP_ROLE role; enum samr_Role server_role; uint32_t expected_state; diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 23f3cdc4a4..7f4384a222 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -53,7 +53,7 @@ static NTSTATUS cli_link_internal(struct cli_tree *tree, ****************************************************************************/ static uint32_t unix_perms_to_wire(mode_t perms) { - unsigned int ret = 0; + uint_t ret = 0; ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index a04e883138..fc6a93d8e1 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -1121,8 +1121,8 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... buf -= 4; if (CVAL(buf,smb_com) != SMBtrans) { - DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int) - CVAL(buf,smb_com), (unsigned int)SMBtrans )); + DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (uint_t) + CVAL(buf,smb_com), (uint_t)SMBtrans )); free_packet(p_ret); continue; } @@ -1142,7 +1142,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... if(SVAL(buf2,0) != QUERYFORPDC_R) { DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", - (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); + (uint_t)SVAL(buf,0), (uint_t)QUERYFORPDC_R )); free_packet(p_ret); continue; } diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index 0fe9ee2453..ef61686e57 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -812,7 +812,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) { memset( (char *)n, '\0', sizeof(struct nmb_name) ); push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); - n->name_type = (unsigned int)type & 0xFF; + n->name_type = (uint_t)type & 0xFF; StrnCpy( n->scope, lp_netbios_scope(), 63 ); strupper( n->scope ); } diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index 88ece25a8e..cdf89ccf96 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -28,7 +28,7 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) { struct dom_sid *ret; - unsigned int rev, ia, num_sub_auths, i; + uint_t rev, ia, num_sub_auths, i; char *p; if (strncasecmp(sidstr, "S-", 2)) { diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index b0efdec157..b2e46e759d 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -412,7 +412,7 @@ void SamOEMhash(uint8_t *data, const uint8_t keystr[16], int len) /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ -void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw) +void sam_pwd_hash(uint_t rid, const uchar *in, uchar *out, int forw) { uchar s[14]; -- cgit From 98d291423ff581786a369ce373c861f94c654aa0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Jun 2004 08:30:34 +0000 Subject: r961: convert 'uchar' to 'uint8_t' metze (This used to be commit 9f914e4af99e18b469d4cf9d8b1514a2bd28ddec) --- source4/libcli/auth/ntlm_check.c | 16 ++++---- source4/libcli/auth/ntlmssp.c | 22 +++++------ source4/libcli/auth/ntlmssp.h | 2 +- source4/libcli/auth/ntlmssp_sign.c | 18 ++++----- source4/libcli/auth/schannel.c | 76 +++++++++++++++++++------------------- source4/libcli/namequery.c | 4 +- source4/libcli/nmblib.c | 30 +++++++-------- source4/libcli/raw/clisession.c | 2 +- source4/libcli/util/smbdes.c | 32 ++++++++-------- source4/libcli/util/smbencrypt.c | 58 ++++++++++++++--------------- 10 files changed, 130 insertions(+), 130 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index cdb092d1b5..d12a271420 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -30,12 +30,12 @@ ****************************************************************************/ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, - const uchar *part_passwd, + const uint8_t *part_passwd, const DATA_BLOB *sec_blob, DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ - uchar p24[24]; + uint8_t p24[24]; if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); @@ -81,16 +81,16 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, ****************************************************************************/ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, - const uchar *part_passwd, + const uint8_t *part_passwd, const DATA_BLOB *sec_blob, const char *user, const char *domain, BOOL upper_case_domain, /* should the domain be transformed into upper case? */ DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ - uchar kr[16]; - uchar value_from_encryption[16]; - uchar client_response[16]; + uint8_t kr[16]; + uint8_t value_from_encryption[16]; + uint8_t client_response[16]; DATA_BLOB client_key_data; if (part_passwd == NULL) { @@ -247,8 +247,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, username)); } else if (lm_pw && lm_response->length) { - uchar dospwd[14]; - uchar p16[16]; + uint8_t dospwd[14]; + uint8_t p16[16]; ZERO_STRUCT(dospwd); memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 4f6c6d02c9..49935f0acb 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -107,7 +107,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) { - static uchar chal[8]; + static uint8_t chal[8]; generate_random_buffer(chal, sizeof(chal), False); return chal; @@ -548,7 +548,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, uint32_t ntlmssp_command, auth_flags; NTSTATUS nt_status; - uchar session_nonce_hash[16]; + uint8_t session_nonce_hash[16]; const char *parse_string; char *domain = NULL; @@ -735,7 +735,7 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, } else { /* When there is no LM response, just use zeros */ - static const uchar zeros[24]; + static const uint8_t zeros[24]; session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_lm_sess_key(zeros, zeros, session_key.data); @@ -985,7 +985,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, char *server_domain; const char *chal_parse_string; const char *auth_gen_string; - uchar lm_hash[16]; + uint8_t lm_hash[16]; DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); @@ -1053,7 +1053,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } if (!ntlmssp_state->password) { - static const uchar zeros[16]; + static const uint8_t zeros[16]; /* do nothing - blobs are zero length */ /* session key is all zeros */ @@ -1088,10 +1088,10 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { struct MD5Context md5_session_nonce_ctx; - uchar nt_hash[16]; - uchar session_nonce[16]; - uchar session_nonce_hash[16]; - uchar user_session_key[16]; + uint8_t nt_hash[16]; + uint8_t session_nonce[16]; + uint8_t session_nonce_hash[16]; + uint8_t user_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); @@ -1124,7 +1124,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* LM Key is incompatible... */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } else { - uchar nt_hash[16]; + uint8_t nt_hash[16]; if (ntlmssp_state->use_nt_response) { nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); @@ -1170,7 +1170,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, new_session_key.data); } else { - static const uchar zeros[24]; + static const uint8_t zeros[24]; SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros, new_session_key.data); } diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index aa7aa7e02b..40592acf85 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -107,7 +107,7 @@ typedef struct ntlmssp_state /* internal variables used by NTLM2 */ BOOL doing_ntlm2; - uchar session_nonce[16]; + uint8_t session_nonce[16]; /* internal variables used by KEY_EXCH (client-supplied user session key */ DATA_BLOB encrypted_session_key; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 22aa877b63..6b41ad7185 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -118,15 +118,15 @@ enum ntlmssp_direction { static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, - const uchar *data, size_t length, + const uint8_t *data, size_t length, enum ntlmssp_direction direction, DATA_BLOB *sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - uchar seq_num[4]; - uchar digest[16]; + uint8_t seq_num[4]; + uint8_t digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); switch (direction) { @@ -174,7 +174,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, - const uchar *data, size_t length, + const uint8_t *data, size_t length, DATA_BLOB *sig) { NTSTATUS nt_status; @@ -199,7 +199,7 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, - const uchar *data, size_t length, + const uint8_t *data, size_t length, const DATA_BLOB *sig) { DATA_BLOB local_sig; @@ -265,7 +265,7 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, - uchar *data, size_t length, + uint8_t *data, size_t length, DATA_BLOB *sig) { if (!ntlmssp_state->session_key.length) { @@ -277,8 +277,8 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - uchar seq_num[4]; - uchar digest[16]; + uint8_t seq_num[4]; + uint8_t digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, @@ -335,7 +335,7 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, - uchar *data, size_t length, + uint8_t *data, size_t length, DATA_BLOB *sig) { if (!ntlmssp_state->session_key.length) { diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 0a26db3037..666eb811ae 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -26,12 +26,12 @@ Encode or Decode the sequence number (which is symmetric) ********************************************************************/ static void netsec_deal_with_seq_num(struct schannel_state *state, - const uchar packet_digest[8], - uchar seq_num[8]) + const uint8_t packet_digest[8], + uint8_t seq_num[8]) { - static const uchar zeros[4]; - uchar sequence_key[16]; - uchar digest1[16]; + static const uint8_t zeros[4]; + uint8_t sequence_key[16]; + uint8_t digest1[16]; hmac_md5(state->session_key, zeros, sizeof(zeros), digest1); hmac_md5(digest1, packet_digest, 8, sequence_key); @@ -44,13 +44,13 @@ static void netsec_deal_with_seq_num(struct schannel_state *state, /******************************************************************* Calculate the key with which to encode the data payload ********************************************************************/ -static void netsec_get_sealing_key(const uchar session_key[16], - const uchar seq_num[8], - uchar sealing_key[16]) +static void netsec_get_sealing_key(const uint8_t session_key[16], + const uint8_t seq_num[8], + uint8_t sealing_key[16]) { - static const uchar zeros[4]; - uchar digest2[16]; - uchar sess_kf0[16]; + static const uint8_t zeros[4]; + uint8_t digest2[16]; + uint8_t sess_kf0[16]; int i; for (i = 0; i < 16; i++) { @@ -66,14 +66,14 @@ static void netsec_get_sealing_key(const uchar session_key[16], Create a digest over the entire packet (including the data), and MD5 it with the session key. ********************************************************************/ -static void schannel_digest(const uchar sess_key[16], - const uchar netsec_sig[8], - const uchar *confounder, - const uchar *data, size_t data_len, - uchar digest_final[16]) +static void schannel_digest(const uint8_t sess_key[16], + const uint8_t netsec_sig[8], + const uint8_t *confounder, + const uint8_t *data, size_t data_len, + uint8_t digest_final[16]) { - uchar packet_digest[16]; - static const uchar zeros[4]; + uint8_t packet_digest[16]; + static const uint8_t zeros[4]; struct MD5Context ctx; MD5Init(&ctx); @@ -94,14 +94,14 @@ static void schannel_digest(const uchar sess_key[16], */ NTSTATUS schannel_unseal_packet(struct schannel_state *state, TALLOC_CTX *mem_ctx, - uchar *data, size_t length, + uint8_t *data, size_t length, DATA_BLOB *sig) { - uchar digest_final[16]; - uchar confounder[8]; - uchar seq_num[8]; - uchar sealing_key[16]; - static const uchar netsec_sig[8] = NETSEC_SEAL_SIGNATURE; + uint8_t digest_final[16]; + uint8_t confounder[8]; + uint8_t seq_num[8]; + uint8_t sealing_key[16]; + static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; if (sig->length != 32) { return NT_STATUS_ACCESS_DENIED; @@ -141,12 +141,12 @@ NTSTATUS schannel_unseal_packet(struct schannel_state *state, check the signature on a packet */ NTSTATUS schannel_check_packet(struct schannel_state *state, - const uchar *data, size_t length, + const uint8_t *data, size_t length, const DATA_BLOB *sig) { - uchar digest_final[16]; - uchar seq_num[8]; - static const uchar netsec_sig[8] = NETSEC_SIGN_SIGNATURE; + uint8_t digest_final[16]; + uint8_t seq_num[8]; + static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; if (sig->length != 32) { return NT_STATUS_ACCESS_DENIED; @@ -185,14 +185,14 @@ NTSTATUS schannel_check_packet(struct schannel_state *state, */ NTSTATUS schannel_seal_packet(struct schannel_state *state, TALLOC_CTX *mem_ctx, - uchar *data, size_t length, + uint8_t *data, size_t length, DATA_BLOB *sig) { - uchar digest_final[16]; - uchar confounder[8]; - uchar seq_num[8]; - uchar sealing_key[16]; - static const uchar netsec_sig[8] = NETSEC_SEAL_SIGNATURE; + uint8_t digest_final[16]; + uint8_t confounder[8]; + uint8_t seq_num[8]; + uint8_t sealing_key[16]; + static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; generate_random_buffer(confounder, 8, False); @@ -236,12 +236,12 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, */ NTSTATUS schannel_sign_packet(struct schannel_state *state, TALLOC_CTX *mem_ctx, - const uchar *data, size_t length, + const uint8_t *data, size_t length, DATA_BLOB *sig) { - uchar digest_final[16]; - uchar seq_num[8]; - static const uchar netsec_sig[8] = NETSEC_SIGN_SIGNATURE; + uint8_t digest_final[16]; + uint8_t seq_num[8]; + static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; RSIVAL(seq_num, 0, state->seq_num); SIVAL(seq_num, 4, state->initiator?0x80:0); diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index fc6a93d8e1..18d1ce3e93 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -226,8 +226,8 @@ int ip_compare(struct in_addr *ip1, struct in_addr *ip2) struct in_addr ip; int bits1, bits2; ip = *iface_n_bcast(i); - bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr); - bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr); + bits1 = matching_quad_bits((uint8_t *)&ip1->s_addr, (uint8_t *)&ip.s_addr); + bits2 = matching_quad_bits((uint8_t *)&ip2->s_addr, (uint8_t *)&ip.s_addr); max_bits1 = MAX(bits1, max_bits1); max_bits2 = MAX(bits2, max_bits2); } diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index ef61686e57..e05eb7966e 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -74,7 +74,7 @@ static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) for (j = 0; j < 16; j++) { - uchar x = res->rdata[i+j]; + uint8_t x = res->rdata[i+j]; if (x < 32 || x > 127) x = '.'; if (i+j >= res->rdlength) break; @@ -86,7 +86,7 @@ static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); + DEBUGADD(4, ("%02X", (uint8_t)res->rdata[i+j])); } DEBUGADD(4, ("\n")); @@ -146,7 +146,7 @@ void debug_nmb_packet(struct packet_struct *p) /******************************************************************* handle "compressed" name pointers ******************************************************************/ -static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, +static BOOL handle_name_ptrs(uint8_t *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; @@ -169,7 +169,7 @@ static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) { int m,n=0; - uchar *ubuf = (uchar *)inbuf; + uint8_t *ubuf = (uint8_t *)inbuf; int ret = 0; BOOL got_pointer=False; int loop_count=0; @@ -196,7 +196,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) ret += m + 2; offset++; while (m > 0) { - uchar c1,c2; + uint8_t c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) @@ -209,7 +209,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) if (n==16) { /* parse out the name type, its always in the 16th byte of the name */ - name->name_type = ((uchar)name->name[15]) & 0xff; + name->name_type = ((uint8_t)name->name[15]) & 0xff; /* remove trailing spaces */ name->name[15] = 0; @@ -385,7 +385,7 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) /******************************************************************* put a compressed name pointer record into a packet ******************************************************************/ -static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset) +static int put_compressed_name_ptr(uint8_t *buf,int offset,struct res_rec *rec,int ptr_offset) { int ret=0; buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); @@ -769,7 +769,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) static int build_dgram(char *buf,struct packet_struct *p) { struct dgram_packet *dgram = &p->packet.dgram; - uchar *ubuf = (uchar *)buf; + uint8_t *ubuf = (uint8_t *)buf; int offset=0; /* put in the header */ @@ -839,7 +839,7 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) static int build_nmb(char *buf,struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - uchar *ubuf = (uchar *)buf; + uint8_t *ubuf = (uint8_t *)buf; int offset=0; /* put in the header */ @@ -1036,7 +1036,7 @@ BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) /**************************************************************************** return the number of bits that match between two 4 character buffers ***************************************************************************/ -int matching_quad_bits(uchar *p1, uchar *p2) +int matching_quad_bits(uint8_t *p1, uint8_t *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { @@ -1055,12 +1055,12 @@ int matching_quad_bits(uchar *p1, uchar *p2) } -static uchar sort_ip[4]; +static uint8_t sort_ip[4]; /**************************************************************************** compare two query reply records ***************************************************************************/ -static int name_query_comp(uchar *p1, uchar *p2) +static int name_query_comp(uint8_t *p1, uint8_t *p2) { return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } @@ -1149,7 +1149,7 @@ static int name_interpret(char *in,char *out) while(*in) { *out++ = '.'; /* Scope names are separated by periods */ - len = *(uchar *)in++; + len = *(uint8_t *)in++; StrnCpy(out, in, len); out += len; *out=0; @@ -1240,7 +1240,7 @@ find a pointer to a netbios name ****************************************************************************/ static char *name_ptr(char *buf,int ofs) { - uchar c = *(uchar *)(buf+ofs); + uint8_t c = *(uint8_t *)(buf+ofs); if ((c & 0xC0) == 0xC0) { @@ -1270,7 +1270,7 @@ return the total storage length of a mangled name int name_len(char *s1) { /* NOTE: this argument _must_ be unsigned */ - uchar *s = (uchar *)s1; + uint8_t *s = (uint8_t *)s1; int len; /* If the two high bits of the byte are set, return 2. */ diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index b3876f2490..641eff053e 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -252,7 +252,7 @@ static void use_nt1_session_keys(struct cli_session *session, const char *password, const DATA_BLOB *nt_response) { struct cli_transport *transport = session->transport; - uchar nt_hash[16]; + uint8_t nt_hash[16]; DATA_BLOB session_key = data_blob(NULL, 16); E_md4hash(password, nt_hash); diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index b2e46e759d..90724cb778 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -46,9 +46,9 @@ */ -#define uchar unsigned char +#define uint8_t unsigned char -static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, +static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, @@ -57,7 +57,7 @@ static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; -static const uchar perm2[48] = {14, 17, 11, 24, 1, 5, +static const uint8_t perm2[48] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, @@ -66,7 +66,7 @@ static const uchar perm2[48] = {14, 17, 11, 24, 1, 5, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; -static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, +static const uint8_t perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, @@ -75,7 +75,7 @@ static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; -static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5, +static const uint8_t perm4[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, @@ -84,7 +84,7 @@ static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; -static const uchar perm5[32] = { 16, 7, 20, 21, +static const uint8_t perm5[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, @@ -94,7 +94,7 @@ static const uchar perm5[32] = { 16, 7, 20, 21, 22, 11, 4, 25}; -static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, +static const uint8_t perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, @@ -104,9 +104,9 @@ static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 33, 1, 41, 9, 49, 17, 57, 25}; -static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; +static const uint8_t sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; -static const uchar sbox[8][4][16] = { +static const uint8_t sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, @@ -147,7 +147,7 @@ static const uchar sbox[8][4][16] = { {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; -static void permute(char *out, const char *in, const uchar *p, int n) +static void permute(char *out, const char *in, const uint8_t *p, int n) { int i; for (i=0;i> 8) & 0xFF); - s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF); - s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF); + s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF); + s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF); + s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); + s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); smbhash(out, in, s, forw); smbhash(out+8, in+8, s+7, forw); diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index d52d24e1e1..fdd5838798 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -32,10 +32,10 @@ Returns False if password must have been truncated to create LM hash */ -BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) +BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) { BOOL ret; - uchar p21[21]; + uint8_t p21[21]; memset(p21,'\0',21); ret = E_deshash(passwd, p21); @@ -58,7 +58,7 @@ BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -void E_md4hash(const char *passwd, uchar p16[16]) +void E_md4hash(const char *passwd, uint8_t p16[16]) { int len; smb_ucs2_t wpwd[129]; @@ -80,7 +80,7 @@ void E_md4hash(const char *passwd, uchar p16[16]) * @note p16 is filled in regardless */ -BOOL E_deshash(const char *passwd, uchar p16[16]) +BOOL E_deshash(const char *passwd, uint8_t p16[16]) { BOOL ret = True; fstring dospwd; @@ -110,7 +110,7 @@ BOOL E_deshash(const char *passwd, uchar p16[16]) */ /* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +void nt_lm_owf_gen(const char *pwd, uint8_t nt_p16[16], uint8_t p16[16]) { /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); @@ -122,7 +122,7 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) dump_data(100, (char *)nt_p16, 16); #endif - E_deshash(pwd, (uchar *)p16); + E_deshash(pwd, (uint8_t *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); @@ -132,10 +132,10 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -BOOL ntv2_owf_gen(const uchar owf[16], +BOOL ntv2_owf_gen(const uint8_t owf[16], const char *user_in, const char *domain_in, BOOL upper_case_domain, /* Transform the domain into UPPER case */ - uchar kr_buf[16]) + uint8_t kr_buf[16]) { smb_ucs2_t *user; smb_ucs2_t *domain; @@ -188,9 +188,9 @@ BOOL ntv2_owf_gen(const uchar owf[16], } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) +void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) { - uchar p21[21]; + uint8_t p21[21]; ZERO_STRUCT(p21); @@ -200,9 +200,9 @@ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) /* Does the NT MD4 hash then des encryption. */ -void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) { - uchar p21[21]; + uint8_t p21[21]; memset(p21,'\0',21); @@ -218,10 +218,10 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) } /* Does the md5 encryption from the Key Response for NTLMv2. */ -void SMBOWFencrypt_ntv2(const uchar kr[16], +void SMBOWFencrypt_ntv2(const uint8_t kr[16], const DATA_BLOB *srv_chal, const DATA_BLOB *cli_chal, - uchar resp_buf[16]) + uint8_t resp_buf[16]) { HMACMD5Context ctx; @@ -238,8 +238,8 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], #endif } -void SMBsesskeygen_ntv2(const uchar kr[16], - const uchar * nt_resp, uint8_t sess_key[16]) +void SMBsesskeygen_ntv2(const uint8_t kr[16], + const uint8_t * nt_resp, uint8_t sess_key[16]) { /* a very nice, 128 bit, variable session key */ @@ -255,7 +255,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], #endif } -void SMBsesskeygen_ntv1(const uchar kr[16], uint8_t sess_key[16]) +void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) { /* yes, this session key does not change - yes, this is a problem - but it is 128 bits */ @@ -268,14 +268,14 @@ void SMBsesskeygen_ntv1(const uchar kr[16], uint8_t sess_key[16]) #endif } -void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], - const uchar lm_resp[24], /* only uses 8 */ +void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], + const uint8_t lm_resp[24], /* only uses 8 */ uint8_t sess_key[16]) { /* Calculate the LM session key (effective length 40 bits, but changes with each session) */ - uchar p24[24]; - uchar p21[21]; + uint8_t p24[24]; + uint8_t p21[21]; memset(p21,'\0',21); memcpy(p21, lm_hash, 8); @@ -306,7 +306,7 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) { - uchar client_chal[8]; + uint8_t client_chal[8]; DATA_BLOB response = data_blob(NULL, 0); char long_date[8]; NTTIME nttime; @@ -330,11 +330,11 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO return response; } -static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], +static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob) { - uchar ntlmv2_response[16]; + uint8_t ntlmv2_response[16]; DATA_BLOB ntlmv2_client_data; DATA_BLOB final_response; @@ -364,10 +364,10 @@ static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], return final_response; } -static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], +static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], const DATA_BLOB *server_chal) { - uchar lmv2_response[16]; + uint8_t lmv2_response[16]; DATA_BLOB lmv2_client_data = data_blob(NULL, 8); DATA_BLOB final_response = data_blob(NULL, 24); @@ -395,8 +395,8 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *user_session_key) { - uchar nt_hash[16]; - uchar ntlm_v2_hash[16]; + uint8_t nt_hash[16]; + uint8_t ntlm_v2_hash[16]; E_md4hash(password, nt_hash); /* We don't use the NT# directly. Instead we use it mashed up with @@ -434,7 +434,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password ************************************************************/ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) { - uchar new_pw[512]; + uint8_t new_pw[512]; size_t new_pw_len; new_pw_len = push_string(NULL, new_pw, -- cgit From 770e3307ce3da928762e15a136c562df86a9c799 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Jun 2004 10:12:52 +0000 Subject: r962: convert 'unsigned' and 'unsigned int' to uint_t metze (This used to be commit 57151e80eb1090281401930c8fe25b20a8cf3a38) --- source4/libcli/auth/ntlmssp_parse.c | 2 +- source4/libcli/clifile.c | 4 ++-- source4/libcli/namequery.c | 2 +- source4/libcli/raw/clikrb5.c | 4 ++-- source4/libcli/raw/rawrequest.c | 32 ++++++++++++++++---------------- source4/libcli/util/asn1.c | 4 ++-- source4/libcli/util/smbdes.c | 4 +--- 7 files changed, 25 insertions(+), 27 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index aa4fc6b98f..251effd7e1 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -286,7 +286,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, break; case 'b': b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, unsigned); + len1 = va_arg(ap, uint_t); /* make sure its in the right format - be strict */ NEED_DATA(len1); if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 7f4384a222..6f1c98555b 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -268,8 +268,8 @@ int cli_open(struct cli_tree *tree, const char *fname, int flags, int share_mode) { union smb_open open_parms; - unsigned openfn=0; - unsigned accessmode=0; + uint_t openfn=0; + uint_t accessmode=0; TALLOC_CTX *mem_ctx; NTSTATUS status; diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 18d1ce3e93..0094cc26bb 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -37,7 +37,7 @@ static int generate_trn_id(void) trn_id = sys_random(); - return trn_id % (unsigned)0x7FFF; + return trn_id % (uint_t)0x7FFF; } diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c index 1d9c02f7f4..ba3e9ccd17 100644 --- a/source4/libcli/raw/clikrb5.c +++ b/source4/libcli/raw/clikrb5.c @@ -278,9 +278,9 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, } /* cope with the ticket being in the future due to clock skew */ - if ((unsigned)credsp->times.starttime > time(NULL)) { + if ((uint_t)credsp->times.starttime > time(NULL)) { time_t t = time(NULL); - int time_offset = (unsigned)credsp->times.starttime - t; + int time_offset = (uint_t)credsp->times.starttime - t; DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(context, t + time_offset + 1, 0); } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index fd2d85cc65..c31f07505f 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -103,7 +103,7 @@ struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, ui setup a SMB packet at transport level */ struct cli_request *cli_request_setup_transport(struct cli_transport *transport, - uint8_t command, unsigned wct, unsigned buflen) + uint8_t command, uint_t wct, uint_t buflen) { struct cli_request *req; @@ -149,7 +149,7 @@ struct cli_request *cli_request_setup_transport(struct cli_transport *transport, way. This interface is used before a session is setup. */ struct cli_request *cli_request_setup_session(struct cli_session *session, - uint8_t command, unsigned wct, unsigned buflen) + uint8_t command, uint_t wct, uint_t buflen) { struct cli_request *req; uint16_t flags2; @@ -190,7 +190,7 @@ struct cli_request *cli_request_setup_session(struct cli_session *session, */ struct cli_request *cli_request_setup(struct cli_tree *tree, uint8_t command, - unsigned wct, unsigned buflen) + uint_t wct, uint_t buflen) { struct cli_request *req; @@ -210,7 +210,7 @@ struct cli_request *cli_request_setup(struct cli_tree *tree, To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ -static void cli_req_grow_allocation(struct cli_request *req, unsigned new_size) +static void cli_req_grow_allocation(struct cli_request *req, uint_t new_size) { int delta; char *buf2; @@ -251,7 +251,7 @@ static void cli_req_grow_allocation(struct cli_request *req, unsigned new_size) To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ -static void cli_req_grow_data(struct cli_request *req, unsigned new_size) +static void cli_req_grow_data(struct cli_request *req, uint_t new_size) { int delta; @@ -524,7 +524,7 @@ BOOL cli_request_is_error(struct cli_request *req) return the number of bytes added to the packet */ -size_t cli_req_append_string(struct cli_request *req, const char *str, unsigned flags) +size_t cli_req_append_string(struct cli_request *req, const char *str, uint_t flags) { size_t len; @@ -555,7 +555,7 @@ size_t cli_req_append_string(struct cli_request *req, const char *str, unsigned this is used in places where the non-terminated string byte length is placed in the packet as a separate field */ -size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsigned flags, int *len) +size_t cli_req_append_string_len(struct cli_request *req, const char *str, uint_t flags, int *len) { int diff = 0; size_t ret; @@ -596,7 +596,7 @@ size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsig if dest_len is -1 then no limit applies */ -size_t cli_req_append_ascii4(struct cli_request *req, const char *str, unsigned flags) +size_t cli_req_append_ascii4(struct cli_request *req, const char *str, uint_t flags) { size_t size; cli_req_append_bytes(req, (const uint8_t *)"\4", 1); @@ -662,7 +662,7 @@ size_t cli_req_append_var_block(struct cli_request *req, const uint8_t *bytes, u of bytes consumed in the packet is returned */ static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, unsigned flags) + char **dest, const char *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; @@ -719,7 +719,7 @@ static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx, of bytes consumed in the packet is returned */ size_t cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, unsigned flags) + char **dest, const char *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; @@ -762,7 +762,7 @@ size_t cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx, of bytes consumed in the packet is returned */ size_t cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, unsigned flags) + char **dest, const char *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { @@ -860,7 +860,7 @@ NTTIME cli_pull_nttime(void *base, uint16_t offset) */ static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, DATA_BLOB *blob, const char **dest, - const char *src, int byte_len, unsigned flags) + const char *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; @@ -919,7 +919,7 @@ static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, */ static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **dest, - const char *src, int byte_len, unsigned flags) + const char *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; @@ -968,7 +968,7 @@ size_t cli_blob_pull_string(struct cli_session *session, DATA_BLOB *blob, WIRE_STRING *dest, uint16_t len_offset, uint16_t str_offset, - unsigned flags) + uint_t flags) { int extra; dest->s = NULL; @@ -1023,7 +1023,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session, DATA_BLOB *blob, const char **dest, uint16_t str_offset, - unsigned flags) + uint_t flags) { int extra = 0; *dest = NULL; @@ -1057,7 +1057,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session, */ size_t cli_blob_append_string(struct cli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - const char *str, unsigned flags) + const char *str, uint_t flags) { size_t max_len; int len; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index b44c62bc50..ddefe0baa6 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -122,7 +122,7 @@ BOOL asn1_write_Integer(ASN1_DATA *data, int i) /* write an object ID to a ASN1 buffer */ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) { - unsigned v, v2; + uint_t v, v2; const char *p = (const char *)OID; char *newp; @@ -328,7 +328,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) pstrcat(aoid, el); while (asn1_tag_remaining(data) > 0) { - unsigned v = 0; + uint_t v = 0; do { asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 90724cb778..967d0ffb82 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -46,8 +46,6 @@ */ -#define uint8_t unsigned char - static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, @@ -306,7 +304,7 @@ void smbhash(uint8_t *out, const uint8_t *in, const uint8_t *key, int forw) void E_P16(const uint8_t *p14,uint8_t *p16) { - unsigned const char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; smbhash(p16, sp8, p14, 1); smbhash(p16+8, sp8, p14+7, 1); } -- cgit From dfbf6201297a39f339a179fbc8444b3748bf5012 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Jun 2004 08:31:47 +0000 Subject: r975: slight improvemet to nt_errstr(), still needs to be fixed properly (getting rid of the static buffer) (This used to be commit 86a6236c2ad14fe94f5d7c488bfdbfb329d2a0bb) --- source4/libcli/util/nterr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 6c4b7c8417..c71dc2247b 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -646,8 +646,6 @@ const char *nt_errstr(NTSTATUS nt_code) static pstring msg; int idx = 0; - slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); - while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) { @@ -656,6 +654,8 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); + return msg; } -- cgit From 8087d844ef59a82617be51f7c887b9bafe362f80 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Jun 2004 23:15:16 +0000 Subject: r995: - renamed many of our crypto routines to use the industry standard names rather than our crazy naming scheme. So DES is now called des_crypt() rather than smbhash() - added the code from the solution of the ADS crypto challenge that allows Samba to correctly handle a 128 bit session key in all of the netr_ServerAuthenticateX() varients. A huge thanks to Luke Howard from PADL for solving this one! - restructured the server side rpc authentication to allow for other than NTLMSSP sign and seal. This commit just adds the structure, the next commit will add schannel server side support. - added 128 bit session key support to our client side code, and testing against w2k3 with smbtorture. Works well. (This used to be commit 729b2f41c924a0b435d44a14209e6dacc2304cee) --- source4/libcli/auth/credentials.c | 106 +++++++++++++++++++++++++++----------- source4/libcli/auth/credentials.h | 6 ++- source4/libcli/auth/ntlmssp.c | 8 +-- source4/libcli/auth/schannel.c | 10 ++-- source4/libcli/auth/session.c | 2 +- source4/libcli/util/smbdes.c | 69 ++++++++++++++----------- 6 files changed, 131 insertions(+), 70 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index cf6d0cca62..27a3e32cf3 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -24,38 +24,66 @@ #include "includes.h" /* - initialise the credentials state + initialise the credentials state for old-style 64 bit session keys this call is made after the netr_ServerReqChallenge call */ -static void creds_init(struct creds_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const uint8_t machine_password[16]) +static void creds_init_64bit(struct creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8_t machine_password[16]) { - struct netr_Credential time_cred; uint32_t sum[2]; uint8_t sum2[8]; - dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); - dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); - dump_data_pw("Machine Pass", machine_password, 16); - sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(creds->session_key, sum2, machine_password); + ZERO_STRUCT(creds->session_key); - SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); - SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); + des_crypt128(creds->session_key, sum2, machine_password); - SIVAL(time_cred.data, 0, IVAL(server_challenge->data, 0)); - SIVAL(time_cred.data, 4, IVAL(server_challenge->data, 4)); - cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); + des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); + des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); + + creds->seed = creds->client; +} + +/* + initialise the credentials state for ADS-style 128 bit session keys + + this call is made after the netr_ServerReqChallenge call +*/ +static void creds_init_128bit(struct creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8_t machine_password[16]) +{ + unsigned char zero[4], tmp[16]; + HMACMD5Context ctx; + struct MD5Context md5; + + ZERO_STRUCT(creds->session_key); + + memset(zero, 0, sizeof(zero)); + + hmac_md5_init_rfc2104(machine_password, 16, &ctx); + MD5Init(&md5); + MD5Update(&md5, zero, sizeof(zero)); + MD5Update(&md5, client_challenge->data, 8); + MD5Update(&md5, server_challenge->data, 8); + MD5Final(tmp, &md5); + hmac_md5_update(tmp, 16, &ctx); + hmac_md5_final(creds->session_key, &ctx); + + creds->client = *client_challenge; + creds->server = *server_challenge; + + des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); + des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); creds->seed = creds->client; } @@ -77,7 +105,7 @@ static void creds_step(struct creds_CredentialState *creds) DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); + des_crypt112(creds->client.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tCLIENT %08x:%08x\n", IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); @@ -88,7 +116,7 @@ static void creds_step(struct creds_CredentialState *creds) DEBUG(5,("\tseed+time+1 %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); + des_crypt112(creds->server.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tSERVER %08x:%08x\n", IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); @@ -103,7 +131,7 @@ static void creds_step(struct creds_CredentialState *creds) void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) { struct netr_Password tmp; - cred_hash3(tmp.data, pass->data, creds->session_key, 1); + des_crypt112_16(tmp.data, pass->data, creds->session_key, 1); *pass = tmp; } @@ -113,7 +141,7 @@ void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) { struct netr_Password tmp; - cred_hash3(tmp.data, pass->data, creds->session_key, 0); + des_crypt112_16(tmp.data, pass->data, creds->session_key, 0); *pass = tmp; } @@ -122,12 +150,9 @@ void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password */ void creds_arcfour_crypt(struct creds_CredentialState *creds, char *data, size_t len) { - DATA_BLOB session_key = data_blob(NULL, 16); - - memcpy(&session_key.data[0], creds->session_key, 8); - memset(&session_key.data[8], '\0', 8); + DATA_BLOB session_key = data_blob(creds->session_key, 16); - SamOEMhashBlob(data, len, &session_key); + arcfour_crypt_blob(data, len, &session_key); data_blob_free(&session_key); } @@ -145,10 +170,24 @@ void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8_t machine_password[16], - struct netr_Credential *initial_credential) + struct netr_Credential *initial_credential, + uint32_t negotiate_flags) { creds->sequence = time(NULL); - creds_init(creds, client_challenge, server_challenge, machine_password); + creds->negotiate_flags = negotiate_flags; + + dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); + dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); + dump_data_pw("Machine Pass", machine_password, 16); + + if (negotiate_flags & NETLOGON_NEG_128BIT) { + creds_init_128bit(creds, client_challenge, server_challenge, machine_password); + } else { + creds_init_64bit(creds, client_challenge, server_challenge, machine_password); + } + + dump_data_pw("Session key", creds->session_key, 16); + dump_data_pw("Credential ", creds->client.data, 8); *initial_credential = creds->client; } @@ -198,9 +237,16 @@ void creds_server_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8_t machine_password[16], - struct netr_Credential *initial_credential) + struct netr_Credential *initial_credential, + uint32_t negotiate_flags) { - creds_init(creds, client_challenge, server_challenge, machine_password); + if (negotiate_flags & NETLOGON_NEG_128BIT) { + creds_init_128bit(creds, client_challenge, server_challenge, + machine_password); + } else { + creds_init_64bit(creds, client_challenge, server_challenge, + machine_password); + } *initial_credential = creds->server; } diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 20eed73cc0..de0e086278 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -21,7 +21,8 @@ */ struct creds_CredentialState { - uint8_t session_key[8]; + uint32_t negotiate_flags; + uint8_t session_key[16]; uint32_t sequence; struct netr_Credential seed; struct netr_Credential client; @@ -29,6 +30,9 @@ struct creds_CredentialState { }; +#define NETLOGON_NEG_128BIT 0x4000 + + /* for the timebeing, use the same neg flags as Samba3. */ /* The 7 here seems to be required to get Win2k not to downgrade us to NT4. Actually, anything other than 1ff would seem to do... */ diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 49935f0acb..5916faf513 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -792,9 +792,9 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, dump_data_pw("KEY_EXCH session key (enc):\n", ntlmssp_state->encrypted_session_key.data, ntlmssp_state->encrypted_session_key.length); - SamOEMhash(ntlmssp_state->encrypted_session_key.data, - session_key.data, - ntlmssp_state->encrypted_session_key.length); + arcfour_crypt(ntlmssp_state->encrypted_session_key.data, + session_key.data, + ntlmssp_state->encrypted_session_key.length); ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, ntlmssp_state->encrypted_session_key.data, ntlmssp_state->encrypted_session_key.length); @@ -1191,7 +1191,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, encrypted_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 666eb811ae..294873feff 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -35,7 +35,7 @@ static void netsec_deal_with_seq_num(struct schannel_state *state, hmac_md5(state->session_key, zeros, sizeof(zeros), digest1); hmac_md5(digest1, packet_digest, 8, sequence_key); - SamOEMhash(seq_num, sequence_key, 8); + arcfour_crypt(seq_num, sequence_key, 8); state->seq_num++; } @@ -113,8 +113,8 @@ NTSTATUS schannel_unseal_packet(struct schannel_state *state, SIVAL(seq_num, 4, state->initiator?0:0x80); netsec_get_sealing_key(state->session_key, seq_num, sealing_key); - SamOEMhash(confounder, sealing_key, 8); - SamOEMhash(data, sealing_key, length); + arcfour_crypt(confounder, sealing_key, 8); + arcfour_crypt(data, sealing_key, length); schannel_digest(state->session_key, netsec_sig, confounder, @@ -204,8 +204,8 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, data, length, digest_final); netsec_get_sealing_key(state->session_key, seq_num, sealing_key); - SamOEMhash(confounder, sealing_key, 8); - SamOEMhash(data, sealing_key, length); + arcfour_crypt(confounder, sealing_key, 8); + arcfour_crypt(data, sealing_key, length); netsec_deal_with_seq_num(state, digest_final, seq_num); diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 1176d7fd0d..598f2d4f28 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -47,7 +47,7 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi } memcpy(key, &session_key->data[k], 7); - smbhash(bout, bin, key, forward?1:0); + des_crypt56(bout, bin, key, forward?1:0); memcpy(&out->data[i], bout, MIN(8, in->length-i)); } diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 967d0ffb82..2492f9a1ba 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -273,8 +273,10 @@ static void str_to_key(const uint8_t *str,uint8_t *key) } } - -void smbhash(uint8_t *out, const uint8_t *in, const uint8_t *key, int forw) +/* + basic des crypt using a 56 bit (7 byte) key +*/ +void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw) { int i; char outb[64]; @@ -305,58 +307,67 @@ void smbhash(uint8_t *out, const uint8_t *in, const uint8_t *key, int forw) void E_P16(const uint8_t *p14,uint8_t *p16) { const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - smbhash(p16, sp8, p14, 1); - smbhash(p16+8, sp8, p14+7, 1); + des_crypt56(p16, sp8, p14, 1); + des_crypt56(p16+8, sp8, p14+7, 1); } void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) { - smbhash(p24, c8, p21, 1); - smbhash(p24+8, c8, p21+7, 1); - smbhash(p24+16, c8, p21+14, 1); + des_crypt56(p24, c8, p21, 1); + des_crypt56(p24+8, c8, p21+7, 1); + des_crypt56(p24+16, c8, p21+14, 1); } void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out) { - smbhash(out, in, p14, 0); - smbhash(out+8, in+8, p14+7, 0); + des_crypt56(out, in, p14, 0); + des_crypt56(out+8, in+8, p14+7, 0); } void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) { - smbhash(out, in, p14, 1); - smbhash(out+8, in+8, p14+7, 1); + des_crypt56(out, in, p14, 1); + des_crypt56(out+8, in+8, p14+7, 1); } -void cred_hash1(uint8_t *out, const uint8_t *in, const uint8_t *key) +/* des encryption with a 128 bit key */ +void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) { uint8_t buf[8]; - - smbhash(buf, in, key, 1); - smbhash(out, buf, key+9, 1); + des_crypt56(buf, in, key, 1); + des_crypt56(out, buf, key+9, 1); } -void cred_hash2(uint8_t *out, const uint8_t *in, const uint8_t *key, int forw) +/* des encryption with a 64 bit key */ +void des_crypt64(uint8_t out[8], const uint8_t in[8], const uint8_t key[8], int forw) { uint8_t buf[8]; uint8_t key2[8]; ZERO_STRUCT(key2); - smbhash(buf, in, key, forw); + des_crypt56(buf, in, key, forw); key2[0] = key[7]; - smbhash(out, buf, key2, forw); + des_crypt56(out, buf, key2, forw); } -void cred_hash3(uint8_t *out, uint8_t *in, const uint8_t *key, int forw) +/* des encryption with a 112 bit (14 byte) key */ +void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw) { - uint8_t key2[8]; - ZERO_STRUCT(key2); - smbhash(out, in, key, forw); - key2[0] = key[7]; - smbhash(out + 8, in + 8, key2, forw); + uint8_t buf[8]; + des_crypt56(buf, in, key, forw); + des_crypt56(out, buf, key+7, forw); } +/* des encryption of a 16 byte lump of data with a 112 bit key */ +void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int forw) +{ + des_crypt56(out, in, key, forw); + des_crypt56(out + 8, in + 8, key+7, forw); +} -void SamOEMhashBlob(uint8_t *data, int len, const DATA_BLOB *key) +/* + arcfour encryption with a blob key +*/ +void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) { uint8_t s_box[256]; uint8_t index_i = 0; @@ -397,11 +408,11 @@ void SamOEMhashBlob(uint8_t *data, int len, const DATA_BLOB *key) a varient that assumes a 16 byte key. This should be removed when the last user is gone */ -void SamOEMhash(uint8_t *data, const uint8_t keystr[16], int len) +void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len) { DATA_BLOB key = data_blob(keystr, 16); - SamOEMhashBlob(data, len, &key); + arcfour_crypt_blob(data, len, &key); data_blob_free(&key); } @@ -419,6 +430,6 @@ void sam_pwd_hash(uint_t rid, const uint8_t *in, uint8_t *out, int forw) s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); - smbhash(out, in, s, forw); - smbhash(out+8, in+8, s+7, forw); + des_crypt56(out, in, s, forw); + des_crypt56(out+8, in+8, s+7, forw); } -- cgit From 8f84a98e299e63b7fb7fdd797e8e7969b68a106f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jun 2004 07:46:24 +0000 Subject: r1001: in samba4 we don't(shouldn't) use typedef's anymore... metze (This used to be commit ac5f6f7e511a730448012c8a709887827aea2281) --- source4/libcli/auth/ntlmssp.c | 22 +++++++++++----------- source4/libcli/auth/ntlmssp.h | 10 +++++----- source4/libcli/auth/ntlmssp_sign.c | 18 +++++++----------- 3 files changed, 23 insertions(+), 27 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 5916faf513..dab8506b81 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -42,8 +42,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, */ static const struct ntlmssp_callbacks { - enum NTLMSSP_ROLE role; - enum NTLM_MESSAGE_TYPE ntlmssp_command; + enum ntlmssp_role role; + enum ntlmssp_message_type ntlmssp_command; NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out); @@ -141,7 +141,7 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch * */ -NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) +NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) { ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); if (!ntlmssp_state->user) { @@ -154,7 +154,7 @@ NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) * Set a password on an NTLMSSP context - ensures it is talloc()ed * */ -NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) +NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) { if (!password) { ntlmssp_state->password = NULL; @@ -171,7 +171,7 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password * Set a domain on an NTLMSSP context - ensures it is talloc()ed * */ -NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) +NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) { ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); if (!ntlmssp_state->domain) { @@ -184,7 +184,7 @@ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) * Set a workstation on an NTLMSSP context - ensures it is talloc()ed * */ -NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) +NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) { ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation); if (!ntlmssp_state->domain) { @@ -198,7 +198,7 @@ NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *works * This copies the data blob */ -NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state, DATA_BLOB response) { ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, @@ -217,7 +217,7 @@ NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, * or NT_STATUS_OK if the user is authenticated. */ -NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { @@ -292,7 +292,7 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, * @param ntlmssp_state NTLMSSP State, free()ed by this function */ -void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) +void ntlmssp_end(struct ntlmssp_state **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; @@ -878,7 +878,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, * @param ntlmssp_state NTLMSSP State, allocated by this function */ -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) { TALLOC_CTX *mem_ctx; @@ -1234,7 +1234,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) +NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) { TALLOC_CTX *mem_ctx; diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 40592acf85..f1b87a7f9d 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -21,14 +21,14 @@ */ /* NTLMSSP mode */ -enum NTLMSSP_ROLE +enum ntlmssp_role { NTLMSSP_SERVER, NTLMSSP_CLIENT }; /* NTLMSSP message types */ -enum NTLM_MESSAGE_TYPE +enum ntlmssp_message_type { NTLMSSP_INITIAL = 0 /* samba internal state */, NTLMSSP_NEGOTIATE = 1, @@ -71,11 +71,11 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_SIGN_VERSION 1 -typedef struct ntlmssp_state +struct ntlmssp_state { TALLOC_CTX *mem_ctx; uint_t ref_count; - enum NTLMSSP_ROLE role; + enum ntlmssp_role role; enum samr_Role server_role; uint32_t expected_state; @@ -184,5 +184,5 @@ typedef struct ntlmssp_state Store it here, until we need it */ DATA_BLOB stored_response; -} NTLMSSP_STATE; +}; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 6b41ad7185..924289cf26 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -27,7 +27,7 @@ #define SRV_SIGN "session key to server-to-client signing key magic constant" #define SRV_SEAL "session key to server-to-client sealing key magic constant" -static void NTLMSSPcalc_ap( uint8_t *hash, uint8_t *data, int len) +static void NTLMSSPcalc_ap(uint8_t *hash, uint8_t *data, int len) { uint8_t index_i = hash[256]; uint8_t index_j = hash[257]; @@ -93,10 +93,6 @@ static void calc_hash(uint8_t hash[258], const char *key, size_t key_len) * claiming to be the correct output of NTLM2 signature generation. * */ - - - - static void calc_ntlmv2_hash(uint8_t hash[258], uint8_t subkey[16], DATA_BLOB session_key, const char *constant) @@ -116,7 +112,7 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; -static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, +static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, enum ntlmssp_direction direction, @@ -172,7 +168,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_OK; } -NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig) @@ -197,7 +193,7 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, const DATA_BLOB *sig) @@ -263,7 +259,7 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) @@ -333,7 +329,7 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, +NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) @@ -363,7 +359,7 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) +NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) { uint8_t p24[24]; ZERO_STRUCT(p24); -- cgit From 9eb6afb00d85c1a7b367d51a19eed41172f7a2e9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 4 Jun 2004 11:58:46 +0000 Subject: r1009: Make all users of NT and LM passwords use the samr_Password structure. This includes the netlogon pipe, for the machine account password change system. Andrew Bartlett (This used to be commit 49d545a82057ee8b60d50aa55e908efe59875150) --- source4/libcli/auth/credentials.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 27a3e32cf3..e0989eff4b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -128,20 +128,20 @@ static void creds_step(struct creds_CredentialState *creds) /* DES encrypt a 16 byte password buffer using the session key */ -void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +void creds_des_encrypt(struct creds_CredentialState *creds, struct samr_Password *pass) { - struct netr_Password tmp; - des_crypt112_16(tmp.data, pass->data, creds->session_key, 1); + struct samr_Password tmp; + des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 1); *pass = tmp; } /* DES decrypt a 16 byte password buffer using the session key */ -void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +void creds_des_decrypt(struct creds_CredentialState *creds, struct samr_Password *pass) { - struct netr_Password tmp; - des_crypt112_16(tmp.data, pass->data, creds->session_key, 0); + struct samr_Password tmp; + des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 0); *pass = tmp; } -- cgit From ae067cdaf70c7725237ec58b5e23bc6f525594c2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jun 2004 03:14:59 +0000 Subject: r1024: Use samr_Password for the machine password here - this ensures we can never pass in something of the wrong length. Andrew Bartlett (This used to be commit d6999ea9c07d8652b0d63147e7294bc35e7063fe) --- source4/libcli/auth/credentials.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index e0989eff4b..1d4db74633 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -31,7 +31,7 @@ static void creds_init_64bit(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16]) + const struct samr_Password *machine_password) { uint32_t sum[2]; uint8_t sum2[8]; @@ -44,7 +44,7 @@ static void creds_init_64bit(struct creds_CredentialState *creds, ZERO_STRUCT(creds->session_key); - des_crypt128(creds->session_key, sum2, machine_password); + des_crypt128(creds->session_key, sum2, machine_password->hash); des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); @@ -60,7 +60,7 @@ static void creds_init_64bit(struct creds_CredentialState *creds, static void creds_init_128bit(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16]) + const struct samr_Password *machine_password) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; @@ -70,13 +70,13 @@ static void creds_init_128bit(struct creds_CredentialState *creds, memset(zero, 0, sizeof(zero)); - hmac_md5_init_rfc2104(machine_password, 16, &ctx); + hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx); MD5Init(&md5); MD5Update(&md5, zero, sizeof(zero)); MD5Update(&md5, client_challenge->data, 8); MD5Update(&md5, server_challenge->data, 8); MD5Final(tmp, &md5); - hmac_md5_update(tmp, 16, &ctx); + hmac_md5_update(tmp, sizeof(tmp), &ctx); hmac_md5_final(creds->session_key, &ctx); creds->client = *client_challenge; @@ -169,7 +169,7 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16], + const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { @@ -178,7 +178,7 @@ void creds_client_init(struct creds_CredentialState *creds, dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); - dump_data_pw("Machine Pass", machine_password, 16); + dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); if (negotiate_flags & NETLOGON_NEG_128BIT) { creds_init_128bit(creds, client_challenge, server_challenge, machine_password); @@ -236,7 +236,7 @@ next comes the server specific functions void creds_server_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16], + const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { -- cgit From c455b0a935dec8c9644634c496f2b95d7678df05 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jun 2004 04:32:50 +0000 Subject: r1028: More consistancy fixes, which should also fix the build. Andrew Bartlett (This used to be commit 0d2ae66d3a82134d86084f63c05214e03dfcb48b) --- source4/libcli/auth/ntlm_check.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index d12a271420..eab150ad4d 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -169,8 +169,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, const DATA_BLOB *challenge, const DATA_BLOB *lm_response, const DATA_BLOB *nt_response, - const DATA_BLOB *lm_interactive_pwd, - const DATA_BLOB *nt_interactive_pwd, + const DATA_BLOB *lm_interactive_password, + const DATA_BLOB *nt_interactive_password, const char *username, const char *client_username, const char *client_domain, @@ -184,14 +184,14 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, username)); } - if (nt_interactive_pwd && nt_interactive_pwd->length && nt_pw) { - if (nt_interactive_pwd->length != 16) { - DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_pwd->length, + if (nt_interactive_password && nt_interactive_password->length && nt_pw) { + if (nt_interactive_password->length != 16) { + DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_password->length, username)); return NT_STATUS_WRONG_PASSWORD; } - if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) { + if (memcmp(nt_interactive_password->data, nt_pw, 16) == 0) { if (user_sess_key) { *user_sess_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_pw, user_sess_key->data); @@ -203,9 +203,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, return NT_STATUS_WRONG_PASSWORD; } - } else if (lm_interactive_pwd && lm_interactive_pwd->length && lm_pw) { - if (lm_interactive_pwd->length != 16) { - DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_pwd->length, + } else if (lm_interactive_password && lm_interactive_password->length && lm_pw) { + if (lm_interactive_password->length != 16) { + DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_password->length, username)); return NT_STATUS_WRONG_PASSWORD; } @@ -216,7 +216,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, return NT_STATUS_WRONG_PASSWORD; } - if (memcmp(lm_interactive_pwd->data, lm_pw, 16) == 0) { + if (memcmp(lm_interactive_password->data, lm_pw, 16) == 0) { return NT_STATUS_OK; } else { DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n", -- cgit From a1318baa5503648ffcff2e9cd625b6848ad285b8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 6 Jun 2004 07:14:10 +0000 Subject: r1041: - pulled the domain join code out of the netlogon test and made it a separate utility function, to allow multiple torture tests to temporarily join a domain - fixed a session key size problem - added a schannel test suite - allow schannel to work with ncacn_ip_tcp (This used to be commit 36f05e4d575099fcb957b8a55781c38dcd2e1177) --- source4/libcli/auth/schannel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 294873feff..95e881d32a 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -286,7 +286,7 @@ void schannel_end(struct schannel_state **state) create an schannel context state */ NTSTATUS schannel_start(struct schannel_state **state, - uint8_t session_key[16], + const uint8_t session_key[16], BOOL initiator) { TALLOC_CTX *mem_ctx; -- cgit From a38f529fd52265f8fefa24510d8bbbb294d2e320 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 6 Jun 2004 08:28:51 +0000 Subject: r1043: allocate signature from the right mem_ctx. Samba4 now passes the schannel torture test. (This used to be commit 95599e3ef79bf5cafb556121c99ffc5c3a8f3314) --- source4/libcli/auth/schannel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 95e881d32a..8a261a506c 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -210,7 +210,7 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); if (!state->signature.data) { - state->signature = data_blob_talloc(mem_ctx, NULL, 32); + state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); if (!state->signature.data) { return NT_STATUS_NO_MEMORY; } @@ -253,7 +253,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); if (!state->signature.data) { - state->signature = data_blob_talloc(mem_ctx, NULL, 32); + state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); if (!state->signature.data) { return NT_STATUS_NO_MEMORY; } -- cgit From 46c88d561f9a5cbaf2b70e937fbc20dff6d31703 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 7 Jun 2004 08:54:49 +0000 Subject: r1061: The start of the SamLogon call for the NETLOGON pipe. Changes: - Check for a valid 'pipe_state' in netr_ServerAuthenticate3 before we dereference it - removes the expansionroom[7] in the netr_SamInfo* structs to 7 individual elements. - renames netr_SamInfo -> netr_SamInfo2 netr_SamInfo2 -> netr_SamInfo3 - Having the thing we always called an 'info3' being 'netr_SamInfo2' was just too confusing. - Expand and fill in extra details about users from the SAM, into the server_info, for processing into the SamLogon reply. - Add a dum_sid_dup() function to duplicate a struct dom_sid The SamLogon code currently does not return supplementary groups, and is only tested with Samba4 smbtorture. Andrew Bartlett (This used to be commit 6c92563b7961f15fc74b02601e105d5e1d04f04d) --- source4/libcli/util/dom_sid.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index cdf89ccf96..9b8b45e302 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -89,3 +89,36 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) return ret; } +/* + convert a string to a dom_sid, returning a talloc'd dom_sid +*/ +struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, struct dom_sid *dom_sid) +{ + struct dom_sid *ret; + int i; + ret = talloc_p(mem_ctx, struct dom_sid); + if (!ret) { + return NULL; + } + + ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, dom_sid->num_auths); + if (!ret->sub_auths) { + return NULL; + } + + ret->sid_rev_num = dom_sid->sid_rev_num; + ret->id_auth[0] = dom_sid->id_auth[0]; + ret->id_auth[1] = dom_sid->id_auth[1]; + ret->id_auth[2] = dom_sid->id_auth[2]; + ret->id_auth[3] = dom_sid->id_auth[3]; + ret->id_auth[4] = dom_sid->id_auth[4]; + ret->id_auth[5] = dom_sid->id_auth[5]; + ret->num_auths = dom_sid->num_auths; + + for (i=0;inum_auths;i++) { + ret->sub_auths[i] = dom_sid->sub_auths[i]; + } + + return ret; +} + -- cgit From f3826432fb14b1e10516afe9f6525aab7c1b720f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 7 Jun 2004 22:17:51 +0000 Subject: r1080: Make sure to initialise all the returned elements in the SamLogon reply also initialise the LM session key, when we have it (was failing because the auth code was setting it's length wrong). Andrew Bartlett (This used to be commit de97d9df224f769953e850a276515923a830839c) --- source4/libcli/auth/ntlm_check.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c index eab150ad4d..f101b230d4 100644 --- a/source4/libcli/auth/ntlm_check.c +++ b/source4/libcli/auth/ntlm_check.c @@ -326,10 +326,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, so use it only if we otherwise allow LM authentication */ if (lp_lanman_auth() && lm_pw) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *lm_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(lm_pw, 8); } return NT_STATUS_OK; } else { @@ -367,11 +364,17 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, if (smb_pwd_check_ntlmv1(lm_response, lm_pw, challenge, NULL)) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); + /* The session key for this response is still very odd. + It not very secure, so use it only if we otherwise + allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8_t first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(lm_pw, 8); + } return NT_STATUS_OK; } } @@ -431,7 +434,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(lm_pw, 8); } return NT_STATUS_OK; } -- cgit From 73c077d37b69267646986ea3fc2ed99d7ef15d4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Jun 2004 00:07:59 +0000 Subject: r1091: Added in timing tests for deferred opens. Added extra debug info to signing mistakes. Jeremy. (This used to be commit 5c3a2417cfe1bdbdfb35d933d49f77f6696790b3) --- source4/libcli/raw/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index c82946ac53..a39f33c290 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -188,7 +188,7 @@ static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) } if (good && i != 1) { - DEBUG(0,("SIGNING OFFSET %d\n", i)); + DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, req->seq_num+1)); } if (!good) { -- cgit From 9f38798509616199d2c53dcd386ea1bc3e21df8f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jun 2004 06:49:18 +0000 Subject: r1129: Remove unused function. Andrew Bartlett (This used to be commit 4d23b9e039872273f3ef433d94d24759bcb87c30) --- source4/libcli/util/smbencrypt.c | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index fdd5838798..72c6589097 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -101,36 +101,6 @@ BOOL E_deshash(const char *passwd, uint8_t p16[16]) return ret; } -/** - * Creates the MD4 and DES (LM) Hash of the users password. - * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password. - * @param passwd password in 'unix' charset. - * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer - * @param p16 return password hashed with des, caller allocated 16 byte buffer - */ - -/* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uint8_t nt_p16[16], uint8_t p16[16]) -{ - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash(pwd, nt_p16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, pwd, strlen(pwd)); - dump_data(100, (char *)nt_p16, 16); -#endif - - E_deshash(pwd, (uint8_t *)p16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, pwd, strlen(pwd)); - dump_data(100, (char *)p16, 16); -#endif -} - /* Does both the NTLMv2 owfs of a user's password */ BOOL ntv2_owf_gen(const uint8_t owf[16], const char *user_in, const char *domain_in, -- cgit From 4d050d4920ca23c8639adab7a88a1996920fb103 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Jun 2004 07:24:52 +0000 Subject: r1131: remove an error msg for failing to open unexpected.tdb (This used to be commit ae393c2ed6b6039d28bb02d5e5104a6d25368ce6) --- source4/libcli/unexpected.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c index c80dfa0465..22795e6c4c 100644 --- a/source4/libcli/unexpected.c +++ b/source4/libcli/unexpected.c @@ -54,7 +54,6 @@ void unexpected_packet(struct packet_struct *p) O_RDWR | O_CREAT, 0644); talloc_destroy(mem_ctx); if (!tdbd) { - DEBUG(0,("Failed to open unexpected.tdb\n")); return; } } -- cgit From 791ee4a58110fc25d5f66e0e21372c766e400bd0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Jun 2004 07:28:05 +0000 Subject: r1134: added a TODO regarding schannel credentials (This used to be commit 17dacf494ac25bb6d9f6dea8cb81968ea2b84c55) --- source4/libcli/auth/credentials.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 1d4db74633..60feee7884 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -270,7 +270,8 @@ BOOL creds_server_step_check(struct creds_CredentialState *creds, struct netr_Authenticator *received_authenticator, struct netr_Authenticator *return_authenticator) { - /* Should we check that this is increasing? */ + /* TODO: this may allow the a replay attack on a non-signed + connection. Should we check that this is increasing? */ creds->sequence = received_authenticator->timestamp; creds_step(creds); if (creds_server_check(creds, &received_authenticator->cred)) { -- cgit From e6ac4b0552a6de834bef446d45d23f15fa25750a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jun 2004 13:53:40 +0000 Subject: r1169: Some more updates to the NTLMSSP NTLM2 code: - implement key weakening - don't create large 'hashes' when we only want a key (signing subkeys) - make more useful debugs. NTLM2 is still off by default, till I figure out how to do NTLM2 signing. Andrew Bartlett (This used to be commit 079c2654851536b0a7918d408ac9597abbab8fd2) --- source4/libcli/auth/ntlmssp.h | 2 - source4/libcli/auth/ntlmssp_sign.c | 92 ++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 46 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index f1b87a7f9d..b7fc914b75 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -171,9 +171,7 @@ struct ntlmssp_state char recv_sign_key[16]; char recv_seal_key[16]; - uint8_t send_sign_hash[258]; uint8_t send_seal_hash[258]; - uint8_t recv_sign_hash[258]; uint8_t recv_seal_hash[258]; /* ntlmv1 */ diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 924289cf26..c9e36b45ad 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -93,9 +93,10 @@ static void calc_hash(uint8_t hash[258], const char *key, size_t key_len) * claiming to be the correct output of NTLM2 signature generation. * */ -static void calc_ntlmv2_hash(uint8_t hash[258], uint8_t subkey[16], - DATA_BLOB session_key, - const char *constant) + +static void calc_ntlmv2_key(uint8_t subkey[16], + DATA_BLOB session_key, + const char *constant) { struct MD5Context ctx3; @@ -103,8 +104,6 @@ static void calc_ntlmv2_hash(uint8_t hash[258], uint8_t subkey[16], MD5Update(&ctx3, session_key.data, session_key.length); MD5Update(&ctx3, constant, strlen(constant)+1); MD5Final(subkey, &ctx3); - - calc_hash(hash, subkey, 16); } enum ntlmssp_direction { @@ -165,6 +164,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat sizeof(ntlmssp_state->ntlmssp_hash)); NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } + dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); return NT_STATUS_OK; } @@ -233,7 +233,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, dump_data(5, sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OK; } } else { if (local_sig.length != sig->length || @@ -249,6 +249,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_ACCESS_DENIED; } } + dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length); return NT_STATUS_OK; } @@ -308,14 +309,11 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, then seal the sequence number - this is becouse the ntlmssp_hash is not constant, but is is rather updated with each iteration */ - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } + dump_data_pw("ntlmssp signature\n", sig->data, sig->length); dump_data_pw("ntlmssp sealed data\n", data, length); /* increment counter on send */ @@ -339,13 +337,10 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_NO_USER_SESSION_KEY; } - DEBUG(10,("ntlmssp__unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length); } else { - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); } dump_data_pw("ntlmssp clear data\n", data, length); @@ -374,6 +369,7 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + DATA_BLOB weak_session_key = ntlmssp_state->session_key; const char *send_sign_const; const char *send_seal_const; const char *recv_sign_const; @@ -393,61 +389,69 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) recv_seal_const = CLI_SEAL; break; } + + /** + Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions. + + We probably should have some parameters to control this, once we get NTLM2 working. + */ + + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { + + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + weak_session_key.length = 6; + } else { /* forty bits */ + weak_session_key.length = 5; + } + dump_data_pw("NTLMSSP weakend master key:\n", + weak_session_key.data, + weak_session_key.length); /* SEND */ - calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, - ntlmssp_state->send_sign_key, - ntlmssp_state->session_key, send_sign_const); + calc_ntlmv2_key(ntlmssp_state->send_sign_key, + ntlmssp_state->session_key, send_sign_const); dump_data_pw("NTLMSSP send sign key:\n", ntlmssp_state->send_sign_key, sizeof(ntlmssp_state->send_sign_key)); - dump_data_pw("NTLMSSP send sign hash:\n", - ntlmssp_state->send_sign_hash, - sizeof(ntlmssp_state->send_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, - ntlmssp_state->send_seal_key, - ntlmssp_state->session_key, send_seal_const); + calc_ntlmv2_key(ntlmssp_state->send_seal_key, + weak_session_key, send_seal_const); dump_data_pw("NTLMSSP send seal key:\n", ntlmssp_state->send_seal_key, sizeof(ntlmssp_state->send_seal_key)); - + + calc_hash(ntlmssp_state->send_seal_hash, + ntlmssp_state->send_seal_key, + sizeof(ntlmssp_state->send_seal_key)); + dump_data_pw("NTLMSSP send sesl hash:\n", ntlmssp_state->send_seal_hash, sizeof(ntlmssp_state->send_seal_hash)); /* RECV */ - calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, - ntlmssp_state->recv_sign_key, - ntlmssp_state->session_key, recv_sign_const); + calc_ntlmv2_key(ntlmssp_state->recv_sign_key, + ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP recv sign key:\n", ntlmssp_state->recv_sign_key, sizeof(ntlmssp_state->recv_sign_key)); - dump_data_pw("NTLMSSP receive sign hash:\n", - ntlmssp_state->recv_sign_hash, - sizeof(ntlmssp_state->recv_sign_hash)); - calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, - ntlmssp_state->recv_seal_key, - ntlmssp_state->session_key, recv_seal_const); + calc_ntlmv2_key(ntlmssp_state->recv_seal_key, + weak_session_key, recv_seal_const); dump_data_pw("NTLMSSP recv seal key:\n", ntlmssp_state->recv_sign_key, sizeof(ntlmssp_state->recv_seal_key)); - dump_data_pw("NTLMSSP receive seal hash:\n", - ntlmssp_state->recv_sign_hash, - sizeof(ntlmssp_state->recv_sign_hash)); + calc_hash(ntlmssp_state->recv_seal_hash, + ntlmssp_state->recv_seal_key, + sizeof(ntlmssp_state->recv_seal_key)); + dump_data_pw("NTLMSSP receive seal hash:\n", + ntlmssp_state->recv_seal_hash, + sizeof(ntlmssp_state->recv_seal_hash)); } else { - if (!ntlmssp_state->session_key.data) { - /* can't sign or check signatures yet */ - DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); + DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), ntlmssp_state->session_key.length); + calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } -- cgit From dd711fee210e4161f8d85f8af39ffc4329d55914 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jun 2004 13:59:52 +0000 Subject: r1170: Remove bogus part of previous commit - session keys, even in NTLMSSP are variable length. Remove extra casts Andrew Bartlett (This used to be commit 84f86b83f88cea5564347f3aa623be2d9feeb4b3) --- source4/libcli/auth/ntlmssp_sign.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index c9e36b45ad..dacfdb194f 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -53,7 +53,7 @@ static void NTLMSSPcalc_ap(uint8_t *hash, uint8_t *data, int len) hash[257] = index_j; } -static void calc_hash(uint8_t hash[258], const char *key, size_t key_len) +static void calc_hash(uint8_t hash[258], const uint8 *key, size_t key_len) { uint8_t j = 0; int ind; @@ -451,7 +451,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) } else { DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); + calc_hash(ntlmssp_state->ntlmssp_hash, + ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } -- cgit From 3e152fcd5b49f727062ed054401e294b6d5d8cb8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jun 2004 11:59:52 +0000 Subject: r1187: * Remove testing hack (actually check signatures on NTLM2). * Remove unreached counter increment * Print the correct NTLMSSP key. (This used to be commit b96700695479c19c7b2c190616420762409fdf0d) --- source4/libcli/auth/ntlmssp_sign.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index dacfdb194f..d680da9495 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -233,7 +233,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, dump_data(5, sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); - return NT_STATUS_OK; + return NT_STATUS_ACCESS_DENIED; } } else { if (local_sig.length != sig->length || @@ -346,9 +346,6 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, dump_data_pw("ntlmssp clear data\n", data, length); return ntlmssp_check_packet(ntlmssp_state, sig_mem_ctx, data, length, sig); - - /* increment counter on recv */ - ntlmssp_state->ntlmssp_seq_num++; } /** @@ -439,7 +436,7 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) calc_ntlmv2_key(ntlmssp_state->recv_seal_key, weak_session_key, recv_seal_const); dump_data_pw("NTLMSSP recv seal key:\n", - ntlmssp_state->recv_sign_key, + ntlmssp_state->recv_seal_key, sizeof(ntlmssp_state->recv_seal_key)); calc_hash(ntlmssp_state->recv_seal_hash, ntlmssp_state->recv_seal_key, -- cgit From bf598954f75bfd924b9aa22649975b372c74a49e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Jun 2004 08:15:41 +0000 Subject: r1198: Merge the Samba 3.0 ntlm_auth, including the kerberos and SPENGO parts. I have moved the SPNEGO and Kerberos code into libcli/auth, and intend to refactor them into the same format as NTLMSSP. Andrew Bartlett (This used to be commit 58da78a7460d5d0a4abee7d7b84799c228e6bc0b) --- source4/libcli/auth/clikrb5.c | 498 +++++++++++++++++++++++++++++++ source4/libcli/auth/kerberos.c | 175 +++++++++++ source4/libcli/auth/kerberos.h | 50 ++++ source4/libcli/auth/kerberos_verify.c | 266 +++++++++++++++++ source4/libcli/auth/spnego.c | 343 ++++++++++++++++++++++ source4/libcli/auth/spnego.h | 65 ++++ source4/libcli/config.m4 | 10 +- source4/libcli/raw/clikrb5.c | 421 -------------------------- source4/libcli/raw/clispnego.c | 539 ---------------------------------- source4/libcli/util/asn1.c | 35 ++- 10 files changed, 1427 insertions(+), 975 deletions(-) create mode 100644 source4/libcli/auth/clikrb5.c create mode 100644 source4/libcli/auth/kerberos.c create mode 100644 source4/libcli/auth/kerberos.h create mode 100644 source4/libcli/auth/kerberos_verify.c create mode 100644 source4/libcli/auth/spnego.c create mode 100644 source4/libcli/auth/spnego.h delete mode 100644 source4/libcli/raw/clikrb5.c delete mode 100644 source4/libcli/raw/clispnego.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c new file mode 100644 index 0000000000..6e19d4dc18 --- /dev/null +++ b/source4/libcli/auth/clikrb5.c @@ -0,0 +1,498 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5 routines for active directory + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002-2003 + + 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" + +#ifdef HAVE_KRB5 + +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + +#ifndef HAVE_KRB5_SET_REAL_TIME +/* + * This function is not in the Heimdal mainline. + */ + krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) +{ + krb5_error_code ret; + int32_t sec, usec; + + ret = krb5_us_timeofday(context, &sec, &usec); + if (ret) + return ret; + + context->kdc_sec_offset = seconds - sec; + context->kdc_usec_offset = microseconds - usec; + + return 0; +} +#endif + +#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_in_tkt_etypes(ctx, enc); +} +#endif + +#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) +/* HEIMDAL */ + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addr_type = KRB5_ADDRESS_INET; + pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) +/* MIT */ + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addrtype = ADDRTYPE_INET; + pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#else + __ERROR__XX__UNKNOWN_ADDRTYPE +#endif + +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + int ret; + krb5_data salt; + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, enctype); + ret = krb5_string_to_key(context, &eblock, key, password, &salt); + SAFE_FREE(salt.data); + return ret; +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, enctype, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_permitted_enctypes(context, enctypes); +} +#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_default_in_tkt_etypes(context, enctypes); +} +#else +#error UNKNOWN_GET_ENCTYPES_FUNCTIONS +#endif + + void free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) +{ +#if defined(HAVE_KRB5_FREE_KTYPES) + krb5_free_ktypes(context, enctypes); + return; +#else + SAFE_FREE(enctypes); + return; +#endif +} + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + + void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + if (tkt->enc_part2) + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); +#else + if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); +#endif +} + + krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->client; +#else + return tkt->client; +#endif +} + +#if !defined(HAVE_KRB5_LOCATE_KDC) + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + krb5_krbhst_handle hnd; + krb5_krbhst_info *hinfo; + krb5_error_code rc; + int num_kdcs, i; + struct sockaddr *sa; + + *addr_pp = NULL; + *naddrs = 0; + + rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); + if (rc) { + DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + return rc; + } + + for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) + ; + + krb5_krbhst_reset(ctx, hnd); + + if (!num_kdcs) { + DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + krb5_krbhst_free(ctx, hnd); + return -1; + } + + sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + if (!sa) { + DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + krb5_krbhst_free(ctx, hnd); + naddrs = 0; + return -1; + } + + memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + + for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { + if (hinfo->ai->ai_family == AF_INET) + memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); + } + + krb5_krbhst_free(ctx, hnd); + + *naddrs = num_kdcs; + *addr_pp = sa; + return 0; +} +#endif + +#if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) + void krb5_free_unparsed_name(krb5_context context, char *val) +{ + SAFE_FREE(val); +} +#endif + +static BOOL ads_cleanup_expired_creds(krb5_context context, + krb5_ccache ccache, + krb5_creds *credsp) +{ + krb5_error_code retval; + TALLOC_CTX *mem_ctx = talloc_init("ticket expied time"); + if (!mem_ctx) { + return False; + } + + DEBUG(3, ("Ticket in ccache[%s] expiration %s\n", + krb5_cc_default_name(context), + http_timestring(mem_ctx, credsp->times.endtime))); + + talloc_destroy(mem_ctx); + + /* we will probably need new tickets if the current ones + will expire within 10 seconds. + */ + if (credsp->times.endtime >= (time(NULL) + 10)) + return False; + + /* heimdal won't remove creds from a file ccache, and + perhaps we shouldn't anyway, since internally we + use memory ccaches, and a FILE one probably means that + we're using creds obtained outside of our exectuable + */ + if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { + DEBUG(5, ("We do not remove creds from a FILE ccache\n")); + return False; + } + + retval = krb5_cc_remove_cred(context, ccache, 0, credsp); + if (retval) { + DEBUG(1, ("krb5_cc_remove_cred failed, err %s\n", + error_message(retval))); + /* If we have an error in this, we want to display it, + but continue as though we deleted it */ + } + return True; +} + +/* + we can't use krb5_mk_req because w2k wants the service to be in a particular format +*/ +static krb5_error_code ads_krb5_mk_req(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf) +{ + krb5_error_code retval; + krb5_principal server; + krb5_creds * credsp; + krb5_creds creds; + krb5_data in_data; + BOOL creds_ready = False; + + TALLOC_CTX *mem_ctx; + + retval = krb5_parse_name(context, principal, &server); + if (retval) { + DEBUG(1,("Failed to parse principal %s\n", principal)); + return retval; + } + + /* obtain ticket & session key */ + ZERO_STRUCT(creds); + if ((retval = krb5_copy_principal(context, server, &creds.server))) { + DEBUG(1,("krb5_copy_principal failed (%s)\n", + error_message(retval))); + goto cleanup_princ; + } + + if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { + DEBUG(1,("krb5_cc_get_principal failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } + + while(!creds_ready) { + if ((retval = krb5_get_credentials(context, 0, ccache, + &creds, &credsp))) { + DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + principal, error_message(retval))); + goto cleanup_creds; + } + + /* cope with ticket being in the future due to clock skew */ + if ((unsigned)credsp->times.starttime > time(NULL)) { + time_t t = time(NULL); + int time_offset =(unsigned)credsp->times.starttime-t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(context, t + time_offset + 1, 0); + } + + if (!ads_cleanup_expired_creds(context, ccache, credsp)) + creds_ready = True; + } + + mem_ctx = talloc_init("ticket expied time"); + if (!mem_ctx) { + retval = ENOMEM; + goto cleanup_creds; + } + DEBUG(10,("Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", + principal, krb5_cc_default_name(context), + http_timestring(mem_ctx, (unsigned)credsp->times.endtime), + (unsigned)credsp->times.endtime)); + + + in_data.length = 0; + retval = krb5_mk_req_extended(context, auth_context, ap_req_options, + &in_data, credsp, outbuf); + if (retval) { + DEBUG(1,("krb5_mk_req_extended failed (%s)\n", + error_message(retval))); + } + + krb5_free_creds(context, credsp); + +cleanup_creds: + krb5_free_cred_contents(context, &creds); + +cleanup_princ: + krb5_free_principal(context, server); + + return retval; +} + +/* + get a kerberos5 ticket for the given service +*/ +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) +{ + krb5_error_code retval; + krb5_data packet; + krb5_context context = NULL; + krb5_ccache ccdef = NULL; + krb5_auth_context auth_context = NULL; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; + + retval = krb5_init_context(&context); + if (retval) { + DEBUG(1,("krb5_init_context failed (%s)\n", + error_message(retval))); + goto failed; + } + + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + + if ((retval = krb5_cc_default(context, &ccdef))) { + DEBUG(1,("krb5_cc_default failed (%s)\n", + error_message(retval))); + goto failed; + } + + if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { + DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n", + error_message(retval))); + goto failed; + } + + if ((retval = ads_krb5_mk_req(context, + &auth_context, + AP_OPTS_USE_SUBKEY, + principal, + ccdef, &packet))) { + goto failed; + } + + get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); + + *ticket = data_blob(packet.data, packet.length); + +/* Hmm, heimdal dooesn't have this - what's the correct call? */ +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(context, &packet); +#endif + +failed: + + if ( context ) { +#if 0 /* JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro */ + if (ccdef) + krb5_cc_close(context, ccdef); +#endif + if (auth_context) + krb5_auth_con_free(context, auth_context); + krb5_free_context(context); + } + + return retval; +} + + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) + { + krb5_keyblock *skey; + krb5_error_code err; + BOOL ret = False; + + memset(session_key, 0, 16); + + if (remote) + err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); + else + err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); + if (err == 0 && skey != NULL) { + DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); + *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + ret = True; + + krb5_free_keyblock(context, skey); + } else { + DEBUG(10, ("KRB5 error getting session key %d\n", err)); + } + + return ret; + } + + +#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) + const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) +{ + static krb5_data kdata; + + kdata.data = krb5_principal_get_comp_string(context, principal, i); + kdata.length = strlen(kdata.data); + return &kdata; +} +#endif + +#else /* HAVE_KRB5 */ + /* this saves a few linking headaches */ +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) +{ + DEBUG(0,("NO KERBEROS SUPPORT\n")); + return 1; +} + +#endif diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c new file mode 100644 index 0000000000..e8bf4b0846 --- /dev/null +++ b/source4/libcli/auth/kerberos.c @@ -0,0 +1,175 @@ +/* + Unix SMB/CIFS implementation. + kerberos utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + + + 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" + +#ifdef HAVE_KRB5 + +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } + } + return 0; +} + +/* + simulate a kinit, putting the tgt in the default cache location + remus@snapserver.com +*/ +int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) +{ + krb5_context ctx = NULL; + krb5_error_code code = 0; + krb5_ccache cc = NULL; + krb5_principal me; + krb5_creds my_creds; + + if ((code = krb5_init_context(&ctx))) + return code; + + if (time_offset != 0) { + krb5_set_real_time(ctx, time(NULL) + time_offset, 0); + } + + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_parse_name(ctx, principal, &me))) { + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + kerb_prompter, + password, 0, NULL, NULL))) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_cc_initialize(ctx, cc, me))) { + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { + krb5_cc_close(ctx, cc); + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if (expire_time) + *expire_time = (time_t) my_creds.times.endtime; + + krb5_cc_close(ctx, cc); + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + + return 0; +} + + + +/* run kinit to setup our ccache */ +int ads_kinit_password(ADS_STRUCT *ads) +{ + char *s; + int ret; + + if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + return KRB5_CC_NOMEM; + } + + if (!ads->auth.password) { + return KRB5_LIBOS_CANTREADPWD; + } + + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); + + if (ret) { + DEBUG(0,("kerberos_kinit_password %s failed: %s\n", + s, error_message(ret))); + } + free(s); + return ret; +} + +int ads_kdestroy(const char *cc_name) +{ + krb5_error_code code; + krb5_context ctx = NULL; + krb5_ccache cc = NULL; + + if ((code = krb5_init_context (&ctx))) { + DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + return code; + } + + if (!cc_name) { + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + } else { + if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", + code)); + krb5_free_context(ctx); + return code; + } + } + + if ((code = krb5_cc_destroy (ctx, cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + } + + krb5_free_context (ctx); + return code; +} + +#endif diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h new file mode 100644 index 0000000000..6f63f6eef2 --- /dev/null +++ b/source4/libcli/auth/kerberos.h @@ -0,0 +1,50 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5 routines for active directory + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002-2003 + + 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. +*/ + +#if defined(HAVE_KRB5) + +#ifndef HAVE_KRB5_SET_REAL_TIME +krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds); +#endif + +#ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES +krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc); +#endif + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) +krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock); +#endif + +#ifndef HAVE_KRB5_FREE_UNPARSED_NAME +void krb5_free_unparsed_name(krb5_context ctx, char *val); +#endif + +/* Samba wrapper function for krb5 functionality. */ +void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr); +int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); +void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt); +krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); +krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); +void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); +BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote); +#endif /* HAVE_KRB5 */ + diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c new file mode 100644 index 0000000000..805a3f570f --- /dev/null +++ b/source4/libcli/auth/kerberos_verify.c @@ -0,0 +1,266 @@ +/* + Unix SMB/CIFS implementation. + kerberos utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + Copyright (C) Luke Howard 2003 + Copyright (C) Guenther Deschner 2003 + Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 + + 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" + +#ifdef HAVE_KRB5 + +/* + verify an incoming ticket and parse out the principal name and + authorization_data if available +*/ +NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data, + DATA_BLOB *ap_rep, + DATA_BLOB *session_key) +{ + NTSTATUS sret = NT_STATUS_LOGON_FAILURE; + krb5_context context = NULL; + krb5_auth_context auth_context = NULL; + krb5_data packet; + krb5_ticket *tkt = NULL; + krb5_rcache rcache = NULL; + int ret, i; + krb5_keyblock *key = NULL; + + krb5_principal host_princ; + char *host_princ_s = NULL; + BOOL free_host_princ = False; + BOOL got_replay_mutex = False; + + fstring myname; + char *password_s = NULL; + krb5_data password; + krb5_enctype *enctypes = NULL; +#if 0 + krb5_address local_addr; + krb5_address remote_addr; +#endif + BOOL auth_ok = False; + + ZERO_STRUCT(packet); + ZERO_STRUCT(password); + ZERO_STRUCTP(auth_data); + ZERO_STRUCTP(ap_rep); + + if (!secrets_init()) { + DEBUG(1,("ads_verify_ticket: secrets_init failed\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password_s = secrets_fetch_machine_password(lp_workgroup()); + if (!password_s) { + DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password.data = password_s; + password.length = strlen(password_s); + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_set_default_realm(context, realm); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + /* This whole process is far more complex than I would + like. We have to go through all this to allow us to store + the secret internally, instead of using /etc/krb5.keytab */ + + ret = krb5_auth_con_init(context, &auth_context); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + fstrcpy(myname, global_myname()); + strlower_m(myname); + asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + ret = krb5_parse_name(context, host_princ_s, &host_princ); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", + host_princ_s, error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + free_host_princ = True; + + /* + * JRA. We must set the rcache here. This will prevent replay attacks. + */ + + ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + ret = krb5_auth_con_setrcache(context, auth_context, rcache); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */ + + if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { + DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 + * code surrounding the replay cache... */ + + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + got_replay_mutex = True; + + /* We need to setup a auth context with each possible encoding type in turn. */ + for (i=0;enctypes[i];i++) { + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + sret = NT_STATUS_NO_MEMORY; + goto out; + } + + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + continue; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + krb5_free_keyblock(context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, + NULL, NULL, &tkt))) { + DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int)enctypes[i] )); + auth_ok = True; + break; + } + + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, + ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", + (unsigned int)enctypes[i], error_message(ret))); + } + + release_server_mutex(); + got_replay_mutex = False; + + if (!auth_ok) { + DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", + error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + ret = krb5_mk_rep(context, auth_context, &packet); + if (ret) { + DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", + error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + *ap_rep = data_blob(packet.data, packet.length); + free(packet.data); + + get_krb5_smb_session_key(context, auth_context, session_key, True); + dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); + +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + /* auth_data is the PAC */ + get_auth_data_from_tkt(auth_data, tkt); + +#if 0 + if (tkt->enc_part2) { + file_save("/tmp/authdata.dat", + tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } +#endif + + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), + principal))) { + DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", + error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + sret = NT_STATUS_OK; + + out: + + if (got_replay_mutex) + release_server_mutex(); + + if (!NT_STATUS_IS_OK(sret)) + data_blob_free(auth_data); + + if (!NT_STATUS_IS_OK(sret)) + data_blob_free(ap_rep); + + if (free_host_princ) + krb5_free_principal(context, host_princ); + + if (tkt != NULL) + krb5_free_ticket(context, tkt); + free_kerberos_etypes(context, enctypes); + SAFE_FREE(password_s); + SAFE_FREE(host_princ_s); + + if (auth_context) + krb5_auth_con_free(context, auth_context); + + if (context) + krb5_free_context(context); + + return sret; +} + +#endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c new file mode 100644 index 0000000000..ddc98f883b --- /dev/null +++ b/source4/libcli/auth/spnego.c @@ -0,0 +1,343 @@ +/* + Unix SMB/CIFS implementation. + + RFC2478 Compliant SPNEGO implementation + + Copyright (C) Jim McDonough 2003 + + 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" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +{ + ZERO_STRUCTP(token); + + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + int i; + + switch (asn1->data[asn1->ofs]) { + /* Read mechTypes */ + case ASN1_CONTEXT(0): + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + token->mechTypes = malloc(sizeof(*token->mechTypes)); + for (i = 0; !asn1->has_error && + 0 < asn1_tag_remaining(asn1); i++) { + token->mechTypes = + realloc(token->mechTypes, (i + 2) * + sizeof(*token->mechTypes)); + asn1_read_OID(asn1, token->mechTypes + i); + } + token->mechTypes[i] = NULL; + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + break; + /* Read reqFlags */ + case ASN1_CONTEXT(1): + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_read_Integer(asn1, &token->reqFlags); + token->reqFlags |= SPNEGO_REQ_FLAG; + asn1_end_tag(asn1); + break; + /* Read mechToken */ + case ASN1_CONTEXT(2): + asn1_start_tag(asn1, ASN1_CONTEXT(2)); + asn1_read_OctetString(asn1, &token->mechToken); + asn1_end_tag(asn1); + break; + /* Read mecListMIC */ + case ASN1_CONTEXT(3): + asn1_start_tag(asn1, ASN1_CONTEXT(3)); + if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { + asn1_read_OctetString(asn1, + &token->mechListMIC); + } else { + /* RFC 2478 says we have an Octet String here, + but W2k sends something different... */ + char *mechListMIC; + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_read_GeneralString(asn1, &mechListMIC); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + token->mechListMIC = + data_blob(mechListMIC, strlen(mechListMIC)); + SAFE_FREE(mechListMIC); + } + asn1_end_tag(asn1); + break; + default: + asn1->has_error = True; + break; + } + } + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + + return !asn1->has_error; +} + +static BOOL write_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +{ + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + + /* Write mechTypes */ + if (token->mechTypes && *token->mechTypes) { + int i; + + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + for (i = 0; token->mechTypes[i]; i++) { + asn1_write_OID(asn1, token->mechTypes[i]); + } + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + } + + /* write reqFlags */ + if (token->reqFlags & SPNEGO_REQ_FLAG) { + int flags = token->reqFlags & ~SPNEGO_REQ_FLAG; + + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_write_Integer(asn1, flags); + asn1_pop_tag(asn1); + } + + /* write mechToken */ + if (token->mechToken.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(2)); + asn1_write_OctetString(asn1, token->mechToken.data, + token->mechToken.length); + asn1_pop_tag(asn1); + } + + /* write mechListMIC */ + if (token->mechListMIC.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(3)); +#if 0 + /* This is what RFC 2478 says ... */ + asn1_write_OctetString(asn1, token->mechListMIC.data, + token->mechListMIC.length); +#else + /* ... but unfortunately this is what Windows + sends/expects */ + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_GENERAL_STRING); + asn1_write(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); +#endif + asn1_pop_tag(asn1); + } + + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + return !asn1->has_error; +} + +static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +{ + ZERO_STRUCTP(token); + + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + switch (asn1->data[asn1->ofs]) { + case ASN1_CONTEXT(0): + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_ENUMERATED); + asn1_read_uint8(asn1, &token->negResult); + asn1_end_tag(asn1); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(1): + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_read_OID(asn1, &token->supportedMech); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(2): + asn1_start_tag(asn1, ASN1_CONTEXT(2)); + asn1_read_OctetString(asn1, &token->responseToken); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(3): + asn1_start_tag(asn1, ASN1_CONTEXT(3)); + asn1_read_OctetString(asn1, &token->mechListMIC); + asn1_end_tag(asn1); + break; + default: + asn1->has_error = True; + break; + } + } + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + + return !asn1->has_error; +} + +static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +{ + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_write_enumerated(asn1, token->negResult); + asn1_pop_tag(asn1); + + if (token->supportedMech) { + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_write_OID(asn1, token->supportedMech); + asn1_pop_tag(asn1); + } + + if (token->responseToken.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(2)); + asn1_write_OctetString(asn1, token->responseToken.data, + token->responseToken.length); + asn1_pop_tag(asn1); + } + + if (token->mechListMIC.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(3)); + asn1_write_OctetString(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + } + + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + return !asn1->has_error; +} + +ssize_t read_spnego_data(DATA_BLOB data, struct spnego_data *token) +{ + ASN1_DATA asn1; + ssize_t ret = -1; + + ZERO_STRUCTP(token); + ZERO_STRUCT(asn1); + asn1_load(&asn1, data); + + switch (asn1.data[asn1.ofs]) { + case ASN1_APPLICATION(0): + asn1_start_tag(&asn1, ASN1_APPLICATION(0)); + asn1_check_OID(&asn1, OID_SPNEGO); + if (read_negTokenInit(&asn1, &token->negTokenInit)) { + token->type = SPNEGO_NEG_TOKEN_INIT; + } + asn1_end_tag(&asn1); + break; + case ASN1_CONTEXT(1): + if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { + token->type = SPNEGO_NEG_TOKEN_TARG; + } + break; + default: + break; + } + + if (!asn1.has_error) ret = asn1.ofs; + asn1_free(&asn1); + + return ret; +} + +ssize_t write_spnego_data(DATA_BLOB *blob, struct spnego_data *spnego) +{ + ASN1_DATA asn1; + ssize_t ret = -1; + + ZERO_STRUCT(asn1); + + switch (spnego->type) { + case SPNEGO_NEG_TOKEN_INIT: + asn1_push_tag(&asn1, ASN1_APPLICATION(0)); + asn1_write_OID(&asn1, OID_SPNEGO); + write_negTokenInit(&asn1, &spnego->negTokenInit); + asn1_pop_tag(&asn1); + break; + case SPNEGO_NEG_TOKEN_TARG: + write_negTokenTarg(&asn1, &spnego->negTokenTarg); + break; + default: + asn1.has_error = True; + break; + } + + if (!asn1.has_error) { + *blob = data_blob(asn1.data, asn1.length); + ret = asn1.ofs; + } + asn1_free(&asn1); + + return ret; +} + +BOOL free_spnego_data(struct spnego_data *spnego) +{ + BOOL ret = True; + + if (!spnego) goto out; + + switch(spnego->type) { + case SPNEGO_NEG_TOKEN_INIT: + if (spnego->negTokenInit.mechTypes) { + int i; + for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { + free(spnego->negTokenInit.mechTypes[i]); + } + free(spnego->negTokenInit.mechTypes); + } + data_blob_free(&spnego->negTokenInit.mechToken); + data_blob_free(&spnego->negTokenInit.mechListMIC); + break; + case SPNEGO_NEG_TOKEN_TARG: + if (spnego->negTokenTarg.supportedMech) { + free(spnego->negTokenTarg.supportedMech); + } + data_blob_free(&spnego->negTokenTarg.responseToken); + data_blob_free(&spnego->negTokenTarg.mechListMIC); + break; + default: + ret = False; + break; + } + ZERO_STRUCTP(spnego); +out: + return ret; +} + diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h new file mode 100644 index 0000000000..e30fa13d26 --- /dev/null +++ b/source4/libcli/auth/spnego.h @@ -0,0 +1,65 @@ +/* + Unix SMB/CIFS implementation. + + RFC2478 Compliant SPNEGO implementation + + Copyright (C) Jim McDonough 2003 + + 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. +*/ + +#ifndef SAMBA_SPNEGO_H +#define SAMBA_SPNEGO_H + +#define SPNEGO_DELEG_FLAG 0x01 +#define SPNEGO_MUTUAL_FLAG 0x02 +#define SPNEGO_REPLAY_FLAG 0x04 +#define SPNEGO_SEQUENCE_FLAG 0x08 +#define SPNEGO_ANON_FLAG 0x10 +#define SPNEGO_CONF_FLAG 0x20 +#define SPNEGO_INTEG_FLAG 0x40 +#define SPNEGO_REQ_FLAG 0x80 + +#define SPNEGO_NEG_TOKEN_INIT 0 +#define SPNEGO_NEG_TOKEN_TARG 1 + +typedef enum _spnego_negResult { + SPNEGO_ACCEPT_COMPLETED = 0, + SPNEGO_ACCEPT_INCOMPLETE = 1, + SPNEGO_REJECT = 2 +} negResult_t; + +struct spnego_negTokenInit { + char **mechTypes; + int reqFlags; + DATA_BLOB mechToken; + DATA_BLOB mechListMIC; +}; + +struct spnego_negTokenTarg { + uint8 negResult; + const char *supportedMech; + DATA_BLOB responseToken; + DATA_BLOB mechListMIC; +}; + +struct spnego_data { + int type; + struct spnego_negTokenInit negTokenInit; + struct spnego_negTokenTarg negTokenTarg; +}; + +#endif diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 82f629b280..49c690c944 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -12,8 +12,6 @@ SMB_SUBSYSTEM(LIBCLI_RAW,[], libcli/raw/clitransport.o libcli/raw/clisession.o libcli/raw/clitree.o - libcli/raw/clikrb5.o - libcli/raw/clispnego.o libcli/raw/rawrequest.o libcli/raw/rawreadwrite.o libcli/raw/rawsearch.o @@ -43,13 +41,17 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], libcli/util/dom_sid.o]) SMB_SUBSYSTEM(LIBCLI_AUTH,[], - [libcli/auth/ntlmssp.o + [libcli/auth/spnego.o + libcli/auth/ntlmssp.o libcli/auth/ntlmssp_parse.o libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o libcli/auth/credentials.o libcli/auth/session.o - libcli/auth/ntlm_check.o]) + libcli/auth/ntlm_check.o + libcli/auth/kerberos.o + libcli/auth/kerberos_verify.o + libcli/auth/clikrb5.o]) SMB_SUBSYSTEM(LIBCLI_NMB,[], [libcli/unexpected.o diff --git a/source4/libcli/raw/clikrb5.c b/source4/libcli/raw/clikrb5.c deleted file mode 100644 index ba3e9ccd17..0000000000 --- a/source4/libcli/raw/clikrb5.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5 routines for active directory - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002-2003 - - 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" - -#ifdef HAVE_KRB5 - -#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE -#define KRB5_KEY_TYPE(k) ((k)->keytype) -#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) -#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -#else -#define KRB5_KEY_TYPE(k) ((k)->enctype) -#define KRB5_KEY_LENGTH(k) ((k)->length) -#define KRB5_KEY_DATA(k) ((k)->contents) -#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ - -#ifndef HAVE_KRB5_SET_REAL_TIME -/* - * This function is not in the Heimdal mainline. - */ - krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) -{ - krb5_error_code ret; - int32_t sec, usec; - - ret = krb5_us_timeofday(context, &sec, &usec); - if (ret) - return ret; - - context->kdc_sec_offset = seconds - sec; - context->kdc_usec_offset = microseconds - usec; - - return 0; -} -#endif - -#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) - krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) -{ - return krb5_set_default_in_tkt_etypes(ctx, enc); -} -#endif - -#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) -/* HEIMDAL */ - void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) -{ - pkaddr->addr_type = KRB5_ADDRESS_INET; - pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); -} -#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) -/* MIT */ - void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) -{ - pkaddr->addrtype = ADDRTYPE_INET; - pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); -} -#else - __ERROR__XX__UNKNOWN_ADDRTYPE -#endif - -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) -{ - int ret; - krb5_data salt; - krb5_encrypt_block eblock; - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return ret; - } - krb5_use_enctype(context, &eblock, enctype); - ret = krb5_string_to_key(context, &eblock, key, password, &salt); - SAFE_FREE(salt.data); - return ret; -} -#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) -{ - int ret; - krb5_salt salt; - - ret = krb5_get_pw_salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); - return ret; - } - return krb5_string_to_key_salt(context, enctype, password->data, - salt, key); -} -#else - __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS -#endif - -#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, - krb5_enctype **enctypes) -{ - return krb5_get_permitted_enctypes(context, enctypes); -} -#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, - krb5_enctype **enctypes) -{ - return krb5_get_default_in_tkt_etypes(context, enctypes); -} -#else -#error UNKNOWN_GET_ENCTYPES_FUNCTIONS -#endif - - void free_kerberos_etypes(krb5_context context, - krb5_enctype *enctypes) -{ -#if defined(HAVE_KRB5_FREE_KTYPES) - krb5_free_ktypes(context, enctypes); - return; -#else - SAFE_FREE(enctypes); - return; -#endif -} - -#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) - krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, - krb5_auth_context auth_context, - krb5_keyblock *keyblock) -{ - return krb5_auth_con_setkey(context, auth_context, keyblock); -} -#endif - - void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) -{ -#if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt->enc_part2) - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); -#else - if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) - *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, - tkt->ticket.authorization_data->val->ad_data.length); -#endif -} - - krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) -{ -#if defined(HAVE_KRB5_TKT_ENC_PART2) - return tkt->enc_part2->client; -#else - return tkt->client; -#endif -} - -#if !defined(HAVE_KRB5_LOCATE_KDC) - krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) -{ - krb5_krbhst_handle hnd; - krb5_krbhst_info *hinfo; - krb5_error_code rc; - int num_kdcs, i; - struct sockaddr *sa; - - *addr_pp = NULL; - *naddrs = 0; - - rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); - if (rc) { - DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); - return rc; - } - - for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) - ; - - krb5_krbhst_reset(ctx, hnd); - - if (!num_kdcs) { - DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); - krb5_krbhst_free(ctx, hnd); - return -1; - } - - sa = malloc( sizeof(struct sockaddr) * num_kdcs ); - if (!sa) { - DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); - krb5_krbhst_free(ctx, hnd); - naddrs = 0; - return -1; - } - - memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); - - for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { - if (hinfo->ai->ai_family == AF_INET) - memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); - } - - krb5_krbhst_free(ctx, hnd); - - *naddrs = num_kdcs; - *addr_pp = sa; - return 0; -} -#endif - -/* - we can't use krb5_mk_req because w2k wants the service to be in a particular format -*/ -static krb5_error_code ads_krb5_mk_req(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf) -{ - krb5_error_code retval; - krb5_principal server; - krb5_creds * credsp; - krb5_creds creds; - krb5_data in_data; - - retval = krb5_parse_name(context, principal, &server); - if (retval) { - DEBUG(1,("Failed to parse principal %s\n", principal)); - return retval; - } - - /* obtain ticket & session key */ - ZERO_STRUCT(creds); - if ((retval = krb5_copy_principal(context, server, &creds.server))) { - DEBUG(1,("krb5_copy_principal failed (%s)\n", - error_message(retval))); - goto cleanup_princ; - } - - if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { - DEBUG(1,("krb5_cc_get_principal failed (%s)\n", - error_message(retval))); - goto cleanup_creds; - } - - if ((retval = krb5_get_credentials(context, 0, - ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", - principal, error_message(retval))); - goto cleanup_creds; - } - - /* cope with the ticket being in the future due to clock skew */ - if ((uint_t)credsp->times.starttime > time(NULL)) { - time_t t = time(NULL); - int time_offset = (uint_t)credsp->times.starttime - t; - DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); - krb5_set_real_time(context, t + time_offset + 1, 0); - } - - in_data.length = 0; - retval = krb5_mk_req_extended(context, auth_context, ap_req_options, - &in_data, credsp, outbuf); - if (retval) { - DEBUG(1,("krb5_mk_req_extended failed (%s)\n", - error_message(retval))); - } - - krb5_free_creds(context, credsp); - -cleanup_creds: - krb5_free_cred_contents(context, &creds); - -cleanup_princ: - krb5_free_principal(context, server); - - return retval; -} - -/* - get a kerberos5 ticket for the given service -*/ -int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) -{ - krb5_error_code retval; - krb5_data packet; - krb5_ccache ccdef; - krb5_context context; - krb5_auth_context auth_context = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; - - retval = krb5_init_context(&context); - if (retval) { - DEBUG(1,("krb5_init_context failed (%s)\n", - error_message(retval))); - goto failed; - } - - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } - - if ((retval = krb5_cc_default(context, &ccdef))) { - DEBUG(1,("krb5_cc_default failed (%s)\n", - error_message(retval))); - goto failed; - } - - if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { - DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n", - error_message(retval))); - goto failed; - } - - if ((retval = ads_krb5_mk_req(context, - &auth_context, - AP_OPTS_USE_SUBKEY, - principal, - ccdef, &packet))) { - goto failed; - } - - get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); - - *ticket = data_blob(packet.data, packet.length); - -/* Hmm, heimdal dooesn't have this - what's the correct call? */ -#ifdef HAVE_KRB5_FREE_DATA_CONTENTS - krb5_free_data_contents(context, &packet); -#endif - -failed: - if ( context ) - krb5_free_context(context); - - return retval; -} - - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) - { - krb5_keyblock *skey; - krb5_error_code err; - BOOL ret = False; - - memset(session_key, 0, 16); - - if (remote) - err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); - else - err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); - if (err == 0 && skey != NULL) { - DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); - *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); - - ret = True; - - krb5_free_keyblock(context, skey); - } else { - DEBUG(10, ("KRB5 error getting session key %d\n", err)); - } - - return ret; - } - - -#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) - const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) -{ - static krb5_data kdata; - - kdata.data = krb5_principal_get_comp_string(context, principal, i); - kdata.length = strlen(kdata.data); - return &kdata; -} -#endif - -#else /* HAVE_KRB5 */ -/* this saves a few linking headaches */ -int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) -{ - DEBUG(0,("NO KERBEROS SUPPORT\n")); - return 1; -} - -#endif diff --git a/source4/libcli/raw/clispnego.c b/source4/libcli/raw/clispnego.c deleted file mode 100644 index ff7d45c8c1..0000000000 --- a/source4/libcli/raw/clispnego.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5/SPNEGO routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 - Copyright (C) Luke Howard 2003 - - 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" - -/* - generate a negTokenInit packet given a GUID, a list of supported - OIDs (the mechanisms) and a principal name string -*/ -DATA_BLOB spnego_gen_negTokenInit(uint8_t guid[16], - const char *OIDs[], - const char *principal) -{ - int i; - ASN1_DATA data; - DATA_BLOB ret; - - memset(&data, 0, sizeof(data)); - - asn1_write(&data, guid, 16); - asn1_push_tag(&data,ASN1_APPLICATION(0)); - asn1_write_OID(&data,OID_SPNEGO); - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); - - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); - for (i=0; OIDs[i]; i++) { - asn1_write_OID(&data,OIDs[i]); - } - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_push_tag(&data, ASN1_CONTEXT(3)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_GeneralString(&data,principal); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - ret = data_blob(data.data, data.length); - asn1_free(&data); - - return ret; -} - -/* - Generate a negTokenInit as used by the client side ... It has a mechType - (OID), and a mechToken (a security blob) ... - - Really, we need to break out the NTLMSSP stuff as well, because it could be - raw in the packets! -*/ -DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) -{ - ASN1_DATA data; - DATA_BLOB ret; - - memset(&data, 0, sizeof(data)); - - asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data,OID_SPNEGO); - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OID(&data, OID); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_push_tag(&data, ASN1_CONTEXT(2)); - asn1_write_OctetString(&data,blob.data,blob.length); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - ret = data_blob(data.data, data.length); - asn1_free(&data); - - return ret; -} - -/* - parse a negTokenInit packet giving a GUID, a list of supported - OIDs (the mechanisms) and a principal name string -*/ -BOOL spnego_parse_negTokenInit(DATA_BLOB blob, - char *OIDs[ASN1_MAX_OIDS], - char **principal) -{ - int i; - BOOL ret; - ASN1_DATA data; - - asn1_load(&data, blob); - - asn1_start_tag(&data,ASN1_APPLICATION(0)); - asn1_check_OID(&data,OID_SPNEGO); - asn1_start_tag(&data,ASN1_CONTEXT(0)); - asn1_start_tag(&data,ASN1_SEQUENCE(0)); - - asn1_start_tag(&data,ASN1_CONTEXT(0)); - asn1_start_tag(&data,ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *aoid = NULL; - asn1_read_OID(&data,&aoid); - OIDs[i] = aoid; - } - OIDs[i] = NULL; - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_start_tag(&data, ASN1_CONTEXT(3)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(&data,principal); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_end_tag(&data); - - ret = !data.has_error; - asn1_free(&data); - return ret; -} - - -/* - generate a negTokenTarg packet given a list of OIDs and a security blob -*/ -DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) -{ - int i; - ASN1_DATA data; - DATA_BLOB ret; - - memset(&data, 0, sizeof(data)); - - asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data,OID_SPNEGO); - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - for (i=0; OIDs[i]; i++) { - asn1_write_OID(&data,OIDs[i]); - } - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_push_tag(&data, ASN1_CONTEXT(2)); - asn1_write_OctetString(&data,blob.data,blob.length); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - ret = data_blob(data.data, data.length); - asn1_free(&data); - - return ret; -} - - -/* - parse a negTokenTarg packet giving a list of OIDs and a security blob -*/ -BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) -{ - int i; - ASN1_DATA data; - - asn1_load(&data, blob); - asn1_start_tag(&data, ASN1_APPLICATION(0)); - asn1_check_OID(&data,OID_SPNEGO); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *aoid = NULL; - asn1_read_OID(&data,&aoid); - OIDs[i] = aoid; - } - OIDs[i] = NULL; - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_start_tag(&data, ASN1_CONTEXT(2)); - asn1_read_OctetString(&data,secblob); - asn1_end_tag(&data); - - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_end_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); - asn1_free(&data); - return False; - } - - asn1_free(&data); - return True; -} - -/* - generate a krb5 GSS-API wrapper packet given a ticket -*/ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8_t tok_id[2]) -{ - ASN1_DATA data; - DATA_BLOB ret; - - memset(&data, 0, sizeof(data)); - - asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data, OID_KERBEROS5); - - asn1_write(&data, tok_id, 2); - asn1_write(&data, ticket.data, ticket.length); - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - ret = data_blob(data.data, data.length); - asn1_free(&data); - - return ret; -} - -/* - parse a krb5 GSS-API wrapper packet giving a ticket -*/ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8_t tok_id[2]) -{ - BOOL ret; - ASN1_DATA data; - int data_remaining; - - asn1_load(&data, blob); - asn1_start_tag(&data, ASN1_APPLICATION(0)); - asn1_check_OID(&data, OID_KERBEROS5); - - data_remaining = asn1_tag_remaining(&data); - - if (data_remaining < 3) { - data.has_error = True; - } else { - asn1_read(&data, tok_id, 2); - data_remaining -= 2; - *ticket = data_blob(NULL, data_remaining); - asn1_read(&data, ticket->data, ticket->length); - } - - asn1_end_tag(&data); - - ret = !data.has_error; - - asn1_free(&data); - - return ret; -} - - -/* - generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY - kerberos session setup -*/ -int spnego_gen_negTokenTarg(const char *principal, int time_offset, - DATA_BLOB *targ, - DATA_BLOB *session_key_krb5) -{ - int retval; - DATA_BLOB tkt, tkt_wrapped; - const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - - /* get a kerberos ticket for the service and extract the session key */ - retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); - - if (retval) - return retval; - - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); - - /* and wrap that in a shiny SPNEGO wrapper */ - *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); - - data_blob_free(&tkt_wrapped); - data_blob_free(&tkt); - - return retval; -} - - -/* - parse a spnego NTLMSSP challenge packet giving two security blobs -*/ -BOOL spnego_parse_challenge(const DATA_BLOB blob, - DATA_BLOB *chal1, DATA_BLOB *chal2) -{ - BOOL ret; - ASN1_DATA data; - - ZERO_STRUCTP(chal1); - ZERO_STRUCTP(chal2); - - asn1_load(&data, blob); - asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_start_tag(&data,ASN1_SEQUENCE(0)); - - asn1_start_tag(&data,ASN1_CONTEXT(0)); - asn1_check_enumerated(&data,1); - asn1_end_tag(&data); - - asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_check_OID(&data, OID_NTLMSSP); - asn1_end_tag(&data); - - asn1_start_tag(&data,ASN1_CONTEXT(2)); - asn1_read_OctetString(&data, chal1); - asn1_end_tag(&data); - - /* the second challenge is optional (XP doesn't send it) */ - if (asn1_tag_remaining(&data)) { - asn1_start_tag(&data,ASN1_CONTEXT(3)); - asn1_read_OctetString(&data, chal2); - asn1_end_tag(&data); - } - - asn1_end_tag(&data); - asn1_end_tag(&data); - - ret = !data.has_error; - asn1_free(&data); - return ret; -} - - -/* - generate a SPNEGO auth packet. This will contain the encrypted passwords -*/ -DATA_BLOB spnego_gen_auth(DATA_BLOB blob) -{ - ASN1_DATA data; - DATA_BLOB ret; - - memset(&data, 0, sizeof(data)); - - asn1_push_tag(&data, ASN1_CONTEXT(1)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_push_tag(&data, ASN1_CONTEXT(2)); - asn1_write_OctetString(&data,blob.data,blob.length); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - ret = data_blob(data.data, data.length); - - asn1_free(&data); - - return ret; -} - -/* - parse a SPNEGO auth packet. This contains the encrypted passwords -*/ -BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) -{ - ASN1_DATA data; - - asn1_load(&data, blob); - asn1_start_tag(&data, ASN1_CONTEXT(1)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(2)); - asn1_read_OctetString(&data,auth); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); - - if (data.has_error) { - DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); - asn1_free(&data); - return False; - } - - asn1_free(&data); - return True; -} - -/* - generate a minimal SPNEGO response packet. Doesn't contain much. -*/ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, - const char *mechOID) -{ - ASN1_DATA data; - DATA_BLOB ret; - uint8_t negResult; - - if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNEGO_NEG_RESULT_ACCEPT; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNEGO_NEG_RESULT_INCOMPLETE; - } else { - negResult = SPNEGO_NEG_RESULT_REJECT; - } - - ZERO_STRUCT(data); - - asn1_push_tag(&data, ASN1_CONTEXT(1)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_enumerated(&data, negResult); - asn1_pop_tag(&data); - - if (reply->data != NULL) { - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, mechOID); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, reply->data, reply->length); - asn1_pop_tag(&data); - } - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - ret = data_blob(data.data, data.length); - asn1_free(&data); - return ret; -} - -/* - parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords -*/ -BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, - DATA_BLOB *auth) -{ - ASN1_DATA data; - uint8_t negResult; - - if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNEGO_NEG_RESULT_ACCEPT; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNEGO_NEG_RESULT_INCOMPLETE; - } else { - negResult = SPNEGO_NEG_RESULT_REJECT; - } - - asn1_load(&data, blob); - asn1_start_tag(&data, ASN1_CONTEXT(1)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_check_enumerated(&data, negResult); - asn1_end_tag(&data); - - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { - asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_check_OID(&data, OID_NTLMSSP); - asn1_end_tag(&data); - - asn1_start_tag(&data,ASN1_CONTEXT(2)); - asn1_read_OctetString(&data, auth); - asn1_end_tag(&data); - } - - asn1_end_tag(&data); - asn1_end_tag(&data); - - if (data.has_error) { - DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data.ofs)); - asn1_free(&data); - data_blob_free(auth); - return False; - } - - asn1_free(&data); - return True; -} - diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index ddefe0baa6..05bc5eace8 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -219,6 +219,11 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) /* read from a ASN1 buffer, advancing the buffer pointer */ BOOL asn1_read(ASN1_DATA *data, void *p, int len) { + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { + data->has_error = True; + return False; + } + if (data->ofs + len > data->length) { data->has_error = True; return False; @@ -315,17 +320,17 @@ int asn1_tag_remaining(ASN1_DATA *data) BOOL asn1_read_OID(ASN1_DATA *data, char **OID) { uint8_t b; - pstring aoid; - fstring el; + char *oid = NULL; + TALLOC_CTX *mem_ctx = talloc_init("asn1_read_OID"); + if (!mem_ctx) { + return False; + } if (!asn1_start_tag(data, ASN1_OID)) return False; asn1_read_uint8(data, &b); - aoid[0] = 0; - snprintf(el, sizeof(el), "%u", b/40); - pstrcat(aoid, el); - snprintf(el, sizeof(el), " %u", b%40); - pstrcat(aoid, el); + oid = talloc_asprintf_append(mem_ctx, oid, "%u", b/40); + oid = talloc_asprintf_append(mem_ctx, oid, " %u", b%40); while (asn1_tag_remaining(data) > 0) { uint_t v = 0; @@ -333,15 +338,15 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); - snprintf(el, sizeof(el), " %u", v); - pstrcat(aoid, el); + oid = talloc_asprintf_append(mem_ctx, oid, " %u", v); } asn1_end_tag(data); - *OID = strdup(aoid); + *OID = strdup(oid); + talloc_destroy(mem_ctx); - return !data->has_error; + return (*OID && !data->has_error); } /* check that the next object ID is correct */ @@ -365,6 +370,10 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) int len; if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } *s = malloc(len+1); if (! *s) { data->has_error = True; @@ -383,6 +392,10 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) ZERO_STRUCTP(blob); if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } *blob = data_blob(NULL, len); asn1_read(data, blob->data, len); asn1_end_tag(data); -- cgit From be081037e09bb78c0308cd6c7a5d7ae563678b7c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jun 2004 00:58:09 +0000 Subject: r1200: Add 'gensec', our generic security layer. This layer is used for DCERPC security, as well as ntlm_auth at this time. It expect things like SASL and the CIFS layer to use it as well. The particular purpose of this layer is to introduce SPENGO, which needs generic access to the actual implementation mechanisms. Schannel, due to it's 'interesting' setup properties is in GENSEC, but is only in the RPC code. Andrew Bartlett (This used to be commit 902af49006fb8cfecaadd3cc0c10e2e542083fb1) --- source4/libcli/auth/gensec.c | 104 +++++++ source4/libcli/auth/gensec.h | 64 +++++ source4/libcli/auth/gensec_ntlmssp.c | 122 ++++++++ source4/libcli/auth/ntlmssp.c | 17 ++ source4/libcli/auth/spnego.c | 522 +++++++++++++++++------------------ source4/libcli/auth/spnego.h | 33 ++- source4/libcli/auth/spnego_parse.c | 343 +++++++++++++++++++++++ source4/libcli/config.m4 | 5 +- source4/libcli/util/asn1.c | 2 +- 9 files changed, 935 insertions(+), 277 deletions(-) create mode 100644 source4/libcli/auth/gensec.c create mode 100644 source4/libcli/auth/gensec.h create mode 100644 source4/libcli/auth/gensec_ntlmssp.c create mode 100644 source4/libcli/auth/spnego_parse.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c new file mode 100644 index 0000000000..138c4af35c --- /dev/null +++ b/source4/libcli/auth/gensec.c @@ -0,0 +1,104 @@ +/* + Unix SMB/CIFS implementation. + + Generic Authentication Interface + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Bartlett 2004 + + 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" + +static const struct gensec_security_ops gensec_ntlmssp_security_ops = { + .name = "ntlmssp", + .sasl_name = "NTLM", + .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, + .oid = OID_NTLMSSP, + .client_start = gensec_ntlmssp_client_start, + .update = gensec_ntlmssp_update, + .seal = gensec_ntlmssp_seal_packet, + .sign = gensec_ntlmssp_sign_packet, + .check_sig = gensec_ntlmssp_check_packet, + .unseal = gensec_ntlmssp_unseal_packet, + .session_key = gensec_ntlmssp_session_key, + .end = gensec_ntlmssp_end +}; + + +static const struct gensec_security_ops gensec_spnego_security_ops = { + .name = "spnego", + .sasl_name = "GSS-SPNEGO", + .oid = OID_SPNEGO, + .client_start = gensec_spnego_client_start, + .update = gensec_spnego_update, + .seal = gensec_spnego_seal_packet, + .sign = gensec_spnego_sign_packet, + .check_sig = gensec_spnego_check_packet, + .unseal = gensec_spnego_unseal_packet, + .session_key = gensec_spnego_session_key, + .end = gensec_spnego_end +}; + +static const struct gensec_security_ops *generic_security_ops[] = { + &gensec_ntlmssp_security_ops, + &gensec_spnego_security_ops, + NULL +}; + +const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) +{ + int i; + for (i=0; generic_security_ops[i]; i++) { + if (generic_security_ops[i]->auth_type == auth_type) { + return generic_security_ops[i]; + } + } + + return NULL; +} + +const struct gensec_security_ops *gensec_security_by_oid(const char *oid) +{ + int i; + for (i=0; generic_security_ops[i]; i++) { + if (generic_security_ops[i]->oid && + (strcmp(generic_security_ops[i]->oid, oid) == 0)) { + return generic_security_ops[i]; + } + } + + return NULL; +} + +const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) +{ + int i; + for (i=0; generic_security_ops[i]; i++) { + if (generic_security_ops[i]->sasl_name + && (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) { + return generic_security_ops[i]; + } + } + + return NULL; +} + +const struct gensec_security_ops **gensec_security_all(void) +{ + return generic_security_ops; +} + diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h new file mode 100644 index 0000000000..2a469e0f57 --- /dev/null +++ b/source4/libcli/auth/gensec.h @@ -0,0 +1,64 @@ +/* + Unix SMB/CIFS implementation. + + Generic Authentication Interface + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Bartlett 2004 + + 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. +*/ + + +struct gensec_security; +struct gensec_user { + const char *domain; + const char *name; + const char *password; +}; +/* GENSEC mode */ +enum gensec_role +{ + GENSEC_SERVER, + GENSEC_CLIENT +}; + +struct gensec_security_ops { + const char *name; + const char *sasl_name; + uint8 auth_type; + const char *oid; /* NULL if not offered by SPENGO */ + NTSTATUS (*client_start)(struct gensec_security *gensec_security); + NTSTATUS (*server_start)(struct gensec_security *gensec_security); + NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out); + NTSTATUS (*seal)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig); + NTSTATUS (*sign)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + const uint8_t *data, size_t length, DATA_BLOB *sig); + NTSTATUS (*check_sig)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + const uint8_t *data, size_t length, const DATA_BLOB *sig); + NTSTATUS (*unseal)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig); + NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); + void (*end)(struct gensec_security *gensec_security); +}; + +struct gensec_security { + struct gensec_user user; + void *private_data; + const struct gensec_security_ops *ops; +}; + diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c new file mode 100644 index 0000000000..f7e9dddd2f --- /dev/null +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -0,0 +1,122 @@ +/* + Unix SMB/CIFS implementation. + + dcerpc authentication operations + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Bartlett 2004 + + 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" + + +NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) +{ + struct ntlmssp_state *ntlmssp_state = NULL; + NTSTATUS status; + + status = ntlmssp_client_start(&ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = ntlmssp_set_domain(ntlmssp_state, gensec_security->user.domain); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = ntlmssp_set_username(ntlmssp_state, gensec_security->user.name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = ntlmssp_set_password(ntlmssp_state, gensec_security->user.password); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + gensec_security->private_data = ntlmssp_state; + + return status; +} + +/* + wrappers for the ntlmssp_*() functions +*/ +NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + return ntlmssp_unseal_packet(ntlmssp_state, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const DATA_BLOB *sig) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + return ntlmssp_check_packet(ntlmssp_state, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + return ntlmssp_seal_packet(ntlmssp_state, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + return ntlmssp_sign_packet(ntlmssp_state, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + return ntlmssp_session_key(ntlmssp_state, session_key); +} + +NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + return ntlmssp_update(ntlmssp_state, out_mem_ctx, in, out); +} + +void gensec_ntlmssp_end(struct gensec_security *gensec_security) +{ + struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + + ntlmssp_end(&ntlmssp_state); + + gensec_security->private_data = NULL; +} diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index dab8506b81..6830db3f90 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -286,6 +286,23 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_INVALID_PARAMETER; } +/** + * Return the NTLMSSP master session key + * + * @param ntlmssp_state NTLMSSP State + */ + +NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB *session_key) +{ + if (!ntlmssp_state->session_key.data) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + *session_key = ntlmssp_state->session_key; + + return NT_STATUS_OK; +} + /** * End an NTLMSSP state machine * diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index ddc98f883b..ae7a3b4042 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -2,8 +2,9 @@ Unix SMB/CIFS implementation. RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough 2003 + + Copyright (C) Jim McDonough 2003 + Copyright (C) Andrew Bartlett 2004 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 @@ -26,318 +27,295 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { - ZERO_STRUCTP(token); - - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - int i; - - switch (asn1->data[asn1->ofs]) { - /* Read mechTypes */ - case ASN1_CONTEXT(0): - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - token->mechTypes = malloc(sizeof(*token->mechTypes)); - for (i = 0; !asn1->has_error && - 0 < asn1_tag_remaining(asn1); i++) { - token->mechTypes = - realloc(token->mechTypes, (i + 2) * - sizeof(*token->mechTypes)); - asn1_read_OID(asn1, token->mechTypes + i); - } - token->mechTypes[i] = NULL; - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - break; - /* Read reqFlags */ - case ASN1_CONTEXT(1): - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_Integer(asn1, &token->reqFlags); - token->reqFlags |= SPNEGO_REQ_FLAG; - asn1_end_tag(asn1); - break; - /* Read mechToken */ - case ASN1_CONTEXT(2): - asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, &token->mechToken); - asn1_end_tag(asn1); - break; - /* Read mecListMIC */ - case ASN1_CONTEXT(3): - asn1_start_tag(asn1, ASN1_CONTEXT(3)); - if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, - &token->mechListMIC); - } else { - /* RFC 2478 says we have an Octet String here, - but W2k sends something different... */ - char *mechListMIC; - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, &mechListMIC); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - token->mechListMIC = - data_blob(mechListMIC, strlen(mechListMIC)); - SAFE_FREE(mechListMIC); - } - asn1_end_tag(asn1); - break; - default: - asn1->has_error = True; - break; - } + struct spnego_state *spnego_state; + TALLOC_CTX *mem_ctx = talloc_init("gensec_spengo_client_start"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + spnego_state = talloc_p(mem_ctx, struct spnego_state); + + if (!spnego_state) { + return NT_STATUS_NO_MEMORY; } - asn1_end_tag(asn1); - asn1_end_tag(asn1); + spnego_state->role = SPNEGO_CLIENT; + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; + spnego_state->state_position = SPNEGO_CLIENT_GET_MECHS; + spnego_state->result = SPNEGO_ACCEPT_INCOMPLETE; + spnego_state->mem_ctx = mem_ctx; - return !asn1->has_error; + gensec_security->private_data = spnego_state; + return NT_STATUS_OK; } -static BOOL write_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +/* + wrappers for the spnego_*() functions +*/ +NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig) { - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + struct spnego_state *spnego_state = gensec_security->private_data; - /* Write mechTypes */ - if (token->mechTypes && *token->mechTypes) { - int i; - - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - for (i = 0; token->mechTypes[i]; i++) { - asn1_write_OID(asn1, token->mechTypes[i]); - } - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + return NT_STATUS_INVALID_PARAMETER; } + + return spnego_state->sub_sec_security.ops->unseal(&spnego_state->sub_sec_security, + mem_ctx, data, length, sig); +} - /* write reqFlags */ - if (token->reqFlags & SPNEGO_REQ_FLAG) { - int flags = token->reqFlags & ~SPNEGO_REQ_FLAG; +NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const DATA_BLOB *sig) +{ + struct spnego_state *spnego_state = gensec_security->private_data; - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_write_Integer(asn1, flags); - asn1_pop_tag(asn1); + return NT_STATUS_NOT_IMPLEMENTED; + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + return NT_STATUS_INVALID_PARAMETER; } + + return spnego_state->sub_sec_security.ops->check_sig(&spnego_state->sub_sec_security, + mem_ctx, data, length, sig); +} - /* write mechToken */ - if (token->mechToken.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(2)); - asn1_write_OctetString(asn1, token->mechToken.data, - token->mechToken.length); - asn1_pop_tag(asn1); - } +NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + struct spnego_state *spnego_state = gensec_security->private_data; - /* write mechListMIC */ - if (token->mechListMIC.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(3)); -#if 0 - /* This is what RFC 2478 says ... */ - asn1_write_OctetString(asn1, token->mechListMIC.data, - token->mechListMIC.length); -#else - /* ... but unfortunately this is what Windows - sends/expects */ - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_GENERAL_STRING); - asn1_write(asn1, token->mechListMIC.data, - token->mechListMIC.length); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); -#endif - asn1_pop_tag(asn1); + return NT_STATUS_NOT_IMPLEMENTED; + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + return NT_STATUS_INVALID_PARAMETER; } + + return spnego_state->sub_sec_security.ops->seal(&spnego_state->sub_sec_security, + mem_ctx, data, length, sig); +} - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); +NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + struct spnego_state *spnego_state = gensec_security->private_data; - return !asn1->has_error; + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + return NT_STATUS_INVALID_PARAMETER; + } + + return spnego_state->sub_sec_security.ops->sign(&spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) { - ZERO_STRUCTP(token); - - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - switch (asn1->data[asn1->ofs]) { - case ASN1_CONTEXT(0): - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_ENUMERATED); - asn1_read_uint8(asn1, &token->negResult); - asn1_end_tag(asn1); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(1): - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, &token->supportedMech); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(2): - asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, &token->responseToken); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(3): - asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, &token->mechListMIC); - asn1_end_tag(asn1); - break; - default: - asn1->has_error = True; - break; - } + struct spnego_state *spnego_state = gensec_security->private_data; + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + return NT_STATUS_INVALID_PARAMETER; } - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - - return !asn1->has_error; + + return spnego_state->sub_sec_security.ops->session_key(&spnego_state->sub_sec_security, + session_key); } -static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) { - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_write_enumerated(asn1, token->negResult); - asn1_pop_tag(asn1); + struct spnego_state *spnego_state = gensec_security->private_data; + DATA_BLOB null_data_blob = data_blob(NULL, 0); + DATA_BLOB unwrapped_out; + struct spnego_data spnego_out; + struct spnego_data spnego; + const struct gensec_security_ops *op; - if (token->supportedMech) { - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_write_OID(asn1, token->supportedMech); - asn1_pop_tag(asn1); - } + ssize_t len; - if (token->responseToken.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(2)); - asn1_write_OctetString(asn1, token->responseToken.data, - token->responseToken.length); - asn1_pop_tag(asn1); + if (!out_mem_ctx) { + out_mem_ctx = spnego_state->mem_ctx; } - if (token->mechListMIC.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(3)); - asn1_write_OctetString(asn1, token->mechListMIC.data, - token->mechListMIC.length); - asn1_pop_tag(asn1); + if (spnego_state->state_position == SPNEGO_FALLBACK) { + return spnego_state->sub_sec_security.ops->update(&spnego_state->sub_sec_security, + out_mem_ctx, in, out); } - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - return !asn1->has_error; -} + len = read_spnego_data(in, &spnego); -ssize_t read_spnego_data(DATA_BLOB data, struct spnego_data *token) -{ - ASN1_DATA asn1; - ssize_t ret = -1; - - ZERO_STRUCTP(token); - ZERO_STRUCT(asn1); - asn1_load(&asn1, data); - - switch (asn1.data[asn1.ofs]) { - case ASN1_APPLICATION(0): - asn1_start_tag(&asn1, ASN1_APPLICATION(0)); - asn1_check_OID(&asn1, OID_SPNEGO); - if (read_negTokenInit(&asn1, &token->negTokenInit)) { - token->type = SPNEGO_NEG_TOKEN_INIT; + if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { + int i; + const struct gensec_security_ops **all_ops = gensec_security_all(); + for (i=0; all_ops[i]; i++) { + NTSTATUS nt_status; + op = all_ops[i]; + if (!op->oid) { + continue; + } + nt_status = op->server_start(&spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + continue; + } + nt_status = op->update(&spnego_state->sub_sec_security, + out_mem_ctx, in, out); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + spnego_state->state_position = SPNEGO_FALLBACK; + return nt_status; + } + op->end(&spnego_state->sub_sec_security); } - asn1_end_tag(&asn1); - break; - case ASN1_CONTEXT(1): - if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { - token->type = SPNEGO_NEG_TOKEN_TARG; + DEBUG(1, ("Failed to parse SPENGO request\n")); + return NT_STATUS_INVALID_PARAMETER; + } else { + + if (spnego.type != spnego_state->expected_packet) { + free_spnego_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + spnego_state->expected_packet)); + return NT_STATUS_INVALID_PARAMETER; } - break; - default: - break; - } - if (!asn1.has_error) ret = asn1.ofs; - asn1_free(&asn1); - - return ret; -} + if (spnego_state->state_position == SPNEGO_CLIENT_GET_MECHS) { -ssize_t write_spnego_data(DATA_BLOB *blob, struct spnego_data *spnego) -{ - ASN1_DATA asn1; - ssize_t ret = -1; - - ZERO_STRUCT(asn1); - - switch (spnego->type) { - case SPNEGO_NEG_TOKEN_INIT: - asn1_push_tag(&asn1, ASN1_APPLICATION(0)); - asn1_write_OID(&asn1, OID_SPNEGO); - write_negTokenInit(&asn1, &spnego->negTokenInit); - asn1_pop_tag(&asn1); - break; - case SPNEGO_NEG_TOKEN_TARG: - write_negTokenTarg(&asn1, &spnego->negTokenTarg); - break; - default: - asn1.has_error = True; - break; - } + /* The server offers a list of mechanisms */ + + char **mechType = spnego.negTokenInit.mechTypes; + char *my_mechs[] = {NULL, NULL}; + int i; + NTSTATUS nt_status; + + for (i=0; mechType[i]; i++) { + op = gensec_security_by_oid(mechType[i]); + if (!op) { + continue; + } + spnego_state->sub_sec_security.ops = op; + spnego_state->sub_sec_security.user = gensec_security->user; + + nt_status = op->client_start(&spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + op->end(&spnego_state->sub_sec_security); + continue; + } + if (i == 0) { + nt_status = op->update(&spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenInit.mechToken, + &unwrapped_out); + } else { + /* only get the helping start blob for the first OID */ + nt_status = op->update(&spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + &unwrapped_out); + } + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", op->name, nt_errstr(nt_status))); + op->end(&spnego_state->sub_sec_security); + } else { + break; + } + } + if (!mechType[i]) { + DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + } - if (!asn1.has_error) { - *blob = data_blob(asn1.data, asn1.length); - ret = asn1.ofs; - } - asn1_free(&asn1); + free_spnego_data(&spnego); + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return nt_status; + } + + /* compose reply */ + my_mechs[0] = op->oid; + + spnego_out.type = SPNEGO_NEG_TOKEN_INIT; + spnego_out.negTokenInit.mechTypes = my_mechs; + spnego_out.negTokenInit.reqFlags = 0; + spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechToken = unwrapped_out; + + if (write_spnego_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } - return ret; -} + /* set next state */ + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->state_position = SPNEGO_TARG; -BOOL free_spnego_data(struct spnego_data *spnego) -{ - BOOL ret = True; + return nt_status; + } else if (spnego_state->state_position == SPNEGO_TARG) { + NTSTATUS nt_status; + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { + return NT_STATUS_ACCESS_DENIED; + } - if (!spnego) goto out; + op = spnego_state->sub_sec_security.ops; + if (spnego.negTokenTarg.responseToken.length) { + nt_status = op->update(&spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + } else { + unwrapped_out = data_blob(NULL, 0); + nt_status = NT_STATUS_OK; + } + + if (NT_STATUS_IS_OK(nt_status) + && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + nt_status = NT_STATUS_INVALID_PARAMETER; + } - switch(spnego->type) { - case SPNEGO_NEG_TOKEN_INIT: - if (spnego->negTokenInit.mechTypes) { - int i; - for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - free(spnego->negTokenInit.mechTypes[i]); + spnego_state->result = spnego.negTokenTarg.negResult; + free_spnego_data(&spnego); + + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* compose reply */ + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego_out.negTokenTarg.supportedMech = op->oid; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + + if (write_spnego_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; } - free(spnego->negTokenInit.mechTypes); - } - data_blob_free(&spnego->negTokenInit.mechToken); - data_blob_free(&spnego->negTokenInit.mechListMIC); - break; - case SPNEGO_NEG_TOKEN_TARG: - if (spnego->negTokenTarg.supportedMech) { - free(spnego->negTokenTarg.supportedMech); + spnego_state->state_position = SPNEGO_TARG; + } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->state_position = SPNEGO_DONE; + } else { + DEBUG(1, ("SPENGO(%s) login failed: %s\n", op->name, nt_errstr(nt_status))); + return nt_status; + } + + return nt_status; + } else { + free_spnego_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); + return NT_STATUS_INVALID_PARAMETER; } - data_blob_free(&spnego->negTokenTarg.responseToken); - data_blob_free(&spnego->negTokenTarg.mechListMIC); - break; - default: - ret = False; - break; } - ZERO_STRUCTP(spnego); -out: - return ret; } +void gensec_spnego_end(struct gensec_security *gensec_security) +{ + struct spnego_state *spnego_state = gensec_security->private_data; + + spnego_state->sub_sec_security.ops->end(&spnego_state->sub_sec_security); + + talloc_destroy(spnego_state->mem_ctx); + + gensec_security->private_data = NULL; +} diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index e30fa13d26..890301314b 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -23,6 +23,12 @@ #ifndef SAMBA_SPNEGO_H #define SAMBA_SPNEGO_H +/* SPNEGO mode */ +enum spnego_role +{ + SPNEGO_SERVER, + SPNEGO_CLIENT +}; #define SPNEGO_DELEG_FLAG 0x01 #define SPNEGO_MUTUAL_FLAG 0x02 @@ -33,9 +39,6 @@ #define SPNEGO_INTEG_FLAG 0x40 #define SPNEGO_REQ_FLAG 0x80 -#define SPNEGO_NEG_TOKEN_INIT 0 -#define SPNEGO_NEG_TOKEN_TARG 1 - typedef enum _spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, @@ -62,4 +65,28 @@ struct spnego_data { struct spnego_negTokenTarg negTokenTarg; }; +enum spnego_message_type { + SPNEGO_NEG_TOKEN_INIT = 0, + SPNEGO_NEG_TOKEN_TARG = 1, +}; + +enum spnego_state_position { + SPNEGO_SERVER_START, + SPNEGO_CLIENT_GET_MECHS, + SPNEGO_CLIENT_SEND_MECHS, + SPNEGO_TARG, + SPNEGO_FALLBACK, + SPNEGO_DONE +}; + +struct spnego_state { + TALLOC_CTX *mem_ctx; + uint_t ref_count; + enum spnego_role role; + enum spnego_message_type expected_packet; + enum spnego_message_type state_position; + negResult_t result; + struct gensec_security sub_sec_security; +}; + #endif diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c new file mode 100644 index 0000000000..6425e0c167 --- /dev/null +++ b/source4/libcli/auth/spnego_parse.c @@ -0,0 +1,343 @@ +/* + Unix SMB/CIFS implementation. + + RFC2478 Compliant SPNEGO implementation + + Copyright (C) Jim McDonough 2003 + + 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" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +{ + ZERO_STRUCTP(token); + + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + int i; + + switch (asn1->data[asn1->ofs]) { + /* Read mechTypes */ + case ASN1_CONTEXT(0): + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + token->mechTypes = malloc(sizeof(*token->mechTypes)); + for (i = 0; !asn1->has_error && + 0 < asn1_tag_remaining(asn1); i++) { + token->mechTypes = + realloc(token->mechTypes, (i + 2) * + sizeof(*token->mechTypes)); + asn1_read_OID(asn1, token->mechTypes + i); + } + token->mechTypes[i] = NULL; + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + break; + /* Read reqFlags */ + case ASN1_CONTEXT(1): + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_read_Integer(asn1, &token->reqFlags); + token->reqFlags |= SPNEGO_REQ_FLAG; + asn1_end_tag(asn1); + break; + /* Read mechToken */ + case ASN1_CONTEXT(2): + asn1_start_tag(asn1, ASN1_CONTEXT(2)); + asn1_read_OctetString(asn1, &token->mechToken); + asn1_end_tag(asn1); + break; + /* Read mecListMIC */ + case ASN1_CONTEXT(3): + asn1_start_tag(asn1, ASN1_CONTEXT(3)); + if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { + asn1_read_OctetString(asn1, + &token->mechListMIC); + } else { + /* RFC 2478 says we have an Octet String here, + but W2k sends something different... */ + char *mechListMIC; + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_read_GeneralString(asn1, &mechListMIC); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + token->mechListMIC = + data_blob(mechListMIC, strlen(mechListMIC)); + SAFE_FREE(mechListMIC); + } + asn1_end_tag(asn1); + break; + default: + asn1->has_error = True; + break; + } + } + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + + return !asn1->has_error; +} + +static BOOL write_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +{ + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + + /* Write mechTypes */ + if (token->mechTypes && *token->mechTypes) { + int i; + + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + for (i = 0; token->mechTypes[i]; i++) { + asn1_write_OID(asn1, token->mechTypes[i]); + } + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + } + + /* write reqFlags */ + if (token->reqFlags & SPNEGO_REQ_FLAG) { + int flags = token->reqFlags & ~SPNEGO_REQ_FLAG; + + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_write_Integer(asn1, flags); + asn1_pop_tag(asn1); + } + + /* write mechToken */ + if (token->mechToken.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(2)); + asn1_write_OctetString(asn1, token->mechToken.data, + token->mechToken.length); + asn1_pop_tag(asn1); + } + + /* write mechListMIC */ + if (token->mechListMIC.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(3)); +#if 0 + /* This is what RFC 2478 says ... */ + asn1_write_OctetString(asn1, token->mechListMIC.data, + token->mechListMIC.length); +#else + /* ... but unfortunately this is what Windows + sends/expects */ + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_GENERAL_STRING); + asn1_write(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); +#endif + asn1_pop_tag(asn1); + } + + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + return !asn1->has_error; +} + +static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +{ + ZERO_STRUCTP(token); + + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + switch (asn1->data[asn1->ofs]) { + case ASN1_CONTEXT(0): + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_ENUMERATED); + asn1_read_uint8(asn1, &token->negResult); + asn1_end_tag(asn1); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(1): + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_read_OID(asn1, &token->supportedMech); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(2): + asn1_start_tag(asn1, ASN1_CONTEXT(2)); + asn1_read_OctetString(asn1, &token->responseToken); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(3): + asn1_start_tag(asn1, ASN1_CONTEXT(3)); + asn1_read_OctetString(asn1, &token->mechListMIC); + asn1_end_tag(asn1); + break; + default: + asn1->has_error = True; + break; + } + } + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + + return !asn1->has_error; +} + +static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +{ + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_write_enumerated(asn1, token->negResult); + asn1_pop_tag(asn1); + + if (token->supportedMech) { + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_write_OID(asn1, token->supportedMech); + asn1_pop_tag(asn1); + } + + if (token->responseToken.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(2)); + asn1_write_OctetString(asn1, token->responseToken.data, + token->responseToken.length); + asn1_pop_tag(asn1); + } + + if (token->mechListMIC.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(3)); + asn1_write_OctetString(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + } + + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + return !asn1->has_error; +} + +ssize_t read_spnego_data(DATA_BLOB data, struct spnego_data *token) +{ + ASN1_DATA asn1; + ssize_t ret = -1; + + ZERO_STRUCTP(token); + ZERO_STRUCT(asn1); + asn1_load(&asn1, data); + + switch (asn1.data[asn1.ofs]) { + case ASN1_APPLICATION(0): + asn1_start_tag(&asn1, ASN1_APPLICATION(0)); + asn1_check_OID(&asn1, OID_SPNEGO); + if (read_negTokenInit(&asn1, &token->negTokenInit)) { + token->type = SPNEGO_NEG_TOKEN_INIT; + } + asn1_end_tag(&asn1); + break; + case ASN1_CONTEXT(1): + if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { + token->type = SPNEGO_NEG_TOKEN_TARG; + } + break; + default: + break; + } + + if (!asn1.has_error) ret = asn1.ofs; + asn1_free(&asn1); + + return ret; +} + +ssize_t write_spnego_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego) +{ + ASN1_DATA asn1; + ssize_t ret = -1; + + ZERO_STRUCT(asn1); + + switch (spnego->type) { + case SPNEGO_NEG_TOKEN_INIT: + asn1_push_tag(&asn1, ASN1_APPLICATION(0)); + asn1_write_OID(&asn1, OID_SPNEGO); + write_negTokenInit(&asn1, &spnego->negTokenInit); + asn1_pop_tag(&asn1); + break; + case SPNEGO_NEG_TOKEN_TARG: + write_negTokenTarg(&asn1, &spnego->negTokenTarg); + break; + default: + asn1.has_error = True; + break; + } + + if (!asn1.has_error) { + *blob = data_blob_talloc(mem_ctx, asn1.data, asn1.length); + ret = asn1.ofs; + } + asn1_free(&asn1); + + return ret; +} + +BOOL free_spnego_data(struct spnego_data *spnego) +{ + BOOL ret = True; + + if (!spnego) goto out; + + switch(spnego->type) { + case SPNEGO_NEG_TOKEN_INIT: + if (spnego->negTokenInit.mechTypes) { + int i; + for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { + free(spnego->negTokenInit.mechTypes[i]); + } + free(spnego->negTokenInit.mechTypes); + } + data_blob_free(&spnego->negTokenInit.mechToken); + data_blob_free(&spnego->negTokenInit.mechListMIC); + break; + case SPNEGO_NEG_TOKEN_TARG: + if (spnego->negTokenTarg.supportedMech) { + free(spnego->negTokenTarg.supportedMech); + } + data_blob_free(&spnego->negTokenTarg.responseToken); + data_blob_free(&spnego->negTokenTarg.mechListMIC); + break; + default: + ret = False; + break; + } + ZERO_STRUCTP(spnego); +out: + return ret; +} + diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 49c690c944..992f84005d 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -42,6 +42,7 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], SMB_SUBSYSTEM(LIBCLI_AUTH,[], [libcli/auth/spnego.o + libcli/auth/spnego_parse.o libcli/auth/ntlmssp.o libcli/auth/ntlmssp_parse.o libcli/auth/ntlmssp_sign.o @@ -51,7 +52,9 @@ SMB_SUBSYSTEM(LIBCLI_AUTH,[], libcli/auth/ntlm_check.o libcli/auth/kerberos.o libcli/auth/kerberos_verify.o - libcli/auth/clikrb5.o]) + libcli/auth/clikrb5.o + libcli/auth/gensec.o + libcli/auth/gensec_ntlmssp.o]) SMB_SUBSYSTEM(LIBCLI_NMB,[], [libcli/unexpected.o diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 05bc5eace8..943ce4d1c1 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -329,7 +329,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) if (!asn1_start_tag(data, ASN1_OID)) return False; asn1_read_uint8(data, &b); - oid = talloc_asprintf_append(mem_ctx, oid, "%u", b/40); + oid = talloc_asprintf(mem_ctx, "%u", b/40); oid = talloc_asprintf_append(mem_ctx, oid, " %u", b%40); while (asn1_tag_remaining(data) > 0) { -- cgit From 68e8c18e33a0aaa4b34be34ccff38e4ec90806ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jun 2004 15:32:44 +0000 Subject: r1229: the name of the protocol should be in first place of a function name rename _spnego_data() into spnego__data metze (This used to be commit 3f57c8f596eb6ad31a024acaf60fefcfd28d8387) --- source4/libcli/auth/spnego.c | 14 +++++++------- source4/libcli/auth/spnego_parse.c | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index ae7a3b4042..321b13afdc 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -152,7 +152,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT out_mem_ctx, in, out); } - len = read_spnego_data(in, &spnego); + len = spnego_read_data(in, &spnego); if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { int i; @@ -180,7 +180,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } else { if (spnego.type != spnego_state->expected_packet) { - free_spnego_data(&spnego); + spnego_free_data(&spnego); DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); return NT_STATUS_INVALID_PARAMETER; @@ -231,7 +231,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); } - free_spnego_data(&spnego); + spnego_free_data(&spnego); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { return nt_status; } @@ -245,7 +245,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT spnego_out.negTokenInit.mechListMIC = null_data_blob; spnego_out.negTokenInit.mechToken = unwrapped_out; - if (write_spnego_data(out_mem_ctx, out, &spnego_out) == -1) { + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -278,7 +278,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } spnego_state->result = spnego.negTokenTarg.negResult; - free_spnego_data(&spnego); + spnego_free_data(&spnego); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* compose reply */ @@ -288,7 +288,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT spnego_out.negTokenTarg.responseToken = unwrapped_out; spnego_out.negTokenTarg.mechListMIC = null_data_blob; - if (write_spnego_data(out_mem_ctx, out, &spnego_out) == -1) { + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -302,7 +302,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT return nt_status; } else { - free_spnego_data(&spnego); + spnego_free_data(&spnego); DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); return NT_STATUS_INVALID_PARAMETER; } diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 6425e0c167..85e18ed4da 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -243,7 +243,7 @@ static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *toke return !asn1->has_error; } -ssize_t read_spnego_data(DATA_BLOB data, struct spnego_data *token) +ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) { ASN1_DATA asn1; ssize_t ret = -1; @@ -276,7 +276,7 @@ ssize_t read_spnego_data(DATA_BLOB data, struct spnego_data *token) return ret; } -ssize_t write_spnego_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego) +ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego) { ASN1_DATA asn1; ssize_t ret = -1; @@ -307,7 +307,7 @@ ssize_t write_spnego_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da return ret; } -BOOL free_spnego_data(struct spnego_data *spnego) +BOOL spnego_free_data(struct spnego_data *spnego) { BOOL ret = True; -- cgit From 81db9ef4425ed0d3397767f722b9f156b334867c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jun 2004 17:07:19 +0000 Subject: r1239: move the old msrpc_() functions to ndr__format_blob() simular to ndr__struct_blob() metze (This used to be commit b25dd341e0febd550a2936ca484b6fecce2ff8c2) --- source4/libcli/auth/ntlmssp.c | 213 +++++++++++++----------- source4/libcli/auth/ntlmssp_parse.c | 321 ------------------------------------ source4/libcli/auth/ntlmssp_sign.c | 32 +++- source4/libcli/config.m4 | 1 - source4/libcli/util/smbencrypt.c | 25 +-- 5 files changed, 159 insertions(+), 433 deletions(-) delete mode 100644 source4/libcli/auth/ntlmssp_parse.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 6830db3f90..f72f98d8a0 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -1,7 +1,7 @@ /* Unix SMB/Netbios implementation. - Version 3.0 - handle NLTMSSP, server side + + NLTMSSP code Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2001-2003 @@ -221,6 +221,7 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { + NTSTATUS nt_status; DATA_BLOB input; uint32_t ntlmssp_command; int i; @@ -257,13 +258,15 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, break; } } else { - if (!msrpc_parse(ntlmssp_state->mem_ctx, - &input, "Cd", - "NTLMSSP", - &ntlmssp_command)) { + nt_status = ndr_pull_format_blob(&input, ntlmssp_state->mem_ctx, + "Cd", + "NTLMSSP", + &ntlmssp_command); + + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); dump_data(2, (const char *)input.data, input.length); - return NT_STATUS_INVALID_PARAMETER; + return nt_status; } } @@ -442,6 +445,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { + NTSTATUS nt_status; DATA_BLOB struct_blob; fstring dnsname, dnsdomname; uint32_t neg_flags = 0; @@ -456,16 +460,18 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (in.length) { - if (!msrpc_parse(ntlmssp_state->mem_ctx, - &in, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { + nt_status = ndr_pull_format_blob(&in, ntlmssp_state->mem_ctx, + "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname); + + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; + return nt_status; } debug_ntlmssp_flags(neg_flags); @@ -515,13 +521,14 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, target_name_dns = dnsname; } - msrpc_gen(out_mem_ctx, - &struct_blob, "aaaaa", - NTLMSSP_NAME_TYPE_DOMAIN, target_name, - NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), - NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, - NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, - 0, ""); + /* TODO: do we need to check the result here? --metze */ + ndr_push_format_blob(&struct_blob, out_mem_ctx, + "aaaaa", + NTLMSSP_NAME_TYPE_DOMAIN, target_name, + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, + NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, + 0, ""); } else { struct_blob = data_blob(NULL, 0); } @@ -534,16 +541,17 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, } else { gen_string = "CdAdbddB"; } - - msrpc_gen(out_mem_ctx, - out, gen_string, - "NTLMSSP", - NTLMSSP_CHALLENGE, - target_name, - chal_flags, - cryptkey, 8, - 0, 0, - struct_blob.data, struct_blob.length); + + /* TODO: do we need to check the result here? --metze */ + ndr_push_format_blob(out, out_mem_ctx, + gen_string, + "NTLMSSP", + NTLMSSP_CHALLENGE, + target_name, + chal_flags, + cryptkey, 8, + 0, 0, + struct_blob.data, struct_blob.length); } ntlmssp_state->expected_state = NTLMSSP_AUTH; @@ -591,18 +599,20 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state->mem_ctx, - &request, parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation, - &ntlmssp_state->encrypted_session_key, - &auth_flags)) { - DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); + nt_status = ndr_pull_format_blob(&request, ntlmssp_state->mem_ctx, + parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation, + &ntlmssp_state->encrypted_session_key, + &auth_flags); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(10, ("ntlmssp_server_preauth: failed to parse NTLMSSP (nonfatal):\n")); dump_data(10, (const char *)request.data, request.length); /* zero this out */ @@ -617,19 +627,20 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, } /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state->mem_ctx, - &request, parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation)) { - DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + nt_status = ndr_pull_format_blob(&request, ntlmssp_state->mem_ctx, + parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1, ("ntlmssp_server_preauth: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)request.data, request.length); - - return NT_STATUS_INVALID_PARAMETER; + return nt_status; } } @@ -958,6 +969,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out) { + NTSTATUS nt_status; + if (ntlmssp_state->unicode) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; } else { @@ -969,13 +982,17 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, } /* generate the ntlmssp negotiate packet */ - msrpc_gen(out_mem_ctx, - out, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - ntlmssp_state->neg_flags, - ntlmssp_state->get_domain(), - ntlmssp_state->get_global_myname()); + nt_status = ndr_push_format_blob(out, out_mem_ctx, + "CddAA", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + ntlmssp_state->neg_flags, + ntlmssp_state->get_domain(), + ntlmssp_state->get_global_myname()); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; @@ -1010,16 +1027,17 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; - if (!msrpc_parse(ntlmssp_state->mem_ctx, - &in, "CdBd", - "NTLMSSP", - &ntlmssp_command, - &server_domain_blob, - &chal_flags)) { + nt_status = ndr_pull_format_blob(&in, ntlmssp_state->mem_ctx, + "CdBd", + "NTLMSSP", + &ntlmssp_command, + &server_domain_blob, + &chal_flags); + + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); dump_data(2, (const char *)in.data, in.length); - - return NT_STATUS_INVALID_PARAMETER; + return nt_status; } data_blob_free(&server_domain_blob); @@ -1049,18 +1067,20 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (!msrpc_parse(ntlmssp_state->mem_ctx, - &in, chal_parse_string, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { + nt_status = ndr_pull_format_blob(&in, ntlmssp_state->mem_ctx, + chal_parse_string, + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob); + + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); dump_data(2, (const char *)in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; + return nt_status; } ntlmssp_state->server_domain = server_domain; @@ -1216,19 +1236,20 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } /* this generates the actual auth packet */ - if (!msrpc_gen(out_mem_ctx, - out, auth_gen_string, - "NTLMSSP", - NTLMSSP_AUTH, - lm_response.data, lm_response.length, - nt_response.data, nt_response.length, - ntlmssp_state->domain, - ntlmssp_state->user, - ntlmssp_state->get_global_myname(), - encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags)) { - - return NT_STATUS_NO_MEMORY; + nt_status = ndr_push_format_blob(out, out_mem_ctx, + auth_gen_string, + "NTLMSSP", + NTLMSSP_AUTH, + lm_response.data, lm_response.length, + nt_response.data, nt_response.length, + ntlmssp_state->domain, + ntlmssp_state->user, + ntlmssp_state->get_global_myname(), + encrypted_session_key.data, encrypted_session_key.length, + ntlmssp_state->neg_flags); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } ntlmssp_state->session_key = session_key; @@ -1242,7 +1263,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->expected_state = NTLMSSP_DONE; - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { + nt_status = ntlmssp_sign_init(ntlmssp_state); + + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); return nt_status; diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c deleted file mode 100644 index 251effd7e1..0000000000 --- a/source4/libcli/auth/ntlmssp_parse.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5/SPNEGO routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 - Copyright (C) Andrew Bartlett 2002-2003 - - 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" - -/* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - const char *format, ...) -{ - int i, n; - va_list ap; - char *s; - uint8_t *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_charnum(s) * 2; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; - case 'a': - n = va_arg(ap, int); - s = va_arg(ap, char *); - data_size += (str_charnum(s) * 2) + 4; - break; - case 'B': - b = va_arg(ap, uint8_t *); - head_size += 8; - data_size += va_arg(ap, int); - break; - case 'b': - b = va_arg(ap, uint8_t *); - head_size += va_arg(ap, int); - break; - case 'd': - n = va_arg(ap, int); - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob_talloc(mem_ctx, NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; - case 'a': - n = va_arg(ap, int); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - break; - - case 'B': - b = va_arg(ap, uint8_t *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - if (n && b) /* don't follow null pointers... */ - memcpy(blob->data+data_ofs, b, n); - data_ofs += n; - break; - case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; - break; - case 'b': - b = va_arg(ap, uint8_t *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); - head_ofs += n; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, - STR_ASCII|STR_TERMINATE); - break; - } - } - va_end(ap); - - return True; -} - - -/* a helpful macro to avoid running over the end of our blob */ -#define NEED_DATA(amount) \ -if ((head_ofs + amount) > blob->length) { \ - return False; \ -} - -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ - -BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - const char **ps, *s; - DATA_BLOB *b; - size_t head_ofs = 0; - uint16_t len1, len2; - uint32_t ptr; - uint32_t *v; - pstring p; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = va_arg(ap, char **); - if (len1 == 0 && len2 == 0) { - *ps = ""; - } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; - } - if (len1 & 1) { - /* if odd length and unicode */ - return False; - } - if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) - return False; - - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = talloc_strdup(mem_ctx, p); - if (!(*ps)) { - return False; - } - } else { - (*ps) = ""; - } - } - break; - case 'A': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = va_arg(ap, char **); - /* make sure its in the right format - be strict */ - if (len1 == 0 && len2 == 0) { - *ps = ""; - } else { - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; - } - - if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) - return False; - - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_ASCII|STR_NOALIGN); - (*ps) = talloc_strdup(mem_ctx, p); - if (!(*ps)) { - return False; - } - } else { - (*ps) = ""; - } - } - break; - case 'B': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - b = (DATA_BLOB *)va_arg(ap, void *); - if (len1 == 0 && len2 == 0) { - *b = data_blob_talloc(mem_ctx, NULL, 0); - } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; - } - - if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) - return False; - - *b = data_blob_talloc(mem_ctx, blob->data + ptr, len1); - } - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, uint_t); - /* make sure its in the right format - be strict */ - NEED_DATA(len1); - if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) - return False; - - *b = data_blob_talloc(mem_ctx, blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32_t *); - NEED_DATA(4); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - - if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) - return False; - - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; - } - break; - } - } - va_end(ap); - - return True; -} diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index d680da9495..385ea18cd2 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -117,6 +117,8 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat enum ntlmssp_direction direction, DATA_BLOB *sig) { + NTSTATUS nt_status; + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; @@ -155,9 +157,18 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat } else { uint32_t crc; + crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; + + nt_status = ndr_push_format_blob(sig, sig_mem_ctx, + "dddd", + NTLMSSP_SIGN_VERSION, + 0, + crc, + ntlmssp_state->ntlmssp_seq_num); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, @@ -264,7 +275,9 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) -{ +{ + NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot seal packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; @@ -300,9 +313,18 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, memcpy(sig->data + 12, seq_num, 4); } else { uint32_t crc; + crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; + + nt_status = ndr_push_format_blob(sig, sig_mem_ctx, + "dddd", + NTLMSSP_SIGN_VERSION, + 0, + crc, + ntlmssp_state->ntlmssp_seq_num); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } /* The order of these two operations matters - we must first seal the packet, diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 992f84005d..eb23c045af 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -44,7 +44,6 @@ SMB_SUBSYSTEM(LIBCLI_AUTH,[], [libcli/auth/spnego.o libcli/auth/spnego_parse.o libcli/auth/ntlmssp.o - libcli/auth/ntlmssp_parse.o libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o libcli/auth/credentials.o diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 72c6589097..e2fb033279 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -267,10 +267,12 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, { DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - msrpc_gen(mem_ctx, &names_blob, "aaa", - NTLMSSP_NAME_TYPE_DOMAIN, domain, - NTLMSSP_NAME_TYPE_SERVER, hostname, - 0, ""); + ndr_push_format_blob(&names_blob ,mem_ctx, + "aaa", + NTLMSSP_NAME_TYPE_DOMAIN, domain, + NTLMSSP_NAME_TYPE_SERVER, hostname, + 0, ""); + return names_blob; } @@ -289,13 +291,14 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - msrpc_gen(mem_ctx, &response, "ddbbdb", - 0x00000101, /* Header */ - 0, /* 'Reserved' */ - long_date, 8, /* Timestamp */ - client_chal, 8, /* client challenge */ - 0, /* Unknown */ - names_blob->data, names_blob->length); /* End of name list */ + ndr_push_format_blob(&response, mem_ctx, + "ddbbdb", + 0x00000101, /* Header */ + 0, /* 'Reserved' */ + long_date, 8, /* Timestamp */ + client_chal, 8, /* client challenge */ + 0, /* Unknown */ + names_blob->data, names_blob->length); /* End of name list */ return response; } -- cgit From 37fcf2236433bc5e74f19d2afac3d1d0055dcd01 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 27 Jun 2004 11:06:10 +0000 Subject: r1268: varient -> variant (This used to be commit de5984c95602ca67e8ac3139c3aa4330b74266e0) --- source4/libcli/raw/clisession.c | 2 +- source4/libcli/util/smbdes.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 641eff053e..780ff5837b 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -403,7 +403,7 @@ static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, /**************************************************************************** Perform a session setup (sync interface) this interface allows for RAW_SESSSETUP_GENERIC to auto-select session -setup varient based on negotiated protocol options +setup variant based on negotiated protocol options ****************************************************************************/ NTSTATUS smb_raw_session_setup(struct cli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 2492f9a1ba..99c2c00977 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -405,7 +405,7 @@ void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) } /* - a varient that assumes a 16 byte key. This should be removed + a variant that assumes a 16 byte key. This should be removed when the last user is gone */ void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len) -- cgit From 25bf685da5c037d1875f96e7e7127106dee2865d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jun 2004 06:46:27 +0000 Subject: r1274: revert -r 1239 as discussed with abartlet metze (This used to be commit 52e2d038252bd745d53c687d266ad3ad62efa6fc) --- source4/libcli/auth/ntlmssp.c | 213 +++++++++++------------- source4/libcli/auth/ntlmssp_parse.c | 321 ++++++++++++++++++++++++++++++++++++ source4/libcli/auth/ntlmssp_sign.c | 32 +--- source4/libcli/config.m4 | 1 + source4/libcli/util/smbencrypt.c | 25 ++- 5 files changed, 433 insertions(+), 159 deletions(-) create mode 100644 source4/libcli/auth/ntlmssp_parse.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index f72f98d8a0..6830db3f90 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -1,7 +1,7 @@ /* Unix SMB/Netbios implementation. - - NLTMSSP code + Version 3.0 + handle NLTMSSP, server side Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2001-2003 @@ -221,7 +221,6 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - NTSTATUS nt_status; DATA_BLOB input; uint32_t ntlmssp_command; int i; @@ -258,15 +257,13 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, break; } } else { - nt_status = ndr_pull_format_blob(&input, ntlmssp_state->mem_ctx, - "Cd", - "NTLMSSP", - &ntlmssp_command); - - if (!NT_STATUS_IS_OK(nt_status)) { + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &input, "Cd", + "NTLMSSP", + &ntlmssp_command)) { DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); dump_data(2, (const char *)input.data, input.length); - return nt_status; + return NT_STATUS_INVALID_PARAMETER; } } @@ -445,7 +442,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - NTSTATUS nt_status; DATA_BLOB struct_blob; fstring dnsname, dnsdomname; uint32_t neg_flags = 0; @@ -460,18 +456,16 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (in.length) { - nt_status = ndr_pull_format_blob(&in, ntlmssp_state->mem_ctx, - "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname); - - if (!NT_STATUS_IS_OK(nt_status)) { + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &in, "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)in.data, in.length); - return nt_status; + return NT_STATUS_INVALID_PARAMETER; } debug_ntlmssp_flags(neg_flags); @@ -521,14 +515,13 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, target_name_dns = dnsname; } - /* TODO: do we need to check the result here? --metze */ - ndr_push_format_blob(&struct_blob, out_mem_ctx, - "aaaaa", - NTLMSSP_NAME_TYPE_DOMAIN, target_name, - NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), - NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, - NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, - 0, ""); + msrpc_gen(out_mem_ctx, + &struct_blob, "aaaaa", + NTLMSSP_NAME_TYPE_DOMAIN, target_name, + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, + NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, + 0, ""); } else { struct_blob = data_blob(NULL, 0); } @@ -541,17 +534,16 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, } else { gen_string = "CdAdbddB"; } - - /* TODO: do we need to check the result here? --metze */ - ndr_push_format_blob(out, out_mem_ctx, - gen_string, - "NTLMSSP", - NTLMSSP_CHALLENGE, - target_name, - chal_flags, - cryptkey, 8, - 0, 0, - struct_blob.data, struct_blob.length); + + msrpc_gen(out_mem_ctx, + out, gen_string, + "NTLMSSP", + NTLMSSP_CHALLENGE, + target_name, + chal_flags, + cryptkey, 8, + 0, 0, + struct_blob.data, struct_blob.length); } ntlmssp_state->expected_state = NTLMSSP_AUTH; @@ -599,20 +591,18 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ - nt_status = ndr_pull_format_blob(&request, ntlmssp_state->mem_ctx, - parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation, - &ntlmssp_state->encrypted_session_key, - &auth_flags); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(10, ("ntlmssp_server_preauth: failed to parse NTLMSSP (nonfatal):\n")); + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation, + &ntlmssp_state->encrypted_session_key, + &auth_flags)) { + DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); dump_data(10, (const char *)request.data, request.length); /* zero this out */ @@ -627,20 +617,19 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, } /* now the NTLMSSP encoded auth hashes */ - nt_status = ndr_pull_format_blob(&request, ntlmssp_state->mem_ctx, - parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("ntlmssp_server_preauth: failed to parse NTLMSSP:\n")); + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)request.data, request.length); - return nt_status; + + return NT_STATUS_INVALID_PARAMETER; } } @@ -969,8 +958,6 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out) { - NTSTATUS nt_status; - if (ntlmssp_state->unicode) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; } else { @@ -982,17 +969,13 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, } /* generate the ntlmssp negotiate packet */ - nt_status = ndr_push_format_blob(out, out_mem_ctx, - "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - ntlmssp_state->neg_flags, - ntlmssp_state->get_domain(), - ntlmssp_state->get_global_myname()); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + msrpc_gen(out_mem_ctx, + out, "CddAA", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + ntlmssp_state->neg_flags, + ntlmssp_state->get_domain(), + ntlmssp_state->get_global_myname()); ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; @@ -1027,17 +1010,16 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; - nt_status = ndr_pull_format_blob(&in, ntlmssp_state->mem_ctx, - "CdBd", - "NTLMSSP", - &ntlmssp_command, - &server_domain_blob, - &chal_flags); - - if (!NT_STATUS_IS_OK(nt_status)) { + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &in, "CdBd", + "NTLMSSP", + &ntlmssp_command, + &server_domain_blob, + &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); dump_data(2, (const char *)in.data, in.length); - return nt_status; + + return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&server_domain_blob); @@ -1067,20 +1049,18 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - nt_status = ndr_pull_format_blob(&in, ntlmssp_state->mem_ctx, - chal_parse_string, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob); - - if (!NT_STATUS_IS_OK(nt_status)) { + if (!msrpc_parse(ntlmssp_state->mem_ctx, + &in, chal_parse_string, + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); dump_data(2, (const char *)in.data, in.length); - return nt_status; + return NT_STATUS_INVALID_PARAMETER; } ntlmssp_state->server_domain = server_domain; @@ -1236,20 +1216,19 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } /* this generates the actual auth packet */ - nt_status = ndr_push_format_blob(out, out_mem_ctx, - auth_gen_string, - "NTLMSSP", - NTLMSSP_AUTH, - lm_response.data, lm_response.length, - nt_response.data, nt_response.length, - ntlmssp_state->domain, - ntlmssp_state->user, - ntlmssp_state->get_global_myname(), - encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + if (!msrpc_gen(out_mem_ctx, + out, auth_gen_string, + "NTLMSSP", + NTLMSSP_AUTH, + lm_response.data, lm_response.length, + nt_response.data, nt_response.length, + ntlmssp_state->domain, + ntlmssp_state->user, + ntlmssp_state->get_global_myname(), + encrypted_session_key.data, encrypted_session_key.length, + ntlmssp_state->neg_flags)) { + + return NT_STATUS_NO_MEMORY; } ntlmssp_state->session_key = session_key; @@ -1263,9 +1242,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->expected_state = NTLMSSP_DONE; - nt_status = ntlmssp_sign_init(ntlmssp_state); - - if (!NT_STATUS_IS_OK(nt_status)) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); return nt_status; diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c new file mode 100644 index 0000000000..251effd7e1 --- /dev/null +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -0,0 +1,321 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 + Copyright (C) Andrew Bartlett 2002-2003 + + 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" + +/* + this is a tiny msrpc packet generator. I am only using this to + avoid tying this code to a particular varient of our rpc code. This + generator is not general enough for all our rpc needs, its just + enough for the spnego/ntlmssp code + + format specifiers are: + + U = unicode string (input is unix string) + a = address (input is char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) + B = data blob (pointer + length) + b = data blob in header (pointer + length) + D + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + const char *format, ...) +{ + int i, n; + va_list ap; + char *s; + uint8_t *b; + int head_size=0, data_size=0; + int head_ofs, data_ofs; + + /* first scan the format to work out the header and body size */ + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_charnum(s) * 2; + break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; + case 'a': + n = va_arg(ap, int); + s = va_arg(ap, char *); + data_size += (str_charnum(s) * 2) + 4; + break; + case 'B': + b = va_arg(ap, uint8_t *); + head_size += 8; + data_size += va_arg(ap, int); + break; + case 'b': + b = va_arg(ap, uint8_t *); + head_size += va_arg(ap, int); + break; + case 'd': + n = va_arg(ap, int); + head_size += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_size += str_charnum(s) + 1; + break; + } + } + va_end(ap); + + /* allocate the space, then scan the format again to fill in the values */ + *blob = data_blob_talloc(mem_ctx, NULL, head_size + data_size); + + head_ofs = 0; + data_ofs = head_size; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + data_ofs += n*2; + break; + case 'A': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; + case 'a': + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + break; + + case 'B': + b = va_arg(ap, uint8_t *); + n = va_arg(ap, int); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + if (n && b) /* don't follow null pointers... */ + memcpy(blob->data+data_ofs, b, n); + data_ofs += n; + break; + case 'd': + n = va_arg(ap, int); + SIVAL(blob->data, head_ofs, n); head_ofs += 4; + break; + case 'b': + b = va_arg(ap, uint8_t *); + n = va_arg(ap, int); + memcpy(blob->data + head_ofs, b, n); + head_ofs += n; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + STR_ASCII|STR_TERMINATE); + break; + } + } + va_end(ap); + + return True; +} + + +/* a helpful macro to avoid running over the end of our blob */ +#define NEED_DATA(amount) \ +if ((head_ofs + amount) > blob->length) { \ + return False; \ +} + +/* + this is a tiny msrpc packet parser. This the the partner of msrpc_gen + + format specifiers are: + + U = unicode string (output is unix string) + A = ascii string + B = data blob + b = data blob in header + d = word (4 bytes) + C = constant ascii string + */ + +BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, + const char *format, ...) +{ + int i; + va_list ap; + const char **ps, *s; + DATA_BLOB *b; + size_t head_ofs = 0; + uint16_t len1, len2; + uint32_t ptr; + uint32_t *v; + pstring p; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + ps = va_arg(ap, char **); + if (len1 == 0 && len2 == 0) { + *ps = ""; + } else { + /* make sure its in the right format - be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + return False; + } + if (len1 & 1) { + /* if odd length and unicode */ + return False; + } + if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) + return False; + + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = talloc_strdup(mem_ctx, p); + if (!(*ps)) { + return False; + } + } else { + (*ps) = ""; + } + } + break; + case 'A': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + ps = va_arg(ap, char **); + /* make sure its in the right format - be strict */ + if (len1 == 0 && len2 == 0) { + *ps = ""; + } else { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + return False; + } + + if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) + return False; + + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_ASCII|STR_NOALIGN); + (*ps) = talloc_strdup(mem_ctx, p); + if (!(*ps)) { + return False; + } + } else { + (*ps) = ""; + } + } + break; + case 'B': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + b = (DATA_BLOB *)va_arg(ap, void *); + if (len1 == 0 && len2 == 0) { + *b = data_blob_talloc(mem_ctx, NULL, 0); + } else { + /* make sure its in the right format - be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + return False; + } + + if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) + return False; + + *b = data_blob_talloc(mem_ctx, blob->data + ptr, len1); + } + break; + case 'b': + b = (DATA_BLOB *)va_arg(ap, void *); + len1 = va_arg(ap, uint_t); + /* make sure its in the right format - be strict */ + NEED_DATA(len1); + if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) + return False; + + *b = data_blob_talloc(mem_ctx, blob->data + head_ofs, len1); + head_ofs += len1; + break; + case 'd': + v = va_arg(ap, uint32_t *); + NEED_DATA(4); + *v = IVAL(blob->data, head_ofs); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + + if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) + return False; + + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (strcmp(s, p) != 0) { + return False; + } + break; + } + } + va_end(ap); + + return True; +} diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 385ea18cd2..d680da9495 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -117,8 +117,6 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat enum ntlmssp_direction direction, DATA_BLOB *sig) { - NTSTATUS nt_status; - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; @@ -157,18 +155,9 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat } else { uint32_t crc; - crc = crc32_calc_buffer((const char *)data, length); - - nt_status = ndr_push_format_blob(sig, sig_mem_ctx, - "dddd", - NTLMSSP_SIGN_VERSION, - 0, - crc, - ntlmssp_state->ntlmssp_seq_num); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; } dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, @@ -275,9 +264,7 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) -{ - NTSTATUS nt_status; - +{ if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot seal packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; @@ -313,18 +300,9 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, memcpy(sig->data + 12, seq_num, 4); } else { uint32_t crc; - crc = crc32_calc_buffer((const char *)data, length); - - nt_status = ndr_push_format_blob(sig, sig_mem_ctx, - "dddd", - NTLMSSP_SIGN_VERSION, - 0, - crc, - ntlmssp_state->ntlmssp_seq_num); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; } /* The order of these two operations matters - we must first seal the packet, diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index eb23c045af..992f84005d 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -44,6 +44,7 @@ SMB_SUBSYSTEM(LIBCLI_AUTH,[], [libcli/auth/spnego.o libcli/auth/spnego_parse.o libcli/auth/ntlmssp.o + libcli/auth/ntlmssp_parse.o libcli/auth/ntlmssp_sign.o libcli/auth/schannel.o libcli/auth/credentials.o diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index e2fb033279..72c6589097 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -267,12 +267,10 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, { DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - ndr_push_format_blob(&names_blob ,mem_ctx, - "aaa", - NTLMSSP_NAME_TYPE_DOMAIN, domain, - NTLMSSP_NAME_TYPE_SERVER, hostname, - 0, ""); - + msrpc_gen(mem_ctx, &names_blob, "aaa", + NTLMSSP_NAME_TYPE_DOMAIN, domain, + NTLMSSP_NAME_TYPE_SERVER, hostname, + 0, ""); return names_blob; } @@ -291,14 +289,13 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - ndr_push_format_blob(&response, mem_ctx, - "ddbbdb", - 0x00000101, /* Header */ - 0, /* 'Reserved' */ - long_date, 8, /* Timestamp */ - client_chal, 8, /* client challenge */ - 0, /* Unknown */ - names_blob->data, names_blob->length); /* End of name list */ + msrpc_gen(mem_ctx, &response, "ddbbdb", + 0x00000101, /* Header */ + 0, /* 'Reserved' */ + long_date, 8, /* Timestamp */ + client_chal, 8, /* client challenge */ + 0, /* Unknown */ + names_blob->data, names_blob->length); /* End of name list */ return response; } -- cgit From dc9f55dbec5f892b39d924d5fd033b5eec1e14e4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 Jun 2004 09:40:10 +0000 Subject: r1294: A nice, large, commit... This implements gensec for Samba's server side, and brings gensec up to the standards of a full subsystem. This means that use of the subsystem is by gensec_* functions, not function pointers in structures (this is internal). This causes changes in all the existing gensec users. Our RPC server no longer contains it's own generalised security scheme, and now calls gensec directly. Gensec has also taken over the role of auth/auth_ntlmssp.c An important part of gensec, is the output of the 'session_info' struct. This is now reference counted, so that we can correctly free it when a pipe is closed, no matter if it was inherited, or created by per-pipe authentication. The schannel code is reworked, to be in the same file for client and server. ntlm_auth is reworked to use gensec. The major problem with this code is the way it relies on subsystem auto-initialisation. The primary reason for this commit now.is to allow these problems to be looked at, and fixed. There are problems with the new code: - I've tested it with smbtorture, but currently don't have VMware and valgrind working (this I'll fix soon). - The SPNEGO code is client-only at this point. - We still do not do kerberos. Andrew Bartlett (This used to be commit 07fd885fd488fd1051eacc905a2d4962f8a018ec) --- source4/libcli/auth/gensec.c | 405 +++++++++++++++++++++++++++++++---- source4/libcli/auth/gensec.h | 39 +++- source4/libcli/auth/gensec_ntlmssp.c | 333 +++++++++++++++++++++++++--- source4/libcli/auth/ntlmssp_sign.c | 2 - source4/libcli/auth/spnego.c | 175 +++++++++------ source4/libcli/auth/spnego.h | 25 --- source4/libcli/config.m4 | 3 +- 7 files changed, 813 insertions(+), 169 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 138c4af35c..f6d6db9e62 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -23,46 +23,14 @@ #include "includes.h" -static const struct gensec_security_ops gensec_ntlmssp_security_ops = { - .name = "ntlmssp", - .sasl_name = "NTLM", - .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, - .oid = OID_NTLMSSP, - .client_start = gensec_ntlmssp_client_start, - .update = gensec_ntlmssp_update, - .seal = gensec_ntlmssp_seal_packet, - .sign = gensec_ntlmssp_sign_packet, - .check_sig = gensec_ntlmssp_check_packet, - .unseal = gensec_ntlmssp_unseal_packet, - .session_key = gensec_ntlmssp_session_key, - .end = gensec_ntlmssp_end -}; - - -static const struct gensec_security_ops gensec_spnego_security_ops = { - .name = "spnego", - .sasl_name = "GSS-SPNEGO", - .oid = OID_SPNEGO, - .client_start = gensec_spnego_client_start, - .update = gensec_spnego_update, - .seal = gensec_spnego_seal_packet, - .sign = gensec_spnego_sign_packet, - .check_sig = gensec_spnego_check_packet, - .unseal = gensec_spnego_unseal_packet, - .session_key = gensec_spnego_session_key, - .end = gensec_spnego_end -}; - -static const struct gensec_security_ops *generic_security_ops[] = { - &gensec_ntlmssp_security_ops, - &gensec_spnego_security_ops, - NULL -}; - -const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) +/* the list of currently registered GENSEC backends */ +const static struct gensec_security_ops **generic_security_ops; +static int num_backends; + +static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) { int i; - for (i=0; generic_security_ops[i]; i++) { + for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->auth_type == auth_type) { return generic_security_ops[i]; } @@ -71,10 +39,10 @@ const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) return NULL; } -const struct gensec_security_ops *gensec_security_by_oid(const char *oid) +static const struct gensec_security_ops *gensec_security_by_oid(const char *oid) { int i; - for (i=0; generic_security_ops[i]; i++) { + for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->oid && (strcmp(generic_security_ops[i]->oid, oid) == 0)) { return generic_security_ops[i]; @@ -84,10 +52,10 @@ const struct gensec_security_ops *gensec_security_by_oid(const char *oid) return NULL; } -const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) +static const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) { int i; - for (i=0; generic_security_ops[i]; i++) { + for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->sasl_name && (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) { return generic_security_ops[i]; @@ -97,8 +65,359 @@ const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_ return NULL; } -const struct gensec_security_ops **gensec_security_all(void) +static const struct gensec_security_ops *gensec_security_by_name(const char *name) +{ + int i; + for (i=0; i < num_backends; i++) { + if (generic_security_ops[i]->name + && (strcmp(generic_security_ops[i]->name, name) == 0)) { + return generic_security_ops[i]; + } + } + + return NULL; +} + +const struct gensec_security_ops **gensec_security_all(int *num_backends_out) { + *num_backends_out = num_backends; return generic_security_ops; } +static NTSTATUS gensec_start(struct gensec_security **gensec_security) +{ + TALLOC_CTX *mem_ctx; + /* awaiting a correct fix from metze */ + if (!gensec_init()) { + return NT_STATUS_INTERNAL_ERROR; + } + + mem_ctx = talloc_init("gensec_security struct"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); + if (!(*gensec_security)) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*gensec_security)->mem_ctx = mem_ctx; + (*gensec_security)->ops = NULL; + + return NT_STATUS_OK; +} + +NTSTATUS gensec_client_start(struct gensec_security **gensec_security) +{ + NTSTATUS status; + status = gensec_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + (*gensec_security)->gensec_role = GENSEC_CLIENT; + (*gensec_security)->password_callback = NULL; + + ZERO_STRUCT((*gensec_security)->user); + + return status; +} + +NTSTATUS gensec_server_start(struct gensec_security **gensec_security) +{ + NTSTATUS status; + status = gensec_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + (*gensec_security)->gensec_role = GENSEC_SERVER; + + return status; +} + +static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) +{ + NTSTATUS status; + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + if (gensec_security->ops->client_start) { + status = gensec_security->ops->client_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Faild to start GENSEC client mech %s: %s\n", + gensec_security->ops->name, nt_errstr(status))); + } + return status; + } + case GENSEC_SERVER: + if (gensec_security->ops->server_start) { + status = gensec_security->ops->server_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Faild to start GENSEC server mech %s: %s\n", + gensec_security->ops->name, nt_errstr(status))); + } + return status; + } + } + return NT_STATUS_INVALID_PARAMETER; +} + +NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, + uint8_t authtype) +{ + gensec_security->ops = gensec_security_by_authtype(authtype); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for authtype=%d\n", (int)authtype)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + +NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, + const char *mech_oid) +{ + gensec_security->ops = gensec_security_by_oid(mech_oid); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + +NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, + const char *sasl_name) +{ + gensec_security->ops = gensec_security_by_sasl_name(sasl_name); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + +/* + wrappers for the gensec function pointers +*/ +NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig) +{ + return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const DATA_BLOB *sig) +{ + return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) +{ + return gensec_security->ops->session_key(gensec_security, session_key); +} + +NTSTATUS gensec_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info) +{ + return gensec_security->ops->session_info(gensec_security, session_info); +} + +/** + * Next state function for the GENSEC state machine + * + * @param gensec_security GENSEC State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + return gensec_security->ops->update(gensec_security, out_mem_ctx, in, out); +} + +void gensec_end(struct gensec_security **gensec_security) +{ + if ((*gensec_security)->ops) { + (*gensec_security)->ops->end(*gensec_security); + } + (*gensec_security)->private_data = NULL; + talloc_destroy((*gensec_security)->mem_ctx); + + gensec_security = NULL; +} + +/** + * Set a username on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) +{ + gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, user); + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a domain on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain) +{ + gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, domain); + if (!gensec_security->user.domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will + * not do a callback + * + */ + +NTSTATUS gensec_set_password(struct gensec_security *gensec_security, + const char *password) +{ + gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); + if (!gensec_security->user.password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a password callback, if the gensec module we use demands a password + */ + +void gensec_set_password_callback(struct gensec_security *gensec_security, + gensec_password_callback callback, void *callback_private_data) +{ + gensec_security->password_callback = callback; + gensec_security->password_callback_private = callback_private_data; +} + +/** + * Get (or call back for) a password. + */ + +NTSTATUS gensec_get_password(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + char **password) +{ + if (gensec_security->user.password) { + *password = talloc_strdup(mem_ctx, gensec_security->user.password); + if (!*password) { + return NT_STATUS_NO_MEMORY; + } else { + return NT_STATUS_OK; + } + } + if (!gensec_security->password_callback) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->password_callback(gensec_security, mem_ctx, password); +} + +/* + register a GENSEC backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. +*/ +static NTSTATUS gensec_register(const void *_ops) +{ + const struct gensec_security_ops *ops = _ops; + + if (gensec_security_by_name(ops->name) != NULL) { + /* its already registered! */ + DEBUG(0,("GENSEC backend '%s' already registered\n", + ops->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + generic_security_ops = Realloc(generic_security_ops, sizeof(generic_security_ops[0]) * (num_backends+1)); + if (!generic_security_ops) { + smb_panic("out of memory in gensec_register"); + } + + generic_security_ops[num_backends] = ops; + + num_backends++; + + DEBUG(3,("GENSEC backend '%s' registered\n", + ops->name)); + + return NT_STATUS_OK; +} + +/* + return the GENSEC interface version, and the size of some critical types + This can be used by backends to either detect compilation errors, or provide + multiple implementations for different smbd compilation options in one module +*/ +const struct gensec_critical_sizes *gensec_interface_version(void) +{ + static const struct gensec_critical_sizes critical_sizes = { + GENSEC_INTERFACE_VERSION, + sizeof(struct gensec_security_ops), + sizeof(struct gensec_security), + }; + + return &critical_sizes; +} + +/* + initialise the GENSEC subsystem +*/ +BOOL gensec_init(void) +{ + static BOOL initialised; + NTSTATUS status; + + /* this is *completly* the wrong way to do this */ + if (initialised) { + return True; + } + + status = register_subsystem("gensec", gensec_register); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + /* FIXME: Perhaps panic if a basic backend, such as NTLMSSP, fails to initialise? */ + gensec_ntlmssp_init(); + gensec_spengo_init(); + gensec_dcerpc_schannel_init(); + + initialised = True; + DEBUG(3,("GENSEC subsystem version %d initialised\n", GENSEC_INTERFACE_VERSION)); + return True; +} diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 2a469e0f57..463b484a7f 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -27,6 +27,7 @@ struct gensec_user { const char *domain; const char *name; const char *password; + char schan_session_key[16]; }; /* GENSEC mode */ enum gensec_role @@ -38,27 +39,47 @@ enum gensec_role struct gensec_security_ops { const char *name; const char *sasl_name; - uint8 auth_type; + uint8 auth_type; /* 0 if not offered on DCE-RPC */ const char *oid; /* NULL if not offered by SPENGO */ NTSTATUS (*client_start)(struct gensec_security *gensec_security); NTSTATUS (*server_start)(struct gensec_security *gensec_security); NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out); - NTSTATUS (*seal)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig); - NTSTATUS (*sign)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + NTSTATUS (*sign_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig); - NTSTATUS (*check_sig)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, const DATA_BLOB *sig); - NTSTATUS (*unseal)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig); + NTSTATUS (*check_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + const uint8_t *data, size_t length, const DATA_BLOB *sig); + NTSTATUS (*unseal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig); NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); + NTSTATUS (*session_info)(struct gensec_security *gensec_security, + struct auth_session_info **session_info); void (*end)(struct gensec_security *gensec_security); }; +typedef NTSTATUS (*gensec_password_callback)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, + char **password); + +#define GENSEC_INTERFACE_VERSION 0 + struct gensec_security { - struct gensec_user user; - void *private_data; + TALLOC_CTX *mem_ctx; + gensec_password_callback password_callback; + void *password_callback_private; const struct gensec_security_ops *ops; + void *private_data; + struct gensec_user user; + enum gensec_role gensec_role; }; +/* this structure is used by backends to determine the size of some critical types */ +struct gensec_critical_sizes { + int interface_version; + int sizeof_gensec_security_ops; + int sizeof_gensec_security; +}; + + + diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index f7e9dddd2f..9f7c4c6f86 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -23,33 +23,220 @@ #include "includes.h" +struct gensec_ntlmssp_state { + TALLOC_CTX *mem_ctx; + struct auth_context *auth_context; + struct auth_serversupplied_info *server_info; + struct ntlmssp_state *ntlmssp_state; +}; -NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) + +/** + * Return the challenge as determined by the authentication subsystem + * @return an 8 byte random challenge + */ + +static const uint8_t *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + + return gensec_ntlmssp_state->auth_context->get_ntlm_challenge(gensec_ntlmssp_state->auth_context); +} + +/** + * Some authentication methods 'fix' the challenge, so we may not be able to set it + * + * @return If the effective challenge used by the auth subsystem may be modified + */ +static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + + return gensec_ntlmssp_state->auth_context->challenge_may_be_modified; +} + +/** + * NTLM2 authentication modifies the effective challenge, + * @param challenge The new challenge value + */ +static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + struct auth_context *auth_context = gensec_ntlmssp_state->auth_context; + + SMB_ASSERT(challenge->length == 8); + + auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, + challenge->data, challenge->length); + + auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)"; + + DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by)); + DEBUG(5, ("challenge is: \n")); + dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length); + return NT_STATUS_OK; +} + +/** + * Check the password on an NTLMSSP login. + * + * Return the session keys used on the connection. + */ + +static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + struct auth_usersupplied_info *user_info = NULL; + NTSTATUS nt_status; + +#if 0 + /* the client has given us its machine name (which we otherwise would not get on port 445). + we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ + + set_remote_machine_name(gensec_ntlmssp_state->ntlmssp_state->workstation, True); + + /* setup the string used by %U */ + /* sub_set_smb_name checks for weird internally */ + sub_set_smb_name(gensec_ntlmssp_state->ntlmssp_state->user); + + reload_services(True); + +#endif + nt_status = make_user_info_map(&user_info, + gensec_ntlmssp_state->ntlmssp_state->user, + gensec_ntlmssp_state->ntlmssp_state->domain, + gensec_ntlmssp_state->ntlmssp_state->workstation, + gensec_ntlmssp_state->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->lm_resp : NULL, + gensec_ntlmssp_state->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->nt_resp : NULL, + NULL, NULL, NULL, + True); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + nt_status = gensec_ntlmssp_state->auth_context->check_ntlm_password(gensec_ntlmssp_state->auth_context, + user_info, &gensec_ntlmssp_state->server_info); + + free_user_info(&user_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + if (gensec_ntlmssp_state->server_info->user_session_key.length) { + DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length)); + *user_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + gensec_ntlmssp_state->server_info->user_session_key.data, + gensec_ntlmssp_state->server_info->user_session_key.length); + } + if (gensec_ntlmssp_state->server_info->lm_session_key.length) { + DEBUG(10, ("Got LM session key of length %u\n", gensec_ntlmssp_state->server_info->lm_session_key.length)); + *lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + gensec_ntlmssp_state->server_info->lm_session_key.data, + gensec_ntlmssp_state->server_info->lm_session_key.length); + } + return nt_status; +} + +static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state; + + TALLOC_CTX *mem_ctx = talloc_init("gensec_ntlmssp"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + gensec_ntlmssp_state = talloc_p(mem_ctx, struct gensec_ntlmssp_state); + if (!gensec_ntlmssp_state) { + return NT_STATUS_NO_MEMORY; + } + + gensec_ntlmssp_state->mem_ctx = mem_ctx; + gensec_ntlmssp_state->ntlmssp_state = NULL; + gensec_ntlmssp_state->auth_context = NULL; + gensec_ntlmssp_state->server_info = NULL; + + gensec_security->private_data = gensec_ntlmssp_state; + return NT_STATUS_OK; +} + +static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + NTSTATUS status; + struct ntlmssp_state *ntlmssp_state; + struct gensec_ntlmssp_state *gensec_ntlmssp_state; + + status = gensec_ntlmssp_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + gensec_ntlmssp_state = gensec_security->private_data; + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&gensec_ntlmssp_state->ntlmssp_state))) { + return nt_status; + } + + ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) { + return nt_status; + } + + ntlmssp_state->auth_context = gensec_ntlmssp_state; + ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; + ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; + ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; + ntlmssp_state->check_password = auth_ntlmssp_check_password; + ntlmssp_state->server_role = lp_server_role(); + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) { - struct ntlmssp_state *ntlmssp_state = NULL; + struct gensec_ntlmssp_state *gensec_ntlmssp_state; + char *password = NULL; + NTSTATUS status; + status = gensec_ntlmssp_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - status = ntlmssp_client_start(&ntlmssp_state); + gensec_ntlmssp_state = gensec_security->private_data; + status = ntlmssp_client_start(&gensec_ntlmssp_state->ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { return status; } - status = ntlmssp_set_domain(ntlmssp_state, gensec_security->user.domain); + status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, + gensec_security->user.domain); if (!NT_STATUS_IS_OK(status)) { return status; } - status = ntlmssp_set_username(ntlmssp_state, gensec_security->user.name); + status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, + gensec_security->user.name); if (!NT_STATUS_IS_OK(status)) { return status; } - status = ntlmssp_set_password(ntlmssp_state, gensec_security->user.password); + status = gensec_get_password(gensec_security, gensec_ntlmssp_state->mem_ctx, &password); if (!NT_STATUS_IS_OK(status)) { return status; } - - gensec_security->private_data = ntlmssp_state; + + if (password) { + status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, + password); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + gensec_security->private_data = gensec_ntlmssp_state; return status; } @@ -57,66 +244,154 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) /* wrappers for the ntlmssp_*() functions */ -NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_unseal_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, const DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_check_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_seal_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_sign_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_session_key(ntlmssp_state, session_key); + return ntlmssp_session_key(gensec_ntlmssp_state->ntlmssp_state, session_key); } -NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, +/** + * Next state function for the wrapped NTLMSSP state machine + * + * @param gensec_ntlmssp_state NTLMSSP State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + + return ntlmssp_update(gensec_ntlmssp_state->ntlmssp_state, out_mem_ctx, in, out); +} + +/** + * Return the credentials of a logged on user, including session keys + * etc. + * + * Only valid after a successful authentication + * + * May only be called once per authentication. + * + */ + +static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info) +{ + NTSTATUS nt_status; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + nt_status = make_session_info(gensec_ntlmssp_state->server_info, session_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + /* the session_info owns this now */ + gensec_ntlmssp_state->server_info = NULL; + + (*session_info)->session_key = data_blob_talloc((*session_info)->mem_ctx, + gensec_ntlmssp_state->ntlmssp_state->session_key.data, + gensec_ntlmssp_state->ntlmssp_state->session_key.length); + + (*session_info)->workstation = talloc_strdup((*session_info)->mem_ctx, + gensec_ntlmssp_state->ntlmssp_state->workstation); - return ntlmssp_update(ntlmssp_state, out_mem_ctx, in, out); + return NT_STATUS_OK; } -void gensec_ntlmssp_end(struct gensec_security *gensec_security) +static void gensec_ntlmssp_end(struct gensec_security *gensec_security) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - ntlmssp_end(&ntlmssp_state); + if (gensec_ntlmssp_state->ntlmssp_state) { + ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state); + } + if (gensec_ntlmssp_state->auth_context) { + free_auth_context(&gensec_ntlmssp_state->auth_context); + } + if (gensec_ntlmssp_state->server_info) { + free_server_info(&gensec_ntlmssp_state->server_info); + } + talloc_destroy(gensec_ntlmssp_state->mem_ctx); gensec_security->private_data = NULL; } + +static const struct gensec_security_ops gensec_ntlmssp_security_ops = { + .name = "ntlmssp", + .sasl_name = "NTLM", + .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, + .oid = OID_NTLMSSP, + .client_start = gensec_ntlmssp_client_start, + .server_start = gensec_ntlmssp_server_start, + .update = gensec_ntlmssp_update, + .seal_packet = gensec_ntlmssp_seal_packet, + .sign_packet = gensec_ntlmssp_sign_packet, + .check_packet = gensec_ntlmssp_check_packet, + .unseal_packet = gensec_ntlmssp_unseal_packet, + .session_key = gensec_ntlmssp_session_key, + .session_info = gensec_ntlmssp_session_info, + .end = gensec_ntlmssp_end +}; + + +NTSTATUS gensec_ntlmssp_init(void) +{ + NTSTATUS ret; + ret = register_backend("gensec", &gensec_ntlmssp_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_ntlmssp_security_ops.name)); + return ret; + } + + /* ugly cludge, but we need the auth subsystem for this to work */ + auth_init(); + + return ret; +} diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index d680da9495..80ce1cccc0 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -160,8 +160,6 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat return NT_STATUS_NO_MEMORY; } - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 321b13afdc..bb9d2504ac 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -27,7 +27,25 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) +enum spnego_state_position { + SPNEGO_SERVER_START, + SPNEGO_CLIENT_GET_MECHS, + SPNEGO_CLIENT_SEND_MECHS, + SPNEGO_TARG, + SPNEGO_FALLBACK, + SPNEGO_DONE +}; + +struct spnego_state { + TALLOC_CTX *mem_ctx; + uint_t ref_count; + enum spnego_message_type expected_packet; + enum spnego_message_type state_position; + negResult_t result; + struct gensec_security *sub_sec_security; +}; + +static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; TALLOC_CTX *mem_ctx = talloc_init("gensec_spengo_client_start"); @@ -40,11 +58,11 @@ NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) return NT_STATUS_NO_MEMORY; } - spnego_state->role = SPNEGO_CLIENT; spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_CLIENT_GET_MECHS; spnego_state->result = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->mem_ctx = mem_ctx; + spnego_state->sub_sec_security = NULL; gensec_security->private_data = spnego_state; return NT_STATUS_OK; @@ -53,9 +71,9 @@ NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) /* wrappers for the spnego_*() functions */ -NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig) +static NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -64,11 +82,11 @@ NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->unseal(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_unseal_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, const DATA_BLOB *sig) @@ -81,11 +99,11 @@ NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->check_sig(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_check_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) @@ -98,11 +116,11 @@ NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->seal(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_seal_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig) @@ -114,11 +132,11 @@ NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->sign(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_sign_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -127,11 +145,11 @@ NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->session_key(&spnego_state->sub_sec_security, - session_key); + return gensec_session_key(spnego_state->sub_sec_security, + session_key); } -NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, +static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -139,7 +157,6 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT DATA_BLOB unwrapped_out; struct spnego_data spnego_out; struct spnego_data spnego; - const struct gensec_security_ops *op; ssize_t len; @@ -148,32 +165,38 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } if (spnego_state->state_position == SPNEGO_FALLBACK) { - return spnego_state->sub_sec_security.ops->update(&spnego_state->sub_sec_security, - out_mem_ctx, in, out); + return gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, in, out); } len = spnego_read_data(in, &spnego); if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { int i; - const struct gensec_security_ops **all_ops = gensec_security_all(); - for (i=0; all_ops[i]; i++) { + int num_ops; + const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); + for (i=0; i < num_ops; i++) { NTSTATUS nt_status; - op = all_ops[i]; - if (!op->oid) { + if (!all_ops[i]->oid) { continue; } - nt_status = op->server_start(&spnego_state->sub_sec_security); + nt_status = gensec_server_start(&spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + all_ops[i]->oid); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); continue; } - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, in, out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, in, out); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { spnego_state->state_position = SPNEGO_FALLBACK; return nt_status; } - op->end(&spnego_state->sub_sec_security); + gensec_end(&spnego_state->sub_sec_security); } DEBUG(1, ("Failed to parse SPENGO request\n")); return NT_STATUS_INVALID_PARAMETER; @@ -196,33 +219,33 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT NTSTATUS nt_status; for (i=0; mechType[i]; i++) { - op = gensec_security_by_oid(mechType[i]); - if (!op) { - continue; + nt_status = gensec_client_start(&spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + break; } - spnego_state->sub_sec_security.ops = op; - spnego_state->sub_sec_security.user = gensec_security->user; - - nt_status = op->client_start(&spnego_state->sub_sec_security); + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechType[i]); if (!NT_STATUS_IS_OK(nt_status)) { - op->end(&spnego_state->sub_sec_security); + gensec_end(&spnego_state->sub_sec_security); continue; } + if (i == 0) { - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenInit.mechToken, - &unwrapped_out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenInit.mechToken, + &unwrapped_out); } else { /* only get the helping start blob for the first OID */ - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - &unwrapped_out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + &unwrapped_out); } if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", op->name, nt_errstr(nt_status))); - op->end(&spnego_state->sub_sec_security); + DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + gensec_end(&spnego_state->sub_sec_security); } else { break; } @@ -237,7 +260,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } /* compose reply */ - my_mechs[0] = op->oid; + my_mechs[0] = spnego_state->sub_sec_security->ops->oid; spnego_out.type = SPNEGO_NEG_TOKEN_INIT; spnego_out.negTokenInit.mechTypes = my_mechs; @@ -261,12 +284,11 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT return NT_STATUS_ACCESS_DENIED; } - op = spnego_state->sub_sec_security.ops; if (spnego.negTokenTarg.responseToken.length) { - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); } else { unwrapped_out = data_blob(NULL, 0); nt_status = NT_STATUS_OK; @@ -284,7 +306,9 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_out.negTokenTarg.supportedMech = op->oid; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; +; spnego_out.negTokenTarg.responseToken = unwrapped_out; spnego_out.negTokenTarg.mechListMIC = null_data_blob; @@ -296,7 +320,9 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } else if (NT_STATUS_IS_OK(nt_status)) { spnego_state->state_position = SPNEGO_DONE; } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", op->name, nt_errstr(nt_status))); + DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); return nt_status; } @@ -309,13 +335,42 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } } -void gensec_spnego_end(struct gensec_security *gensec_security) +static void gensec_spnego_end(struct gensec_security *gensec_security) { struct spnego_state *spnego_state = gensec_security->private_data; - - spnego_state->sub_sec_security.ops->end(&spnego_state->sub_sec_security); + + if (spnego_state->sub_sec_security) { + gensec_end(&spnego_state->sub_sec_security); + } talloc_destroy(spnego_state->mem_ctx); gensec_security->private_data = NULL; } + +static const struct gensec_security_ops gensec_spnego_security_ops = { + .name = "spnego", + .sasl_name = "GSS-SPNEGO", + .oid = OID_SPNEGO, + .client_start = gensec_spnego_client_start, + .update = gensec_spnego_update, + .seal_packet = gensec_spnego_seal_packet, + .sign_packet = gensec_spnego_sign_packet, + .check_packet = gensec_spnego_check_packet, + .unseal_packet = gensec_spnego_unseal_packet, + .session_key = gensec_spnego_session_key, + .end = gensec_spnego_end +}; + +NTSTATUS gensec_spengo_init(void) +{ + NTSTATUS ret; + ret = register_backend("gensec", &gensec_spnego_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_spnego_security_ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index 890301314b..60ef4c1d36 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -23,12 +23,6 @@ #ifndef SAMBA_SPNEGO_H #define SAMBA_SPNEGO_H -/* SPNEGO mode */ -enum spnego_role -{ - SPNEGO_SERVER, - SPNEGO_CLIENT -}; #define SPNEGO_DELEG_FLAG 0x01 #define SPNEGO_MUTUAL_FLAG 0x02 @@ -70,23 +64,4 @@ enum spnego_message_type { SPNEGO_NEG_TOKEN_TARG = 1, }; -enum spnego_state_position { - SPNEGO_SERVER_START, - SPNEGO_CLIENT_GET_MECHS, - SPNEGO_CLIENT_SEND_MECHS, - SPNEGO_TARG, - SPNEGO_FALLBACK, - SPNEGO_DONE -}; - -struct spnego_state { - TALLOC_CTX *mem_ctx; - uint_t ref_count; - enum spnego_role role; - enum spnego_message_type expected_packet; - enum spnego_message_type state_position; - negResult_t result; - struct gensec_security sub_sec_security; -}; - #endif diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 992f84005d..9e19499003 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -54,7 +54,8 @@ SMB_SUBSYSTEM(LIBCLI_AUTH,[], libcli/auth/kerberos_verify.o libcli/auth/clikrb5.o libcli/auth/gensec.o - libcli/auth/gensec_ntlmssp.o]) + libcli/auth/gensec_ntlmssp.o], + [], [AUTH SCHANNELDB]) SMB_SUBSYSTEM(LIBCLI_NMB,[], [libcli/unexpected.o -- cgit From 0fa0eaa3837551bb04fd850d78633cc08a3dbdcc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jul 2004 20:33:17 +0000 Subject: r1342: When fixing _lsa_lookupsids in samba3 I wanted to find out the number of SIDs w2k3 can handle in a single request. With the samba3 client rpc libs I can do about 21000 SIDs in a single request. test_many_LookupSIDs with 10000 SIDs fails on the subsequent request with a NET_WRITE_FAULT. Maybe the Samba4 DCE people want to take a look at this -- I don't see the problem. Bug fix: SID components should be treated as unsigned when parsing Volker (This used to be commit 8c997a2ad2e89a640f854b556ef76a3d52c15963) --- source4/libcli/util/dom_sid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index 9b8b45e302..0ca4cd731f 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -79,7 +79,7 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) return NULL; } sidstr++; - ret->sub_auths[i] = strtol(sidstr, &p, 10); + ret->sub_auths[i] = strtoul(sidstr, &p, 10); if (p == sidstr) { return NULL; } -- cgit From 8bebc53df8ff46e801ed1258206126f6ebe9a1c3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 Jul 2004 23:26:07 +0000 Subject: r1344: add gensec_start_mech_by_name() some gensec spnego fixes (NULL pointer and length checks) metze (This used to be commit 41ff6d0cd47f6295fe7fe1d31fec7306416ce199) --- source4/libcli/auth/gensec.c | 11 ++ source4/libcli/auth/spnego.c | 238 ++++++++++++++++++++++--------------------- source4/libcli/auth/spnego.h | 4 +- 3 files changed, 137 insertions(+), 116 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index f6d6db9e62..8ece7c76dc 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -162,6 +162,17 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) return NT_STATUS_INVALID_PARAMETER; } +NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security, + const char *name) +{ + gensec_security->ops = gensec_security_by_name(name); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for name=%s\n", name)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, uint8_t authtype) { diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index bb9d2504ac..eb1ed15368 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -41,7 +41,7 @@ struct spnego_state { uint_t ref_count; enum spnego_message_type expected_packet; enum spnego_message_type state_position; - negResult_t result; + enum spnego_negResult result; struct gensec_security *sub_sec_security; }; @@ -169,9 +169,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA out_mem_ctx, in, out); } - len = spnego_read_data(in, &spnego); - - if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { + if (spnego_state->state_position == SPNEGO_SERVER_START) { int i; int num_ops; const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); @@ -198,140 +196,152 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } gensec_end(&spnego_state->sub_sec_security); } + DEBUG(1, ("Failed to start SPENGO SERVER\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + len = spnego_read_data(in, &spnego); + if (len == -1) { DEBUG(1, ("Failed to parse SPENGO request\n")); return NT_STATUS_INVALID_PARAMETER; - } else { + } - if (spnego.type != spnego_state->expected_packet) { - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, - spnego_state->expected_packet)); - return NT_STATUS_INVALID_PARAMETER; - } + if (spnego.type != spnego_state->expected_packet) { + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + spnego_state->expected_packet)); + return NT_STATUS_INVALID_PARAMETER; + } - if (spnego_state->state_position == SPNEGO_CLIENT_GET_MECHS) { + if (spnego_state->state_position == SPNEGO_CLIENT_GET_MECHS) { - /* The server offers a list of mechanisms */ - - char **mechType = spnego.negTokenInit.mechTypes; - char *my_mechs[] = {NULL, NULL}; - int i; - NTSTATUS nt_status; - - for (i=0; mechType[i]; i++) { - nt_status = gensec_client_start(&spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - break; - } - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechType[i]); - if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); - continue; - } - - if (i == 0) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenInit.mechToken, - &unwrapped_out); - } else { - /* only get the helping start blob for the first OID */ - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - &unwrapped_out); - } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", - spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - gensec_end(&spnego_state->sub_sec_security); - } else { - break; - } - } - if (!mechType[i]) { - DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); - } + /* The server offers a list of mechanisms */ + + char **mechType = spnego.negTokenInit.mechTypes; + char *my_mechs[] = {NULL, NULL}; + int i; + NTSTATUS nt_status; - spnego_free_data(&spnego); - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return nt_status; - } - - /* compose reply */ - my_mechs[0] = spnego_state->sub_sec_security->ops->oid; + spnego_state->sub_sec_security = NULL; - spnego_out.type = SPNEGO_NEG_TOKEN_INIT; - spnego_out.negTokenInit.mechTypes = my_mechs; - spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = null_data_blob; - spnego_out.negTokenInit.mechToken = unwrapped_out; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; + for (i=0; mechType && mechType[i]; i++) { + nt_status = gensec_client_start(&spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + break; } - - /* set next state */ - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_TARG; - - return nt_status; - } else if (spnego_state->state_position == SPNEGO_TARG) { - NTSTATUS nt_status; - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - return NT_STATUS_ACCESS_DENIED; + /* forward the user info to the sub context */ + spnego_state->sub_sec_security->user = gensec_security->user; + spnego_state->sub_sec_security->password_callback = gensec_security->password_callback; + spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; + /* select the sub context */ + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechType[i]); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); + continue; } - if (spnego.negTokenTarg.responseToken.length) { + if (i == 0) { nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, - spnego.negTokenTarg.responseToken, + spnego.negTokenInit.mechToken, &unwrapped_out); } else { - unwrapped_out = data_blob(NULL, 0); - nt_status = NT_STATUS_OK; + /* only get the helping start blob for the first OID */ + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + &unwrapped_out); } - - if (NT_STATUS_IS_OK(nt_status) - && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { - nt_status = NT_STATUS_INVALID_PARAMETER; + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + gensec_end(&spnego_state->sub_sec_security); + } else { + break; } + } + if (!spnego_state->sub_sec_security) { + DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + spnego_free_data(&spnego); + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return nt_status; + } + + /* compose reply */ + my_mechs[0] = spnego_state->sub_sec_security->ops->oid; + + spnego_out.type = SPNEGO_NEG_TOKEN_INIT; + spnego_out.negTokenInit.mechTypes = my_mechs; + spnego_out.negTokenInit.reqFlags = 0; + spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechToken = unwrapped_out; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* set next state */ + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->state_position = SPNEGO_TARG; + + return nt_status; + } else if (spnego_state->state_position == SPNEGO_TARG) { + NTSTATUS nt_status; + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { + return NT_STATUS_ACCESS_DENIED; + } + + if (spnego.negTokenTarg.responseToken.length) { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + } else { + unwrapped_out = data_blob(NULL, 0); + nt_status = NT_STATUS_OK; + } + + if (NT_STATUS_IS_OK(nt_status) + && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + nt_status = NT_STATUS_INVALID_PARAMETER; + } - spnego_state->result = spnego.negTokenTarg.negResult; - spnego_free_data(&spnego); + spnego_state->result = spnego.negTokenTarg.negResult; + spnego_free_data(&spnego); + + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* compose reply */ + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; -; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; } - spnego_state->state_position = SPNEGO_TARG; - } else if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->state_position = SPNEGO_DONE; - } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); - return nt_status; - } - - return nt_status; + spnego_state->state_position = SPNEGO_TARG; + } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->state_position = SPNEGO_DONE; } else { - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); - return NT_STATUS_INVALID_PARAMETER; + DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); + return nt_status; } + + return nt_status; + } else { + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); + return NT_STATUS_INVALID_PARAMETER; } } diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index 60ef4c1d36..eba98c5218 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -33,11 +33,11 @@ #define SPNEGO_INTEG_FLAG 0x40 #define SPNEGO_REQ_FLAG 0x80 -typedef enum _spnego_negResult { +enum spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, SPNEGO_REJECT = 2 -} negResult_t; +}; struct spnego_negTokenInit { char **mechTypes; -- cgit From 4f0e5e069064c11a8efc407cd42412d38534d0d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 Jul 2004 23:28:49 +0000 Subject: r1345: add extended security spnego support to the smb client code set lp_use_spnego = False, because I can't get it working yet but I commit it so others can help me metze (This used to be commit 2445cceba9ab9bd928c8bc50927a39509e4526b0) --- source4/libcli/raw/clisession.c | 111 ++++++++++++++++++++++++++++++++++++-- source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/clitree.c | 4 +- source4/libcli/raw/rawnegotiate.c | 47 +++++++++++----- source4/libcli/raw/smb_signing.c | 50 +++++++++++++++++ 5 files changed, 194 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 780ff5837b..7ff5db59c3 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -121,10 +121,12 @@ struct cli_request *smb_raw_session_setup_send(struct cli_session *session, unio SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num); SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey); SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length); + SIVAL(req->out.vwv, VWV(8), 0); /* reserved */ SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities); cli_req_append_blob(req, &parms->spnego.in.secblob); cli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE); cli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); + cli_req_append_string(req, parms->spnego.in.domain, STR_TERMINATE); break; } @@ -369,6 +371,109 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, return NT_STATUS_OK; } +/**************************************************************************** + Perform a session setup (sync interface) using generic interface and the SPNEGO + style sesssetup call +****************************************************************************/ +static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session, + TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) +{ + NTSTATUS status; + union smb_sesssetup s2; + + s2.generic.level = RAW_SESSSETUP_SPNEGO; + s2.spnego.in.bufsize = ~0; + s2.spnego.in.mpx_max = 50; + s2.spnego.in.vc_num = 1; + s2.spnego.in.sesskey = parms->generic.in.sesskey; + s2.spnego.in.capabilities = parms->generic.in.capabilities; + s2.spnego.in.domain = parms->generic.in.domain; + s2.spnego.in.os = "Unix"; + s2.spnego.in.lanman = "Samba"; + + cli_temp_set_signing(session->transport); + + status = gensec_client_start(&session->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); + goto done; + } + + status = gensec_set_domain(session->gensec, parms->generic.in.domain); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", + parms->generic.in.domain, nt_errstr(status))); + goto done; + } + + status = gensec_set_username(session->gensec, parms->generic.in.user); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", + parms->generic.in.user, nt_errstr(status))); + goto done; + } + + status = gensec_set_password(session->gensec, parms->generic.in.password); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_start_mech_by_name(session->gensec, "spnego"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_update(session->gensec, mem_ctx, + session->transport->negotiate.secblob, + &s2.spnego.in.secblob); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto done; + } + + while(1) { + status = smb_raw_session_setup(session, mem_ctx, &s2); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto done; + } + + status = gensec_update(session->gensec, mem_ctx, + s2.spnego.out.secblob, + &s2.spnego.in.secblob); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto done; + } + } + +done: + if (NT_STATUS_IS_OK(status)) { + DATA_BLOB null_data_blob = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + + status = gensec_session_key(session->gensec, &session_key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + cli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + + cli_session_set_user_session_key(session, &session_key); + + parms->generic.out.vuid = s2.spnego.out.vuid; + parms->generic.out.os = s2.spnego.out.os; + parms->generic.out.lanman = s2.spnego.out.lanman; + parms->generic.out.domain = s2.spnego.out.domain; + } + + return status; +} /**************************************************************************** Perform a session setup (sync interface) using generic interface @@ -389,14 +494,12 @@ static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, } /* see if we should use the NT1 interface */ - if (!(session->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) || - !session->transport->options.use_spnego) { + if (!(session->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY)) { return smb_raw_session_setup_generic_nt1(session, mem_ctx, parms); } /* default to using SPNEGO/NTLMSSP */ - DEBUG(0,("Need to add client SPNEGO code back in\n")); - return NT_STATUS_UNSUCCESSFUL; + return smb_raw_session_setup_generic_spnego(session, mem_ctx, parms); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 1e9032459f..a378ac8aad 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -38,6 +38,7 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) transport->mem_ctx = mem_ctx; transport->socket = sock; transport->negotiate.protocol = PROTOCOL_NT1; + transport->options.use_spnego = lp_use_spnego(); transport->negotiate.max_xmit = ~0; cli_null_set_signing(transport); transport->socket->reference_count++; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index b35bf67c94..3b16c4c336 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -235,9 +235,7 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, /* prepare a session setup to establish a security context */ setup.generic.level = RAW_SESSSETUP_GENERIC; setup.generic.in.sesskey = transport->negotiate.sesskey; - setup.generic.in.capabilities = CAP_UNICODE | CAP_STATUS32 | - CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | - CAP_W2K_SMBS | CAP_LARGE_READX | CAP_LARGE_WRITEX; + setup.generic.in.capabilities = transport->negotiate.capabilities; if (!user || !user[0]) { setup.generic.in.password = NULL; setup.generic.in.user = ""; diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 5b94ef63d8..6bf35fb26d 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -32,6 +32,7 @@ static const struct { {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2,"LANMAN2.1"}, {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, @@ -44,12 +45,25 @@ struct cli_request *smb_negprot_send(struct cli_transport *transport, int maxpro { struct cli_request *req; int i; + uint16_t flags2 = 0; req = cli_request_setup_transport(transport, SMBnegprot, 0, 0); if (!req) { return NULL; } + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + flags2 |= FLAGS2_UNICODE_STRINGS; + flags2 |= FLAGS2_EXTENDED_ATTRIBUTES; + flags2 |= FLAGS2_LONG_PATH_COMPONENTS; + flags2 |= FLAGS2_IS_LONG_NAME; + + if (transport->options.use_spnego) { + flags2 |= FLAGS2_EXTENDED_SECURITY; + } + + SSVAL(req->out.hdr,HDR_FLG2, flags2); + /* setup the protocol strings */ for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) { cli_req_append_bytes(req, "\2", 1); @@ -102,26 +116,35 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) transport->negotiate.max_mux = SVAL(req->in.vwv,VWV(1)+1); transport->negotiate.max_xmit = IVAL(req->in.vwv,VWV(3)+1); transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(7)+1); - transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60; + transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); /* this time arrives in real GMT */ ntt = cli_pull_nttime(req->in.vwv, VWV(11)+1); - transport->negotiate.server_time = nt_time_to_unix(ntt); - transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); + transport->negotiate.server_time = nt_time_to_unix(ntt); + transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60; + transport->negotiate.key_len = CVAL(req->in.vwv,VWV(16)+1); + + if (transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) { + if (req->in.data_size < 16) { + goto failed; + } + transport->negotiate.server_guid = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, 16); + transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data + 16, req->in.data_size - 16); + } else { + if (req->in.data_size < (transport->negotiate.key_len)) { + goto failed; + } + transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, transport->negotiate.key_len); + cli_req_pull_string(req, transport->mem_ctx, &transport->negotiate.server_domain, + req->in.data+transport->negotiate.key_len, + req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN); + /* here comes the server name */ + } - transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, req->in.data_size); if (transport->negotiate.capabilities & CAP_RAW_MODE) { transport->negotiate.readbraw_supported = True; transport->negotiate.writebraw_supported = True; } - - /* work out if they sent us a workgroup */ - if ((transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) && - req->in.data_size > 16) { - cli_req_pull_string(req, transport->mem_ctx, &transport->negotiate.server_domain, - req->in.data+16, - req->in.data_size-16, STR_UNICODE|STR_NOALIGN); - } } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) { CLI_CHECK_WCT(req, 13); transport->negotiate.sec_mode = SVAL(req->in.vwv,VWV(1)); diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index a39f33c290..20b44a5348 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -299,6 +299,56 @@ BOOL cli_null_set_signing(struct cli_transport *transport) return True; } +/*********************************************************** + SMB signing - TEMP implementation - calculate a MAC to send. +************************************************************/ +static void cli_request_temp_sign_outgoing_message(struct cli_request *req) +{ + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(req); + + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8); + return; +} + +/*********************************************************** + SMB signing - TEMP implementation - check a MAC sent by server. +************************************************************/ +static BOOL cli_request_temp_check_incoming_message(struct cli_request *req) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ +static void cli_temp_free_signing_context(struct cli_transport *transport) +{ + return; +} + +/** + SMB signing - TEMP implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ +BOOL cli_temp_set_signing(struct cli_transport *transport) +{ + if (!set_smb_signing_common(transport)) { + return False; + } + + transport->negotiate.sign_info.signing_context = NULL; + + transport->negotiate.sign_info.sign_outgoing_message = cli_request_temp_sign_outgoing_message; + transport->negotiate.sign_info.check_incoming_message = cli_request_temp_check_incoming_message; + transport->negotiate.sign_info.free_signing_context = cli_temp_free_signing_context; + + return True; +} /** * Free the signing context -- cgit From 50ce5fd990a9ce49be006340ba797c550a0322e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 00:09:10 +0000 Subject: r1346: revert my last spnego changes metze (This used to be commit 7b8237bfb3c302a448a7db0236c0a953603dcd89) --- source4/libcli/auth/spnego.c | 238 +++++++++++++++++++++---------------------- source4/libcli/auth/spnego.h | 4 +- 2 files changed, 116 insertions(+), 126 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index eb1ed15368..bb9d2504ac 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -41,7 +41,7 @@ struct spnego_state { uint_t ref_count; enum spnego_message_type expected_packet; enum spnego_message_type state_position; - enum spnego_negResult result; + negResult_t result; struct gensec_security *sub_sec_security; }; @@ -169,7 +169,9 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA out_mem_ctx, in, out); } - if (spnego_state->state_position == SPNEGO_SERVER_START) { + len = spnego_read_data(in, &spnego); + + if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { int i; int num_ops; const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); @@ -196,152 +198,140 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } gensec_end(&spnego_state->sub_sec_security); } - DEBUG(1, ("Failed to start SPENGO SERVER\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - len = spnego_read_data(in, &spnego); - if (len == -1) { DEBUG(1, ("Failed to parse SPENGO request\n")); return NT_STATUS_INVALID_PARAMETER; - } + } else { - if (spnego.type != spnego_state->expected_packet) { - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, - spnego_state->expected_packet)); - return NT_STATUS_INVALID_PARAMETER; - } + if (spnego.type != spnego_state->expected_packet) { + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + spnego_state->expected_packet)); + return NT_STATUS_INVALID_PARAMETER; + } - if (spnego_state->state_position == SPNEGO_CLIENT_GET_MECHS) { + if (spnego_state->state_position == SPNEGO_CLIENT_GET_MECHS) { - /* The server offers a list of mechanisms */ - - char **mechType = spnego.negTokenInit.mechTypes; - char *my_mechs[] = {NULL, NULL}; - int i; - NTSTATUS nt_status; + /* The server offers a list of mechanisms */ + + char **mechType = spnego.negTokenInit.mechTypes; + char *my_mechs[] = {NULL, NULL}; + int i; + NTSTATUS nt_status; + + for (i=0; mechType[i]; i++) { + nt_status = gensec_client_start(&spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + break; + } + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechType[i]); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); + continue; + } + + if (i == 0) { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenInit.mechToken, + &unwrapped_out); + } else { + /* only get the helping start blob for the first OID */ + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + &unwrapped_out); + } + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + gensec_end(&spnego_state->sub_sec_security); + } else { + break; + } + } + if (!mechType[i]) { + DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + } - spnego_state->sub_sec_security = NULL; + spnego_free_data(&spnego); + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return nt_status; + } + + /* compose reply */ + my_mechs[0] = spnego_state->sub_sec_security->ops->oid; - for (i=0; mechType && mechType[i]; i++) { - nt_status = gensec_client_start(&spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - break; + spnego_out.type = SPNEGO_NEG_TOKEN_INIT; + spnego_out.negTokenInit.mechTypes = my_mechs; + spnego_out.negTokenInit.reqFlags = 0; + spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechToken = unwrapped_out; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; } - /* forward the user info to the sub context */ - spnego_state->sub_sec_security->user = gensec_security->user; - spnego_state->sub_sec_security->password_callback = gensec_security->password_callback; - spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; - /* select the sub context */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechType[i]); - if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); - continue; + + /* set next state */ + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->state_position = SPNEGO_TARG; + + return nt_status; + } else if (spnego_state->state_position == SPNEGO_TARG) { + NTSTATUS nt_status; + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { + return NT_STATUS_ACCESS_DENIED; } - if (i == 0) { + if (spnego.negTokenTarg.responseToken.length) { nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, - spnego.negTokenInit.mechToken, + spnego.negTokenTarg.responseToken, &unwrapped_out); } else { - /* only get the helping start blob for the first OID */ - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - &unwrapped_out); + unwrapped_out = data_blob(NULL, 0); + nt_status = NT_STATUS_OK; } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", - spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - gensec_end(&spnego_state->sub_sec_security); - } else { - break; + + if (NT_STATUS_IS_OK(nt_status) + && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + nt_status = NT_STATUS_INVALID_PARAMETER; } - } - if (!spnego_state->sub_sec_security) { - DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - spnego_free_data(&spnego); - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return nt_status; - } - - /* compose reply */ - my_mechs[0] = spnego_state->sub_sec_security->ops->oid; - - spnego_out.type = SPNEGO_NEG_TOKEN_INIT; - spnego_out.negTokenInit.mechTypes = my_mechs; - spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = null_data_blob; - spnego_out.negTokenInit.mechToken = unwrapped_out; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* set next state */ - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_TARG; - - return nt_status; - } else if (spnego_state->state_position == SPNEGO_TARG) { - NTSTATUS nt_status; - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - return NT_STATUS_ACCESS_DENIED; - } - - if (spnego.negTokenTarg.responseToken.length) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - } else { - unwrapped_out = data_blob(NULL, 0); - nt_status = NT_STATUS_OK; - } - - if (NT_STATUS_IS_OK(nt_status) - && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { - nt_status = NT_STATUS_INVALID_PARAMETER; - } - spnego_state->result = spnego.negTokenTarg.negResult; - spnego_free_data(&spnego); - - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; + spnego_state->result = spnego.negTokenTarg.negResult; + spnego_free_data(&spnego); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* compose reply */ + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; +; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; } - spnego_state->state_position = SPNEGO_TARG; - } else if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->state_position = SPNEGO_DONE; - } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); + spnego_state->state_position = SPNEGO_TARG; + } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->state_position = SPNEGO_DONE; + } else { + DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); + return nt_status; + } + return nt_status; + } else { + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); + return NT_STATUS_INVALID_PARAMETER; } - - return nt_status; - } else { - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); - return NT_STATUS_INVALID_PARAMETER; } } diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index eba98c5218..60ef4c1d36 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -33,11 +33,11 @@ #define SPNEGO_INTEG_FLAG 0x40 #define SPNEGO_REQ_FLAG 0x80 -enum spnego_negResult { +typedef enum _spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, SPNEGO_REJECT = 2 -}; +} negResult_t; struct spnego_negTokenInit { char **mechTypes; -- cgit From fff5d40ab5f23b9ca8c2c38b3f962ade4c02de2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 00:15:39 +0000 Subject: r1347: - remove typedef - pass down gensec_user to the sub context - if segfault when mechType is NULL metze (This used to be commit 3f84263c27add3bf01eea88618f707da925bed5c) --- source4/libcli/auth/spnego.c | 17 +++++++++++++---- source4/libcli/auth/spnego.h | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index bb9d2504ac..d8d3682fd4 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -41,7 +41,7 @@ struct spnego_state { uint_t ref_count; enum spnego_message_type expected_packet; enum spnego_message_type state_position; - negResult_t result; + enum spnego_negResult result; struct gensec_security *sub_sec_security; }; @@ -184,6 +184,11 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } + /* forward the user info to the sub context */ + spnego_state->sub_sec_security->user = gensec_security->user; + spnego_state->sub_sec_security->password_callback = gensec_security->password_callback; + spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; + /* select the sub context */ nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, all_ops[i]->oid); if (!NT_STATUS_IS_OK(nt_status)) { @@ -218,11 +223,16 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA int i; NTSTATUS nt_status; - for (i=0; mechType[i]; i++) { + for (i=0; mechType && mechType[i]; i++) { nt_status = gensec_client_start(&spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { break; } + /* forward the user info to the sub context */ + spnego_state->sub_sec_security->user = gensec_security->user; + spnego_state->sub_sec_security->password_callback = gensec_security->password_callback; + spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; + /* select the sub context */ nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, mechType[i]); if (!NT_STATUS_IS_OK(nt_status)) { @@ -250,7 +260,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA break; } } - if (!mechType[i]) { + if (!mechType || !mechType[i]) { DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); } @@ -308,7 +318,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; spnego_out.negTokenTarg.supportedMech = spnego_state->sub_sec_security->ops->oid; -; spnego_out.negTokenTarg.responseToken = unwrapped_out; spnego_out.negTokenTarg.mechListMIC = null_data_blob; diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index 60ef4c1d36..eba98c5218 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -33,11 +33,11 @@ #define SPNEGO_INTEG_FLAG 0x40 #define SPNEGO_REQ_FLAG 0x80 -typedef enum _spnego_negResult { +enum spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, SPNEGO_REJECT = 2 -} negResult_t; +}; struct spnego_negTokenInit { char **mechTypes; -- cgit From 1828f5d50696682be5f81408fe3cc0dd44d8406e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 00:22:27 +0000 Subject: r1348: get gensec backend by OID instead of name metze (This used to be commit 38e00f87191b86901b603e66aec1e7e71f74c29f) --- source4/libcli/auth/gensec.c | 11 ----------- source4/libcli/raw/clisession.c | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 8ece7c76dc..f6d6db9e62 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -162,17 +162,6 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) return NT_STATUS_INVALID_PARAMETER; } -NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security, - const char *name) -{ - gensec_security->ops = gensec_security_by_name(name); - if (!gensec_security->ops) { - DEBUG(1, ("Could not find GENSEC backend for name=%s\n", name)); - return NT_STATUS_INVALID_PARAMETER; - } - return gensec_start_mech(gensec_security); -} - NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, uint8_t authtype) { diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 7ff5db59c3..fd6737eeb7 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -421,7 +421,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session goto done; } - status = gensec_start_mech_by_name(session->gensec, "spnego"); + status = gensec_start_mech_by_oid(session->gensec, OID_SPNEGO); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", nt_errstr(status))); -- cgit From 3acfc94511cd963597f02d34742dea5d8ed2d609 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 01:01:39 +0000 Subject: r1349: don't segfault with empty data_blob metze (This used to be commit a826accd55e90cb0628f198886ba1ae6c845e68b) --- source4/libcli/auth/spnego_parse.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 85e18ed4da..b38226c014 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -250,6 +250,11 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) ZERO_STRUCTP(token); ZERO_STRUCT(asn1); + + if (data.length == 0) { + return ret; + } + asn1_load(&asn1, data); switch (asn1.data[asn1.ofs]) { -- cgit From 49d6c46fa3fa0b074e1544d33c814f9de0f544aa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 01:03:36 +0000 Subject: r1350: - init nt_status- found by valgrind - set auth_type = DCERPC_AUTH_TYPE_SPNEGO metze (This used to be commit 7354521f3cfaa2ead8fac38a68b7704d43731f72) --- source4/libcli/auth/spnego.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index d8d3682fd4..901ff7cf73 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -221,7 +221,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA char **mechType = spnego.negTokenInit.mechTypes; char *my_mechs[] = {NULL, NULL}; int i; - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; for (i=0; mechType && mechType[i]; i++) { nt_status = gensec_client_start(&spnego_state->sub_sec_security); @@ -360,6 +360,7 @@ static void gensec_spnego_end(struct gensec_security *gensec_security) static const struct gensec_security_ops gensec_spnego_security_ops = { .name = "spnego", .sasl_name = "GSS-SPNEGO", + .auth_type = DCERPC_AUTH_TYPE_SPNEGO, .oid = OID_SPNEGO, .client_start = gensec_spnego_client_start, .update = gensec_spnego_update, -- cgit From b359f5d89301882bbec657084b99c8d3e93dc3f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jul 2004 01:28:12 +0000 Subject: r1352: Add a 'peek' function to our ASN1 code, so we can safely perform the various switches without looking one byte past te end of the buffer. (This used to be commit 5bce188d429b4166f3d0314922ae40204de182a7) --- source4/libcli/auth/spnego_parse.c | 59 ++++++++++++++++++++++++++------------ source4/libcli/util/asn1.c | 22 ++++++++++++++ 2 files changed, 63 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index b38226c014..dfaf9cf320 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -35,8 +35,13 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { int i; + uint8_t context; + if (!asn1_peek_uint8(asn1, &context)) { + asn1->has_error = True; + break; + } - switch (asn1->data[asn1->ofs]) { + switch (context) { /* Read mechTypes */ case ASN1_CONTEXT(0): asn1_start_tag(asn1, ASN1_CONTEXT(0)); @@ -70,8 +75,14 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token break; /* Read mecListMIC */ case ASN1_CONTEXT(3): + { + uint8_t type_peek; asn1_start_tag(asn1, ASN1_CONTEXT(3)); - if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { + if (!asn1_peek_uint8(asn1, &type_peek)) { + asn1->has_error = True; + break; + } + if (type_peek == ASN1_OCTET_STRING) { asn1_read_OctetString(asn1, &token->mechListMIC); } else { @@ -90,6 +101,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token } asn1_end_tag(asn1); break; + } default: asn1->has_error = True; break; @@ -173,7 +185,13 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token asn1_start_tag(asn1, ASN1_SEQUENCE(0)); while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - switch (asn1->data[asn1->ofs]) { + uint8_t context; + if (!asn1_peek_uint8(asn1, &context)) { + asn1->has_error = True; + break; + } + + switch (context) { case ASN1_CONTEXT(0): asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_ENUMERATED); @@ -257,22 +275,27 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) asn1_load(&asn1, data); - switch (asn1.data[asn1.ofs]) { - case ASN1_APPLICATION(0): - asn1_start_tag(&asn1, ASN1_APPLICATION(0)); - asn1_check_OID(&asn1, OID_SPNEGO); - if (read_negTokenInit(&asn1, &token->negTokenInit)) { - token->type = SPNEGO_NEG_TOKEN_INIT; - } - asn1_end_tag(&asn1); - break; - case ASN1_CONTEXT(1): - if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { - token->type = SPNEGO_NEG_TOKEN_TARG; + uint8_t context; + if (!asn1_peek_uint8(asn1, &context)) { + asn1->has_error = True; + } else { + switch (context) { + case ASN1_APPLICATION(0): + asn1_start_tag(&asn1, ASN1_APPLICATION(0)); + asn1_check_OID(&asn1, OID_SPNEGO); + if (read_negTokenInit(&asn1, &token->negTokenInit)) { + token->type = SPNEGO_NEG_TOKEN_INIT; + } + asn1_end_tag(&asn1); + break; + case ASN1_CONTEXT(1): + if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { + token->type = SPNEGO_NEG_TOKEN_TARG; + } + break; + default: + break; } - break; - default: - break; } if (!asn1.has_error) ret = asn1.ofs; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 943ce4d1c1..da51340774 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -239,6 +239,28 @@ BOOL asn1_read_uint8(ASN1_DATA *data, uint8_t *v) return asn1_read(data, v, 1); } +/* read from a ASN1 buffer, advancing the buffer pointer */ +BOOL asn1_peek(ASN1_DATA *data, void *p, int len) +{ + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { + data->has_error = True; + return False; + } + + if (data->ofs + len > data->length) { + data->has_error = True; + return False; + } + memcpy(p, data->data + data->ofs, len); + return True; +} + +/* read a uint8_t from a ASN1 buffer */ +BOOL asn1_peek_uint8(ASN1_DATA *data, uint8_t *v) +{ + return asn1_peek(data, v, 1); +} + /* start reading a nested asn1 structure */ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) { -- cgit From 674ad2378942ea053e17f6d2b21c9d332145aa8c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jul 2004 02:18:24 +0000 Subject: r1353: Fix compile with new ASN1 peek code. Andrew Bartlett (This used to be commit 9039a2a1128d8af278cae76c0aa6d5362b3671e4) --- source4/libcli/auth/spnego_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index dfaf9cf320..c2e23c0ffe 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -276,8 +276,8 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) asn1_load(&asn1, data); uint8_t context; - if (!asn1_peek_uint8(asn1, &context)) { - asn1->has_error = True; + if (!asn1_peek_uint8(&asn1, &context)) { + asn1.has_error = True; } else { switch (context) { case ASN1_APPLICATION(0): -- cgit From 93665a132dd76a4012db2ffcf14e861edbb1f755 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jul 2004 02:59:05 +0000 Subject: r1357: Work on GENSEC: - Add the concept of a 'subcontext' into gensec, so that the spengo code doesn't have to figure out how to make one. (A subcontext inherits the username, domain, password (or callback) from the main context). - Add comments to some other routines, and explain a bit about what the various 'start' functions are for. Andrew Bartlett (This used to be commit 7aedbfbdd92b4ca93cbd0babff16e7526201ee88) --- source4/libcli/auth/gensec.c | 55 ++++++++++++++++++++++++++++++++++++++++---- source4/libcli/auth/gensec.h | 1 + 2 files changed, 51 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index f6d6db9e62..7ccaf4acc3 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -106,9 +106,35 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) (*gensec_security)->mem_ctx = mem_ctx; (*gensec_security)->ops = NULL; + (*gensec_security)->subcontext = False; return NT_STATUS_OK; } +/** + * Start a GENSEC subcontext, with a copy of the properties of the parent + * + * @note Used by SPENGO in particular, for the actual implementation mechanism + */ + +NTSTATUS gensec_subcontext_start(struct gensec_security *parent, + struct gensec_security **gensec_security) +{ + NTSTATUS status; + + (*gensec_security) = talloc_p(parent->mem_ctx, struct gensec_security); + if (!(*gensec_security)) { + return NT_STATUS_NO_MEMORY; + } + + (**gensec_security) = *parent; + (*gensec_security)->ops = NULL; + (*gensec_security)->private_data = NULL; + + (*gensec_security)->subcontext = True; + + return status; +} + NTSTATUS gensec_client_start(struct gensec_security **gensec_security) { NTSTATUS status; @@ -162,34 +188,50 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) return NT_STATUS_INVALID_PARAMETER; } +/** + * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number + */ + NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, uint8_t authtype) { gensec_security->ops = gensec_security_by_authtype(authtype); if (!gensec_security->ops) { - DEBUG(1, ("Could not find GENSEC backend for authtype=%d\n", (int)authtype)); + DEBUG(3, ("Could not find GENSEC backend for authtype=%d\n", (int)authtype)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security); } +/** + * Start a GENSEC sub-mechanism by OID, used in SPNEGO + * + * @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a + * well-known #define to hook it in. + */ + NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid) { gensec_security->ops = gensec_security_by_oid(mech_oid); if (!gensec_security->ops) { - DEBUG(1, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); + DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security); } +/** + * Start a GENSEC sub-mechanism by a well know SASL name + * + */ + NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, const char *sasl_name) { gensec_security->ops = gensec_security_by_sasl_name(sasl_name); if (!gensec_security->ops) { - DEBUG(1, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name)); + DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security); @@ -264,8 +306,11 @@ void gensec_end(struct gensec_security **gensec_security) (*gensec_security)->ops->end(*gensec_security); } (*gensec_security)->private_data = NULL; - talloc_destroy((*gensec_security)->mem_ctx); - + + if (!(*gensec_security)->subcontext) { + /* don't destory this if this is a subcontext - it belongs to the parent */ + talloc_destroy((*gensec_security)->mem_ctx); + } gensec_security = NULL; } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 463b484a7f..e30369ba0b 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -72,6 +72,7 @@ struct gensec_security { void *private_data; struct gensec_user user; enum gensec_role gensec_role; + BOOL subcontext; }; /* this structure is used by backends to determine the size of some critical types */ -- cgit From 14e8aab1823b3d6b40638b5967cfee5fd94de7ca Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jul 2004 03:02:33 +0000 Subject: r1358: Re-indent the SPENGO implementation, and work on the basis of a switch, rather than a series of if statements. Also start to use the GENSEC subcontexts, and add some comments explaining some of the 'odd' logic in parts. I'll probably break these out into subfunctions soon. Thanks to metze for getting me to do this :-) Andrew Bartlett (This used to be commit 73e03596d3b2ad5927e8154d0fbfbdae9ec3f717) --- source4/libcli/auth/spnego.c | 347 +++++++++++++++++++++++++------------------ 1 file changed, 201 insertions(+), 146 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 901ff7cf73..59ccbc7ba7 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -29,7 +29,7 @@ enum spnego_state_position { SPNEGO_SERVER_START, - SPNEGO_CLIENT_GET_MECHS, + SPNEGO_CLIENT_START, SPNEGO_CLIENT_SEND_MECHS, SPNEGO_TARG, SPNEGO_FALLBACK, @@ -59,7 +59,7 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi } spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; - spnego_state->state_position = SPNEGO_CLIENT_GET_MECHS; + spnego_state->state_position = SPNEGO_CLIENT_START; spnego_state->result = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->mem_ctx = mem_ctx; spnego_state->sub_sec_security = NULL; @@ -149,6 +149,51 @@ static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_securit session_key); } +/** Fallback to another GENSEC mechanism, based on magic strings + * + * This is the 'fallback' case, where we don't get SPENGO, and have to + * try all the other options (and hope they all have a magic string + * they check) +*/ + +static NTSTATUS gensec_spengo_server_try_fallback(struct gensec_security *gensec_security, + struct spnego_state *spnego_state, + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + int i; + int num_ops; + const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); + for (i=0; i < num_ops; i++) { + NTSTATUS nt_status; + if (!all_ops[i]->oid) { + continue; + } + nt_status = gensec_subcontext_start(gensec_security, + &spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + /* select the sub context */ + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + all_ops[i]->oid); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); + continue; + } + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, in, out); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + spnego_state->state_position = SPNEGO_FALLBACK; + return nt_status; + } + gensec_end(&spnego_state->sub_sec_security); + } + DEBUG(1, ("Failed to parse SPENGO request\n")); + return NT_STATUS_INVALID_PARAMETER; + +} + static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { @@ -164,25 +209,59 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA out_mem_ctx = spnego_state->mem_ctx; } - if (spnego_state->state_position == SPNEGO_FALLBACK) { + /* and switch into the state machine */ + + switch (spnego_state->state_position) { + case SPNEGO_FALLBACK: return gensec_update(spnego_state->sub_sec_security, out_mem_ctx, in, out); + case SPNEGO_SERVER_START: + { + if (in.length) { + len = spnego_read_data(in, &spnego); + if (len == -1) { + return gensec_spengo_server_try_fallback(gensec_security, spnego_state, out_mem_ctx, in, out); + } else { + /* client sent NegTargetInit */ + } + } else { + /* server needs to send NegTargetInit */ + } } - len = spnego_read_data(in, &spnego); - - if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { + case SPNEGO_CLIENT_START: + { + /* The server offers a list of mechanisms */ + + char **mechType; + char *my_mechs[] = {NULL, NULL}; int i; - int num_ops; - const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); - for (i=0; i < num_ops; i++) { - NTSTATUS nt_status; - if (!all_ops[i]->oid) { - continue; - } - nt_status = gensec_server_start(&spnego_state->sub_sec_security); + NTSTATUS nt_status; + + if (!in.length) { + /* client to produce negTokenInit */ + return NT_STATUS_INVALID_PARAMETER; + } + + len = spnego_read_data(in, &spnego); + + if (len == -1) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* OK, so it's real SPNEGO, check the packet's the one we expect */ + if (spnego.type != spnego_state->expected_packet) { + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + spnego_state->expected_packet)); + return NT_STATUS_INVALID_PARAMETER; + } + + mechType = spnego.negTokenInit.mechTypes; + for (i=0; mechType && mechType[i]; i++) { + nt_status = gensec_client_start(&spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + break; } /* forward the user info to the sub context */ spnego_state->sub_sec_security->user = gensec_security->user; @@ -190,157 +269,133 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; /* select the sub context */ nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - all_ops[i]->oid); + mechType[i]); if (!NT_STATUS_IS_OK(nt_status)) { gensec_end(&spnego_state->sub_sec_security); continue; } - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, in, out); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - spnego_state->state_position = SPNEGO_FALLBACK; - return nt_status; + + if (i == 0) { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenInit.mechToken, + &unwrapped_out); + } else { + /* only get the helping start blob for the first OID */ + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + &unwrapped_out); + } + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + gensec_end(&spnego_state->sub_sec_security); + } else { + break; } - gensec_end(&spnego_state->sub_sec_security); } - DEBUG(1, ("Failed to parse SPENGO request\n")); - return NT_STATUS_INVALID_PARAMETER; - } else { - + if (!mechType || !mechType[i]) { + DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + } + + spnego_free_data(&spnego); + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return nt_status; + } + + /* compose reply */ + my_mechs[0] = spnego_state->sub_sec_security->ops->oid; + + spnego_out.type = SPNEGO_NEG_TOKEN_INIT; + spnego_out.negTokenInit.mechTypes = my_mechs; + spnego_out.negTokenInit.reqFlags = 0; + spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechToken = unwrapped_out; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* set next state */ + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->state_position = SPNEGO_TARG; + + return nt_status; + } + case SPNEGO_TARG: + { + NTSTATUS nt_status; + if (!in.length) { + return NT_STATUS_INVALID_PARAMETER; + } + + len = spnego_read_data(in, &spnego); + + if (len == -1) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* OK, so it's real SPNEGO, check the packet's the one we expect */ if (spnego.type != spnego_state->expected_packet) { spnego_free_data(&spnego); DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); return NT_STATUS_INVALID_PARAMETER; } - - if (spnego_state->state_position == SPNEGO_CLIENT_GET_MECHS) { - - /* The server offers a list of mechanisms */ - - char **mechType = spnego.negTokenInit.mechTypes; - char *my_mechs[] = {NULL, NULL}; - int i; - NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; - - for (i=0; mechType && mechType[i]; i++) { - nt_status = gensec_client_start(&spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - break; - } - /* forward the user info to the sub context */ - spnego_state->sub_sec_security->user = gensec_security->user; - spnego_state->sub_sec_security->password_callback = gensec_security->password_callback; - spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; - /* select the sub context */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechType[i]); - if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); - continue; - } - - if (i == 0) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenInit.mechToken, - &unwrapped_out); - } else { - /* only get the helping start blob for the first OID */ - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - &unwrapped_out); - } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", - spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - gensec_end(&spnego_state->sub_sec_security); - } else { - break; - } - } - if (!mechType || !mechType[i]) { - DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); - } - - spnego_free_data(&spnego); - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return nt_status; - } - + + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { + return NT_STATUS_ACCESS_DENIED; + } + + if (spnego.negTokenTarg.responseToken.length) { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + } else { + unwrapped_out = data_blob(NULL, 0); + nt_status = NT_STATUS_OK; + } + + if (NT_STATUS_IS_OK(nt_status) + && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + nt_status = NT_STATUS_INVALID_PARAMETER; + } + + spnego_state->result = spnego.negTokenTarg.negResult; + spnego_free_data(&spnego); + + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* compose reply */ - my_mechs[0] = spnego_state->sub_sec_security->ops->oid; - - spnego_out.type = SPNEGO_NEG_TOKEN_INIT; - spnego_out.negTokenInit.mechTypes = my_mechs; - spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = null_data_blob; - spnego_out.negTokenInit.mechToken = unwrapped_out; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* set next state */ - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_TARG; - - return nt_status; - } else if (spnego_state->state_position == SPNEGO_TARG) { - NTSTATUS nt_status; - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - return NT_STATUS_ACCESS_DENIED; - } - - if (spnego.negTokenTarg.responseToken.length) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - } else { - unwrapped_out = data_blob(NULL, 0); - nt_status = NT_STATUS_OK; - } - - if (NT_STATUS_IS_OK(nt_status) - && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { - nt_status = NT_STATUS_INVALID_PARAMETER; - } - - spnego_state->result = spnego.negTokenTarg.negResult; - spnego_free_data(&spnego); + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; } - spnego_state->state_position = SPNEGO_TARG; - } else if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->state_position = SPNEGO_DONE; - } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); - return nt_status; - } - - return nt_status; + spnego_state->state_position = SPNEGO_TARG; + } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->state_position = SPNEGO_DONE; } else { - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); - return NT_STATUS_INVALID_PARAMETER; + DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); + return nt_status; } + + return nt_status; + } + default: + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); + return NT_STATUS_INVALID_PARAMETER; } } -- cgit From f9c7b6303ceeeb69bcd4dda41ebae52780f00817 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 14:42:07 +0000 Subject: r1359: fix uninit var - found by valgrind metze (This used to be commit 264afea9ec3ada4df51e5f5de4c0b977024af40b) --- source4/libcli/auth/gensec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 7ccaf4acc3..2491410494 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -119,8 +119,6 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) NTSTATUS gensec_subcontext_start(struct gensec_security *parent, struct gensec_security **gensec_security) { - NTSTATUS status; - (*gensec_security) = talloc_p(parent->mem_ctx, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; @@ -132,7 +130,7 @@ NTSTATUS gensec_subcontext_start(struct gensec_security *parent, (*gensec_security)->subcontext = True; - return status; + return NT_STATUS_OK; } NTSTATUS gensec_client_start(struct gensec_security **gensec_security) -- cgit From 1432bb01f38b3791356bb5e45193452a0770da96 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 15:03:31 +0000 Subject: r1360: - remove unused state SPNEGO_CLIENT_SEND_MECHS - remove unsed gensec_user forward, it's done by the gensec layer know metze (This used to be commit e19e5a91f2fd988546f42473bf241dff3c2fe198) --- source4/libcli/auth/spnego.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 59ccbc7ba7..5ba0e239c5 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -30,7 +30,6 @@ enum spnego_state_position { SPNEGO_SERVER_START, SPNEGO_CLIENT_START, - SPNEGO_CLIENT_SEND_MECHS, SPNEGO_TARG, SPNEGO_FALLBACK, SPNEGO_DONE @@ -263,10 +262,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!NT_STATUS_IS_OK(nt_status)) { break; } - /* forward the user info to the sub context */ - spnego_state->sub_sec_security->user = gensec_security->user; - spnego_state->sub_sec_security->password_callback = gensec_security->password_callback; - spnego_state->sub_sec_security->password_callback_private = gensec_security->password_callback_private; /* select the sub context */ nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, mechType[i]); -- cgit From 215c400aee73160bae0d036db8617be0aa3c8b99 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 17:46:47 +0000 Subject: r1363: add SPNEGO_NONE_RESULT as spnego_negResult value this should indicate that we don't send a spnego_negResult t all over the wire metze (This used to be commit 69d685d81784e5fb33e41d3244498ac620a2f5f0) --- source4/libcli/auth/spnego.h | 3 ++- source4/libcli/auth/spnego_parse.c | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index eba98c5218..decd79e107 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -36,7 +36,8 @@ enum spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, - SPNEGO_REJECT = 2 + SPNEGO_REJECT = 2, + SPNEGO_NONE_RESULT = 3 }; struct spnego_negTokenInit { diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index c2e23c0ffe..9c50e3887d 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -231,9 +231,11 @@ static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *toke asn1_push_tag(asn1, ASN1_CONTEXT(1)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_write_enumerated(asn1, token->negResult); - asn1_pop_tag(asn1); + if (token->negResult != SPNEGO_NONE_RESULT) { + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_write_enumerated(asn1, token->negResult); + asn1_pop_tag(asn1); + } if (token->supportedMech) { asn1_push_tag(asn1, ASN1_CONTEXT(1)); -- cgit From 6f0d8e67ffb3c45992bce37e1d2ab511908dedcf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 17:53:44 +0000 Subject: r1364: the SPNEGO_SERVER_TARG state is different from the SPNEGO_CLIENT_TARG the client checks but not send spnego_negResult metze (This used to be commit 49e4d375e9504f595aaa64ac62ddb421f082c424) --- source4/libcli/auth/spnego.c | 76 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 5ba0e239c5..02bc9043f5 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -30,7 +30,8 @@ enum spnego_state_position { SPNEGO_SERVER_START, SPNEGO_CLIENT_START, - SPNEGO_TARG, + SPNEGO_SERVER_TARG, + SPNEGO_CLIENT_TARG, SPNEGO_FALLBACK, SPNEGO_DONE }; @@ -315,11 +316,11 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA /* set next state */ spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_TARG; + spnego_state->state_position = SPNEGO_CLIENT_TARG; return nt_status; } - case SPNEGO_TARG: + case SPNEGO_SERVER_TARG: { NTSTATUS nt_status; if (!in.length) { @@ -375,7 +376,74 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; } - spnego_state->state_position = SPNEGO_TARG; + spnego_state->state_position = SPNEGO_SERVER_TARG; + } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->state_position = SPNEGO_DONE; + } else { + DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); + return nt_status; + } + + return nt_status; + } + case SPNEGO_CLIENT_TARG: + { + NTSTATUS nt_status; + if (!in.length) { + return NT_STATUS_INVALID_PARAMETER; + } + + len = spnego_read_data(in, &spnego); + + if (len == -1) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* OK, so it's real SPNEGO, check the packet's the one we expect */ + if (spnego.type != spnego_state->expected_packet) { + spnego_free_data(&spnego); + DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + spnego_state->expected_packet)); + return NT_STATUS_INVALID_PARAMETER; + } + + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { + return NT_STATUS_ACCESS_DENIED; + } + + if (spnego.negTokenTarg.responseToken.length) { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + } else { + unwrapped_out = data_blob(NULL, 0); + nt_status = NT_STATUS_OK; + } + + if (NT_STATUS_IS_OK(nt_status) + && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + nt_status = NT_STATUS_INVALID_PARAMETER; + } + + spnego_state->result = spnego.negTokenTarg.negResult; + spnego_free_data(&spnego); + + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* compose reply */ + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; + spnego_out.negTokenTarg.supportedMech = NULL; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; + } + spnego_state->state_position = SPNEGO_CLIENT_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { spnego_state->state_position = SPNEGO_DONE; } else { -- cgit From c688a1e18ff5e3f50005a8438bdbfb0e4382ca18 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 17:58:56 +0000 Subject: r1365: in SPNEGO_SERVER_TARG we should not check the spnego_negResult because the client don't send this metze (This used to be commit b1217a4ef6592082bb02fd0596a0563bacdf1d8e) --- source4/libcli/auth/spnego.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 02bc9043f5..aa0f83700d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -340,10 +340,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_state->expected_packet)); return NT_STATUS_INVALID_PARAMETER; } - - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - return NT_STATUS_ACCESS_DENIED; - } if (spnego.negTokenTarg.responseToken.length) { nt_status = gensec_update(spnego_state->sub_sec_security, @@ -355,11 +351,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA nt_status = NT_STATUS_OK; } - if (NT_STATUS_IS_OK(nt_status) - && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { - nt_status = NT_STATUS_INVALID_PARAMETER; - } - spnego_state->result = spnego.negTokenTarg.negResult; spnego_free_data(&spnego); -- cgit From 4b7cd833a09634d1a94d4b7170286549f883fdfb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 18:07:00 +0000 Subject: r1366: handle the case where the client need to send the negTokenInit before getting something from the server. (this is needed by SPNEGO in dcerpc) metze (This used to be commit ec978555f0bd612b80dfa49ccc880a3858285879) --- source4/libcli/auth/spnego.c | 89 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index aa0f83700d..b0135dca56 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -194,6 +194,93 @@ static NTSTATUS gensec_spengo_server_try_fallback(struct gensec_security *gensec } +/** create a client netTokenInit + * + * This is the case, where the client is the first one who sends data +*/ + +static NTSTATUS gensec_spengo_client_netTokenInit(struct gensec_security *gensec_security, + struct spnego_state *spnego_state, + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + NTSTATUS nt_status; + int i; + int num_ops; + char **mechTypes = NULL; + const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); + DATA_BLOB null_data_blob = data_blob(NULL,0); + DATA_BLOB unwrapped_out = data_blob(NULL,0); + + if (num_ops < 1) { + DEBUG(1, ("no GENSEC backends available\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* build a mechTypes list we want to offer */ + for (i=0; i < num_ops; i++) { + if (!all_ops[i]->oid) { + continue; + } + + /* skip SPNEGO itself */ + if (strcmp(OID_SPNEGO,all_ops[i]->oid)==0) { + continue; + } + + mechTypes = talloc_realloc_p(out_mem_ctx, mechTypes, char *, i+2); + if (!mechTypes) { + DEBUG(1, ("talloc_realloc_p(out_mem_ctx, mechTypes, char *, i+1) failed\n")); + return NT_STATUS_NO_MEMORY; + } + + mechTypes[i] = all_ops[i]->oid; + mechTypes[i+1] = NULL; + } + + if (!mechTypes) { + DEBUG(1, ("no GENSEC OID backends available\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_subcontext_start(gensec_security, + &spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + /* select our preferred mech */ + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechTypes[0]); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); + return nt_status; + } + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, in, &unwrapped_out); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + struct spnego_data spnego_out; + spnego_out.type = SPNEGO_NEG_TOKEN_INIT; + spnego_out.negTokenInit.mechTypes = mechTypes; + spnego_out.negTokenInit.reqFlags = 0; + spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechToken = unwrapped_out; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* set next state */ + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->state_position = SPNEGO_CLIENT_TARG; + return nt_status; + } + gensec_end(&spnego_state->sub_sec_security); + + DEBUG(1, ("Failed to setup SPENGO netTokenInit request\n")); + return NT_STATUS_INVALID_PARAMETER; +} + static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { @@ -240,7 +327,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!in.length) { /* client to produce negTokenInit */ - return NT_STATUS_INVALID_PARAMETER; + return gensec_spengo_client_netTokenInit(gensec_security, spnego_state, out_mem_ctx, in, out); } len = spnego_read_data(in, &spnego); -- cgit From 7c139a6815b6c8f877f69eec0b3299416630e101 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Jul 2004 18:53:12 +0000 Subject: r1367: SPNEGO know uses gensec_subcontext_start() in all places metze (This used to be commit f7379324025c599cd201ce6d0905f0ca2c24ce73) --- source4/libcli/auth/spnego.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index b0135dca56..b680fe170e 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -346,7 +346,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA mechType = spnego.negTokenInit.mechTypes; for (i=0; mechType && mechType[i]; i++) { - nt_status = gensec_client_start(&spnego_state->sub_sec_security); + nt_status = gensec_subcontext_start(gensec_security, + &spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { break; } -- cgit From e59e82b90204107a3b6e2e6e3fc52d48634adc7a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jul 2004 23:20:23 +0000 Subject: r1372: Remove the 'default' case from the SPENGO state machine, and fix up some compiler warnings that allowed us to see. Andrew Bartlett (This used to be commit 1a6c2018dd49519e6fccdd5a7f35d70b67d45275) --- source4/libcli/auth/spnego.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index b680fe170e..502d30b30f 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -40,7 +40,7 @@ struct spnego_state { TALLOC_CTX *mem_ctx; uint_t ref_count; enum spnego_message_type expected_packet; - enum spnego_message_type state_position; + enum spnego_state_position state_position; enum spnego_negResult result; struct gensec_security *sub_sec_security; }; @@ -314,8 +314,9 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } else { /* server needs to send NegTargetInit */ } + return NT_STATUS_INVALID_PARAMETER; } - + case SPNEGO_CLIENT_START: { /* The server offers a list of mechanisms */ @@ -534,11 +535,10 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return nt_status; } - default: - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d\n", spnego.type)); - return NT_STATUS_INVALID_PARAMETER; + case SPNEGO_DONE: + return NT_STATUS_OK; } + return NT_STATUS_INVALID_PARAMETER; } static void gensec_spnego_end(struct gensec_security *gensec_security) -- cgit From 0fa2b94c5629104000afe12e7eb0447ac515613f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Jul 2004 18:03:14 +0000 Subject: r1406: I got spnego in the smb client working so I set 'use spnego = True' metze (This used to be commit e06898f88c82c286574f9d73de1a9de829b1ded8) --- source4/libcli/raw/clisession.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index fd6737eeb7..dd13657549 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -391,6 +391,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session s2.spnego.in.domain = parms->generic.in.domain; s2.spnego.in.os = "Unix"; s2.spnego.in.lanman = "Samba"; + s2.spnego.out.vuid = UID_FIELD_INVALID; cli_temp_set_signing(session->transport); @@ -437,7 +438,9 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session } while(1) { + session->vuid = s2.spnego.out.vuid; status = smb_raw_session_setup(session, mem_ctx, &s2); + session->vuid = UID_FIELD_INVALID; if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { goto done; -- cgit From 2c87cb390d9c46bb1259c4fae95f4a44be97297b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Jul 2004 18:32:53 +0000 Subject: r1409: if we have no user name don't use extended security the capabilities in the union smb_sesssetup should be used to decide if we can use extented security metze (This used to be commit e3760fcc17cc645d942f0fc7f7325976391309ea) --- source4/libcli/raw/clisession.c | 2 +- source4/libcli/raw/clitree.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index dd13657549..d420aa7cd6 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -497,7 +497,7 @@ static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, } /* see if we should use the NT1 interface */ - if (!(session->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY)) { + if (!(parms->generic.in.capabilities & CAP_EXTENDED_SECURITY)) { return smb_raw_session_setup_generic_nt1(session, mem_ctx, parms); } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 3b16c4c336..f1513ea51c 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -240,6 +240,7 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, setup.generic.in.password = NULL; setup.generic.in.user = ""; setup.generic.in.domain = ""; + setup.generic.in.capabilities &= ~CAP_EXTENDED_SECURITY; } else { setup.generic.in.password = password; setup.generic.in.user = user; -- cgit From bdb0b60861dd2c352dd30ff1c1822c57ce304d0f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Jul 2004 11:46:42 +0000 Subject: r1418: Merge Samba 3.0's recent kerberos changes into Samba4. None of this is used yet. Andrew Bartlett (This used to be commit 7596f311c9a18314716f64476030ce3dfcdd98bb) --- source4/libcli/auth/clikrb5.c | 22 ++- source4/libcli/auth/kerberos.c | 4 +- source4/libcli/auth/kerberos_verify.c | 314 +++++++++++++++++++++++----------- 3 files changed, 233 insertions(+), 107 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 6e19d4dc18..b3aa9008ca 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -124,13 +124,13 @@ #endif #if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) { return krb5_get_permitted_enctypes(context, enctypes); } #elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) { return krb5_get_default_in_tkt_etypes(context, enctypes); @@ -434,9 +434,12 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, failed: if ( context ) { -#if 0 /* JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro */ +/* Removed by jra. They really need to fix their kerberos so we don't leak memory. + JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro +*/ if (ccdef) +#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ krb5_cc_close(context, ccdef); #endif if (auth_context) @@ -486,6 +489,17 @@ failed: } #endif + krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) +{ +#if defined(HAVE_KRB5_KT_FREE_ENTRY) + return krb5_kt_free_entry(context, kt_entry); +#elif defined(HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS) + return krb5_free_keytab_entry_contents(context, kt_entry); +#else +#error UNKNOWN_KT_FREE_FUNCTION +#endif +} + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index e8bf4b0846..97b895a241 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -79,9 +79,9 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, - password, 0, NULL, NULL))) { + NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 805a3f570f..e93d3aa6e8 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -26,10 +26,182 @@ #ifdef HAVE_KRB5 -/* - verify an incoming ticket and parse out the principal name and - authorization_data if available -*/ +/********************************************************************************** + Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so + it's more like what microsoft does... see comment in utils/net_ads.c in the + ads_keytab_add_entry function for details. +***********************************************************************************/ + +static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) +{ + krb5_error_code ret = 0; + BOOL auth_ok = False; + + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor; + krb5_keytab_entry kt_entry; + char *princ_name = NULL; + + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); + + ret = krb5_kt_default(context, &keytab); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); + goto out; + } + + while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { + ret = krb5_unparse_name(context, kt_entry.principal, &princ_name); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + goto out; + } + /* Look for a CIFS ticket */ + if (!StrnCaseCmp(princ_name, "cifs/", 5)) { +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK + krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); +#else + krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.key); +#endif + + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + + if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { + unsigned int keytype; + krb5_free_unparsed_name(context, princ_name); + princ_name = NULL; +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK + keytype = (unsigned int) kt_entry.keyblock.keytype; +#else + keytype = (unsigned int) kt_entry.key.enctype; +#endif + DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", + keytype)); + auth_ok = True; + break; + } + } + krb5_free_unparsed_name(context, princ_name); + princ_name = NULL; + } + if (ret && ret != KRB5_KT_END) { + /* This failed because something went wrong, not because the keytab file was empty. */ + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_next_entry failed (%s)\n", error_message(ret))); + goto out; + } + + out: + + if (princ_name) { + krb5_free_unparsed_name(context, princ_name); + } + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } + } + if (keytab) { + krb5_kt_close(context, keytab); + } + + return auth_ok; +} + +/********************************************************************************** + Try to verify a ticket using the secrets.tdb. +***********************************************************************************/ + +static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, + krb5_principal host_princ, + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) +{ + krb5_error_code ret = 0; + BOOL auth_ok = False; + char *password_s = NULL; + krb5_data password; + krb5_enctype *enctypes = NULL; + int i; + + if (!secrets_init()) { + DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); + return False; + } + + password_s = secrets_fetch_machine_password(lp_workgroup()); + if (!password_s) { + DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n")); + return False; + } + + password.data = password_s; + password.length = strlen(password_s); + + /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ + + if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { + DEBUG(1,("ads_secrets_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); + goto out; + } + + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + + /* We need to setup a auth context with each possible encoding type in turn. */ + for (i=0;enctypes[i];i++) { + krb5_keyblock *key = NULL; + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + goto out; + } + + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + SAFE_FREE(key); + continue; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + krb5_free_keyblock(context, key); + + if (!(ret = krb5_rd_req(context, &auth_context, p_packet, + NULL, + NULL, NULL, pp_tkt))) { + DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int)enctypes[i] )); + auth_ok = True; + break; + } + + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, + ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", + (unsigned int)enctypes[i], error_message(ret))); + } + + out: + + free_kerberos_etypes(context, enctypes); + SAFE_FREE(password_s); + + return auth_ok; +} + +/********************************************************************************** + Verify an incoming ticket and parse out the principal name and + authorization_data if available. +***********************************************************************************/ + NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep, @@ -41,43 +213,21 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; - int ret, i; - krb5_keyblock *key = NULL; + int ret; - krb5_principal host_princ; + krb5_principal host_princ = NULL; char *host_princ_s = NULL; - BOOL free_host_princ = False; BOOL got_replay_mutex = False; fstring myname; - char *password_s = NULL; - krb5_data password; - krb5_enctype *enctypes = NULL; -#if 0 - krb5_address local_addr; - krb5_address remote_addr; -#endif BOOL auth_ok = False; ZERO_STRUCT(packet); - ZERO_STRUCT(password); ZERO_STRUCTP(auth_data); ZERO_STRUCTP(ap_rep); + ZERO_STRUCTP(session_key); - if (!secrets_init()) { - DEBUG(1,("ads_verify_ticket: secrets_init failed\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password_s = secrets_fetch_machine_password(lp_workgroup()); - if (!password_s) { - DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password.data = password_s; - password.length = strlen(password_s); - + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); @@ -87,7 +237,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, realm); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -98,22 +247,29 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, ret = krb5_auth_con_init(context, &auth_context); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } - fstrcpy(myname, global_myname()); + name_to_fqdn(myname, global_myname()); strlower_m(myname); - asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + asprintf(&host_princ_s, "host/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } - free_host_princ = True; + + /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 + * code surrounding the replay cache... */ + + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); + goto out; + } + + got_replay_mutex = True; /* * JRA. We must set the rcache here. This will prevent replay attacks. @@ -122,67 +278,19 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } ret = krb5_auth_con_setrcache(context, auth_context, rcache); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } - /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */ - - if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { - DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; - goto out; - } - - /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 - * code surrounding the replay cache... */ - - if (!grab_server_mutex("replay cache mutex")) { - DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); - sret = NT_STATUS_LOGON_FAILURE; - goto out; - } - - got_replay_mutex = True; - - /* We need to setup a auth context with each possible encoding type in turn. */ - for (i=0;enctypes[i];i++) { - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - sret = NT_STATUS_NO_MEMORY; - goto out; - } - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { - continue; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - krb5_free_keyblock(context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - - if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, - NULL, NULL, &tkt))) { - DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", - (unsigned int)enctypes[i] )); - auth_ok = True; - break; - } - - DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, - ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", - (unsigned int)enctypes[i], error_message(ret))); + auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt); + if (!auth_ok) { + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ticket, &packet, &tkt); } release_server_mutex(); @@ -191,7 +299,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -199,12 +306,12 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (ret) { DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } *ap_rep = data_blob(packet.data, packet.length); - free(packet.data); + SAFE_FREE(packet.data); + packet.length = 0; get_krb5_smb_session_key(context, auth_context, session_key, True); dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); @@ -213,7 +320,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - /* auth_data is the PAC */ get_auth_data_from_tkt(auth_data, tkt); #if 0 @@ -236,29 +342,35 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, out: - if (got_replay_mutex) + if (got_replay_mutex) { release_server_mutex(); + } - if (!NT_STATUS_IS_OK(sret)) + if (!NT_STATUS_IS_OK(sret)) { data_blob_free(auth_data); + } - if (!NT_STATUS_IS_OK(sret)) + if (!NT_STATUS_IS_OK(sret)) { data_blob_free(ap_rep); + } - if (free_host_princ) + if (host_princ) { krb5_free_principal(context, host_princ); + } - if (tkt != NULL) + if (tkt != NULL) { krb5_free_ticket(context, tkt); - free_kerberos_etypes(context, enctypes); - SAFE_FREE(password_s); + } + SAFE_FREE(host_princ_s); - if (auth_context) + if (auth_context) { krb5_auth_con_free(context, auth_context); + } - if (context) + if (context) { krb5_free_context(context); + } return sret; } -- cgit From 7381ba30c499135b40471ed5757551401359bd0d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Jul 2004 12:28:38 +0000 Subject: r1420: be more strict reject if the context has the wrong type metze (This used to be commit db19d6047c25698d0c3b7aeaab77b2a02385dbb5) --- source4/libcli/auth/spnego_parse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 9c50e3887d..bcc32def16 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -296,6 +296,7 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) } break; default: + asn1.has_error = True; break; } } -- cgit From 7caf17319a4c66b63f257294f2c3dd884e795f72 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Jul 2004 12:29:33 +0000 Subject: r1421: fix a uninitialized var (thanks valgrind:-) add a view debug messages metze (This used to be commit 79953dccc1f21dbabddff73a4b6d862eace29eb9) --- source4/libcli/auth/spnego.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 502d30b30f..c9d0c6f97d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -324,7 +324,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA char **mechType; char *my_mechs[] = {NULL, NULL}; int i; - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; if (!in.length) { /* client to produce negTokenInit */ @@ -334,14 +334,17 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA len = spnego_read_data(in, &spnego); if (len == -1) { + DEBUG(1, ("Invalid SPNEGO request:\n")); + dump_data(1, (const char *)in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } /* OK, so it's real SPNEGO, check the packet's the one we expect */ if (spnego.type != spnego_state->expected_packet) { - spnego_free_data(&spnego); DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); + dump_data(1, (const char *)in.data, in.length); + spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } @@ -419,14 +422,17 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA len = spnego_read_data(in, &spnego); if (len == -1) { + DEBUG(1, ("Invalid SPNEGO request:\n")); + dump_data(1, (const char *)in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } /* OK, so it's real SPNEGO, check the packet's the one we expect */ if (spnego.type != spnego_state->expected_packet) { - spnego_free_data(&spnego); DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); + dump_data(1, (const char *)in.data, in.length); + spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } @@ -478,14 +484,17 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA len = spnego_read_data(in, &spnego); if (len == -1) { + DEBUG(1, ("Invalid SPNEGO request:\n")); + dump_data(1, (const char *)in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } /* OK, so it's real SPNEGO, check the packet's the one we expect */ if (spnego.type != spnego_state->expected_packet) { - spnego_free_data(&spnego); - DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); + dump_data(1, (const char *)in.data, in.length); + spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } @@ -505,6 +514,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (NT_STATUS_IS_OK(nt_status) && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + DEBUG(1,("gensec_update ok but not accepted\n")); nt_status = NT_STATUS_INVALID_PARAMETER; } -- cgit From 82e59d11c363bc0b85e4f1f6c1612cbaf1fb0300 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Jul 2004 13:33:10 +0000 Subject: r1423: Make sure to destory the mem_ctx. Andrew Bartlett (This used to be commit c5a1529d54e6b8ec2bbf7017a2f48d7535f1f016) --- source4/libcli/auth/clikrb5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index b3aa9008ca..2c036cfcf8 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -300,7 +300,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_data in_data; BOOL creds_ready = False; - TALLOC_CTX *mem_ctx; + TALLOC_CTX *mem_ctx = NULL; retval = krb5_parse_name(context, principal, &server); if (retval) { @@ -352,7 +352,6 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, http_timestring(mem_ctx, (unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); - in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); @@ -369,6 +368,9 @@ cleanup_creds: cleanup_princ: krb5_free_principal(context, server); + if (mem_ctx) { + talloc_destory(mem_ctx); + } return retval; } -- cgit From 102f5bc17da8948f1d6133a6874bf81f1145a395 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Jul 2004 23:38:13 +0000 Subject: r1426: Fix some of my silly compile errors... Andrew Bartlett (This used to be commit c283837556109b9392a8cdcd867e5ae0dac1509b) --- source4/libcli/auth/clikrb5.c | 2 +- source4/libcli/auth/spnego_parse.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 2c036cfcf8..cf0c4b6424 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -369,7 +369,7 @@ cleanup_princ: krb5_free_principal(context, server); if (mem_ctx) { - talloc_destory(mem_ctx); + talloc_destroy(mem_ctx); } return retval; } diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index bcc32def16..b239a4ebf0 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -267,6 +267,7 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) { ASN1_DATA asn1; ssize_t ret = -1; + uint8_t context; ZERO_STRUCTP(token); ZERO_STRUCT(asn1); @@ -277,7 +278,6 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) asn1_load(&asn1, data); - uint8_t context; if (!asn1_peek_uint8(&asn1, &context)) { asn1.has_error = True; } else { -- cgit From efb010202f8c2edb35ab6fbbb57650140c21734a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 10 Jul 2004 10:24:58 +0000 Subject: r1429: enable spnego in smbclient too. metze (This used to be commit ae2e6b58629397d75a3e446ff0c50b594d029206) --- source4/libcli/cliconnect.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index e2d9665792..8b064f161e 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -76,12 +76,17 @@ NTSTATUS cli_session_setup(struct cli_state *cli, setup.generic.level = RAW_SESSSETUP_GENERIC; setup.generic.in.sesskey = cli->transport->negotiate.sesskey; - setup.generic.in.capabilities = CAP_UNICODE | CAP_STATUS32 | - CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | - CAP_W2K_SMBS | CAP_LARGE_READX | CAP_LARGE_WRITEX; - setup.generic.in.password = password; - setup.generic.in.user = user; - setup.generic.in.domain = domain; + setup.generic.in.capabilities = cli->transport->negotiate.capabilities; + if (!user || !user[0]) { + setup.generic.in.password = NULL; + setup.generic.in.user = ""; + setup.generic.in.domain = ""; + setup.generic.in.capabilities &= ~CAP_EXTENDED_SECURITY; + } else { + setup.generic.in.password = password; + setup.generic.in.user = user; + setup.generic.in.domain = domain; + } status = smb_raw_session_setup(cli->session, mem_ctx, &setup); -- cgit From 74508c718bf726b549469077248b6c0f7d4099a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:07:51 +0000 Subject: r1436: Move GENSEC across to config.mk Andrew Bartlett (This used to be commit 2de3a3082344fd292b1084a73a332549d6b2e25d) --- source4/libcli/config.m4 | 19 ++----------------- source4/libcli/config.mk | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 source4/libcli/config.mk (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 9e19499003..c926d7dae6 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -40,28 +40,13 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], libcli/util/smbencrypt.o libcli/util/dom_sid.o]) -SMB_SUBSYSTEM(LIBCLI_AUTH,[], - [libcli/auth/spnego.o - libcli/auth/spnego_parse.o - libcli/auth/ntlmssp.o - libcli/auth/ntlmssp_parse.o - libcli/auth/ntlmssp_sign.o - libcli/auth/schannel.o - libcli/auth/credentials.o - libcli/auth/session.o - libcli/auth/ntlm_check.o - libcli/auth/kerberos.o - libcli/auth/kerberos_verify.o - libcli/auth/clikrb5.o - libcli/auth/gensec.o - libcli/auth/gensec_ntlmssp.o], - [], [AUTH SCHANNELDB]) - SMB_SUBSYSTEM(LIBCLI_NMB,[], [libcli/unexpected.o libcli/namecache.o libcli/nmblib.o libcli/namequery.o]) +SMB_SUBSYSTEM_MK(LIBCLI_AUTH,libcli/config.mk) + SMB_SUBSYSTEM(LIBCLI,[],[],[], [LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB]) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk new file mode 100644 index 0000000000..f07103d7c6 --- /dev/null +++ b/source4/libcli/config.mk @@ -0,0 +1,23 @@ +################################# +# Start SUBSYSTEM LIBCLI_AUTH +[SUBSYSTEM::LIBCLI_AUTH] +ADD_OBJ_FILES = \ + libcli/auth/spnego.o \ + libcli/auth/spnego_parse.o \ + libcli/auth/ntlmssp.o \ + libcli/auth/ntlmssp_parse.o \ + libcli/auth/ntlmssp_sign.o \ + libcli/auth/schannel.o \ + libcli/auth/credentials.o \ + libcli/auth/session.o \ + libcli/auth/ntlm_check.o \ + libcli/auth/kerberos_kinit.o \ + libcli/auth/kerberos_verify.o \ + libcli/auth/clikrb5.o \ + libcli/auth/gensec.o \ + libcli/auth/gensec_ntlmssp.o +REQUIRED_SUBSYSTEMS = \ + AUTH SCHANNELDB +# End SUBSYSTEM LIBCLI_AUTH +################################# + -- cgit From b0d61c8b42dff8cafa502c279acad5db43c0dea8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:16:36 +0000 Subject: r1437: Intermediate commit of krb5 for GENSEC. The session key in the client is wrong, we don't do signing/sealing and we are sending raw Kerberos, not GSSAPI. But it's a start, and if we continue to have to call Krb5 directly, this will be the basis. I also intend to provide an alternate implementation, using just GSSAPI. Andrew Bartlett (This used to be commit eb0dd4a821dc3dbe370aea9a9c9fb05cf2592e4d) --- source4/libcli/auth/gensec_krb5.c | 351 ++++++++++++++++++++++++++++++++++ source4/libcli/auth/kerberos_verify.c | 49 +---- 2 files changed, 360 insertions(+), 40 deletions(-) create mode 100644 source4/libcli/auth/gensec_krb5.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c new file mode 100644 index 0000000000..2035a5bf9a --- /dev/null +++ b/source4/libcli/auth/gensec_krb5.c @@ -0,0 +1,351 @@ +/* + Unix SMB/CIFS implementation. + + Kerberos backend for GENSEC + + Copyright (C) Andrew Bartlett 2004 + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002-2003 + + 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" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +enum GENSEC_KRB5_STATE { + GENSEC_KRB5_SERVER_START, + GENSEC_KRB5_CLIENT_START, + GENSEC_KRB5_CLIENT_MUTUAL_AUTH, + GENSEC_KRB5_DONE +}; + +struct gensec_krb5_state { + TALLOC_CTX *mem_ctx; + DATA_BLOB session_key; + DATA_BLOB pac; + enum GENSEC_KRB5_STATE state_position; + krb5_context krb5_context; + krb5_auth_context krb5_auth_context; +}; + +static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) +{ + struct gensec_krb5_state *gensec_krb5_state; + krb5_error_code ret = 0; + + TALLOC_CTX *mem_ctx = talloc_init("gensec_krb5"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + gensec_krb5_state = talloc_p(mem_ctx, struct gensec_krb5_state); + if (!gensec_krb5_state) { + return NT_STATUS_NO_MEMORY; + } + + gensec_krb5_state->mem_ctx = mem_ctx; + + gensec_security->private_data = gensec_krb5_state; + + initialize_krb5_error_table(); + gensec_krb5_state->krb5_context = NULL; + gensec_krb5_state->krb5_auth_context = NULL; + gensec_krb5_state->session_key = data_blob(NULL, 0); + + ret = krb5_init_context(&gensec_krb5_state->krb5_context); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", error_message(ret))); + return NT_STATUS_INTERNAL_ERROR; + } + + if (lp_realm() && *lp_realm()) { + ret = krb5_set_default_realm(gensec_krb5_state->krb5_context, lp_realm()); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_set_default_realm failed (%s)\n", error_message(ret))); + return NT_STATUS_INTERNAL_ERROR; + } + } + + ret = krb5_auth_con_init(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_auth_context); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n", error_message(ret))); + return NT_STATUS_INTERNAL_ERROR; + } + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + struct gensec_krb5_state *gensec_krb5_state; + + nt_status = gensec_krb5_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_krb5_state = gensec_security->private_data; + gensec_krb5_state->state_position = GENSEC_KRB5_SERVER_START; + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security) +{ + struct gensec_krb5_state *gensec_krb5_state; + + NTSTATUS nt_status; + nt_status = gensec_krb5_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_krb5_state = gensec_security->private_data; + gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; + + return NT_STATUS_OK; +} + +static void gensec_krb5_end(struct gensec_security *gensec_security) +{ + struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + + if (gensec_krb5_state->krb5_auth_context) { + krb5_auth_con_free(gensec_krb5_state->krb5_context, + gensec_krb5_state->krb5_auth_context); + } + + if (gensec_krb5_state->krb5_context) { + krb5_free_context(gensec_krb5_state->krb5_context); + } + + talloc_destroy(gensec_krb5_state->mem_ctx); + gensec_security->private_data = NULL; +} + + +/** + * Next state function for the Krb5 GENSEC mechanism + * + * @param gensec_krb5_state KRB5 State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + krb5_error_code ret = 0; + DATA_BLOB pac; + NTSTATUS nt_status; + + switch (gensec_krb5_state->state_position) { + case GENSEC_KRB5_CLIENT_START: + { + krb5_data packet; + krb5_ccache ccdef = NULL; + +#if 0 /* When we get some way to input the time offset */ + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } +#endif + + ret = krb5_cc_default(gensec_krb5_state->krb5_context, &ccdef); + if (ret) { + DEBUG(1,("krb5_cc_default failed (%s)\n", + error_message(ret))); + return NT_STATUS_INTERNAL_ERROR; + } + + ret = ads_krb5_mk_req(gensec_krb5_state->krb5_context, + &gensec_krb5_state->krb5_auth_context, + AP_OPTS_USE_SUBKEY +#ifdef MUTUAL_AUTH + | AP_OPTS_MUTUAL_REQUIRED +#endif + , + gensec_security->target.principal, + ccdef, &packet); + if (ret) { + DEBUG(1,("ads_krb5_mk_req (request ticket) failed (%s)\n", + error_message(ret))); + nt_status = NT_STATUS_LOGON_FAILURE; + } else { + *out = data_blob_talloc(out_mem_ctx, packet.data, packet.length); + + /* Hmm, heimdal dooesn't have this - what's the correct call? */ +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(gensec_krb5_state->krb5_context, &packet); +#endif +#ifdef MUTUAL_AUTH + gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; +#else + gensec_krb5_state->state_position = GENSEC_KRB5_DONE; + nt_status = NT_STATUS_OK; +#endif + } + + /* Removed by jra. They really need to fix their kerberos so we don't leak memory. + JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro + */ +#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ + krb5_cc_close(context, ccdef); +#endif + return nt_status; + } + + case GENSEC_KRB5_CLIENT_MUTUAL_AUTH: + { + krb5_data inbuf; + krb5_ap_rep_enc_part *repl = NULL; + inbuf.data = in.data; + inbuf.length = in.length; + ret = krb5_rd_rep(gensec_krb5_state->krb5_context, + gensec_krb5_state->krb5_auth_context, + &inbuf, &repl); + if (ret) { + DEBUG(1,("krb5_rd_rep (mutual authentication) failed (%s)\n", + error_message(ret))); + dump_data_pw("Mutual authentication message:\n", in.data, in.length); + nt_status = NT_STATUS_ACCESS_DENIED; + } else { + *out = data_blob(NULL, 0); + nt_status = NT_STATUS_OK; + gensec_krb5_state->state_position = GENSEC_KRB5_DONE; + } + if (repl) { + krb5_free_ap_rep_enc_part(gensec_krb5_state->krb5_context, repl); + } + return nt_status; + } + + case GENSEC_KRB5_SERVER_START: + { + char *principal; + + nt_status = ads_verify_ticket(out_mem_ctx, + gensec_krb5_state->krb5_context, + gensec_krb5_state->krb5_auth_context, + lp_realm(), &in, + &principal, &pac, out); + gensec_krb5_state->pac = data_blob_talloc_steal(out_mem_ctx, gensec_krb5_state->mem_ctx, + &pac); + /* TODO: parse the pac */ + + if (NT_STATUS_IS_OK(nt_status)) { + gensec_krb5_state->state_position = GENSEC_KRB5_DONE; + } + SAFE_FREE(principal); + return nt_status; + } + case GENSEC_KRB5_DONE: + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_PARAMETER; +} + +static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) +{ + struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + krb5_context context = gensec_krb5_state->krb5_context; + krb5_auth_context auth_context = gensec_krb5_state->krb5_auth_context; + krb5_keyblock *skey; + krb5_error_code err; + + if (gensec_krb5_state->session_key.data) { + *session_key = gensec_krb5_state->session_key; + return NT_STATUS_OK; + } + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); + break; + case GENSEC_SERVER: + err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); + break; + } + if (err == 0 && skey != NULL) { + DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); + gensec_krb5_state->session_key = data_blob_talloc(gensec_krb5_state->mem_ctx, + KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + *session_key = gensec_krb5_state->session_key; + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + krb5_free_keyblock(context, skey); + return NT_STATUS_OK; + } else { + DEBUG(10, ("KRB5 error getting session key %d\n", err)); + return NT_STATUS_NO_USER_SESSION_KEY; + } +} + + +static const struct gensec_security_ops gensec_krb5_security_ops = { + .name = "krb5", + .auth_type = DCERPC_AUTH_TYPE_KRB5, + .oid = OID_KERBEROS5, + .client_start = gensec_krb5_client_start, + .server_start = gensec_krb5_server_start, + .update = gensec_krb5_update, + .session_key = gensec_krb5_session_key, + .end = gensec_krb5_end +}; + +static const struct gensec_security_ops gensec_ms_krb5_security_ops = { + .name = "ms_krb5", + .auth_type = DCERPC_AUTH_TYPE_KRB5, + .oid = OID_KERBEROS5_OLD, + .client_start = gensec_krb5_client_start, + .server_start = gensec_krb5_server_start, + .update = gensec_krb5_update, + .session_key = gensec_krb5_session_key, + .end = gensec_krb5_end +}; + + +NTSTATUS gensec_krb5_init(void) +{ + NTSTATUS ret; + ret = register_backend("gensec", &gensec_krb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_krb5_security_ops.name)); + return ret; + } + + ret = register_backend("gensec", &gensec_ms_krb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_krb5_security_ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index e93d3aa6e8..d24244e0d9 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -202,14 +202,14 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au authorization_data if available. ***********************************************************************************/ -NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, +NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, + krb5_context context, + krb5_auth_context auth_context, + const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep, - DATA_BLOB *session_key) + DATA_BLOB *ap_rep) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; - krb5_context context = NULL; - krb5_auth_context auth_context = NULL; krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; @@ -219,38 +219,18 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char *host_princ_s = NULL; BOOL got_replay_mutex = False; - fstring myname; + char *myname; BOOL auth_ok = False; ZERO_STRUCT(packet); ZERO_STRUCTP(auth_data); ZERO_STRUCTP(ap_rep); - ZERO_STRUCTP(session_key); - - initialize_krb5_error_table(); - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_set_default_realm(context, realm); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); - goto out; - } /* This whole process is far more complex than I would like. We have to go through all this to allow us to store the secret internally, instead of using /etc/krb5.keytab */ - ret = krb5_auth_con_init(context, &auth_context); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); - goto out; - } - - name_to_fqdn(myname, global_myname()); + myname = name_to_fqdn(mem_ctx, global_myname()); strlower_m(myname); asprintf(&host_princ_s, "host/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); @@ -309,18 +289,15 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } - *ap_rep = data_blob(packet.data, packet.length); + *ap_rep = data_blob_talloc(mem_ctx, packet.data, packet.length); SAFE_FREE(packet.data); packet.length = 0; - get_krb5_smb_session_key(context, auth_context, session_key, True); - dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); - #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - get_auth_data_from_tkt(auth_data, tkt); + get_auth_data_from_tkt(mem_ctx, auth_data, tkt); #if 0 if (tkt->enc_part2) { @@ -364,14 +341,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, SAFE_FREE(host_princ_s); - if (auth_context) { - krb5_auth_con_free(context, auth_context); - } - - if (context) { - krb5_free_context(context); - } - return sret; } -- cgit From 47fc62a097b0529657114f77f89858ad7fb52528 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:20:42 +0000 Subject: r1438: Record the principal name we are sent in the SPENGO mechListMIC in a seperate char *, not a DATA_BLOB. This allows us to tell if we were sent a string here, or a real MIC. (This used to be commit 06b997c826e3ec00e0528da800e3eae0e3497a54) --- source4/libcli/auth/spnego.h | 1 + source4/libcli/auth/spnego_parse.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index decd79e107..926cb7f88d 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -45,6 +45,7 @@ struct spnego_negTokenInit { int reqFlags; DATA_BLOB mechToken; DATA_BLOB mechListMIC; + char *targetPrincipal; }; struct spnego_negTokenTarg { diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index b239a4ebf0..d32fd65c4d 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -95,9 +95,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token asn1_pop_tag(asn1); asn1_pop_tag(asn1); - token->mechListMIC = - data_blob(mechListMIC, strlen(mechListMIC)); - SAFE_FREE(mechListMIC); + token->targetPrincipal = mechListMIC; } asn1_end_tag(asn1); break; @@ -355,6 +353,7 @@ BOOL spnego_free_data(struct spnego_data *spnego) } data_blob_free(&spnego->negTokenInit.mechToken); data_blob_free(&spnego->negTokenInit.mechListMIC); + SAFE_FREE(spnego->negTokenInit.targetPrincipal); break; case SPNEGO_NEG_TOKEN_TARG: if (spnego->negTokenTarg.supportedMech) { -- cgit From 43e7d4109f144e20d661fe0559cb47708b511978 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:26:50 +0000 Subject: r1439: Once we are authenticated, always return NT_STATUS_OK. (Makes SPENGO easier to code, as it may return an 'ok' with an empty blob). Andrew Bartlett (This used to be commit e48557158ed99eee7d3ef8231c629bbd14cda9d3) --- source4/libcli/auth/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 6830db3f90..3c656f4e9e 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -228,7 +228,7 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, *out = data_blob(NULL, 0); if (ntlmssp_state->expected_state == NTLMSSP_DONE) { - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_OK; } if (!out_mem_ctx) { -- cgit From b0d94c8e7d6ee223198600747c7e70028b2ff418 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:29:54 +0000 Subject: r1440: GENSEC improvements: - Infrustructure for kerberos - Don't segfault on un-implemented backend functions - Add comments. Andrew Bartlett (This used to be commit 1c31aa42710421917428d6ba86328ea5179751bd) --- source4/libcli/auth/gensec.c | 58 +++++++++++++++++++++++++++++++++++++++++++- source4/libcli/auth/gensec.h | 9 +++++++ 2 files changed, 66 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 2491410494..83738109c6 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -242,6 +242,9 @@ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) { + if (!gensec_security->ops->unseal_packet) { + return NT_STATUS_NOT_IMPLEMENTED; + } return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, data, length, sig); } @@ -250,6 +253,9 @@ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, const uint8_t *data, size_t length, const DATA_BLOB *sig) { + if (!gensec_security->ops->check_packet) { + return NT_STATUS_NOT_IMPLEMENTED; + } return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, sig); } @@ -258,6 +264,9 @@ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, uint8_t *data, size_t length, DATA_BLOB *sig) { + if (!gensec_security->ops->seal_packet) { + return NT_STATUS_NOT_IMPLEMENTED; + } return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, sig); } @@ -266,15 +275,31 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, const uint8_t *data, size_t length, DATA_BLOB *sig) { + if (!gensec_security->ops->sign_packet) { + return NT_STATUS_NOT_IMPLEMENTED; + } return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, sig); } NTSTATUS gensec_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { + if (!gensec_security->ops->session_key) { + return NT_STATUS_NOT_IMPLEMENTED; + } return gensec_security->ops->session_key(gensec_security, session_key); } +/** + * Return the credentials of a logged on user, including session keys + * etc. + * + * Only valid after a successful authentication + * + * May only be called once per authentication. + * + */ + NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info) { @@ -356,6 +381,34 @@ NTSTATUS gensec_set_password(struct gensec_security *gensec_security, return NT_STATUS_OK; } +/** + * Set a kerberos realm on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *realm) +{ + gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, realm); + if (!gensec_security->user.realm) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set the target principal name (if already known) on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) +{ + gensec_security->target.principal = talloc_strdup(gensec_security->mem_ctx, principal); + if (!gensec_security->target.principal) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + /** * Set a password callback, if the gensec module we use demands a password */ @@ -457,7 +510,10 @@ BOOL gensec_init(void) /* FIXME: Perhaps panic if a basic backend, such as NTLMSSP, fails to initialise? */ gensec_ntlmssp_init(); - gensec_spengo_init(); +#if 0 + gensec_krb5_init(); +#endif + gensec_spnego_init(); gensec_dcerpc_schannel_init(); initialised = True; diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index e30369ba0b..7cd56936d2 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -25,10 +25,18 @@ struct gensec_security; struct gensec_user { const char *domain; + const char *realm; const char *name; const char *password; char schan_session_key[16]; }; +struct gensec_target { + const char *principal; + const char *hostname; + const struct sock_addr *addr; +}; + + /* GENSEC mode */ enum gensec_role { @@ -71,6 +79,7 @@ struct gensec_security { const struct gensec_security_ops *ops; void *private_data; struct gensec_user user; + struct gensec_target target; enum gensec_role gensec_role; BOOL subcontext; }; -- cgit From b615397325c894cafd2705e616a7c6642edcf4f0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:38:31 +0000 Subject: r1441: Indentation and comment fixes. Andrew Bartlett (This used to be commit 231e505dea9e9aca28eb336bcbcfb2b7b83c089c) --- source4/libcli/auth/gensec_ntlmssp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 9f7c4c6f86..99247fb626 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -284,7 +284,7 @@ static NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_securi } static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) + DATA_BLOB *session_key) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; @@ -294,7 +294,7 @@ static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_securi /** * Next state function for the wrapped NTLMSSP state machine * - * @param gensec_ntlmssp_state NTLMSSP State + * @param gensec_security GENSEC state, initialised to NTLMSSP * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on * @param in The request, as a DATA_BLOB * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx @@ -303,7 +303,7 @@ static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_securi */ static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) + const DATA_BLOB in, DATA_BLOB *out) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; -- cgit From 0f3f9090faa0f35b5ead4a4ac6801a5caa43766c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:41:44 +0000 Subject: r1442: I was going to rename kerberos.c -> kerberos_kinit.c, but didn't. Fix config.mk... (oh, and this file is somehow marked as binary...) Andrew Bartlett (This used to be commit 3e9aa67e3fdd9be18bdead6d45a982d30e5fd5b4) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index f07103d7c6..0894ac7174 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -11,7 +11,7 @@ ADD_OBJ_FILES = \ libcli/auth/credentials.o \ libcli/auth/session.o \ libcli/auth/ntlm_check.o \ - libcli/auth/kerberos_kinit.o \ + libcli/auth/kerberos.o \ libcli/auth/kerberos_verify.o \ libcli/auth/clikrb5.o \ libcli/auth/gensec.o \ -- cgit From bd38d43214ebe71715776f1c0c1b9edf6e1b28ef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 10:47:41 +0000 Subject: r1443: More changes towards Kerberos in Samba4's GENSEC. The kerberos context is now tied in life to the GENSEC context. Andrew Bartlett (This used to be commit 64e99170c3b53a14d7f8d29cf78283f2bc22c1f7) --- source4/libcli/auth/clikrb5.c | 139 +++-------------------------------------- source4/libcli/auth/kerberos.h | 17 ++++- 2 files changed, 24 insertions(+), 132 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index cf0c4b6424..17824ceefe 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -23,16 +23,6 @@ #ifdef HAVE_KRB5 -#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE -#define KRB5_KEY_TYPE(k) ((k)->keytype) -#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) -#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -#else -#define KRB5_KEY_TYPE(k) ((k)->enctype) -#define KRB5_KEY_LENGTH(k) ((k)->length) -#define KRB5_KEY_DATA(k) ((k)->contents) -#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ - #ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. @@ -160,7 +150,8 @@ } #endif - void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, + DATA_BLOB *auth_data, krb5_ticket *tkt) { #if defined(HAVE_KRB5_TKT_ENC_PART2) if (tkt->enc_part2) @@ -286,12 +277,12 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -static krb5_error_code ads_krb5_mk_req(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf) + krb5_error_code ads_krb5_mk_req(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf) { krb5_error_code retval; krb5_principal server; @@ -374,111 +365,6 @@ cleanup_princ: return retval; } -/* - get a kerberos5 ticket for the given service -*/ -int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) -{ - krb5_error_code retval; - krb5_data packet; - krb5_context context = NULL; - krb5_ccache ccdef = NULL; - krb5_auth_context auth_context = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; - - retval = krb5_init_context(&context); - if (retval) { - DEBUG(1,("krb5_init_context failed (%s)\n", - error_message(retval))); - goto failed; - } - - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } - - if ((retval = krb5_cc_default(context, &ccdef))) { - DEBUG(1,("krb5_cc_default failed (%s)\n", - error_message(retval))); - goto failed; - } - - if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { - DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n", - error_message(retval))); - goto failed; - } - - if ((retval = ads_krb5_mk_req(context, - &auth_context, - AP_OPTS_USE_SUBKEY, - principal, - ccdef, &packet))) { - goto failed; - } - - get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); - - *ticket = data_blob(packet.data, packet.length); - -/* Hmm, heimdal dooesn't have this - what's the correct call? */ -#ifdef HAVE_KRB5_FREE_DATA_CONTENTS - krb5_free_data_contents(context, &packet); -#endif - -failed: - - if ( context ) { -/* Removed by jra. They really need to fix their kerberos so we don't leak memory. - JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro -*/ - if (ccdef) -#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ - krb5_cc_close(context, ccdef); -#endif - if (auth_context) - krb5_auth_con_free(context, auth_context); - krb5_free_context(context); - } - - return retval; -} - - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) - { - krb5_keyblock *skey; - krb5_error_code err; - BOOL ret = False; - - memset(session_key, 0, 16); - - if (remote) - err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); - else - err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); - if (err == 0 && skey != NULL) { - DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); - *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); - - ret = True; - - krb5_free_keyblock(context, skey); - } else { - DEBUG(10, ("KRB5 error getting session key %d\n", err)); - } - - return ret; - } - #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) @@ -502,13 +388,4 @@ failed: #endif } -#else /* HAVE_KRB5 */ - /* this saves a few linking headaches */ -int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) -{ - DEBUG(0,("NO KERBEROS SUPPORT\n")); - return 1; -} - #endif diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 6f63f6eef2..193a1a9438 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -21,6 +21,16 @@ #if defined(HAVE_KRB5) +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + #ifndef HAVE_KRB5_SET_REAL_TIME krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds); #endif @@ -40,11 +50,16 @@ void krb5_free_unparsed_name(krb5_context ctx, char *val); /* Samba wrapper function for krb5 functionality. */ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr); int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); -void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt); krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote); +krb5_error_code ads_krb5_mk_req(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf); #endif /* HAVE_KRB5 */ -- cgit From f17eb8f2a9d0234b0d31f7ded76b8ef9ab945f02 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 11:45:56 +0000 Subject: r1445: Ensure get_auth_data_from_tkt doesn't get into proto.h Andrew Bartlett (This used to be commit 159c234589e8e148180217f9ef4853b3031877db) --- source4/libcli/auth/clikrb5.c | 4 ++-- source4/libcli/auth/kerberos.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 17824ceefe..c4bab57996 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -150,8 +150,8 @@ } #endif -void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, - DATA_BLOB *auth_data, krb5_ticket *tkt) + void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, + DATA_BLOB *auth_data, krb5_ticket *tkt) { #if defined(HAVE_KRB5_TKT_ENC_PART2) if (tkt->enc_part2) diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 193a1a9438..fae00a5646 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -61,5 +61,7 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, const char *principal, krb5_ccache ccache, krb5_data *outbuf); +void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, + DATA_BLOB *auth_data, krb5_ticket *tkt); #endif /* HAVE_KRB5 */ -- cgit From 59a3aece8129d35e7b6c540b75cd585e88b4c05f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 11:48:21 +0000 Subject: r1446: Another funciton to avoid in proto.h Andrew Bartlett (This used to be commit 310a570936c0d2d5af168aeca1b33206622d8355) --- source4/libcli/auth/kerberos.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index fae00a5646..75dd4eeaa2 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -63,5 +63,11 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_data *outbuf); void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt); +NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, + krb5_context context, + krb5_auth_context auth_context, + const char *realm, const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data, + DATA_BLOB *ap_rep) #endif /* HAVE_KRB5 */ -- cgit From 7980759352877a1aa67d9afd398debbbc6e0743a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 11:52:01 +0000 Subject: r1447: Fix compile. Andrew Bartlett (This used to be commit b97ea8a63f044d2c20781c876575978cc4725285) --- source4/libcli/auth/kerberos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 75dd4eeaa2..4a9d82acf1 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -68,6 +68,6 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_auth_context auth_context, const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep) + DATA_BLOB *ap_rep); #endif /* HAVE_KRB5 */ -- cgit From f9ddbad0067606cf2aca0ee62e701ed21491cdec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Jul 2004 12:08:33 +0000 Subject: r1448: Indent this so proto doesn't pick it up. Andrew Bartlett (This used to be commit 1164be10af8e1b47824df391196ec37c395a4040) --- source4/libcli/auth/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index d24244e0d9..76e98cb39a 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -202,7 +202,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au authorization_data if available. ***********************************************************************************/ -NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, + NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, krb5_auth_context auth_context, const char *realm, const DATA_BLOB *ticket, -- cgit From 396a729686644838468d06c2b011c33705e731cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Jul 2004 12:15:58 +0000 Subject: r1449: Use the config system somewhat better in libcli/auth (This used to be commit 69de0d95c585c1a73072e921884cbd427c160176) --- source4/libcli/auth/gensec.c | 9 ++------- source4/libcli/auth/spnego.c | 2 +- source4/libcli/config.m4 | 2 -- source4/libcli/config.mk | 23 ----------------------- 4 files changed, 3 insertions(+), 33 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 83738109c6..f4abfd00e5 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -498,7 +498,7 @@ BOOL gensec_init(void) static BOOL initialised; NTSTATUS status; - /* this is *completly* the wrong way to do this */ + /* this is *completely* the wrong way to do this */ if (initialised) { return True; } @@ -508,12 +508,7 @@ BOOL gensec_init(void) return False; } - /* FIXME: Perhaps panic if a basic backend, such as NTLMSSP, fails to initialise? */ - gensec_ntlmssp_init(); -#if 0 - gensec_krb5_init(); -#endif - gensec_spnego_init(); + static_init_gensec; gensec_dcerpc_schannel_init(); initialised = True; diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index c9d0c6f97d..7e0cda42ba 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -579,7 +579,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .end = gensec_spnego_end }; -NTSTATUS gensec_spengo_init(void) +NTSTATUS gensec_spnego_init(void) { NTSTATUS ret; ret = register_backend("gensec", &gensec_spnego_security_ops); diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index c926d7dae6..41f7ad6812 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -46,7 +46,5 @@ SMB_SUBSYSTEM(LIBCLI_NMB,[], libcli/nmblib.o libcli/namequery.o]) -SMB_SUBSYSTEM_MK(LIBCLI_AUTH,libcli/config.mk) - SMB_SUBSYSTEM(LIBCLI,[],[],[], [LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB]) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0894ac7174..e69de29bb2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -1,23 +0,0 @@ -################################# -# Start SUBSYSTEM LIBCLI_AUTH -[SUBSYSTEM::LIBCLI_AUTH] -ADD_OBJ_FILES = \ - libcli/auth/spnego.o \ - libcli/auth/spnego_parse.o \ - libcli/auth/ntlmssp.o \ - libcli/auth/ntlmssp_parse.o \ - libcli/auth/ntlmssp_sign.o \ - libcli/auth/schannel.o \ - libcli/auth/credentials.o \ - libcli/auth/session.o \ - libcli/auth/ntlm_check.o \ - libcli/auth/kerberos.o \ - libcli/auth/kerberos_verify.o \ - libcli/auth/clikrb5.o \ - libcli/auth/gensec.o \ - libcli/auth/gensec_ntlmssp.o -REQUIRED_SUBSYSTEMS = \ - AUTH SCHANNELDB -# End SUBSYSTEM LIBCLI_AUTH -################################# - -- cgit From 453e1e79fb01674f52a5e93ac62cd4e9891782c2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Jul 2004 12:38:27 +0000 Subject: r1450: Oops.. Missing files :-) (This used to be commit eaa2940ba039f59e13d44c6e2dda919ed8e388f5) --- source4/libcli/auth/gensec.m4 | 5 +++++ source4/libcli/auth/gensec.mk | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 source4/libcli/auth/gensec.m4 create mode 100644 source4/libcli/auth/gensec.mk (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 new file mode 100644 index 0000000000..8f8faf5d7c --- /dev/null +++ b/source4/libcli/auth/gensec.m4 @@ -0,0 +1,5 @@ +SMB_SUBSYSTEM_MK(GENSEC,libcli/auth/gensec.mk) +SMB_MODULE_MK(gensec_krb5, GENSEC, NOT, libcli/auth/gensec.mk) +SMB_MODULE_MK(gensec_ntlmssp, GENSEC, STATIC, libcli/auth/gensec.mk) +SMB_MODULE_MK(gensec_spnego, GENSEC, STATIC, libcli/auth/gensec.mk) + diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk new file mode 100644 index 0000000000..7c2c21bafd --- /dev/null +++ b/source4/libcli/auth/gensec.mk @@ -0,0 +1,42 @@ +################################# +# Start SUBSYSTEM GENSEC +[SUBSYSTEM::GENSEC] +INIT_OBJ_FILES = libcli/auth/gensec.o +REQUIRED_SUBSYSTEMS = \ + AUTH SCHANNELDB +# End SUBSYSTEM GENSEC +################################# + +################################################ +# Start MODULE gensec_krb5 +[MODULE::gensec_krb5] +INIT_OBJ_FILES = libcli/auth/gensec_krb5.o +ADD_OBJ_FILES = \ + libcli/auth/clikrb5.o \ + libcli/auth/kerberos.o \ + libcli/auth/kerberos_verify.o +REQUIRED_SUBSYSTEMS = GENSEC +# End MODULE gensec_krb5 +################################################ + +################################################ +# Start MODULE gensec_spnego +[MODULE::gensec_spnego] +INIT_OBJ_FILES = libcli/auth/spnego.o +ADD_OBJ_FILES = \ + libcli/auth/spnego_parse.o +REQUIRED_SUBSYSTEMS = GENSEC +# End MODULE gensec_spnego +################################################ + +################################################ +# Start MODULE gensec_ntlmssp +[MODULE::gensec_ntlmssp] +INIT_OBJ_FILES = libcli/auth/gensec_ntlmssp.o +ADD_OBJ_FILES = \ + libcli/auth/ntlmssp.o \ + libcli/auth/ntlmssp_parse.o \ + libcli/auth/ntlmssp_sign.o +REQUIRED_SUBSYSTEMS = GENSEC AUTH +# End MODULE gensec_ntlmssp +################################################ -- cgit From fb8ae4518ac22df2bd629050292190b18d1f8afb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Jul 2004 12:51:01 +0000 Subject: r1451: More missing files... (This used to be commit 7e9884799e4f450b9693b6e29d7490288ebc969e) --- source4/libcli/auth/config.m4 | 1 + source4/libcli/auth/config.mk | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 source4/libcli/auth/config.m4 create mode 100644 source4/libcli/auth/config.mk (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.m4 b/source4/libcli/auth/config.m4 new file mode 100644 index 0000000000..ae189d651e --- /dev/null +++ b/source4/libcli/auth/config.m4 @@ -0,0 +1 @@ +SMB_SUBSYSTEM_MK(LIBCLI_AUTH,libcli/auth/config.mk) diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk new file mode 100644 index 0000000000..0c7586026b --- /dev/null +++ b/source4/libcli/auth/config.mk @@ -0,0 +1,11 @@ +################################# +# Start SUBSYSTEM GENSEC +[SUBSYSTEM::LIBCLI_AUTH] +ADD_OBJ_FILES = libcli/auth/schannel.o \ + libcli/auth/credentials.o \ + libcli/auth/session.o \ + libcli/auth/ntlm_check.o +REQUIRED_SUBSYSTEMS = \ + AUTH SCHANNELDB GENSEC +# End SUBSYSTEM LIBCLI_AUTH +################################# -- cgit From df290b04df092d0a2c8cc1c33381a2d915184695 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Jul 2004 04:26:50 +0000 Subject: r1457: Add the GSSAPI layer to our gensec_krb5 code. Andrew Bartlett (This used to be commit 893a9a3865d7046d8b1cb0418aaf48b88beefa05) --- source4/libcli/auth/gensec_krb5.c | 87 +++++++++++++++++++++++-------------- source4/libcli/auth/gssapi_parse.c | 88 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 33 deletions(-) create mode 100644 source4/libcli/auth/gssapi_parse.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 2035a5bf9a..dbb2a10659 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -66,6 +66,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) initialize_krb5_error_table(); gensec_krb5_state->krb5_context = NULL; gensec_krb5_state->krb5_auth_context = NULL; + gensec_krb5_state->krb5_ccdef = NULL; gensec_krb5_state->session_key = data_blob(NULL, 0); ret = krb5_init_context(&gensec_krb5_state->krb5_context); @@ -120,6 +121,13 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_krb5_state = gensec_security->private_data; gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; + ret = krb5_cc_default(gensec_krb5_state->krb5_context, &gensec_krb5_state->ccdef); + if (ret) { + DEBUG(1,("krb5_cc_default failed (%s)\n", + error_message(ret))); + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; } @@ -127,6 +135,16 @@ static void gensec_krb5_end(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + if (gensec_krb5_state->krb5_ccdef) { + /* Removed by jra. They really need to fix their kerberos so we don't leak memory. + JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro + */ +#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ + krb5_cc_close(context, gensec_krb5_state->krb5_ccdef); +#endif + } + if (gensec_krb5_state->krb5_auth_context) { krb5_auth_con_free(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context); @@ -164,7 +182,6 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL case GENSEC_KRB5_CLIENT_START: { krb5_data packet; - krb5_ccache ccdef = NULL; #if 0 /* When we get some way to input the time offset */ if (time_offset != 0) { @@ -172,20 +189,9 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL } #endif - ret = krb5_cc_default(gensec_krb5_state->krb5_context, &ccdef); - if (ret) { - DEBUG(1,("krb5_cc_default failed (%s)\n", - error_message(ret))); - return NT_STATUS_INTERNAL_ERROR; - } - ret = ads_krb5_mk_req(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_auth_context, - AP_OPTS_USE_SUBKEY -#ifdef MUTUAL_AUTH - | AP_OPTS_MUTUAL_REQUIRED -#endif - , + AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, gensec_security->target.principal, ccdef, &packet); if (ret) { @@ -193,28 +199,19 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL error_message(ret))); nt_status = NT_STATUS_LOGON_FAILURE; } else { - *out = data_blob_talloc(out_mem_ctx, packet.data, packet.length); + DATA_BLOB unwrapped_out; + unwrapped_out = data_blob_talloc(out_mem_ctx, packet.data, packet.length); + /* wrap that up in a nice GSS-API wrapping */ + *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REQ); /* Hmm, heimdal dooesn't have this - what's the correct call? */ #ifdef HAVE_KRB5_FREE_DATA_CONTENTS krb5_free_data_contents(gensec_krb5_state->krb5_context, &packet); #endif -#ifdef MUTUAL_AUTH gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; -#else - gensec_krb5_state->state_position = GENSEC_KRB5_DONE; - nt_status = NT_STATUS_OK; -#endif } - /* Removed by jra. They really need to fix their kerberos so we don't leak memory. - JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro - */ -#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ - krb5_cc_close(context, ccdef); -#endif return nt_status; } @@ -222,8 +219,16 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL { krb5_data inbuf; krb5_ap_rep_enc_part *repl = NULL; - inbuf.data = in.data; - inbuf.length = in.length; + uint8 tok_id[2]; + DATA_BLOB unwrapped_in; + + if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { + return NT_STATUS_INVALID_PARAMETER; + } + /* TODO: check the tok_id */ + + inbuf.data = unwrapped_in.data; + inbuf.length = unwrapped_in.length; ret = krb5_rd_rep(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context, &inbuf, &repl); @@ -246,18 +251,34 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL case GENSEC_KRB5_SERVER_START: { char *principal; + DATA_BLOB unwrapped_in; + DATA_BLOB unwrapped_out; + uint8 tok_id[2]; + + /* Parse the GSSAPI wrapping, if it's there... (win2k3 allows it to be omited) */ + if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { + nt_status = ads_verify_ticket(out_mem_ctx, + gensec_krb5_state->krb5_context, + gensec_krb5_state->krb5_auth_context, + lp_realm(), &in, + &principal, &pac, &unwrapped_out); + } else { + /* TODO: check the tok_id */ + nt_status = ads_verify_ticket(out_mem_ctx, + gensec_krb5_state->krb5_context, + gensec_krb5_state->krb5_auth_context, + lp_realm(), &unwrapped_in, + &principal, &pac, &unwrapped_out); + } - nt_status = ads_verify_ticket(out_mem_ctx, - gensec_krb5_state->krb5_context, - gensec_krb5_state->krb5_auth_context, - lp_realm(), &in, - &principal, &pac, out); gensec_krb5_state->pac = data_blob_talloc_steal(out_mem_ctx, gensec_krb5_state->mem_ctx, &pac); /* TODO: parse the pac */ if (NT_STATUS_IS_OK(nt_status)) { gensec_krb5_state->state_position = GENSEC_KRB5_DONE; + /* wrap that up in a nice GSS-API wrapping */ + *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REP); } SAFE_FREE(principal); return nt_status; diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c new file mode 100644 index 0000000000..4a80e1d799 --- /dev/null +++ b/source4/libcli/auth/gssapi_parse.c @@ -0,0 +1,88 @@ +/* + Unix SMB/CIFS implementation. + + simple GSSAPI wrappers + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 + + 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" + +/* + generate a krb5 GSS-API wrapper packet given a ticket +*/ +DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8 tok_id[2]) +{ + ASN1_DATA data; + DATA_BLOB ret; + + ZERO_STRUCT(data); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data, OID_KERBEROS5); + + asn1_write(&data, tok_id, 2); + asn1_write(&data, ticket->data, ticket->length); + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob_talloc(mem_ctx, data.data, data.length); + asn1_free(&data); + + return ret; +} + +/* + parse a krb5 GSS-API wrapper packet giving a ticket +*/ +BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8 tok_id[2]) +{ + BOOL ret; + ASN1_DATA data; + int data_remaining; + + asn1_load(&data, *blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data, OID_KERBEROS5); + + data_remaining = asn1_tag_remaining(&data); + + if (data_remaining < 3) { + data.has_error = True; + } else { + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob_talloc(mem_ctx, NULL, data_remaining); + asn1_read(&data, ticket->data, ticket->length); + } + + asn1_end_tag(&data); + + ret = !data.has_error; + + asn1_free(&data); + + return ret; +} + + -- cgit From e053c719ab0f270dbad46dfb9e6eeae22e3b833d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Jul 2004 09:02:09 +0000 Subject: r1460: Avoid a compile warning. Andrew Bartlett (This used to be commit 10a973da88441b255eda7cbc263ef5c4f2f0fcae) --- source4/libcli/raw/clitree.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index f1513ea51c..fcb0a9a660 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -189,6 +189,7 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, union smb_sesssetup setup; union smb_tcon tcon; TALLOC_CTX *mem_ctx; + char *in_path = NULL; *ret_tree = NULL; @@ -272,7 +273,9 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, tcon.generic.level = RAW_TCON_TCONX; tcon.tconx.in.flags = 0; tcon.tconx.in.password = data_blob(NULL, 0); - asprintf(&tcon.tconx.in.path, "\\\\%s\\%s", dest_host, service); + + asprintf(in_path, "\\\\%s\\%s", dest_host, service); + tcon.tconx.in.path = in_path; if (!service_type) { if (strequal(service, "IPC$")) service_type = "IPC"; @@ -283,7 +286,7 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, status = smb_tree_connect(tree, mem_ctx, &tcon); - free(tcon.tconx.in.path); + SAFE_FREE(in_path); if (!NT_STATUS_IS_OK(status)) { cli_tree_close(tree); -- cgit From b62e6f1ec13c6cad5a94a2a27dc14d3fdfdd4cfc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Jul 2004 09:07:10 +0000 Subject: r1461: ntlm_check.c is a server-side peice of code, so it belongs in AUTH. Andrew Bartlett (This used to be commit 67ac9600664e93aa2fe9426127313b57ddaec2cf) --- source4/libcli/auth/ntlm_check.c | 447 --------------------------------------- 1 file changed, 447 deletions(-) delete mode 100644 source4/libcli/auth/ntlm_check.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c deleted file mode 100644 index f101b230d4..0000000000 --- a/source4/libcli/auth/ntlm_check.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Andrew Bartlett 2001-2004 - Copyright (C) Gerald Carter 2003 - Copyright (C) Luke Kenneth Casson Leighton 1996-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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -/**************************************************************************** - Core of smb password checking routine. -****************************************************************************/ - -static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, - const uint8_t *part_passwd, - const DATA_BLOB *sec_blob, - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uint8_t p24[24]; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false ! */ - return False; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return False; - } - - if (nt_response->length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", - (unsigned long)nt_response->length)); - return False; - } - - SMBOWFencrypt(part_passwd, sec_blob->data, p24); - if (user_sess_key != NULL) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(part_passwd, user_sess_key->data); - } - - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, nt_response->data, nt_response->length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, p24, 24); -#endif - return (memcmp(p24, nt_response->data, 24) == 0); -} - -/**************************************************************************** - Core of smb password checking routine. (NTLMv2, LMv2) - Note: The same code works with both NTLMv2 and LMv2. -****************************************************************************/ - -static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, - const uint8_t *part_passwd, - const DATA_BLOB *sec_blob, - const char *user, const char *domain, - BOOL upper_case_domain, /* should the domain be transformed into upper case? */ - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uint8_t kr[16]; - uint8_t value_from_encryption[16]; - uint8_t client_response[16]; - DATA_BLOB client_key_data; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always False */ - return False; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return False; - } - - if (ntv2_response->length < 24) { - /* We MUST have more than 16 bytes, or the stuff below will go - crazy. No known implementation sends less than the 24 bytes - for LMv2, let alone NTLMv2. */ - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", - (unsigned long)ntv2_response->length)); - return False; - } - - client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); - /* - todo: should we be checking this for anything? We can't for LMv2, - but for NTLMv2 it is meant to contain the current time etc. - */ - - memcpy(client_response, ntv2_response->data, sizeof(client_response)); - - if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { - return False; - } - - SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); - if (user_sess_key != NULL) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); - } - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, ntv2_response->data, ntv2_response->length); - DEBUGADD(100,("Variable data from client was |\n")); - dump_data(100, client_key_data.data, client_key_data.length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, value_from_encryption, 16); -#endif - data_blob_clear_free(&client_key_data); - return (memcmp(value_from_encryption, client_response, 16) == 0); -} - -/** - * Check a challenge-response password against the value of the NT or - * LM password hash. - * - * @param mem_ctx talloc context - * @param challenge 8-byte challenge. If all zero, forces plaintext comparison - * @param nt_response 'unicode' NT response to the challenge, or unicode password - * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param nt_pw MD4 unicode password from our passdb or similar - * @param lm_pw LANMAN ASCII password from our passdb or similar - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - const DATA_BLOB *challenge, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, - const DATA_BLOB *lm_interactive_password, - const DATA_BLOB *nt_interactive_password, - const char *username, - const char *client_username, - const char *client_domain, - const uint8_t *lm_pw, const uint8_t *nt_pw, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key) -{ - static const uint8_t zeros[8]; - if (nt_pw == NULL) { - DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", - username)); - } - - if (nt_interactive_password && nt_interactive_password->length && nt_pw) { - if (nt_interactive_password->length != 16) { - DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_password->length, - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (memcmp(nt_interactive_password->data, nt_pw, 16) == 0) { - if (user_sess_key) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_pw, user_sess_key->data); - } - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - } else if (lm_interactive_password && lm_interactive_password->length && lm_pw) { - if (lm_interactive_password->length != 16) { - DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_password->length, - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (!lp_lanman_auth()) { - DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (memcmp(lm_interactive_password->data, lm_pw, 16) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } - - /* Check for cleartext netlogon. Used by Exchange 5.5. */ - if (challenge->length == sizeof(zeros) && - (memcmp(challenge->data, zeros, challenge->length) == 0 )) { - - DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", - username)); - if (nt_pw && nt_response->length) { - uint8_t pwhash[16]; - mdfour(pwhash, nt_response->data, nt_response->length); - if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NT (Unicode) plaintext password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - } else if (!lp_lanman_auth()) { - DEBUG(3,("ntlm_password_check: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", - username)); - - } else if (lm_pw && lm_response->length) { - uint8_t dospwd[14]; - uint8_t p16[16]; - ZERO_STRUCT(dospwd); - - memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); - /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - - /* we *might* need to upper-case the string here */ - E_P16((const uint8_t *)dospwd, p16); - - if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: LANMAN (ASCII) plaintext password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); - return NT_STATUS_WRONG_PASSWORD; - } - } - - if (nt_response->length != 0 && nt_response->length < 24) { - DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - } - - if (nt_response->length >= 24 && nt_pw) { - if (nt_response->length > 24) { - /* We have the NT MD4 hash challenge available - see if we can - use it - */ - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2( nt_response, - nt_pw, challenge, - client_username, - client_domain, - False, - user_sess_key)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2( nt_response, - nt_pw, challenge, - client_username, - client_domain, - True, - user_sess_key)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( nt_response, - nt_pw, challenge, - client_username, - "", - False, - user_sess_key)) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } - } - - if (lp_ntlm_auth()) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(nt_response, - nt_pw, challenge, - user_sess_key)) { - /* The LM session key for this response is not very secure, - so use it only if we otherwise allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - *lm_sess_key = data_blob(lm_pw, 8); - } - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n", - username)); - /* no return, becouse we might pick up LMv2 in the LM field */ - } - } - - if (lm_response->length == 0) { - DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (lm_response->length < 24) { - DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (!lp_lanman_auth()) { - DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", - username)); - } else if (!lm_pw) { - DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n", - username)); - } else { - DEBUG(4,("ntlm_password_check: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(lm_response, - lm_pw, challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(lm_pw, 8); - } - return NT_STATUS_OK; - } - } - - if (!nt_pw) { - DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username)); - return NT_STATUS_WRONG_PASSWORD; - } - - /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. - - related to Win9X, legacy NAS pass-though authentication - */ - DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2( lm_response, - nt_pw, challenge, - client_username, - client_domain, - False, - NULL)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2( lm_response, - nt_pw, challenge, - client_username, - client_domain, - True, - NULL)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( lm_response, - nt_pw, challenge, - client_username, - "", - False, - NULL)) { - return NT_STATUS_OK; - } - - /* Apparently NT accepts NT responses in the LM field - - I think this is related to Win9X pass-though authentication - */ - DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); - if (lp_ntlm_auth()) { - if (smb_pwd_check_ntlmv1(lm_response, - nt_pw, challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(lm_pw, 8); - } - return NT_STATUS_OK; - } - DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); - } else { - DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); - } - return NT_STATUS_WRONG_PASSWORD; -} - -- cgit From 88002b851bd30e3c03a5a9442baf3ced7aa6090f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Jul 2004 09:11:13 +0000 Subject: r1462: GENSEC Kerberos and SPENGO work: - Spelling - it's SPNEGO, not SPENGO - SMB signing - Krb5 logins are now correctly signed - SPNEGO - Changes to always tell GENSEC about incoming packets, empty or not. Andrew Bartlett (This used to be commit cea578d6f39a2ea4a24e7a0064c95193ab6f6df7) --- source4/libcli/auth/config.mk | 3 +- source4/libcli/auth/gensec.mk | 5 +- source4/libcli/auth/gensec_krb5.c | 13 ++-- source4/libcli/auth/spnego.c | 122 +++++++++++++++++++------------------- source4/libcli/raw/clisession.c | 30 ++++++---- source4/libcli/raw/clitransport.c | 4 +- source4/libcli/raw/smb_signing.c | 101 +++++++++++++++++++++++-------- 7 files changed, 168 insertions(+), 110 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 0c7586026b..a3bb3f1c78 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -3,8 +3,7 @@ [SUBSYSTEM::LIBCLI_AUTH] ADD_OBJ_FILES = libcli/auth/schannel.o \ libcli/auth/credentials.o \ - libcli/auth/session.o \ - libcli/auth/ntlm_check.o + libcli/auth/session.o REQUIRED_SUBSYSTEMS = \ AUTH SCHANNELDB GENSEC # End SUBSYSTEM LIBCLI_AUTH diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index 7c2c21bafd..5c6a8260e5 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -3,7 +3,7 @@ [SUBSYSTEM::GENSEC] INIT_OBJ_FILES = libcli/auth/gensec.o REQUIRED_SUBSYSTEMS = \ - AUTH SCHANNELDB + SCHANNELDB # End SUBSYSTEM GENSEC ################################# @@ -14,7 +14,8 @@ INIT_OBJ_FILES = libcli/auth/gensec_krb5.o ADD_OBJ_FILES = \ libcli/auth/clikrb5.o \ libcli/auth/kerberos.o \ - libcli/auth/kerberos_verify.o + libcli/auth/kerberos_verify.o \ + libcli/auth/gssapi_parse.o REQUIRED_SUBSYSTEMS = GENSEC # End MODULE gensec_krb5 ################################################ diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index dbb2a10659..3a4f995937 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -42,6 +42,7 @@ struct gensec_krb5_state { enum GENSEC_KRB5_STATE state_position; krb5_context krb5_context; krb5_auth_context krb5_auth_context; + krb5_ccache krb5_ccache; }; static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) @@ -66,7 +67,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) initialize_krb5_error_table(); gensec_krb5_state->krb5_context = NULL; gensec_krb5_state->krb5_auth_context = NULL; - gensec_krb5_state->krb5_ccdef = NULL; + gensec_krb5_state->krb5_ccache = NULL; gensec_krb5_state->session_key = data_blob(NULL, 0); ret = krb5_init_context(&gensec_krb5_state->krb5_context); @@ -111,7 +112,7 @@ static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state; - + krb5_error_code ret; NTSTATUS nt_status; nt_status = gensec_krb5_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -121,7 +122,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_krb5_state = gensec_security->private_data; gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; - ret = krb5_cc_default(gensec_krb5_state->krb5_context, &gensec_krb5_state->ccdef); + ret = krb5_cc_default(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_ccache); if (ret) { DEBUG(1,("krb5_cc_default failed (%s)\n", error_message(ret))); @@ -135,13 +136,13 @@ static void gensec_krb5_end(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - if (gensec_krb5_state->krb5_ccdef) { + if (gensec_krb5_state->krb5_ccache) { /* Removed by jra. They really need to fix their kerberos so we don't leak memory. JERRY -- disabled since it causes heimdal 0.6.1rc3 to die SuSE 9.1 Pro */ #if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ - krb5_cc_close(context, gensec_krb5_state->krb5_ccdef); + krb5_cc_close(context, gensec_krb5_state->krb5_ccache); #endif } @@ -193,7 +194,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL &gensec_krb5_state->krb5_auth_context, AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, gensec_security->target.principal, - ccdef, &packet); + gensec_krb5_state->krb5_ccache, &packet); if (ret) { DEBUG(1,("ads_krb5_mk_req (request ticket) failed (%s)\n", error_message(ret))); diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 7e0cda42ba..32846cf580 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -48,7 +48,7 @@ struct spnego_state { static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; - TALLOC_CTX *mem_ctx = talloc_init("gensec_spengo_client_start"); + TALLOC_CTX *mem_ctx = talloc_init("gensec_spnego_client_start"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } @@ -151,12 +151,12 @@ static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_securit /** Fallback to another GENSEC mechanism, based on magic strings * - * This is the 'fallback' case, where we don't get SPENGO, and have to + * This is the 'fallback' case, where we don't get SPNEGO, and have to * try all the other options (and hope they all have a magic string * they check) */ -static NTSTATUS gensec_spengo_server_try_fallback(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec_security, struct spnego_state *spnego_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) @@ -189,7 +189,7 @@ static NTSTATUS gensec_spengo_server_try_fallback(struct gensec_security *gensec } gensec_end(&spnego_state->sub_sec_security); } - DEBUG(1, ("Failed to parse SPENGO request\n")); + DEBUG(1, ("Failed to parse SPNEGO request\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -199,7 +199,7 @@ static NTSTATUS gensec_spengo_server_try_fallback(struct gensec_security *gensec * This is the case, where the client is the first one who sends data */ -static NTSTATUS gensec_spengo_client_netTokenInit(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_client_netTokenInit(struct gensec_security *gensec_security, struct spnego_state *spnego_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) @@ -266,7 +266,7 @@ static NTSTATUS gensec_spengo_client_netTokenInit(struct gensec_security *gensec spnego_out.negTokenInit.mechToken = unwrapped_out; if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -277,7 +277,7 @@ static NTSTATUS gensec_spengo_client_netTokenInit(struct gensec_security *gensec } gensec_end(&spnego_state->sub_sec_security); - DEBUG(1, ("Failed to setup SPENGO netTokenInit request\n")); + DEBUG(1, ("Failed to setup SPNEGO netTokenInit request\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -286,7 +286,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA { struct spnego_state *spnego_state = gensec_security->private_data; DATA_BLOB null_data_blob = data_blob(NULL, 0); - DATA_BLOB unwrapped_out; + DATA_BLOB unwrapped_out = data_blob(NULL, 0); struct spnego_data spnego_out; struct spnego_data spnego; @@ -307,7 +307,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (in.length) { len = spnego_read_data(in, &spnego); if (len == -1) { - return gensec_spengo_server_try_fallback(gensec_security, spnego_state, out_mem_ctx, in, out); + return gensec_spnego_server_try_fallback(gensec_security, spnego_state, out_mem_ctx, in, out); } else { /* client sent NegTargetInit */ } @@ -328,7 +328,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!in.length) { /* client to produce negTokenInit */ - return gensec_spengo_client_netTokenInit(gensec_security, spnego_state, out_mem_ctx, in, out); + return gensec_spnego_client_netTokenInit(gensec_security, spnego_state, out_mem_ctx, in, out); } len = spnego_read_data(in, &spnego); @@ -341,13 +341,21 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA /* OK, so it's real SPNEGO, check the packet's the one we expect */ if (spnego.type != spnego_state->expected_packet) { - DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); dump_data(1, (const char *)in.data, in.length); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } + if (spnego.negTokenInit.targetPrincipal) { + nt_status = gensec_set_target_principal(gensec_security, + spnego.negTokenInit.targetPrincipal); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + } + mechType = spnego.negTokenInit.mechTypes; for (i=0; mechType && mechType[i]; i++) { nt_status = gensec_subcontext_start(gensec_security, @@ -375,8 +383,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA null_data_blob, &unwrapped_out); } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { + DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); gensec_end(&spnego_state->sub_sec_security); } else { @@ -384,11 +392,11 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } } if (!mechType || !mechType[i]) { - DEBUG(1, ("SPENGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); } spnego_free_data(&spnego); - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -402,7 +410,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_out.negTokenInit.mechToken = unwrapped_out; if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_INIT\n")); + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -410,7 +418,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; spnego_state->state_position = SPNEGO_CLIENT_TARG; - return nt_status; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } case SPNEGO_SERVER_TARG: { @@ -429,49 +437,47 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA /* OK, so it's real SPNEGO, check the packet's the one we expect */ if (spnego.type != spnego_state->expected_packet) { - DEBUG(1, ("Invalid SPENGO request: %d, expected %d\n", spnego.type, + DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); dump_data(1, (const char *)in.data, in.length); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } - if (spnego.negTokenTarg.responseToken.length) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - } else { - unwrapped_out = data_blob(NULL, 0); - nt_status = NT_STATUS_OK; - } + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); spnego_state->result = spnego.negTokenTarg.negResult; spnego_free_data(&spnego); + /* compose reply */ + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } spnego_state->state_position = SPNEGO_SERVER_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; spnego_state->state_position = SPNEGO_DONE; } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; + DEBUG(1, ("SPNEGO(%s) login failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - return nt_status; + spnego_state->state_position = SPNEGO_DONE; } + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; + } + return nt_status; } case SPNEGO_CLIENT_TARG: @@ -501,16 +507,11 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { return NT_STATUS_ACCESS_DENIED; } - - if (spnego.negTokenTarg.responseToken.length) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - } else { - unwrapped_out = data_blob(NULL, 0); - nt_status = NT_STATUS_OK; - } + + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); if (NT_STATUS_IS_OK(nt_status) && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { @@ -521,27 +522,28 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_state->result = spnego.negTokenTarg.negResult; spnego_free_data(&spnego); + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; + spnego_out.negTokenTarg.supportedMech = NULL; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; - spnego_out.negTokenTarg.supportedMech = NULL; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPENGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } spnego_state->state_position = SPNEGO_CLIENT_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { spnego_state->state_position = SPNEGO_DONE; } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", + DEBUG(1, ("SPNEGO(%s) login failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); return nt_status; } + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; + } return nt_status; } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index d420aa7cd6..5aaceb103a 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -260,7 +260,7 @@ static void use_nt1_session_keys(struct cli_session *session, E_md4hash(password, nt_hash); SMBsesskeygen_ntv1(nt_hash, session_key.data); - cli_transport_simple_set_signing(transport, session_key, *nt_response); + cli_transport_simple_set_signing(transport, session_key, *nt_response, 0); cli_session_set_user_session_key(session, &session_key); data_blob_free(&session_key); @@ -381,6 +381,8 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session { NTSTATUS status; union smb_sesssetup s2; + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB null_data_blob = data_blob(NULL, 0); s2.generic.level = RAW_SESSSETUP_SPNEGO; s2.spnego.in.bufsize = ~0; @@ -433,39 +435,41 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session session->transport->negotiate.secblob, &s2.spnego.in.secblob); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto done; - } - while(1) { + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { + break; + } + + status = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(status)) { + cli_transport_simple_set_signing(session->transport, session_key, null_data_blob, 0); + } + session->vuid = s2.spnego.out.vuid; status = smb_raw_session_setup(session, mem_ctx, &s2); session->vuid = UID_FIELD_INVALID; if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto done; + break; } status = gensec_update(session->gensec, mem_ctx, s2.spnego.out.secblob, &s2.spnego.in.secblob); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto done; + if (NT_STATUS_IS_OK(status)) { + break; } } done: if (NT_STATUS_IS_OK(status)) { - DATA_BLOB null_data_blob = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); - status = gensec_session_key(session->gensec, &session_key); if (!NT_STATUS_IS_OK(status)) { return status; } - - cli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + + cli_transport_simple_set_signing(session->transport, session_key, null_data_blob, 2 /* two legs on last packet */); cli_session_set_user_session_key(session, &session_key); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index a378ac8aad..18784fe33a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -40,7 +40,9 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(); transport->negotiate.max_xmit = ~0; - cli_null_set_signing(transport); + + cli_init_signing(transport); + transport->socket->reference_count++; ZERO_STRUCT(transport->called); diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 20b44a5348..52e08d05f8 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -40,14 +40,18 @@ static BOOL set_smb_signing_common(struct cli_transport *transport) if (transport->negotiate.sign_info.doing_signing) { return False; } - + + if (!transport->negotiate.sign_info.allow_smb_signing) { + return False; + } + if (transport->negotiate.sign_info.free_signing_context) transport->negotiate.sign_info.free_signing_context(transport); /* These calls are INCOMPATIBLE with SMB signing */ transport->negotiate.readbraw_supported = False; transport->negotiate.writebraw_supported = False; - + return True; } @@ -56,9 +60,8 @@ static BOOL set_smb_signing_common(struct cli_transport *transport) ************************************************************/ static BOOL set_smb_signing_real_common(struct cli_transport *transport) { - if (transport->negotiate.sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { + if (transport->negotiate.sign_info.mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); - transport->negotiate.sign_info.doing_signing = True; } DEBUG(5, ("SMB signing enabled!\n")); @@ -74,24 +77,37 @@ static void mark_packet_signed(struct cli_request *req) SSVAL(req->out.hdr, HDR_FLG2, flags2); } -static BOOL signing_good(struct cli_request *req, BOOL good) +static BOOL signing_good(struct cli_request *req, int seq, BOOL good) { - if (good && !req->transport->negotiate.sign_info.doing_signing) { - req->transport->negotiate.sign_info.doing_signing = True; - } - - if (!good) { - if (req->transport->negotiate.sign_info.doing_signing) { - DEBUG(1, ("SMB signature check failed!\n")); - return False; + if (good) { + if (!req->transport->negotiate.sign_info.doing_signing) { + req->transport->negotiate.sign_info.doing_signing = True; + } + if (!req->transport->negotiate.sign_info.seen_valid) { + req->transport->negotiate.sign_info.seen_valid = True; + } + } else { + if (!req->transport->negotiate.sign_info.mandatory_signing && !req->transport->negotiate.sign_info.seen_valid) { + + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" + "isn't sending correct signatures. Turning off.\n")); + req->transport->negotiate.sign_info.negotiated_smb_signing = False; + req->transport->negotiate.sign_info.allow_smb_signing = False; + req->transport->negotiate.sign_info.doing_signing = False; + if (req->transport->negotiate.sign_info.free_signing_context) + req->transport->negotiate.sign_info.free_signing_context(req->transport); + cli_null_set_signing(req->transport); + return True; } else { - DEBUG(3, ("Server did not sign reply correctly\n")); - cli_transport_free_signing_context(req->transport); + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (seq) + DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); return False; } } return True; -} +} /*********************************************************** SMB signing - Simple implementation - calculate a MAC to send. @@ -139,6 +155,9 @@ static void cli_request_simple_sign_outgoing_message(struct cli_request *req) memcpy(&req->out.hdr[HDR_SS_FIELD], calc_md5_mac, 8); + DEBUG(5, ("cli_request_simple_sign_outgoing_message: SENT SIG (seq: %d, next %d): sent SMB signature of\n", + req->seq_num, data->next_seq_num)); + dump_data(5, calc_md5_mac, 8); /* req->out.hdr[HDR_SS_FIELD+2]=0; Uncomment this to test if the remote server actually verifies signitures...*/ } @@ -184,6 +203,20 @@ static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (i == 1) { + if (!good) { + DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", req->seq_num + i)); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", req->seq_num + i)); + dump_data(5, server_sent_mac, 8); + } else { + DEBUG(15, ("cli_request_simple_check_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", req->seq_num + i)); + dump_data(5, server_sent_mac, 8); + } + } + if (good) break; } @@ -191,14 +224,7 @@ static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, req->seq_num+1)); } - if (!good) { - DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, calc_md5_mac, 8); - - DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, server_sent_mac, 8); - } - return signing_good(req, good); + return signing_good(req, req->seq_num+1, good); } @@ -221,7 +247,8 @@ static void cli_transport_simple_free_signing_context(struct cli_transport *tran ************************************************************/ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, const DATA_BLOB user_session_key, - const DATA_BLOB response) + const DATA_BLOB response, + int seq_num) { struct smb_basic_signing_context *data; @@ -245,7 +272,7 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, } /* Initialise the sequence number */ - data->next_seq_num = 0; + data->next_seq_num = seq_num; transport->negotiate.sign_info.sign_outgoing_message = cli_request_simple_sign_outgoing_message; transport->negotiate.sign_info.check_incoming_message = cli_request_simple_check_incoming_message; @@ -393,3 +420,25 @@ BOOL cli_request_check_sign_mac(struct cli_request *req) return True; } + + +BOOL cli_init_signing(struct cli_transport *transport) +{ + if (!cli_null_set_signing(transport)) { + return False; + } + + switch (lp_client_signing()) { + case SMB_SIGNING_OFF: + transport->negotiate.sign_info.allow_smb_signing = False; + break; + case SMB_SIGNING_SUPPORTED: + transport->negotiate.sign_info.allow_smb_signing = True; + break; + case SMB_SIGNING_REQUIRED: + transport->negotiate.sign_info.allow_smb_signing = True; + transport->negotiate.sign_info.mandatory_signing = True; + break; + } + return True; +} -- cgit From 39c3f220348b2bf2f9b81e8972cc65a2cc7e4b63 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Jul 2004 13:15:53 +0000 Subject: r1463: fix the krb5 build metze (This used to be commit fc8d00b8ab28535da4ec0b7e6931bbf402a37013) --- source4/libcli/auth/gensec.m4 | 5 ++++- source4/libcli/auth/gensec.mk | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 8f8faf5d7c..673db77f82 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -1,5 +1,8 @@ +if test t$SMB_EXT_LIB_ENABLE_KRB5 = tYES; then + SMB_MODULE_DEFAULT(gensec_krb5, STATIC) +fi + SMB_SUBSYSTEM_MK(GENSEC,libcli/auth/gensec.mk) SMB_MODULE_MK(gensec_krb5, GENSEC, NOT, libcli/auth/gensec.mk) SMB_MODULE_MK(gensec_ntlmssp, GENSEC, STATIC, libcli/auth/gensec.mk) SMB_MODULE_MK(gensec_spnego, GENSEC, STATIC, libcli/auth/gensec.mk) - diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index 5c6a8260e5..bab79ea2fd 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -17,6 +17,7 @@ ADD_OBJ_FILES = \ libcli/auth/kerberos_verify.o \ libcli/auth/gssapi_parse.o REQUIRED_SUBSYSTEMS = GENSEC +REQUIRED_LIBRARIES = KRB5 # End MODULE gensec_krb5 ################################################ -- cgit From 7193ed39982d6894234b4f5a22d5e4d9a7cdde59 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 12 Jul 2004 13:23:01 +0000 Subject: r1466: the name "oid" is taken by some silly system headers - avoid it in our code (This used to be commit ea5659b051f95402441e69ba4ce5aea1ed6f5c86) --- source4/libcli/auth/gensec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index f4abfd00e5..f4aeedf692 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -39,12 +39,12 @@ static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t aut return NULL; } -static const struct gensec_security_ops *gensec_security_by_oid(const char *oid) +static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_string) { int i; for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->oid && - (strcmp(generic_security_ops[i]->oid, oid) == 0)) { + (strcmp(generic_security_ops[i]->oid, oid_string) == 0)) { return generic_security_ops[i]; } } -- cgit From e5173cfd3aeb53378a78d66115a07694fd924d09 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Jul 2004 13:53:35 +0000 Subject: r1467: disable gensec_krb5 by default till abartlet add the kinit code metze (This used to be commit 9a876be76cee3983676d8c89549162b5c4eba8b0) --- source4/libcli/auth/gensec.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 673db77f82..3d22632a3e 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -1,5 +1,6 @@ if test t$SMB_EXT_LIB_ENABLE_KRB5 = tYES; then - SMB_MODULE_DEFAULT(gensec_krb5, STATIC) + /* enable this when krb5 is fully working */ + SMB_MODULE_DEFAULT(gensec_krb5, NOT) fi SMB_SUBSYSTEM_MK(GENSEC,libcli/auth/gensec.mk) -- cgit From bff4e6963c0b7b58a0886a207f4da0398377157f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Jul 2004 15:34:34 +0000 Subject: r1469: fix a segfault and compiler warning, introduced by the "compiler warning fix" in rev 1460... metze (This used to be commit ffb7ba35cdb2fb19b8271a3585eef075948bef9c) --- source4/libcli/raw/clitree.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index fcb0a9a660..a580ded010 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -272,9 +272,8 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, /* connect to a share using a tree connect */ tcon.generic.level = RAW_TCON_TCONX; tcon.tconx.in.flags = 0; - tcon.tconx.in.password = data_blob(NULL, 0); - - asprintf(in_path, "\\\\%s\\%s", dest_host, service); + tcon.tconx.in.password = data_blob(NULL, 0); + asprintf(&in_path, "\\\\%s\\%s", dest_host, service); tcon.tconx.in.path = in_path; if (!service_type) { if (strequal(service, "IPC$")) -- cgit From ed03516c915c4a4c8ae6f7decfa04d51049d9dd5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Jul 2004 05:14:59 +0000 Subject: r1475: More kerberos work - We can now connect to hosts that follow the SPNEGO RFC, and *do not* give us their principal name in the mechListMIC. - The client code now remembers the hostname it connects to - We now kinit for a user, if there is not valid ticket already - Re-introduce clock skew compensation TODO: - See if the username in the ccache matches the username specified - Use a private ccache, rather then the global one, for a 'new' kinit - Determine 'default' usernames. - The default for Krb5 is the one in the ccache, then $USER - For NTLMSSP, it's just $USER Andrew Bartlett (This used to be commit de5da669397db4ac87c6da08d3533ca3030da2b0) --- source4/libcli/auth/gensec.c | 189 ++++++++++++++++++++++++++++++++++++-- source4/libcli/auth/gensec.h | 2 + source4/libcli/auth/gensec_krb5.c | 114 +++++++++++++++++++---- source4/libcli/auth/kerberos.c | 64 ++++++++----- source4/libcli/auth/kerberos.h | 1 + source4/libcli/auth/spnego.c | 3 +- source4/libcli/raw/clisession.c | 7 ++ source4/libcli/raw/clisocket.c | 11 ++- 8 files changed, 338 insertions(+), 53 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index f4aeedf692..e91497bee4 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -106,6 +106,14 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) (*gensec_security)->mem_ctx = mem_ctx; (*gensec_security)->ops = NULL; + ZERO_STRUCT((*gensec_security)->user); + ZERO_STRUCT((*gensec_security)->target); + ZERO_STRUCT((*gensec_security)->default_user); + + (*gensec_security)->default_user.name = ""; + (*gensec_security)->default_user.domain = talloc_strdup(mem_ctx, lp_workgroup()); + (*gensec_security)->default_user.realm = talloc_strdup(mem_ctx, lp_realm()); + (*gensec_security)->subcontext = False; return NT_STATUS_OK; } @@ -163,6 +171,9 @@ NTSTATUS gensec_server_start(struct gensec_security **gensec_security) static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) { NTSTATUS status; + DEBUG(5, ("Starting GENSEC %smechanism %s\n", + gensec_security->subcontext ? "sub" : "", + gensec_security->ops->name)); switch (gensec_security->gensec_role) { case GENSEC_CLIENT: if (gensec_security->ops->client_start) { @@ -337,6 +348,61 @@ void gensec_end(struct gensec_security **gensec_security) gensec_security = NULL; } +/** + * Set a username on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, const char *user) +{ + char *p; + char *u = talloc_strdup(gensec_security->mem_ctx, user); + if (!u) { + return NT_STATUS_NO_MEMORY; + } + + p = strchr_m(user, '@'); + + if (p) { + *p = '\0'; + gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, u); + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + + gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, p+1); + if (!gensec_security->user.realm) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; + } + + p = strchr_m(user, '\\'); + if (!p) { + p = strchr_m(user, '/'); + } + + if (p) { + *p = '\0'; + gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, u); + if (!gensec_security->user.domain) { + return NT_STATUS_NO_MEMORY; + } + gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, p+1); + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; + } + + gensec_security->user.name = u; + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + /** * Set a username on a GENSEC context - ensures it is talloc()ed * @@ -351,6 +417,19 @@ NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char return NT_STATUS_OK; } +/** + * Set a username on a GENSEC context - ensures it is talloc()ed + * + */ + +const char *gensec_get_username(struct gensec_security *gensec_security) +{ + if (gensec_security->user.name) { + return gensec_security->user.name; + } + return gensec_security->default_user.name; +} + /** * Set a domain on a GENSEC context - ensures it is talloc()ed * @@ -366,19 +445,18 @@ NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char * } /** - * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will - * not do a callback + * Return the NT domain for this GENSEC context * */ -NTSTATUS gensec_set_password(struct gensec_security *gensec_security, - const char *password) +const char *gensec_get_domain(struct gensec_security *gensec_security) { - gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); - if (!gensec_security->user.password) { - return NT_STATUS_NO_MEMORY; + if (gensec_security->user.domain) { + return gensec_security->user.domain; + } else if (gensec_security->user.realm) { + return gensec_security->user.realm; } - return NT_STATUS_OK; + return gensec_security->default_user.domain; } /** @@ -395,6 +473,54 @@ NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *r return NT_STATUS_OK; } +/** + * Return the Krb5 realm for this context + * + */ + +const char *gensec_get_realm(struct gensec_security *gensec_security) +{ + if (gensec_security->user.realm) { + return gensec_security->user.realm; + } else if (gensec_security->user.domain) { + return gensec_security->user.domain; + } + return gensec_security->default_user.realm; +} + +/** + * Return a kerberos principal for this context, if one has been set + * + */ + +char *gensec_get_client_principal(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx) +{ + const char *realm = gensec_get_realm(gensec_security); + if (realm) { + return talloc_asprintf(mem_ctx, "%s@%s", + gensec_get_username(gensec_security), + gensec_get_realm(gensec_security)); + } else { + return talloc_strdup(mem_ctx, gensec_get_username(gensec_security)); + } +} + +/** + * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will + * not do a callback + * + */ + +NTSTATUS gensec_set_password(struct gensec_security *gensec_security, + const char *password) +{ + gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); + if (!gensec_security->user.password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + /** * Set the target principal name (if already known) on a GENSEC context - ensures it is talloc()ed * @@ -409,6 +535,53 @@ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, co return NT_STATUS_OK; } +/** + * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service) +{ + gensec_security->target.service = talloc_strdup(gensec_security->mem_ctx, service); + if (!gensec_security->target.service) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname) +{ + gensec_security->target.hostname = talloc_strdup(gensec_security->mem_ctx, hostname); + if (!gensec_security->target.hostname) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +const char *gensec_get_target_hostname(struct gensec_security *gensec_security) +{ + if (gensec_security->target.hostname) { + return gensec_security->target.hostname; + } + + /* TODO: Add a 'set sockaddr' call, and do a reverse lookup */ + return NULL; +} + +const char *gensec_get_target_service(struct gensec_security *gensec_security) +{ + if (gensec_security->target.service) { + return gensec_security->target.service; + } + + return "host"; +} + /** * Set a password callback, if the gensec module we use demands a password */ diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 7cd56936d2..8e2787530c 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -34,6 +34,7 @@ struct gensec_target { const char *principal; const char *hostname; const struct sock_addr *addr; + const char *service; }; @@ -79,6 +80,7 @@ struct gensec_security { const struct gensec_security_ops *ops; void *private_data; struct gensec_user user; + struct gensec_user default_user; struct gensec_target target; enum gensec_role gensec_role; BOOL subcontext; diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 3a4f995937..78b6e334a7 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -43,6 +43,7 @@ struct gensec_krb5_state { krb5_context krb5_context; krb5_auth_context krb5_auth_context; krb5_ccache krb5_ccache; + krb5_data ticket; }; static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) @@ -68,6 +69,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) gensec_krb5_state->krb5_context = NULL; gensec_krb5_state->krb5_auth_context = NULL; gensec_krb5_state->krb5_ccache = NULL; + ZERO_STRUCT(gensec_krb5_state->ticket); gensec_krb5_state->session_key = data_blob(NULL, 0); ret = krb5_init_context(&gensec_krb5_state->krb5_context); @@ -114,6 +116,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security struct gensec_krb5_state *gensec_krb5_state; krb5_error_code ret; NTSTATUS nt_status; + nt_status = gensec_krb5_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -122,6 +125,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_krb5_state = gensec_security->private_data; gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; + /* TODO: This is effecivly a static/global variable... */ ret = krb5_cc_default(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_ccache); if (ret) { DEBUG(1,("krb5_cc_default failed (%s)\n", @@ -129,13 +133,101 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security return NT_STATUS_INTERNAL_ERROR; } - return NT_STATUS_OK; + while (1) { + if (gensec_security->target.principal) { + DEBUG(5, ("Finding ticket for target [%s]\n", gensec_security->target.principal)); + ret = ads_krb5_mk_req(gensec_krb5_state->krb5_context, + &gensec_krb5_state->krb5_auth_context, + AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, + gensec_security->target.principal, + gensec_krb5_state->krb5_ccache, + &gensec_krb5_state->ticket); + if (ret) { + DEBUG(1,("ads_krb5_mk_req failed (%s)\n", + error_message(ret))); + } + } else { + krb5_data in_data; + in_data.length = 0; + const char *hostname = gensec_get_target_hostname(gensec_security); + if (!hostname) { + DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); + return NT_STATUS_ACCESS_DENIED; + } + ret = krb5_mk_req(gensec_krb5_state->krb5_context, + &gensec_krb5_state->krb5_auth_context, + AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, + gensec_get_target_service(gensec_security), + hostname, + &in_data, gensec_krb5_state->krb5_ccache, + &gensec_krb5_state->ticket); + if (ret) { + DEBUG(1,("krb5_mk_req failed (%s)\n", + error_message(ret))); + } + + } + switch (ret) { + case 0: + return NT_STATUS_OK; + case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: + DEBUG(3, ("Server is not registered with our KDC: %s\n", + error_message(ret))); + return NT_STATUS_ACCESS_DENIED; + case KRB5KDC_ERR_PREAUTH_FAILED: + case KRB5KRB_AP_ERR_TKT_EXPIRED: + case KRB5_CC_END: + case KRB5_FCC_NOFILE: + case KRB5_CC_NOTFOUND: + { + char *password; + time_t kdc_time; + DEBUG(3, ("kerberos: %s\n", + error_message(ret))); + nt_status = gensec_get_password(gensec_security, + gensec_security->mem_ctx, + &password); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + ret = kerberos_kinit_password_cc(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache, + gensec_get_client_principal(gensec_security, gensec_security->mem_ctx), + password, NULL, &kdc_time); + + /* cope with ticket being in the future due to clock skew */ + if ((unsigned)kdc_time > time(NULL)) { + time_t t = time(NULL); + int time_offset =(unsigned)kdc_time-t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(gensec_krb5_state->krb5_context, t + time_offset + 1, 0); + } + + if (ret) { + DEBUG(1,("kinit failed (%s)\n", + error_message(ret))); + return NT_STATUS_WRONG_PASSWORD; + } + break; + } + default: + DEBUG(0, ("kerberos: %s\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + } } static void gensec_krb5_end(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + if (gensec_krb5_state->ticket.length) { + /* Hmm, heimdal dooesn't have this - what's the correct call? */ +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); +#endif + } if (gensec_krb5_state->krb5_ccache) { /* Removed by jra. They really need to fix their kerberos so we don't leak memory. JERRY -- disabled since it causes heimdal 0.6.1rc3 to die @@ -182,33 +274,17 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL switch (gensec_krb5_state->state_position) { case GENSEC_KRB5_CLIENT_START: { - krb5_data packet; - -#if 0 /* When we get some way to input the time offset */ - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } -#endif - - ret = ads_krb5_mk_req(gensec_krb5_state->krb5_context, - &gensec_krb5_state->krb5_auth_context, - AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, - gensec_security->target.principal, - gensec_krb5_state->krb5_ccache, &packet); if (ret) { DEBUG(1,("ads_krb5_mk_req (request ticket) failed (%s)\n", error_message(ret))); nt_status = NT_STATUS_LOGON_FAILURE; } else { DATA_BLOB unwrapped_out; - unwrapped_out = data_blob_talloc(out_mem_ctx, packet.data, packet.length); + unwrapped_out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->ticket.data, gensec_krb5_state->ticket.length); /* wrap that up in a nice GSS-API wrapping */ *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REQ); - /* Hmm, heimdal dooesn't have this - what's the correct call? */ -#ifdef HAVE_KRB5_FREE_DATA_CONTENTS - krb5_free_data_contents(gensec_krb5_state->krb5_context, &packet); -#endif + gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; } diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 97b895a241..b08c7f505c 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -54,28 +54,13 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) + int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, const char *principal, const char *password, time_t *expire_time, time_t *kdc_time) { - krb5_context ctx = NULL; krb5_error_code code = 0; - krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; - if ((code = krb5_init_context(&ctx))) - return code; - - if (time_offset != 0) { - krb5_set_real_time(ctx, time(NULL) + time_offset, 0); - } - - if ((code = krb5_cc_default(ctx, &cc))) { - krb5_free_context(ctx); - return code; - } - if ((code = krb5_parse_name(ctx, principal, &me))) { - krb5_free_context(ctx); return code; } @@ -83,32 +68,63 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); - krb5_free_context(ctx); return code; } if ((code = krb5_cc_initialize(ctx, cc, me))) { krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); - krb5_free_context(ctx); return code; } if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); - krb5_free_context(ctx); return code; } - if (expire_time) + if (expire_time) { *expire_time = (time_t) my_creds.times.endtime; + } + + if (kdc_time) { + *kdc_time = (time_t) my_creds.times.starttime; + } - krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); - krb5_free_context(ctx); + + return 0; +} + + +/* + simulate a kinit, putting the tgt in the default cache location + remus@snapserver.com +*/ +int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time, time_t *kdc_time) +{ + krb5_context ctx = NULL; + krb5_error_code code = 0; + krb5_ccache cc = NULL; + + if ((code = krb5_init_context(&ctx))) + return code; + + if (time_offset != 0) { + krb5_set_real_time(ctx, time(NULL) + time_offset, 0); + } + + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + + if ((code = kerberos_kinit_password_cc(ctx, cc, principal, password, expire_time, kdc_time))) { + krb5_cc_close(ctx, cc); + krb5_free_context(ctx); + return code; + } return 0; } @@ -129,7 +145,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire, NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 4a9d82acf1..ca796d0c86 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -69,5 +69,6 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep); +int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, const char *principal, const char *password, time_t *expire_time, time_t *kdc_time); #endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 32846cf580..d4910eb92f 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -256,7 +256,7 @@ static NTSTATUS gensec_spnego_client_netTokenInit(struct gensec_security *gensec return nt_status; } nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, in, &unwrapped_out); + out_mem_ctx, in, &unwrapped_out); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { struct spnego_data spnego_out; spnego_out.type = SPNEGO_NEG_TOKEN_INIT; @@ -349,6 +349,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } if (spnego.negTokenInit.targetPrincipal) { + DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal)); nt_status = gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 5aaceb103a..e31cf07bf8 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -424,6 +424,13 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session goto done; } + status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + status = gensec_start_mech_by_oid(session->gensec, OID_SPNEGO); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 4dae7d517d..5cd6f33689 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -45,6 +45,8 @@ struct cli_socket *cli_sock_init(void) /* 20 second default timeout */ sock->timeout = 20000; + sock->hostname = NULL; + return sock; } @@ -140,6 +142,7 @@ BOOL cli_sock_connect_byname(struct cli_socket *sock, const char *host, int port struct in_addr ip; TALLOC_CTX *mem_ctx; char *name, *p; + BOOL ret; if (getenv("LIBSMB_PROG")) { sock->fd = sock_exec(getenv("LIBSMB_PROG")); @@ -162,7 +165,13 @@ BOOL cli_sock_connect_byname(struct cli_socket *sock, const char *host, int port return False; } + ret = cli_sock_connect(sock, &ip, port); + + if (ret) { + sock->hostname = talloc_steal(mem_ctx, sock->mem_ctx, name); + } + talloc_destroy(mem_ctx); - return cli_sock_connect(sock, &ip, port); + return ret; } -- cgit From a92d87f1f735f1d5003845fa45b650231382e9ec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Jul 2004 06:39:55 +0000 Subject: r1476: Don't print messages about the CCACHE not being found - this is normal. Andrew Bartlett (This used to be commit 30d88580efe45dc792f8d5c04f4abe0497d1551c) --- source4/libcli/auth/gensec_krb5.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 78b6e334a7..8268eb6051 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -177,13 +177,17 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5KRB_AP_ERR_TKT_EXPIRED: case KRB5_CC_END: + { + DEBUG(3, ("kerberos: %s\n", + error_message(ret))); + /* fall down to remaining code */ + } + /* just don't print a message for these really ordinary messages */ case KRB5_FCC_NOFILE: case KRB5_CC_NOTFOUND: { char *password; time_t kdc_time; - DEBUG(3, ("kerberos: %s\n", - error_message(ret))); nt_status = gensec_get_password(gensec_security, gensec_security->mem_ctx, &password); -- cgit From ad8d0190f1c188e74d61e4867f8c5ebd7fb20994 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Jul 2004 09:00:28 +0000 Subject: r1494: fix debug message metze (This used to be commit 463982bf3f37bac67e1aaa488e4142d0ecc23307) --- source4/libcli/raw/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 52e08d05f8..fc10413108 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -90,7 +90,7 @@ static BOOL signing_good(struct cli_request *req, int seq, BOOL good) if (!req->transport->negotiate.sign_info.mandatory_signing && !req->transport->negotiate.sign_info.seen_valid) { /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" + DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); req->transport->negotiate.sign_info.negotiated_smb_signing = False; req->transport->negotiate.sign_info.allow_smb_signing = False; -- cgit From 71d28b8265726a50b6f077115e7dacdb8c4b06f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Jul 2004 11:28:34 +0000 Subject: r1497: add forward declaration for struct auth_session_info (fix compiler warning) metze (This used to be commit 65147f5aa2a56220a387876d990a546beb93a2d7) --- source4/libcli/auth/gensec.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 8e2787530c..880ee45265 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -45,6 +45,8 @@ enum gensec_role GENSEC_CLIENT }; +struct auth_session_info; + struct gensec_security_ops { const char *name; const char *sasl_name; -- cgit From f607197054436a8195e3d0a695fe31574b418059 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jul 2004 12:14:07 +0000 Subject: r1498: (merge from 3.0) Rework our random number generation system. On systems with /dev/urandom, this avoids a change to secrets.tdb for every fork(). For other systems, we now only re-seed after a fork, and on startup. No need to do it per-operation. This removes the 'need_reseed' parameter from generate_random_buffer(). This also requires that we start the secrets subsystem, as that is where the reseed value is stored, for systems without /dev/urandom. In order to aviod identical streams in forked children, the random state is re-initialised after the fork(), at the same point were we do that to the tdbs. Andrew Bartlett (This used to be commit b97d3cb2efd68310b1aea8a3ac40a64979c8cdae) --- source4/libcli/auth/ntlmssp.c | 6 +++--- source4/libcli/auth/schannel.c | 2 +- source4/libcli/util/smbencrypt.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 3c656f4e9e..75c1e30f56 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -108,7 +108,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) { static uint8_t chal[8]; - generate_random_buffer(chal, sizeof(chal), False); + generate_random_buffer(chal, sizeof(chal)); return chal; } @@ -1112,7 +1112,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - generate_random_buffer(lm_response.data, 8, False); + generate_random_buffer(lm_response.data, 8); memset(lm_response.data+8, 0, 16); memcpy(session_nonce, challenge_blob.data, 8); @@ -1202,7 +1202,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { /* Make up a new session key */ uint8_t client_session_key[16]; - generate_random_buffer(client_session_key, sizeof(client_session_key), False); + generate_random_buffer(client_session_key, sizeof(client_session_key)); /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 8a261a506c..aa89e7b84f 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -194,7 +194,7 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, uint8_t sealing_key[16]; static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; - generate_random_buffer(confounder, 8, False); + generate_random_buffer(confounder, 8); RSIVAL(seq_num, 0, state->seq_num); SIVAL(seq_num, 4, state->initiator?0x80:0); diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 72c6589097..a02fdaa38b 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -283,7 +283,7 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO unix_to_nt_time(&nttime, time(NULL)); - generate_random_buffer(client_chal, sizeof(client_chal), False); + generate_random_buffer(client_chal, sizeof(client_chal)); push_nttime(long_date, 0, nttime); @@ -343,7 +343,7 @@ static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], /* LMv2 */ /* client-supplied random data */ - generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); @@ -413,7 +413,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - generate_random_buffer((uint8_t *)buffer, 512 - new_pw_len, False); + generate_random_buffer((uint8_t *)buffer, 512 - new_pw_len); /* * The length of the new password is in the last 4 bytes of -- cgit From b3c46674a670ea51607d5c2a73271dff531ae7d6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 16 Jul 2004 02:54:57 +0000 Subject: r1521: Updates to our SMB signing code. - This causes our client and server code to use the same core code, with the same debugs etc. - In turn, this will allow the 'mandetory/fallback' signing algorithms to be shared, and only written once. Updates to the SPNEGO code - Don't wrap an empty token to the server, if we are actually already finished. Andrew Bartlett (This used to be commit 35b83eb329482ac1b3bc67285854cc47844ff353) --- source4/libcli/auth/gensec_krb5.c | 4 +- source4/libcli/auth/spnego.c | 43 ++++++----- source4/libcli/raw/clisession.c | 43 +++++++---- source4/libcli/raw/smb_signing.c | 152 +++++++++++++++++++++----------------- 4 files changed, 141 insertions(+), 101 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 8268eb6051..c7c1a18d24 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -304,6 +304,8 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL DATA_BLOB unwrapped_in; if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { + DEBUG(1,("gensec_gssapi_parse_krb5_wrap(mutual authentication) failed to parse\n")); + dump_data_pw("Mutual authentication message:\n", in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } /* TODO: check the tok_id */ @@ -316,7 +318,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL if (ret) { DEBUG(1,("krb5_rd_rep (mutual authentication) failed (%s)\n", error_message(ret))); - dump_data_pw("Mutual authentication message:\n", in.data, in.length); + dump_data_pw("Mutual authentication message:\n", inbuf.data, inbuf.length); nt_status = NT_STATUS_ACCESS_DENIED; } else { *out = data_blob(NULL, 0); diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index d4910eb92f..c16d77dad9 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -41,7 +41,6 @@ struct spnego_state { uint_t ref_count; enum spnego_message_type expected_packet; enum spnego_state_position state_position; - enum spnego_negResult result; struct gensec_security *sub_sec_security; }; @@ -60,7 +59,6 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_CLIENT_START; - spnego_state->result = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->mem_ctx = mem_ctx; spnego_state->sub_sec_security = NULL; @@ -140,8 +138,7 @@ static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_securit DATA_BLOB *session_key) { struct spnego_state *spnego_state = gensec_security->private_data; - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { + if (!spnego_state->sub_sec_security) { return NT_STATUS_INVALID_PARAMETER; } @@ -450,7 +447,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego.negTokenTarg.responseToken, &unwrapped_out); - spnego_state->result = spnego.negTokenTarg.negResult; spnego_free_data(&spnego); /* compose reply */ @@ -514,38 +510,45 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego.negTokenTarg.responseToken, &unwrapped_out); - if (NT_STATUS_IS_OK(nt_status) - && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { + + if ((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) + && !NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("gensec_update ok but not accepted\n")); nt_status = NT_STATUS_INVALID_PARAMETER; - } + } - spnego_state->result = spnego.negTokenTarg.negResult; spnego_free_data(&spnego); - - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; - spnego_out.negTokenTarg.supportedMech = NULL; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; + + if (unwrapped_out.length) { + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; + spnego_out.negTokenTarg.supportedMech = NULL; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } else { + *out = null_data_blob; + } if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* compose reply */ + spnego_state->state_position = SPNEGO_CLIENT_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { + /* all done - server has accepted, and we agree */ spnego_state->state_position = SPNEGO_DONE; + return NT_STATUS_OK; } else { DEBUG(1, ("SPNEGO(%s) login failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); return nt_status; } - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } - return nt_status; } case SPNEGO_DONE: diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index e31cf07bf8..c6d7f800a4 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -260,7 +260,7 @@ static void use_nt1_session_keys(struct cli_session *session, E_md4hash(password, nt_hash); SMBsesskeygen_ntv1(nt_hash, session_key.data); - cli_transport_simple_set_signing(transport, session_key, *nt_response, 0); + cli_transport_simple_set_signing(transport, session_key, *nt_response); cli_session_set_user_session_key(session, &session_key); data_blob_free(&session_key); @@ -380,6 +380,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session union smb_sesssetup *parms) { NTSTATUS status; + NTSTATUS session_key_err = NT_STATUS_NO_USER_SESSION_KEY; union smb_sesssetup s2; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); @@ -443,15 +444,20 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session &s2.spnego.in.secblob); while(1) { + if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) { + break; + } if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { break; } - status = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(status)) { - cli_transport_simple_set_signing(session->transport, session_key, null_data_blob, 0); + if (!NT_STATUS_IS_OK(session_key_err)) { + session_key_err = gensec_session_key(session->gensec, &session_key); } - + if (NT_STATUS_IS_OK(session_key_err)) { + cli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } + session->vuid = s2.spnego.out.vuid; status = smb_raw_session_setup(session, mem_ctx, &s2); session->vuid = UID_FIELD_INVALID; @@ -464,19 +470,14 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session s2.spnego.out.secblob, &s2.spnego.in.secblob); - if (NT_STATUS_IS_OK(status)) { - break; - } } done: if (NT_STATUS_IS_OK(status)) { - status = gensec_session_key(session->gensec, &session_key); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (!NT_STATUS_IS_OK(session_key_err)) { + DEBUG(1, ("Failed to get user session key: %s\n", nt_errstr(session_key_err))); + return session_key_err; } - - cli_transport_simple_set_signing(session->transport, session_key, null_data_blob, 2 /* two legs on last packet */); cli_session_set_user_session_key(session, &session_key); @@ -484,6 +485,9 @@ done: parms->generic.out.os = s2.spnego.out.os; parms->generic.out.lanman = s2.spnego.out.lanman; parms->generic.out.domain = s2.spnego.out.domain; + } else { + DEBUG(1, ("Failed to login with SPNEGO: %s\n", nt_errstr(status))); + return status; } return status; @@ -528,7 +532,18 @@ NTSTATUS smb_raw_session_setup(struct cli_session *session, TALLOC_CTX *mem_ctx, struct cli_request *req; if (parms->generic.level == RAW_SESSSETUP_GENERIC) { - return smb_raw_session_setup_generic(session, mem_ctx, parms); + NTSTATUS ret = smb_raw_session_setup_generic(session, mem_ctx, parms); + + if (NT_STATUS_IS_OK(ret) + && parms->generic.in.user + && *parms->generic.in.user) { + if (!session->transport->negotiate.sign_info.doing_signing + && session->transport->negotiate.sign_info.mandatory_signing) { + DEBUG(0, ("SMB signing required, but server does not support it\n")); + return NT_STATUS_ACCESS_DENIED; + } + } + return ret; } req = smb_raw_session_setup_send(session, parms); diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index fc10413108..20f8921acb 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -69,15 +69,15 @@ static BOOL set_smb_signing_real_common(struct cli_transport *transport) return True; } -static void mark_packet_signed(struct cli_request *req) +static void mark_packet_signed(struct request_buffer *out) { uint16_t flags2; - flags2 = SVAL(req->out.hdr, HDR_FLG2); + flags2 = SVAL(out->hdr, HDR_FLG2); flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(req->out.hdr, HDR_FLG2, flags2); + SSVAL(out->hdr, HDR_FLG2, flags2); } -static BOOL signing_good(struct cli_request *req, int seq, BOOL good) +static BOOL signing_good(struct cli_request *req, unsigned int seq, BOOL good) { if (good) { if (!req->transport->negotiate.sign_info.doing_signing) { @@ -87,9 +87,8 @@ static BOOL signing_good(struct cli_request *req, int seq, BOOL good) req->transport->negotiate.sign_info.seen_valid = True; } } else { - if (!req->transport->negotiate.sign_info.mandatory_signing && !req->transport->negotiate.sign_info.seen_valid) { - - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + if (!req->transport->negotiate.sign_info.seen_valid) { + /* If we have never seen a good packet, just turn it off */ DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); req->transport->negotiate.sign_info.negotiated_smb_signing = False; @@ -100,119 +99,97 @@ static BOOL signing_good(struct cli_request *req, int seq, BOOL good) cli_null_set_signing(req->transport); return True; } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (seq) - DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); + /* bad packet after signing started - fail and disconnect. */ + DEBUG(0, ("signing_good: BAD SIG: seq %u\n", seq)); return False; } } return True; } -/*********************************************************** - SMB signing - Simple implementation - calculate a MAC to send. -************************************************************/ -static void cli_request_simple_sign_outgoing_message(struct cli_request *req) +void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_t seq_num) { uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; - struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; - -#if 0 - /* enable this when packet signing is preventing you working out why valgrind - says that data is uninitialised */ - file_save("pkt.dat", req->out.buffer, req->out.size); -#endif - - req->seq_num = data->next_seq_num; - - /* some requests (eg. NTcancel) are one way, and the sequence number - should be increased by 1 not 2 */ - if (req->one_way_request) { - data->next_seq_num += 1; - } else { - data->next_seq_num += 2; - } - /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. */ - SIVAL(req->out.hdr, HDR_SS_FIELD, req->seq_num); - SIVAL(req->out.hdr, HDR_SS_FIELD + 4, 0); + SIVAL(out->hdr, HDR_SS_FIELD, seq_num); + SIVAL(out->hdr, HDR_SS_FIELD + 4, 0); /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(req); + mark_packet_signed(out); /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); - MD5Update(&md5_ctx, data->mac_key.data, - data->mac_key.length); + MD5Update(&md5_ctx, mac_key->data, + mac_key->length); MD5Update(&md5_ctx, - req->out.buffer + NBT_HDR_SIZE, - req->out.size - NBT_HDR_SIZE); + out->buffer + NBT_HDR_SIZE, + out->size - NBT_HDR_SIZE); MD5Final(calc_md5_mac, &md5_ctx); - memcpy(&req->out.hdr[HDR_SS_FIELD], calc_md5_mac, 8); + memcpy(&out->hdr[HDR_SS_FIELD], calc_md5_mac, 8); - DEBUG(5, ("cli_request_simple_sign_outgoing_message: SENT SIG (seq: %d, next %d): sent SMB signature of\n", - req->seq_num, data->next_seq_num)); + DEBUG(5, ("sign_outgoing_message: SENT SIG (seq: %d): sent SMB signature of\n", + seq_num)); dump_data(5, calc_md5_mac, 8); /* req->out.hdr[HDR_SS_FIELD+2]=0; Uncomment this to test if the remote server actually verifies signitures...*/ } - -/*********************************************************** - SMB signing - Simple implementation - check a MAC sent by server. -************************************************************/ -static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) +BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) { BOOL good; uint8_t calc_md5_mac[16]; uint8_t server_sent_mac[8]; uint8_t sequence_buf[8]; struct MD5Context md5_ctx; - struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; const size_t offset_end_of_sig = (HDR_SS_FIELD + 8); int i; const int sign_range = 0; + /* room enough for the signature? */ + if (in->size < NBT_HDR_SIZE + HDR_SS_FIELD + 8) { + return False; + } + /* its quite bogus to be guessing sequence numbers, but very useful when debugging signing implementations */ - for (i = 1-sign_range; i <= 1+sign_range; i++) { + for (i = 0-sign_range; i <= 0+sign_range; i++) { /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. */ - SIVAL(sequence_buf, 0, req->seq_num+i); + SIVAL(sequence_buf, 0, seq_num + i); SIVAL(sequence_buf, 4, 0); /* get a copy of the server-sent mac */ - memcpy(server_sent_mac, &req->in.hdr[HDR_SS_FIELD], sizeof(server_sent_mac)); + memcpy(server_sent_mac, &in->hdr[HDR_SS_FIELD], sizeof(server_sent_mac)); /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); - MD5Update(&md5_ctx, data->mac_key.data, - data->mac_key.length); - MD5Update(&md5_ctx, req->in.hdr, HDR_SS_FIELD); + MD5Update(&md5_ctx, mac_key->data, + mac_key->length); + MD5Update(&md5_ctx, in->hdr, HDR_SS_FIELD); MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); - MD5Update(&md5_ctx, req->in.hdr + offset_end_of_sig, - req->in.size - NBT_HDR_SIZE - (offset_end_of_sig)); + MD5Update(&md5_ctx, in->hdr + offset_end_of_sig, + in->size - NBT_HDR_SIZE - (offset_end_of_sig)); MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - if (i == 1) { + if (i == 0) { if (!good) { - DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", req->seq_num + i)); + DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", seq_num + i)); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", req->seq_num + i)); + DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", seq_num + i)); dump_data(5, server_sent_mac, 8); } else { - DEBUG(15, ("cli_request_simple_check_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", req->seq_num + i)); + DEBUG(15, ("check_signed_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", seq_num + i)); dump_data(5, server_sent_mac, 8); } } @@ -220,10 +197,51 @@ static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) if (good) break; } - if (good && i != 1) { - DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, req->seq_num+1)); + if (good && i != 0) { + DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, seq_num)); + } + return good; +} + +/*********************************************************** + SMB signing - Simple implementation - calculate a MAC to send. +************************************************************/ +static void cli_request_simple_sign_outgoing_message(struct cli_request *req) +{ + struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; + +#if 0 + /* enable this when packet signing is preventing you working out why valgrind + says that data is uninitialised */ + file_save("pkt.dat", req->out.buffer, req->out.size); +#endif + + req->seq_num = data->next_seq_num; + + /* some requests (eg. NTcancel) are one way, and the sequence number + should be increased by 1 not 2 */ + if (req->one_way_request) { + data->next_seq_num += 1; + } else { + data->next_seq_num += 2; } + + sign_outgoing_message(&req->out, &data->mac_key, req->seq_num); +} + +/*********************************************************** + SMB signing - Simple implementation - check a MAC sent by server. +************************************************************/ +static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) +{ + struct smb_basic_signing_context *data + = req->transport->negotiate.sign_info.signing_context; + + BOOL good = check_signed_incoming_message(&req->in, + &data->mac_key, + req->seq_num+1); + return signing_good(req, req->seq_num+1, good); } @@ -247,8 +265,7 @@ static void cli_transport_simple_free_signing_context(struct cli_transport *tran ************************************************************/ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, const DATA_BLOB user_session_key, - const DATA_BLOB response, - int seq_num) + const DATA_BLOB response) { struct smb_basic_signing_context *data; @@ -271,8 +288,10 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); } + dump_data_pw("Started Signing with key:\n", data->mac_key.data, data->mac_key.length); + /* Initialise the sequence number */ - data->next_seq_num = seq_num; + data->next_seq_num = 0; transport->negotiate.sign_info.sign_outgoing_message = cli_request_simple_sign_outgoing_message; transport->negotiate.sign_info.check_incoming_message = cli_request_simple_check_incoming_message; @@ -332,11 +351,12 @@ BOOL cli_null_set_signing(struct cli_transport *transport) static void cli_request_temp_sign_outgoing_message(struct cli_request *req) { /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(req); + mark_packet_signed(&req->out); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8); + return; } -- cgit From d093b7e7771c3f143546889c95f97dd0be16998f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 19 Jul 2004 10:35:05 +0000 Subject: r1547: rename 'enum _level' -> 'enum smb__level' e.g. we now have 'union smb_mkdir' and 'enum smb_mkdir_level' in sync we may should also rename 'RAW_MKDIR_*' -> 'SMB_MKDIR_*' metze (This used to be commit 0bb50dcf1ccb9797000fcbea4d8a73f2d2a3db77) --- source4/libcli/clilist.c | 2 +- source4/libcli/raw/rawsearch.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 09d536a710..f5ff4bd699 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -95,7 +95,7 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, char *mask; int ff_eos = 0, i, ff_searchcount; int ff_dir_handle=0; - enum search_level level; + enum smb_search_level level; /* initialize state for search */ state.dirlist = NULL; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index bdb57aa6c4..a4ba8e8696 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -235,7 +235,7 @@ static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, */ static int parse_trans2_search(struct cli_tree *tree, TALLOC_CTX *mem_ctx, - enum search_level level, + enum smb_search_level level, uint16_t flags, DATA_BLOB *blob, union smb_search_data *data) @@ -449,7 +449,7 @@ static int parse_trans2_search(struct cli_tree *tree, ****************************************************************************/ static NTSTATUS smb_raw_t2search_backend(struct cli_tree *tree, TALLOC_CTX *mem_ctx, - enum search_level level, + enum smb_search_level level, uint16_t flags, int16_t count, DATA_BLOB *blob, -- cgit From 5ddf678e0113f81aa2b5f99134cda4fe8c01afb7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 Jul 2004 06:40:49 +0000 Subject: r1578: the first stage of the async client rewrite. Up to now the client code has had an async API, and operated asynchronously at the packet level, but was not truly async in that it assumed that it could always write to the socket and when a partial packet came in that it could block waiting for the rest of the packet. This change makes the SMB client library full async, by adding a separate outgoing packet queue, using non-blocking socket IO and having a input buffer that can fill asynchonously until the full packet has arrived. The main complexity was in dealing with the events structure when using the CIFS proxy backend. In that case the same events structure needs to be used in both the client library and the main smbd server, so that when the client library is waiting for a reply that the main server keeps processing packets. This required some changes in the events library code. Next step is to make the generated rpc client code use these new capabilities. (This used to be commit 96bf4da3edc4d64b0f58ef520269f3b385b8da02) --- source4/libcli/raw/clisocket.c | 8 +- source4/libcli/raw/clitransport.c | 337 +++++++++++++++++++++++++++++++++----- source4/libcli/raw/rawrequest.c | 186 +-------------------- 3 files changed, 306 insertions(+), 225 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 5cd6f33689..eb5d3c0342 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -72,7 +72,13 @@ BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) &sock->dest_ip, sock->port, LONG_CONNECT_TIMEOUT); - return (sock->fd != -1); + if (sock->fd == -1) { + return False; + } + + set_blocking(sock->fd, False); + + return True; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 18784fe33a..96d5a18a71 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -21,6 +21,17 @@ #include "includes.h" +/* + an event has happened on the socket +*/ +static void cli_transport_event_handler(struct event_context *ev, struct fd_event *fde, + time_t t, uint16_t flags) +{ + struct cli_transport *transport = fde->private; + + cli_transport_process(transport); +} + /* create a transport structure based on an established socket */ @@ -28,6 +39,7 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) { TALLOC_CTX *mem_ctx; struct cli_transport *transport; + struct fd_event fde; mem_ctx = talloc_init("cli_transport"); if (!mem_ctx) return NULL; @@ -35,6 +47,12 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) transport = talloc_zero(mem_ctx, sizeof(*transport)); if (!transport) return NULL; + transport->event.ctx = event_context_init(); + if (transport->event.ctx == NULL) { + talloc_destroy(mem_ctx); + return NULL; + } + transport->mem_ctx = mem_ctx; transport->socket = sock; transport->negotiate.protocol = PROTOCOL_NT1; @@ -47,6 +65,14 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) ZERO_STRUCT(transport->called); + fde.fd = sock->fd; + fde.flags = EVENT_FD_READ; + fde.handler = cli_transport_event_handler; + fde.private = transport; + fde.ref_count = 1; + + transport->event.fde = event_add_fd(transport->event.ctx, &fde); + return transport; } @@ -59,6 +85,9 @@ void cli_transport_close(struct cli_transport *transport) transport->reference_count--; if (transport->reference_count <= 0) { cli_sock_close(transport->socket); + event_remove_fd(transport->event.ctx, transport->event.fde); + event_remove_timed(transport->event.ctx, transport->event.te); + event_context_destroy(transport->event.ctx); talloc_destroy(transport->mem_ctx); } } @@ -72,6 +101,21 @@ void cli_transport_dead(struct cli_transport *transport) } +/* + enable select for write on a transport +*/ +static void cli_transport_write_enable(struct cli_transport *transport) +{ + transport->event.fde->flags |= EVENT_FD_WRITE; +} + +/* + disable select for write on a transport +*/ +static void cli_transport_write_disable(struct cli_transport *transport) +{ + transport->event.fde->flags &= ~EVENT_FD_WRITE; +} /**************************************************************************** send a session request (if appropriate) @@ -145,7 +189,7 @@ again: /* the zero mid is reserved for requests that don't have a mid */ if (mid == 0) mid = 1; - for (req=transport->pending_requests; req; req=req->next) { + for (req=transport->pending_recv; req; req=req->next) { if (req->mid == mid) { mid++; goto again; @@ -156,81 +200,284 @@ again: return mid; } +static void idle_handler(struct event_context *ev, + struct timed_event *te, time_t t) +{ + struct cli_transport *transport = te->private; + te->next_event = t + transport->idle.period; + transport->idle.func(transport, transport->idle.private); +} + /* setup the idle handler for a transport + the period is in seconds */ void cli_transport_idle_handler(struct cli_transport *transport, void (*idle_func)(struct cli_transport *, void *), uint_t period, void *private) { + struct timed_event te; transport->idle.func = idle_func; transport->idle.private = private; transport->idle.period = period; -} + if (transport->event.te != NULL) { + event_remove_timed(transport->event.ctx, transport->event.te); + } + + te.next_event = time(NULL) + period; + te.handler = idle_handler; + te.private = transport; + transport->event.te = event_add_timed(transport->event.ctx, &te); +} /* - determine if a packet is pending for receive on a transport + process some pending sends */ -BOOL cli_transport_pending(struct cli_transport *transport) +static void cli_transport_process_send(struct cli_transport *transport) { - return socket_pending(transport->socket->fd); -} - + while (transport->pending_send) { + struct cli_request *req = transport->pending_send; + ssize_t ret; + ret = cli_sock_write(transport->socket, req->out.buffer, req->out.size); + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) { + return; + } + cli_transport_dead(transport); + } + req->out.buffer += ret; + req->out.size -= ret; + if (req->out.size == 0) { + req->state = CLI_REQUEST_RECV; + DLIST_REMOVE(transport->pending_send, req); + DLIST_ADD(transport->pending_recv, req); + } + } + /* we're out of requests to send, so don't wait for write + events any more */ + cli_transport_write_disable(transport); +} /* - wait for data on a transport, periodically calling a wait function - if one has been defined - return True if a packet is received -*/ -BOOL cli_transport_select(struct cli_transport *transport) + we have a full request in our receive buffer - match it to a pending request + and process + */ +static void cli_transport_finish_recv(struct cli_transport *transport) { - fd_set fds; - int selrtn; - int fd; - struct timeval timeout; + uint8_t *buffer, *hdr, *vwv; + int len; + uint16_t wct, mid = 0; + struct cli_request *req; - fd = transport->socket->fd; + buffer = transport->recv_buffer.buffer; + len = transport->recv_buffer.req_size; - if (fd == -1) { - return False; + hdr = buffer+NBT_HDR_SIZE; + vwv = hdr + HDR_VWV; + + /* see if it could be an oplock break request */ + if (handle_oplock_break(transport, len, hdr, vwv)) { + talloc_free(transport->mem_ctx, buffer); + ZERO_STRUCT(transport->recv_buffer); + return; } - do { - uint_t period = 1000; + /* at this point we need to check for a readbraw reply, as + these can be any length */ + if (transport->readbraw_pending) { + transport->readbraw_pending = 0; + + /* it must match the first entry in the pending queue + as the client is not allowed to have outstanding + readbraw requests */ + req = transport->pending_recv; + if (!req) goto error; + + req->in.buffer = buffer; + talloc_steal(transport->mem_ctx, req->mem_ctx, buffer); + req->in.size = len + NBT_HDR_SIZE; + req->in.allocated = req->in.size; + goto async; + } - FD_ZERO(&fds); - FD_SET(fd,&fds); - - if (transport->idle.func) { - period = transport->idle.period; + if (len >= MIN_SMB_SIZE) { + /* extract the mid for matching to pending requests */ + mid = SVAL(hdr, HDR_MID); + wct = CVAL(hdr, HDR_WCT); + } + + /* match the incoming request against the list of pending requests */ + for (req=transport->pending_recv; req; req=req->next) { + if (req->mid == mid) break; + } + + if (!req) { + DEBUG(1,("Discarding unmatched reply with mid %d\n", mid)); + goto error; + } + + /* fill in the 'in' portion of the matching request */ + req->in.buffer = buffer; + talloc_steal(transport->mem_ctx, req->mem_ctx, buffer); + req->in.size = len + NBT_HDR_SIZE; + req->in.allocated = req->in.size; + + /* handle non-SMB replies */ + if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) { + req->state = CLI_REQUEST_ERROR; + goto error; + } + + if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { + DEBUG(2,("bad reply size for mid %d\n", mid)); + req->status = NT_STATUS_UNSUCCESSFUL; + req->state = CLI_REQUEST_ERROR; + goto error; + } + + req->in.hdr = hdr; + req->in.vwv = vwv; + req->in.wct = wct; + if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { + req->in.data = req->in.vwv + VWV(wct) + 2; + req->in.data_size = SVAL(req->in.vwv, VWV(wct)); + if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) { + DEBUG(3,("bad data size for mid %d\n", mid)); + /* blergh - w2k3 gives a bogus data size values in some + openX replies */ + req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)); } + } + req->in.ptr = req->in.data; + req->flags2 = SVAL(req->in.hdr, HDR_FLG2); + + if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) { + transport->error.etype = ETYPE_DOS; + transport->error.e.dos.eclass = CVAL(req->in.hdr,HDR_RCLS); + transport->error.e.dos.ecode = SVAL(req->in.hdr,HDR_ERR); + req->status = dos_to_ntstatus(transport->error.e.dos.eclass, + transport->error.e.dos.ecode); + } else { + transport->error.etype = ETYPE_NT; + transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS)); + req->status = transport->error.e.nt_status; + } + + if (!cli_request_check_sign_mac(req)) { + transport->error.etype = ETYPE_SOCKET; + transport->error.e.socket_error = SOCKET_READ_BAD_SIG; + req->state = CLI_REQUEST_ERROR; + goto error; + }; + +async: + /* if this request has an async handler then call that to + notify that the reply has been received. This might destroy + the request so it must happen last */ + ZERO_STRUCT(transport->recv_buffer); + DLIST_REMOVE(transport->pending_recv, req); + req->state = CLI_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + return; + +error: + if (req) { + DLIST_REMOVE(transport->pending_recv, req); + req->state = CLI_REQUEST_ERROR; + } + ZERO_STRUCT(transport->recv_buffer); +} - timeout.tv_sec = period / 1000; - timeout.tv_usec = 1000*(period%1000); - - selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout); - - if (selrtn == 1) { - /* the fd is readable */ - return True; +/* + process some pending receives +*/ +static void cli_transport_process_recv(struct cli_transport *transport) +{ + /* a incoming packet goes through 2 stages - first we read the + 4 byte header, which tells us how much more is coming. Then + we read the rest */ + if (transport->recv_buffer.received < NBT_HDR_SIZE) { + ssize_t ret; + ret = cli_sock_read(transport->socket, + transport->recv_buffer.header + + transport->recv_buffer.received, + NBT_HDR_SIZE - transport->recv_buffer.received); + if (ret == -1) { + if (errno == EINTR || errno == EAGAIN) { + return; + } + cli_transport_dead(transport); + return; } - - if (selrtn == -1) { - /* sys_select_intr() already handles EINTR, so this - is an error. The socket is probably dead */ - return False; + + transport->recv_buffer.received += ret; + + if (transport->recv_buffer.received == NBT_HDR_SIZE) { + /* we've got a full header */ + transport->recv_buffer.req_size = smb_len(transport->recv_buffer.header) + NBT_HDR_SIZE; + transport->recv_buffer.buffer = talloc(transport->mem_ctx, + NBT_HDR_SIZE+transport->recv_buffer.req_size); + if (transport->recv_buffer.buffer == NULL) { + cli_transport_dead(transport); + return; + } + memcpy(transport->recv_buffer.buffer, transport->recv_buffer.header, NBT_HDR_SIZE); } - - /* only other possibility is that we timed out - call the idle function - if there is one */ - if (transport->idle.func) { - transport->idle.func(transport, transport->idle.private); + } + + if (transport->recv_buffer.received < transport->recv_buffer.req_size) { + ssize_t ret; + ret = cli_sock_read(transport->socket, + transport->recv_buffer.buffer + + transport->recv_buffer.received, + transport->recv_buffer.req_size - + transport->recv_buffer.received); + if (ret == -1) { + if (errno == EINTR || errno == EAGAIN) { + return; + } + cli_transport_dead(transport); + return; } - } while (selrtn == 0); + transport->recv_buffer.received += ret; + } + + if (transport->recv_buffer.received != 0 && + transport->recv_buffer.received == transport->recv_buffer.req_size) { + cli_transport_finish_recv(transport); + } +} +/* + process some read/write requests that are pending + return False if the socket is dead +*/ +BOOL cli_transport_process(struct cli_transport *transport) +{ + cli_transport_process_send(transport); + cli_transport_process_recv(transport); + if (transport->socket->fd == -1) { + return False; + } return True; } + + +/* + put a request into the send queue +*/ +void cli_transport_send(struct cli_request *req) +{ + /* put it on the outgoing socket queue */ + req->state = CLI_REQUEST_SEND; + DLIST_ADD(req->transport->pending_send, req); + + /* make sure we look for write events */ + cli_transport_write_enable(req->transport); +} diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index c31f07505f..ce6cd0a1a4 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -43,7 +43,7 @@ NTSTATUS cli_request_destroy(struct cli_request *req) if (req->transport) { /* remove it from the list of pending requests (a null op if its not in the list) */ - DLIST_REMOVE(req->transport->pending_requests, req); + DLIST_REMOVE(req->transport->pending_recv, req); } /* ahh, its so nice to destroy a complex structure in such a @@ -79,6 +79,7 @@ struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, ui ZERO_STRUCTP(req); /* setup the request context */ + req->state = CLI_REQUEST_INIT; req->mem_ctx = mem_ctx; req->transport = transport; req->session = NULL; @@ -266,32 +267,20 @@ static void cli_req_grow_data(struct cli_request *req, uint_t new_size) SSVAL(req->out.vwv, VWV(req->out.wct), new_size); } + /* send a message */ BOOL cli_request_send(struct cli_request *req) { - uint_t ret; - if (IVAL(req->out.buffer, 0) == 0) { _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); } cli_request_calculate_sign_mac(req); - ret = cli_sock_write(req->transport->socket, req->out.buffer, req->out.size); - - if (req->out.size != ret) { - req->transport->error.etype = ETYPE_SOCKET; - req->transport->error.e.socket_error = SOCKET_WRITE_ERROR; - DEBUG(0,("Error writing %d bytes to server - %s\n", - (int)req->out.size, strerror(errno))); - return False; - } + cli_transport_send(req); - /* add it to the list of pending requests */ - DLIST_ADD(req->transport->pending_requests, req); - return True; } @@ -306,17 +295,8 @@ BOOL cli_request_receive(struct cli_request *req) if (!req) return False; /* keep receiving packets until this one is replied to */ - while (!req->in.buffer) { - if (!cli_transport_select(req->transport)) { - req->status = NT_STATUS_UNSUCCESSFUL; - return False; - } - - if (!cli_request_receive_next(req->transport)) { - cli_transport_dead(req->transport); - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - return False; - } + while (req->state <= CLI_REQUEST_RECV) { + event_loop_once(req->transport->event.ctx); } return True; @@ -327,7 +307,7 @@ BOOL cli_request_receive(struct cli_request *req) handle oplock break requests from the server - return True if the request was an oplock break */ -static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char *hdr, const char *vwv) +BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char *hdr, const char *vwv) { /* we must be very fussy about what we consider an oplock break to avoid matching readbraw replies */ @@ -350,158 +330,6 @@ static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, con return True; } - -/* - receive an async message from the server - this function assumes that the caller already knows that the socket is readable - and that there is a packet waiting - - The packet is not actually returned by this function, instead any - registered async message handlers are called - - return True if a packet was successfully received and processed - return False if the socket appears to be dead -*/ -BOOL cli_request_receive_next(struct cli_transport *transport) -{ - BOOL ret; - int len; - char header[NBT_HDR_SIZE]; - char *buffer, *hdr, *vwv; - TALLOC_CTX *mem_ctx; - struct cli_request *req; - uint16_t wct, mid = 0; - - len = cli_sock_read(transport->socket, header, 4); - if (len != 4) { - return False; - } - - len = smb_len(header); - - mem_ctx = talloc_init("cli_request_receive_next"); - - /* allocate the incoming buffer at the right size */ - buffer = talloc(mem_ctx, len+NBT_HDR_SIZE); - if (!buffer) { - talloc_destroy(mem_ctx); - return False; - } - - /* fill in the already received header */ - memcpy(buffer, header, NBT_HDR_SIZE); - - ret = cli_sock_read(transport->socket, buffer + NBT_HDR_SIZE, len); - /* If the server is not responding, note that now */ - if (ret != len) { - return False; - } - - hdr = buffer+NBT_HDR_SIZE; - vwv = hdr + HDR_VWV; - - /* see if it could be an oplock break request */ - if (handle_oplock_break(transport, len, hdr, vwv)) { - goto done; - } - - /* at this point we need to check for a readbraw reply, as these can be any length */ - if (transport->readbraw_pending) { - transport->readbraw_pending = 0; - - /* it must match the first entry in the pending queue as the client is not allowed - to have outstanding readbraw requests */ - req = transport->pending_requests; - if (!req) goto done; - - req->in.buffer = buffer; - talloc_steal(mem_ctx, req->mem_ctx, buffer); - req->in.size = len + NBT_HDR_SIZE; - req->in.allocated = req->in.size; - goto async; - } - - if (len >= MIN_SMB_SIZE) { - /* extract the mid for matching to pending requests */ - mid = SVAL(hdr, HDR_MID); - wct = CVAL(hdr, HDR_WCT); - } - - /* match the incoming request against the list of pending requests */ - for (req=transport->pending_requests; req; req=req->next) { - if (req->mid == mid) break; - } - - if (!req) { - DEBUG(3,("Discarding unmatched reply with mid %d\n", mid)); - goto done; - } - - /* fill in the 'in' portion of the matching request */ - req->in.buffer = buffer; - talloc_steal(mem_ctx, req->mem_ctx, buffer); - req->in.size = len + NBT_HDR_SIZE; - req->in.allocated = req->in.size; - - /* handle non-SMB replies */ - if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) { - goto done; - } - - if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { - DEBUG(2,("bad reply size for mid %d\n", mid)); - req->status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - req->in.hdr = hdr; - req->in.vwv = vwv; - req->in.wct = wct; - if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { - req->in.data = req->in.vwv + VWV(wct) + 2; - req->in.data_size = SVAL(req->in.vwv, VWV(wct)); - if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) { - DEBUG(3,("bad data size for mid %d\n", mid)); - /* blergh - w2k3 gives a bogus data size values in some - openX replies */ - req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)); - } - } - req->in.ptr = req->in.data; - req->flags2 = SVAL(req->in.hdr, HDR_FLG2); - - if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) { - transport->error.etype = ETYPE_DOS; - transport->error.e.dos.eclass = CVAL(req->in.hdr,HDR_RCLS); - transport->error.e.dos.ecode = SVAL(req->in.hdr,HDR_ERR); - req->status = dos_to_ntstatus(transport->error.e.dos.eclass, - transport->error.e.dos.ecode); - } else { - transport->error.etype = ETYPE_NT; - transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS)); - req->status = transport->error.e.nt_status; - } - - if (!cli_request_check_sign_mac(req)) { - transport->error.etype = ETYPE_SOCKET; - transport->error.e.socket_error = SOCKET_READ_BAD_SIG; - return False; - }; - -async: - /* if this request has an async handler then call that to - notify that the reply has been received. This might destroy - the request so it must happen last */ - if (req->async.fn) { - req->async.fn(req); - } - -done: - talloc_destroy(mem_ctx); - return True; -} - - /* wait for a reply to be received for a packet that just returns an error code and nothing more -- cgit From b5061894dc91cd307d0e6b9157b36bd4f36a5c41 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 Jul 2004 08:14:34 +0000 Subject: r1602: make sure we honor the use_spnego flag (This used to be commit de764d9004a0d90479158e78e30b1266eb529e3e) --- source4/libcli/raw/clisession.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index c6d7f800a4..d5373bc76f 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -512,7 +512,8 @@ static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, } /* see if we should use the NT1 interface */ - if (!(parms->generic.in.capabilities & CAP_EXTENDED_SECURITY)) { + if (!session->transport->options.use_spnego || + !(parms->generic.in.capabilities & CAP_EXTENDED_SECURITY)) { return smb_raw_session_setup_generic_nt1(session, mem_ctx, parms); } -- cgit From 2de2ead42d93804d94407aaa92fc9dca4ed87129 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 Jul 2004 09:30:54 +0000 Subject: r1603: fixed in.size to not overstate the packet size by 4 bytes my apologies to abartlett for thinking this was his bug! (This used to be commit 6edbc55ddd2fc0d4686ec3075ba9bfc72ac24315) --- source4/libcli/raw/clitransport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 96d5a18a71..abdcc0d392 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -298,7 +298,7 @@ static void cli_transport_finish_recv(struct cli_transport *transport) req->in.buffer = buffer; talloc_steal(transport->mem_ctx, req->mem_ctx, buffer); - req->in.size = len + NBT_HDR_SIZE; + req->in.size = len; req->in.allocated = req->in.size; goto async; } @@ -322,7 +322,7 @@ static void cli_transport_finish_recv(struct cli_transport *transport) /* fill in the 'in' portion of the matching request */ req->in.buffer = buffer; talloc_steal(transport->mem_ctx, req->mem_ctx, buffer); - req->in.size = len + NBT_HDR_SIZE; + req->in.size = len; req->in.allocated = req->in.size; /* handle non-SMB replies */ -- cgit From f1a215f5cb174a0bfe50f288fbd998c8fabb0b63 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Jul 2004 10:13:34 +0000 Subject: r1604: Samba4 avoids memcpy() as much as possible - we don't need to make a copy here. Andrew Bartlett (This used to be commit 9efc94eeafbf0eb4488c53a1456cc7026c937f9f) --- source4/libcli/raw/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 20f8921acb..80615f2d72 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -143,7 +143,7 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key { BOOL good; uint8_t calc_md5_mac[16]; - uint8_t server_sent_mac[8]; + uint8_t *server_sent_mac; uint8_t sequence_buf[8]; struct MD5Context md5_ctx; const size_t offset_end_of_sig = (HDR_SS_FIELD + 8); @@ -166,7 +166,7 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key SIVAL(sequence_buf, 4, 0); /* get a copy of the server-sent mac */ - memcpy(server_sent_mac, &in->hdr[HDR_SS_FIELD], sizeof(server_sent_mac)); + server_sent_mac = &in->hdr[HDR_SS_FIELD]; /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); -- cgit From 188a8014ea77e8d03916da8b6bc103bc49086155 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Jul 2004 10:33:36 +0000 Subject: r1605: GENSEC krb5 updates - fix a valgrind found uninitialised variable, and allow tests for 'unwrapped' krb5, allowed by Win2k3. SPENGO changes, trying to get the logic right (when and what sub-mechanisms to wrap). Andrew Bartlett (This used to be commit 8a0f7bf5e282d021afe93994a91fd76fa9c05f42) --- source4/libcli/auth/gensec_krb5.c | 8 ++++++-- source4/libcli/auth/spnego.c | 32 ++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index c7c1a18d24..f5f02d1421 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -187,7 +187,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security case KRB5_CC_NOTFOUND: { char *password; - time_t kdc_time; + time_t kdc_time = 0; nt_status = gensec_get_password(gensec_security, gensec_security->mem_ctx, &password); @@ -284,11 +284,15 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL nt_status = NT_STATUS_LOGON_FAILURE; } else { DATA_BLOB unwrapped_out; + +#ifndef GENSEC_SEND_UNWRAPPED_KRB5 /* This should be a switch for the torture code to set */ unwrapped_out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->ticket.data, gensec_krb5_state->ticket.length); /* wrap that up in a nice GSS-API wrapping */ *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REQ); - +#else + *out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->ticket.data, gensec_krb5_state->ticket.length); +#endif gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; } diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index c16d77dad9..23f0b1c070 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -511,15 +511,16 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA &unwrapped_out); - if ((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) - && !NT_STATUS_IS_OK(nt_status)) { + if (NT_STATUS_IS_OK(nt_status) + && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { DEBUG(1,("gensec_update ok but not accepted\n")); nt_status = NT_STATUS_INVALID_PARAMETER; } spnego_free_data(&spnego); - if (unwrapped_out.length) { + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; spnego_out.negTokenTarg.supportedMech = NULL; @@ -530,24 +531,31 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; } - } else { - *out = null_data_blob; - } - - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - /* compose reply */ - spnego_state->state_position = SPNEGO_CLIENT_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { /* all done - server has accepted, and we agree */ + + if (unwrapped_out.length) { + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; + spnego_out.negTokenTarg.supportedMech = NULL; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } else { + *out = null_data_blob; + } + spnego_state->state_position = SPNEGO_DONE; - return NT_STATUS_OK; } else { DEBUG(1, ("SPNEGO(%s) login failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - return nt_status; } return nt_status; } -- cgit From 27ce337277211f7536b7bd750bb42b8a87089fc4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Aug 2004 05:51:42 +0000 Subject: r1618: fixed the receipt of multi-part replies to SMBtrans2 (This used to be commit bd4106a8e57fc98d1feddc01b58f87f68164247a) --- source4/libcli/raw/rawrequest.c | 13 +++++++++++++ source4/libcli/raw/rawtrans.c | 5 +---- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index ce6cd0a1a4..9c53c4b18c 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -303,6 +303,19 @@ BOOL cli_request_receive(struct cli_request *req) } +/* + receive another reply to a request - this is used for requests that + have multi-part replies (such as SMBtrans2) +*/ +BOOL cli_request_receive_more(struct cli_request *req) +{ + req->state = CLI_REQUEST_RECV; + DLIST_ADD(req->transport->pending_recv, req); + + return cli_request_receive(req); +} + + /* handle oplock break requests from the server - return True if the request was an oplock break diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index fb2abf3e2d..5dde753368 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -180,10 +180,7 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, if (total_data <= parms->out.data.length && total_param <= parms->out.params.length) break; - /* to receive more requests we need to mark this request as not received */ - req->in.buffer = NULL; - - if (!cli_request_receive(req)) { + if (!cli_request_receive_more(req)) { req->status = NT_STATUS_UNSUCCESSFUL; return cli_request_destroy(req); } -- cgit From ae81794cf8de793bd18aae98777a6dc648ef3432 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Aug 2004 07:40:55 +0000 Subject: r1619: - add support for older systems to cli_list*() - make cli_list_new() use the last_name continue method rather than the trans2 findnext continue flag, as the continue flag is broken on win2003 (win2003 sometimes misses up to 1/3 of all files in a directory) (This used to be commit daa9648b3f6919b1615a5737b96310c3a41a0192) --- source4/libcli/clilist.c | 57 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index f5ff4bd699..7dac7399a7 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -27,7 +27,8 @@ struct search_private { int dirlist_len; int ff_searchcount; /* total received in 1 server trip */ int total_received; /* total received all together */ - int info_level; + enum smb_search_level info_level; + const char *last_name; /* used to continue trans2 search */ DATA_BLOB status; /* used for old-style search */ }; @@ -35,7 +36,7 @@ struct search_private { /**************************************************************************** Interpret a long filename structure. ****************************************************************************/ -static BOOL interpret_long_filename(int level, +static BOOL interpret_long_filename(enum smb_search_level level, union smb_search_data *info, file_info *finfo) { @@ -43,17 +44,35 @@ static BOOL interpret_long_filename(int level, if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); - - finfo->size = info->both_directory_info.size; - finfo->ctime = nt_time_to_unix(info->both_directory_info.create_time); - finfo->atime = nt_time_to_unix(info->both_directory_info.access_time); - finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time); - finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */ - if (info->both_directory_info.short_name.s) { - strncpy(finfo->short_name, info->both_directory_info.short_name.s, - sizeof(finfo->short_name)-1); + + switch (level) { + case RAW_SEARCH_STANDARD: + finfo->size = info->standard.size; + finfo->ctime = info->standard.create_time; + finfo->atime = info->standard.access_time; + finfo->mtime = info->standard.write_time; + finfo->mode = info->standard.attrib; + finfo->name = info->standard.name.s; + break; + + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + finfo->size = info->both_directory_info.size; + finfo->ctime = nt_time_to_unix(info->both_directory_info.create_time); + finfo->atime = nt_time_to_unix(info->both_directory_info.access_time); + finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time); + finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */ + if (info->both_directory_info.short_name.s) { + strncpy(finfo->short_name, info->both_directory_info.short_name.s, + sizeof(finfo->short_name)-1); + } + finfo->name = info->both_directory_info.name.s; + break; + + default: + DEBUG(0,("Unhandled level %d in interpret_long_filename\n", (int)level)); + return False; } - finfo->name = info->both_directory_info.name.s; + return True; } @@ -75,6 +94,7 @@ static BOOL cli_list_new_callback(void *private, union smb_search_data *file) interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]); + state->last_name = state->dirlist[state->total_received].name; state->total_received++; state->ff_searchcount++; @@ -95,7 +115,6 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, char *mask; int ff_eos = 0, i, ff_searchcount; int ff_dir_handle=0; - enum smb_search_level level; /* initialize state for search */ state.dirlist = NULL; @@ -106,9 +125,9 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, mask = talloc_strdup(state.mem_ctx, Mask); if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) { - level = RAW_SEARCH_BOTH_DIRECTORY_INFO; + state.info_level = RAW_SEARCH_BOTH_DIRECTORY_INFO; } else { - level = RAW_SEARCH_STANDARD; + state.info_level = RAW_SEARCH_STANDARD; } while (1) { @@ -116,7 +135,7 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, if (first) { NTSTATUS status; - first_parms.t2ffirst.level = level; + first_parms.t2ffirst.level = state.info_level; first_parms.t2ffirst.in.max_count = max_matches; first_parms.t2ffirst.in.search_attrib = attribute; first_parms.t2ffirst.in.pattern = mask; @@ -142,12 +161,12 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, } else { NTSTATUS status; - next_parms.t2fnext.level = level; + next_parms.t2fnext.level = state.info_level; next_parms.t2fnext.in.max_count = max_matches; - next_parms.t2fnext.in.last_name = mask; + next_parms.t2fnext.in.last_name = state.last_name; next_parms.t2fnext.in.handle = ff_dir_handle; next_parms.t2fnext.in.resume_key = 0; - next_parms.t2fnext.in.flags = FLAG_TRANS2_FIND_CONTINUE | FLAG_TRANS2_FIND_CLOSE_IF_END; + next_parms.t2fnext.in.flags = FLAG_TRANS2_FIND_CLOSE_IF_END; status = smb_raw_search_next(tree, state.mem_ctx, -- cgit From f0ff2eccad1309f5a3e79686977b76c110c4ddb3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Aug 2004 04:15:05 +0000 Subject: r1627: make sure we initialise write_time in the deprecated function cli_ctemp() (This used to be commit 48b5b740f1d0c252f248aa944d8487a83c016fa1) --- source4/libcli/clifile.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 6f1c98555b..b3acb9136a 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -652,6 +652,7 @@ int cli_ctemp(struct cli_tree *tree, const char *path, char **tmp_path) open_parms.openx.level = RAW_OPEN_CTEMP; open_parms.ctemp.in.attrib = 0; open_parms.ctemp.in.directory = path; + open_parms.ctemp.in.write_time = 0; status = smb_raw_open(tree, mem_ctx, &open_parms); if (tmp_path) { -- cgit From 94fb514376e7cb1c3ba4f89e10289350052d1294 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Aug 2004 05:47:24 +0000 Subject: r1630: - fixed the replacement timegm() function to work correctly for DST changes - got rid of global_myname(), using lp_netbios_name() instead (This used to be commit e8d4b390884e487163d81f66a5a7ac1de1305d9a) --- source4/libcli/auth/kerberos_verify.c | 2 +- source4/libcli/auth/ntlmssp.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 76e98cb39a..5cd22b3749 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -230,7 +230,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au like. We have to go through all this to allow us to store the secret internally, instead of using /etc/krb5.keytab */ - myname = name_to_fqdn(mem_ctx, global_myname()); + myname = name_to_fqdn(mem_ctx, lp_netbios_name()); strlower_m(myname); asprintf(&host_princ_s, "host/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 75c1e30f56..9579f3612c 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -915,7 +915,7 @@ NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->set_challenge = set_challenge; (*ntlmssp_state)->may_set_challenge = may_set_challenge; - (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_global_myname = lp_netbios_name; (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ @@ -1268,7 +1268,7 @@ NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->mem_ctx = mem_ctx; - (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_global_myname = lp_netbios_name; (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True); -- cgit From cfdd3e68bed5f0c8cfa7d50ee8d7ce70826aa664 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Aug 2004 05:59:28 +0000 Subject: r1631: don't use req->transport after req has been destroyed (This used to be commit 35f4ad4700de25085a2d0e5d0f9674ca2e606cd1) --- source4/libcli/raw/rawfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 5128ba96ce..0d00ffcca6 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -267,6 +267,7 @@ static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, ****************************************************************************/ static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) { + struct cli_transport *transport = req?req->transport:NULL; struct smb_trans2 t2; NTSTATUS status; @@ -279,8 +280,7 @@ static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx parms->t2open.out.fnum = SVAL(t2.out.params.data, VWV(0)); parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1)); - parms->t2open.out.write_time = raw_pull_dos_date3(req->transport, - t2.out.params.data + VWV(2)); + parms->t2open.out.write_time = raw_pull_dos_date3(transport, t2.out.params.data + VWV(2)); parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4)); parms->t2open.out.access = SVAL(t2.out.params.data, VWV(6)); parms->t2open.out.ftype = SVAL(t2.out.params.data, VWV(7)); -- cgit From 53781e9d37b9adb1cf2d5be2a6ae6c1f5ace26c9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Aug 2004 06:52:06 +0000 Subject: r1633: fixed a couple of async oplock handling errors (This used to be commit d7e2f39b90122088e94d4a8e8c7ffa7c91d7d664) --- source4/libcli/raw/clioplock.c | 5 ++++- source4/libcli/raw/clitransport.c | 14 +++++++++----- source4/libcli/raw/rawnotify.c | 3 ++- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/raw/smb_signing.c | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index 0cd6adb41f..29e44fc940 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -39,8 +39,11 @@ BOOL cli_oplock_ack(struct cli_tree *tree, uint16_t fnum, uint16_t ack_level) SSVAL(req->out.vwv,VWV(6),0); SSVAL(req->out.vwv,VWV(7),0); + /* this request does not expect a reply, so tell the signing + subsystem not to allocate an id for a reply */ + req->one_way_request = 1; + ret = cli_request_send(req); - cli_request_destroy(req); return ret; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index abdcc0d392..d2d78d0789 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -250,9 +250,14 @@ static void cli_transport_process_send(struct cli_transport *transport) req->out.buffer += ret; req->out.size -= ret; if (req->out.size == 0) { - req->state = CLI_REQUEST_RECV; DLIST_REMOVE(transport->pending_send, req); - DLIST_ADD(transport->pending_recv, req); + if (req->one_way_request) { + req->state = CLI_REQUEST_DONE; + cli_request_destroy(req); + } else { + req->state = CLI_REQUEST_RECV; + DLIST_ADD(transport->pending_recv, req); + } } } @@ -275,13 +280,14 @@ static void cli_transport_finish_recv(struct cli_transport *transport) buffer = transport->recv_buffer.buffer; len = transport->recv_buffer.req_size; + ZERO_STRUCT(transport->recv_buffer); + hdr = buffer+NBT_HDR_SIZE; vwv = hdr + HDR_VWV; /* see if it could be an oplock break request */ if (handle_oplock_break(transport, len, hdr, vwv)) { talloc_free(transport->mem_ctx, buffer); - ZERO_STRUCT(transport->recv_buffer); return; } @@ -377,7 +383,6 @@ async: /* if this request has an async handler then call that to notify that the reply has been received. This might destroy the request so it must happen last */ - ZERO_STRUCT(transport->recv_buffer); DLIST_REMOVE(transport->pending_recv, req); req->state = CLI_REQUEST_DONE; if (req->async.fn) { @@ -390,7 +395,6 @@ error: DLIST_REMOVE(transport->pending_recv, req); req->state = CLI_REQUEST_ERROR; } - ZERO_STRUCT(transport->recv_buffer); } /* diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index b8efa2fcd6..a9215fee10 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -108,9 +108,10 @@ NTSTATUS smb_raw_ntcancel(struct cli_request *oldreq) /* this request does not expect a reply, so tell the signing subsystem not to allocate an id for a reply */ + req->sign_single_increment = 1; req->one_way_request = 1; cli_request_send(req); - return cli_request_destroy(req); + return NT_STATUS_OK; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 9c53c4b18c..38b8f71f57 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -324,7 +324,7 @@ BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char { /* we must be very fussy about what we consider an oplock break to avoid matching readbraw replies */ - if (len != MIN_SMB_SIZE + VWV(8) || + if (len != MIN_SMB_SIZE + VWV(8) + NBT_HDR_SIZE || (CVAL(hdr, HDR_FLG) & FLAG_REPLY) || CVAL(hdr,HDR_COM) != SMBlockingX || SVAL(hdr, HDR_MID) != 0xFFFF || diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 80615f2d72..9c02fe50ec 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -220,7 +220,7 @@ static void cli_request_simple_sign_outgoing_message(struct cli_request *req) /* some requests (eg. NTcancel) are one way, and the sequence number should be increased by 1 not 2 */ - if (req->one_way_request) { + if (req->sign_single_increment) { data->next_seq_num += 1; } else { data->next_seq_num += 2; -- cgit From 682a02d7d41b7653e5c9e90e65d290a8314045f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Aug 2004 07:16:41 +0000 Subject: r1634: to get signing right for async requests we must send requests in order. Fixed the linked list add to always add to the end for outgoing requests. (This used to be commit 81c450b434bb28b0fa8620c309f39203e8950497) --- source4/libcli/raw/clitransport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index d2d78d0789..a33cc5e8f6 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -480,7 +480,7 @@ void cli_transport_send(struct cli_request *req) { /* put it on the outgoing socket queue */ req->state = CLI_REQUEST_SEND; - DLIST_ADD(req->transport->pending_send, req); + DLIST_ADD_END(req->transport->pending_send, req, struct cli_request *); /* make sure we look for write events */ cli_transport_write_enable(req->transport); -- cgit From bff2c7a5780433d815eea7a3d735ac562a0dbdf9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Aug 2004 08:04:11 +0000 Subject: r1635: when a transport dies, setup errors for all pending sends and recvs, plus disalllow any more sends (This used to be commit 326fdc8c9d2848c6c08a49e34c72430fe0116d23) --- source4/libcli/raw/clitransport.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index a33cc5e8f6..3b3c10ed01 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -98,6 +98,28 @@ void cli_transport_close(struct cli_transport *transport) void cli_transport_dead(struct cli_transport *transport) { cli_sock_dead(transport->socket); + + /* all pending sends become errors */ + while (transport->pending_send) { + struct cli_request *req = transport->pending_send; + req->state = CLI_REQUEST_ERROR; + req->status = NT_STATUS_NET_WRITE_FAULT; + DLIST_REMOVE(transport->pending_send, req); + if (req->async.fn) { + req->async.fn(req); + } + } + + /* as do all pending receives */ + while (transport->pending_recv) { + struct cli_request *req = transport->pending_recv; + req->state = CLI_REQUEST_ERROR; + req->status = NT_STATUS_NET_WRITE_FAULT; + DLIST_REMOVE(transport->pending_recv, req); + if (req->async.fn) { + req->async.fn(req); + } + } } @@ -478,6 +500,13 @@ BOOL cli_transport_process(struct cli_transport *transport) */ void cli_transport_send(struct cli_request *req) { + /* check if the transport is dead */ + if (req->transport->socket->fd == -1) { + req->state = CLI_REQUEST_ERROR; + req->status = NT_STATUS_NET_WRITE_FAULT; + return; + } + /* put it on the outgoing socket queue */ req->state = CLI_REQUEST_SEND; DLIST_ADD_END(req->transport->pending_send, req, struct cli_request *); -- cgit From c5fbb6f23c2d399c7510bc552cdb1a27b1ef66a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 4 Aug 2004 13:23:35 +0000 Subject: r1654: rename cli_ -> smbcli_ rename CLI_ -> SMBCLI_ metze (This used to be commit 8441750fd9427dd6fe477f27e603821b4026f038) --- source4/libcli/cliconnect.c | 58 +++++----- source4/libcli/clideltree.c | 36 +++--- source4/libcli/clidfs.c | 224 ++++++++++++++++++------------------ source4/libcli/clifile.c | 64 +++++------ source4/libcli/clilist.c | 26 ++--- source4/libcli/climessage.c | 54 ++++----- source4/libcli/clireadwrite.c | 6 +- source4/libcli/clisecdesc.c | 6 +- source4/libcli/clitrans2.c | 22 ++-- source4/libcli/namequery_dc.c | 2 +- source4/libcli/raw/clioplock.c | 12 +- source4/libcli/raw/clisession.c | 140 +++++++++++----------- source4/libcli/raw/clisocket.c | 34 +++--- source4/libcli/raw/clitransport.c | 124 ++++++++++---------- source4/libcli/raw/clitree.c | 100 ++++++++-------- source4/libcli/raw/rawacl.c | 12 +- source4/libcli/raw/rawdate.c | 12 +- source4/libcli/raw/rawfile.c | 224 ++++++++++++++++++------------------ source4/libcli/raw/rawfileinfo.c | 118 +++++++++---------- source4/libcli/raw/rawfsinfo.c | 42 +++---- source4/libcli/raw/rawioctl.c | 46 ++++---- source4/libcli/raw/rawnegotiate.c | 48 ++++---- source4/libcli/raw/rawnotify.c | 16 +-- source4/libcli/raw/rawreadwrite.c | 62 +++++----- source4/libcli/raw/rawrequest.c | 144 +++++++++++------------ source4/libcli/raw/rawsearch.c | 138 +++++++++++----------- source4/libcli/raw/rawsetfileinfo.c | 68 +++++------ source4/libcli/raw/rawtrans.c | 110 +++++++++--------- source4/libcli/raw/smb_signing.c | 62 +++++----- source4/libcli/util/clierror.c | 12 +- source4/libcli/util/cliutil.c | 2 +- source4/libcli/util/smbencrypt.c | 8 +- 32 files changed, 1016 insertions(+), 1016 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 8b064f161e..8753f26b5f 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -21,45 +21,45 @@ #include "includes.h" /* - wrapper around cli_sock_connect() + wrapper around smbcli_sock_connect() */ -BOOL cli_socket_connect(struct cli_state *cli, const char *server, struct in_addr *ip) +BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server, struct in_addr *ip) { - struct cli_socket *sock; + struct smbcli_socket *sock; - sock = cli_sock_init(); + sock = smbcli_sock_init(); if (!sock) return False; - if (!cli_sock_connect_byname(sock, server, 0)) { - cli_sock_close(sock); + if (!smbcli_sock_connect_byname(sock, server, 0)) { + smbcli_sock_close(sock); return False; } - cli->transport = cli_transport_init(sock); + cli->transport = smbcli_transport_init(sock); if (!cli->transport) { - cli_sock_close(sock); + smbcli_sock_close(sock); return False; } return True; } -/* wrapper around cli_transport_connect() */ -BOOL cli_transport_establish(struct cli_state *cli, +/* wrapper around smbcli_transport_connect() */ +BOOL smbcli_transport_establish(struct smbcli_state *cli, struct nmb_name *calling, struct nmb_name *called) { - return cli_transport_connect(cli->transport, calling, called); + return smbcli_transport_connect(cli->transport, calling, called); } /* wrapper around smb_raw_negotiate() */ -NTSTATUS cli_negprot(struct cli_state *cli) +NTSTATUS smbcli_negprot(struct smbcli_state *cli) { return smb_raw_negotiate(cli->transport); } /* wrapper around smb_raw_session_setup() */ -NTSTATUS cli_session_setup(struct cli_state *cli, +NTSTATUS smbcli_session_setup(struct smbcli_state *cli, const char *user, const char *password, const char *domain) @@ -68,10 +68,10 @@ NTSTATUS cli_session_setup(struct cli_state *cli, NTSTATUS status; TALLOC_CTX *mem_ctx; - cli->session = cli_session_init(cli->transport); + cli->session = smbcli_session_init(cli->transport); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; - mem_ctx = talloc_init("cli_session_setup"); + mem_ctx = talloc_init("smbcli_session_setup"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; setup.generic.level = RAW_SESSSETUP_GENERIC; @@ -98,14 +98,14 @@ NTSTATUS cli_session_setup(struct cli_state *cli, } /* wrapper around smb_tree_connect() */ -NTSTATUS cli_send_tconX(struct cli_state *cli, const char *sharename, +NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, const char *devtype, const char *password) { union smb_tcon tcon; TALLOC_CTX *mem_ctx; NTSTATUS status; - cli->tree = cli_tree_init(cli->session); + cli->tree = smbcli_tree_init(cli->session); if (!cli->tree) return NT_STATUS_UNSUCCESSFUL; cli->tree->reference_count++; @@ -132,9 +132,9 @@ NTSTATUS cli_send_tconX(struct cli_state *cli, const char *sharename, /* - easy way to get to a fully connected cli_state in one call + easy way to get to a fully connected smbcli_state in one call */ -NTSTATUS cli_full_connection(struct cli_state **ret_cli, +NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, const char *myname, const char *host, struct in_addr *ip, @@ -146,12 +146,12 @@ NTSTATUS cli_full_connection(struct cli_state **ret_cli, uint_t flags, BOOL *retry) { - struct cli_tree *tree; + struct smbcli_tree *tree; NTSTATUS status; char *p; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("cli_full_connection"); + mem_ctx = talloc_init("smbcli_full_connection"); *ret_cli = NULL; @@ -162,13 +162,13 @@ NTSTATUS cli_full_connection(struct cli_state **ret_cli, username = talloc_strdup(mem_ctx, p+1); } - status = cli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, + status = smbcli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, username, domain, password); if (!NT_STATUS_IS_OK(status)) { goto done; } - (*ret_cli) = cli_state_init(); + (*ret_cli) = smbcli_state_init(); (*ret_cli)->tree = tree; (*ret_cli)->session = tree->session; @@ -184,7 +184,7 @@ done: /* disconnect the tree */ -NTSTATUS cli_tdis(struct cli_state *cli) +NTSTATUS smbcli_tdis(struct smbcli_state *cli) { return smb_tree_disconnect(cli->tree); } @@ -192,12 +192,12 @@ NTSTATUS cli_tdis(struct cli_state *cli) /**************************************************************************** Initialise a client state structure. ****************************************************************************/ -struct cli_state *cli_state_init(void) +struct smbcli_state *smbcli_state_init(void) { - struct cli_state *cli; + struct smbcli_state *cli; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("cli_state"); + mem_ctx = talloc_init("smbcli_state"); if (!mem_ctx) return NULL; cli = talloc_zero(mem_ctx, sizeof(*cli)); @@ -209,12 +209,12 @@ struct cli_state *cli_state_init(void) /**************************************************************************** Shutdown a client structure. ****************************************************************************/ -void cli_shutdown(struct cli_state *cli) +void smbcli_shutdown(struct smbcli_state *cli) { if (!cli) return; if (cli->tree) { cli->tree->reference_count++; - cli_tree_close(cli->tree); + smbcli_tree_close(cli->tree); } if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 2bbfd9bd22..aa73f5b90b 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -21,7 +21,7 @@ #include "includes.h" struct delete_state { - struct cli_tree *tree; + struct smbcli_tree *tree; int total_deleted; BOOL failed; }; @@ -41,30 +41,30 @@ static void delete_fn(file_info *finfo, const char *name, void *state) asprintf(&s, "%s%s", n, finfo->name); if (finfo->mode & FILE_ATTRIBUTE_READONLY) { - if (NT_STATUS_IS_ERR(cli_setatr(dstate->tree, s, 0, 0))) { + if (NT_STATUS_IS_ERR(smbcli_setatr(dstate->tree, s, 0, 0))) { DEBUG(2,("Failed to remove READONLY on %s - %s\n", - s, cli_errstr(dstate->tree))); + s, smbcli_errstr(dstate->tree))); } } if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { char *s2; asprintf(&s2, "%s\\*", s); - cli_unlink(dstate->tree, s2); - cli_list(dstate->tree, s2, + smbcli_unlink(dstate->tree, s2); + smbcli_list(dstate->tree, s2, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, state); free(s2); - if (NT_STATUS_IS_ERR(cli_rmdir(dstate->tree, s))) { + if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate->tree, s))) { DEBUG(2,("Failed to delete %s - %s\n", - s, cli_errstr(dstate->tree))); + s, smbcli_errstr(dstate->tree))); dstate->failed = True; } dstate->total_deleted++; } else { - if (NT_STATUS_IS_ERR(cli_unlink(dstate->tree, s))) { + if (NT_STATUS_IS_ERR(smbcli_unlink(dstate->tree, s))) { DEBUG(2,("Failed to delete %s - %s\n", - s, cli_errstr(dstate->tree))); + s, smbcli_errstr(dstate->tree))); dstate->failed = True; } dstate->total_deleted++; @@ -77,7 +77,7 @@ static void delete_fn(file_info *finfo, const char *name, void *state) recursively descend a tree deleting all files returns the number of files deleted, or -1 on error */ -int cli_deltree(struct cli_tree *tree, const char *dname) +int smbcli_deltree(struct smbcli_tree *tree, const char *dname) { char *mask; struct delete_state dstate; @@ -87,24 +87,24 @@ int cli_deltree(struct cli_tree *tree, const char *dname) dstate.failed = False; /* it might be a file */ - if (NT_STATUS_IS_OK(cli_unlink(tree, dname))) { + if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { return 1; } - if (NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) || - NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) || - NT_STATUS_EQUAL(cli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) { + if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) || + NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) || + NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) { return 0; } asprintf(&mask, "%s\\*", dname); - cli_unlink(dstate.tree, mask); - cli_list(dstate.tree, mask, + smbcli_unlink(dstate.tree, mask); + smbcli_list(dstate.tree, mask, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, &dstate); free(mask); - if (NT_STATUS_IS_ERR(cli_rmdir(dstate.tree, dname))) { + if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate.tree, dname))) { DEBUG(2,("Failed to delete %s - %s\n", - dname, cli_errstr(dstate.tree))); + dname, smbcli_errstr(dstate.tree))); return -1; } dstate.total_deleted++; diff --git a/source4/libcli/clidfs.c b/source4/libcli/clidfs.c index ae7a8dc6eb..674666a60a 100644 --- a/source4/libcli/clidfs.c +++ b/source4/libcli/clidfs.c @@ -20,21 +20,21 @@ #include "includes.h" -BOOL cli_client_initialize(struct cli_client* context, +BOOL smbcli_client_initialize(struct smbcli_client* context, const char* sockops, char* username, char* password, char* workgroup, int flags) { int i; for (i=0; i < DFS_MAX_CLUSTER_SIZE ; i++) { - context->cli[i] = cli_raw_initialise(); + context->cli[i] = smbcli_raw_initialise(); } context->sockops = sockops; context->username = username; context->password = password; context->workgroup = workgroup; context->connection_flags = flags; - if (flags & CLI_FULL_CONNECTION_USE_DFS) + if (flags & SMBCLI_FULL_CONNECTION_USE_DFS) context->use_dfs = True; context->number_members = DFS_MAX_CLUSTER_SIZE; return True; @@ -46,7 +46,7 @@ BOOL cli_client_initialize(struct cli_client* context, The structure of a Dfs referral depends on the info level. ****************************************************************************/ -static int interpret_referral(struct cli_state *cli, +static int interpret_referral(struct smbcli_state *cli, int level,char *p,referral_info *rinfo) { char* q; @@ -99,12 +99,12 @@ static int interpret_referral(struct cli_state *cli, } #if 0 -int cli_select_dfs_referral(struct cli_state *cli, dfs_info* dinfo) +int smbcli_select_dfs_referral(struct smbcli_state *cli, dfs_info* dinfo) { return (int)sys_random()%dinfo->number_referrals; } -int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinfo) +int smbcli_get_dfs_referral(struct smbcli_state *cli,const char *Fname, dfs_info* dinfo) { struct smb_trans2 parms; int info_level; @@ -123,20 +123,20 @@ int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinf pstrcpy(fname,Fname); setup = TRANSACT2_GET_DFS_REFERRAL ; - SSVAL(param,0,CLI_DFS_MAX_REFERRAL_LEVEL); /* attribute */ + SSVAL(param,0,SMBCLI_DFS_MAX_REFERRAL_LEVEL); /* attribute */ p = param+2; p += clistr_push(cli, param+2, fname, -1, STR_TERMINATE); param_len = PTR_DIFF(p, param); - DEBUG(3,("cli_get_dfs_referral: sending request\n")); + DEBUG(3,("smbcli_get_dfs_referral: sending request\n")); trans_param.length = param_len; trans_param.data = param; trans_data.length = 0; trans_data.data = NULL; - if (!cli_send_trans(cli, SMBtrans2, + if (!smbcli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ @@ -147,25 +147,25 @@ int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinf return 0; } - if (!cli_receive_trans(cli, SMBtrans2, + if (!smbcli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && - cli_is_dos_error(cli)) { + smbcli_is_dos_error(cli)) { return 0; } - //printf("cli_get_dfs_referral: received response, rdata=%p, rparam=%p\n", + //printf("smbcli_get_dfs_referral: received response, rdata=%p, rparam=%p\n", // rdata, rparam); - if (cli_is_error(cli) || !rdata) + if (smbcli_is_error(cli) || !rdata) return 0; /* parse out some important return info */ - //printf("cli_get_dfs_referral: valid response\n"); + //printf("smbcli_get_dfs_referral: valid response\n"); p = rdata; dinfo->path_consumed = SVAL(p,0); dinfo->number_referrals = SVAL(p,2); dinfo->referral_flags = SVAL(p,4); - DEBUG(3,("cli_get_dfs_referral: path_consumed=%d, # referrals=%d, flags=0x%x\n", + DEBUG(3,("smbcli_get_dfs_referral: path_consumed=%d, # referrals=%d, flags=0x%x\n", dinfo->path_consumed, dinfo->number_referrals, dinfo->referral_flags)); @@ -181,7 +181,7 @@ int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinf DEBUG(3,("received %d Dfs referrals\n", dinfo->number_referrals)); - dinfo->selected_referral = cli_select_dfs_referral(cli, dinfo); + dinfo->selected_referral = smbcli_select_dfs_referral(cli, dinfo); DEBUG(3, ("selected Dfs referral %d %s\n", dinfo->selected_referral, dinfo->referrals[dinfo->selected_referral].node)); @@ -190,12 +190,12 @@ int cli_get_dfs_referral(struct cli_state *cli,const char *Fname, dfs_info* dinf #endif /* check if the server produced Dfs redirect */ -BOOL cli_check_dfs_redirect(struct cli_state* c, char* fname, +BOOL smbcli_check_dfs_redirect(struct smbcli_state* c, char* fname, dfs_info* dinfo) { //printf("check_dfs_redirect: error %s\n", - // cli_errstr(c)); - if (cli_is_dos_error(c)) { + // smbcli_errstr(c)); + if (smbcli_is_dos_error(c)) { printf("got dos error\n"); return False; @@ -204,7 +204,7 @@ BOOL cli_check_dfs_redirect(struct cli_state* c, char* fname, /* Check NT error */ - status = cli_nt_error(c); + status = smbcli_nt_error(c); //printf("got nt error 0x%x\n", status); if (NT_STATUS_V(NT_STATUS_PATH_NOT_COVERED) != NT_STATUS_V(status)) { @@ -213,27 +213,27 @@ BOOL cli_check_dfs_redirect(struct cli_state* c, char* fname, } /* execute trans2 getdfsreferral */ //printf("check_dfs_redirect: process referral\n"); - //cli_get_dfs_referral(c, fname, dinfo); + //smbcli_get_dfs_referral(c, fname, dinfo); return True; } -int cli_dfs_open_connection(struct cli_client* cluster, +int smbcli_dfs_open_connection(struct smbcli_client* cluster, char* host, char* share, int flags) { int i; BOOL retry; - struct cli_state* c; + struct smbcli_state* c; // check if already connected for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { - if (cluster->cli[i]->in_use && strequal(host, cli_state_get_host(cluster->cli[i])) - && strequal(share, cli_state_get_share(cluster->cli[i]))) { - DEBUG(3,("cli_dfs_open_connection: already connected to \\\\%s\\%s\n", host, share)); + if (cluster->cli[i]->in_use && strequal(host, smbcli_state_get_host(cluster->cli[i])) + && strequal(share, smbcli_state_get_share(cluster->cli[i]))) { + DEBUG(3,("smbcli_dfs_open_connection: already connected to \\\\%s\\%s\n", host, share)); return i; } } // open connection - DEBUG(3,("cli_dfs_open_connection: opening \\\\%s\\%s %s@%s\n", + DEBUG(3,("smbcli_dfs_open_connection: opening \\\\%s\\%s %s@%s\n", host, share, cluster->username, cluster->workgroup)); for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { if (!cluster->cli[i]->in_use) { @@ -244,19 +244,19 @@ int cli_dfs_open_connection(struct cli_client* cluster, return -1; c = cluster->cli[i]; - if (NT_STATUS_IS_ERR(cli_full_connection(&c, + if (NT_STATUS_IS_ERR(smbcli_full_connection(&c, NULL, host, NULL, 0, share, "?????", cluster->username, cluster->workgroup, cluster->password, flags, &retry))) return -1; - cli_state_set_sockopt(cluster->cli[i], cluster->sockops); - cli_state_set_host(cluster->cli[i], host); - cli_state_set_share(cluster->cli[i], share); + smbcli_state_set_sockopt(cluster->cli[i], cluster->sockops); + smbcli_state_set_host(cluster->cli[i], host); + smbcli_state_set_share(cluster->cli[i], share); cluster->cli[i]->in_use = True; - DEBUG(3,("cli_dfs_open_connection: connected \\\\%s\\%s (%d) %s@%s\n", - cli_state_get_host(cluster->cli[i]), cli_state_get_share(cluster->cli[i]), i, + DEBUG(3,("smbcli_dfs_open_connection: connected \\\\%s\\%s (%d) %s@%s\n", + smbcli_state_get_host(cluster->cli[i]), smbcli_state_get_share(cluster->cli[i]), i, cluster->username, cluster->workgroup)); return i; @@ -267,7 +267,7 @@ int cli_dfs_open_connection(struct cli_client* cluster, into the dfs_path structure **********************************************************************/ -BOOL cli_parse_dfs_path(char* pathname, struct dfs_path* pdp) +BOOL smbcli_parse_dfs_path(char* pathname, struct dfs_path* pdp) { pstring pathname_local; char* p,*temp; @@ -278,7 +278,7 @@ BOOL cli_parse_dfs_path(char* pathname, struct dfs_path* pdp) ZERO_STRUCTP(pdp); trim_string(temp,"\\","\\"); - DEBUG(10,("temp in cli_parse_dfs_path: .%s. after trimming \\'s\n",temp)); + DEBUG(10,("temp in smbcli_parse_dfs_path: .%s. after trimming \\'s\n",temp)); /* now tokenize */ /* parse out hostname */ @@ -308,7 +308,7 @@ BOOL cli_parse_dfs_path(char* pathname, struct dfs_path* pdp) return True; } -char* rebuild_filename(char *referral_fname, struct cli_state* c, +char* rebuild_filename(char *referral_fname, struct smbcli_state* c, char* fname, int path_consumed) { const char *template = "\\\\%s\\%s\\%s"; @@ -317,12 +317,12 @@ char* rebuild_filename(char *referral_fname, struct cli_state* c, // TODO: handle consumed length DEBUG(3,("rebuild_filename: %s, %d consumed of %d\n", fname, path_consumed, strlen(fname))); - if (cli_parse_dfs_path(fname, &dp)) { + if (smbcli_parse_dfs_path(fname, &dp)) { DEBUG(3,("rebuild_filename: reqpath=%s\n", dp.reqpath)); asprintf(&referral_fname, - template, cli_state_get_host(c), - cli_state_get_share(c), dp.reqpath); + template, smbcli_state_get_host(c), + smbcli_state_get_share(c), dp.reqpath); } else return NULL; @@ -334,7 +334,7 @@ char* rebuild_filename(char *referral_fname, struct cli_state* c, Open a file (allowing for Dfs referral). ****************************************************************************/ -int cli_dfs_open(struct cli_client* cluster, int *server, +int smbcli_dfs_open(struct smbcli_client* cluster, int *server, char *fname_src, int flags, int share_mode) { int referral_number; @@ -342,15 +342,15 @@ int cli_dfs_open(struct cli_client* cluster, int *server, char *referral_fname; int fnum; - DEBUG(3,("cli_dfs_open: open %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + DEBUG(3,("smbcli_dfs_open: open %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); cluster->cli[*server]->dfs_referral = *server; - if ((fnum = cli_open(cluster->cli[*server], fname_src, flags, share_mode)) < 0) { - if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + if ((fnum = smbcli_open(cluster->cli[*server], fname_src, flags, share_mode)) < 0) { + if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { // choose referral, check if already connected, open if not referral_number = dinfo.selected_referral; - DEBUG(3,("cli_dfs_open: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + DEBUG(3,("smbcli_dfs_open: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, dinfo.referrals[referral_number].host, dinfo.referrals[referral_number].share, cluster->connection_flags); @@ -361,17 +361,17 @@ int cli_dfs_open(struct cli_client* cluster, int *server, if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) return False; fname_src = referral_fname; - DEBUG(3,("cli_dfs_open: Dfs open %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); - fnum = cli_open(cluster->cli[*server], fname_src, flags, share_mode); + DEBUG(3,("smbcli_dfs_open: Dfs open %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); + fnum = smbcli_open(cluster->cli[*server], fname_src, flags, share_mode); } - if (cli_is_error(cluster->cli[*server])) { - printf("cli_dfs_open: open of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); + if (smbcli_is_error(cluster->cli[*server])) { + printf("smbcli_dfs_open: open of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); return -1; } } - DEBUG(3,("cli_dfs_open: open %s fnum=%d\n", + DEBUG(3,("smbcli_dfs_open: open %s fnum=%d\n", fname_src, fnum)); return fnum; } @@ -380,7 +380,7 @@ int cli_dfs_open(struct cli_client* cluster, int *server, Delete a file (allowing for Dfs referral). ****************************************************************************/ -NTSTATUS cli_nt_unlink(struct cli_client* cluster, int *server, +NTSTATUS smbcli_nt_unlink(struct smbcli_client* cluster, int *server, char *fname_src, uint16_t FileAttributes) { int referral_number; @@ -388,20 +388,20 @@ NTSTATUS cli_nt_unlink(struct cli_client* cluster, int *server, char *referral_fname; struct smb_unlink parms; - DEBUG(3,("cli_nt_unlink: delete %s on server %s(%d), attributes=0x%x\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server, + DEBUG(3,("smbcli_nt_unlink: delete %s on server %s(%d), attributes=0x%x\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server, FileAttributes)); cluster->cli[*server]->dfs_referral = *server; parms.in.pattern = fname_src; parms.in.dirtype = FileAttributes; - if (NT_STATUS_IS_ERR(cli_raw_unlink(cluster->cli[*server], &parms))) { - printf("cli_nt_unlink: delete of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); - if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + if (NT_STATUS_IS_ERR(smbcli_raw_unlink(cluster->cli[*server], &parms))) { + printf("smbcli_nt_unlink: delete of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); + if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { // choose referral, check if already connected, open if not referral_number = dinfo.selected_referral; - DEBUG(3,("cli_nt_unlink: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + DEBUG(3,("smbcli_nt_unlink: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, dinfo.referrals[referral_number].host, dinfo.referrals[referral_number].share, cluster->connection_flags); @@ -412,38 +412,38 @@ NTSTATUS cli_nt_unlink(struct cli_client* cluster, int *server, if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) return NT_STATUS_INTERNAL_ERROR; fname_src = referral_fname; - DEBUG(3,("cli_nt_unlink: Dfs delete %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); - cli_raw_unlink(cluster->cli[*server], &parms); + DEBUG(3,("smbcli_nt_unlink: Dfs delete %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); + smbcli_raw_unlink(cluster->cli[*server], &parms); } - if (cli_is_error(cluster->cli[*server])) { - printf("cli_nt_unlink: delete of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); + if (smbcli_is_error(cluster->cli[*server])) { + printf("smbcli_nt_unlink: delete of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); } } - return cli_nt_error(cluster->cli[*server]); + return smbcli_nt_error(cluster->cli[*server]); } /**************************************************************************** Rename a file (allowing for Dfs referral). ****************************************************************************/ -BOOL cli_dfs_rename(struct cli_client* cluster, int *server, +BOOL smbcli_dfs_rename(struct smbcli_client* cluster, int *server, char *fname_src, char *fname_dst) { int referral_number; dfs_info dinfo; char *referral_fname; - DEBUG(3,("cli_dfs_rename: rename %s to %s on server %s(%d)\n", - fname_src, fname_dst, cli_state_get_host(cluster->cli[*server]), *server)); + DEBUG(3,("smbcli_dfs_rename: rename %s to %s on server %s(%d)\n", + fname_src, fname_dst, smbcli_state_get_host(cluster->cli[*server]), *server)); cluster->cli[*server]->dfs_referral = *server; - if (!cli_rename(cluster->cli[*server], fname_src, fname_dst)) { - if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + if (!smbcli_rename(cluster->cli[*server], fname_src, fname_dst)) { + if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { // choose referral, check if already connected, open if not referral_number = dinfo.selected_referral; - DEBUG(3,("cli_dfs_rename: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + DEBUG(3,("smbcli_dfs_rename: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, dinfo.referrals[referral_number].host, dinfo.referrals[referral_number].share, cluster->connection_flags); @@ -454,13 +454,13 @@ BOOL cli_dfs_rename(struct cli_client* cluster, int *server, if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) return False; fname_src = referral_fname; - DEBUG(3,("cli_dfs_rename: Dfs rename %s to %s on server %s(%d)\n", - fname_src, fname_dst, cli_state_get_host(cluster->cli[*server]), *server)); - cli_rename(cluster->cli[*server], fname_src, fname_dst); + DEBUG(3,("smbcli_dfs_rename: Dfs rename %s to %s on server %s(%d)\n", + fname_src, fname_dst, smbcli_state_get_host(cluster->cli[*server]), *server)); + smbcli_rename(cluster->cli[*server], fname_src, fname_dst); } - if (cli_is_error(cluster->cli[*server])) { - printf("cli_dfs_rename: rename of %s to %s failed (%s)\n", - fname_src, fname_dst, cli_errstr(cluster->cli[*server])); + if (smbcli_is_error(cluster->cli[*server])) { + printf("smbcli_dfs_rename: rename of %s to %s failed (%s)\n", + fname_src, fname_dst, smbcli_errstr(cluster->cli[*server])); return False; } } @@ -471,24 +471,24 @@ BOOL cli_dfs_rename(struct cli_client* cluster, int *server, Make directory (allowing for Dfs referral). ****************************************************************************/ -BOOL cli_dfs_mkdir(struct cli_client* cluster, int *server, +BOOL smbcli_dfs_mkdir(struct smbcli_client* cluster, int *server, char *fname_src) { int referral_number; dfs_info dinfo; char *referral_fname; - DEBUG(3,("cli_dfs_mkdir: mkdir %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + DEBUG(3,("smbcli_dfs_mkdir: mkdir %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); cluster->cli[*server]->dfs_referral = *server; - if (!cli_mkdir(cluster->cli[*server], fname_src)) { - printf("cli_dfs_mkdir: mkdir of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); - if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + if (!smbcli_mkdir(cluster->cli[*server], fname_src)) { + printf("smbcli_dfs_mkdir: mkdir of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); + if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { // choose referral, check if already connected, open if not referral_number = dinfo.selected_referral; - DEBUG(3,("cli_dfs_mkdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + DEBUG(3,("smbcli_dfs_mkdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, dinfo.referrals[referral_number].host, dinfo.referrals[referral_number].share, cluster->connection_flags); @@ -499,13 +499,13 @@ BOOL cli_dfs_mkdir(struct cli_client* cluster, int *server, if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) return False; fname_src = referral_fname; - DEBUG(3,("cli_dfs_mkdir: Dfs mkdir %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); - cli_mkdir(cluster->cli[*server], fname_src); + DEBUG(3,("smbcli_dfs_mkdir: Dfs mkdir %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); + smbcli_mkdir(cluster->cli[*server], fname_src); } - if (cli_is_error(cluster->cli[*server])) { - printf("cli_dfs_mkdir: mkdir of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); + if (smbcli_is_error(cluster->cli[*server])) { + printf("smbcli_dfs_mkdir: mkdir of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); return False; } } @@ -516,24 +516,24 @@ BOOL cli_dfs_mkdir(struct cli_client* cluster, int *server, Remove directory (allowing for Dfs referral). ****************************************************************************/ -BOOL cli_dfs_rmdir(struct cli_client* cluster, int *server, +BOOL smbcli_dfs_rmdir(struct smbcli_client* cluster, int *server, char *fname_src) { int referral_number; dfs_info dinfo; char *referral_fname; - DEBUG(3,("cli_dfs_rmdir: rmdir %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); + DEBUG(3,("smbcli_dfs_rmdir: rmdir %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); cluster->cli[*server]->dfs_referral = *server; - if (!cli_rmdir(cluster->cli[*server], fname_src)) { - printf("cli_dfs_rmdir: rmdir of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); - if (cli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { + if (!smbcli_rmdir(cluster->cli[*server], fname_src)) { + printf("smbcli_dfs_rmdir: rmdir of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); + if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { // choose referral, check if already connected, open if not referral_number = dinfo.selected_referral; - DEBUG(3,("cli_dfs_rmdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = cli_dfs_open_connection(cluster, + DEBUG(3,("smbcli_dfs_rmdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); + cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, dinfo.referrals[referral_number].host, dinfo.referrals[referral_number].share, cluster->connection_flags); @@ -544,13 +544,13 @@ BOOL cli_dfs_rmdir(struct cli_client* cluster, int *server, if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) return False; fname_src = referral_fname; - DEBUG(3,("cli_dfs_rmdir: Dfs rmdir %s on server %s(%d)\n", - fname_src, cli_state_get_host(cluster->cli[*server]), *server)); - cli_rmdir(cluster->cli[*server], fname_src); + DEBUG(3,("smbcli_dfs_rmdir: Dfs rmdir %s on server %s(%d)\n", + fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); + smbcli_rmdir(cluster->cli[*server], fname_src); } - if (cli_is_error(cluster->cli[*server])) { - printf("cli_dfs_rmdir: rmdir of %s failed (%s)\n", - fname_src, cli_errstr(cluster->cli[*server])); + if (smbcli_is_error(cluster->cli[*server])) { + printf("smbcli_dfs_rmdir: rmdir of %s failed (%s)\n", + fname_src, smbcli_errstr(cluster->cli[*server])); return False; } } diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index b3acb9136a..d3ebe0bf72 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -26,7 +26,7 @@ Hard/Symlink a file (UNIX extensions). ****************************************************************************/ -static NTSTATUS cli_link_internal(struct cli_tree *tree, +static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, const char *fname_src, const char *fname_dst, BOOL hard_link) { @@ -79,26 +79,26 @@ static uint32_t unix_perms_to_wire(mode_t perms) /**************************************************************************** Symlink a file (UNIX extensions). ****************************************************************************/ -NTSTATUS cli_unix_symlink(struct cli_tree *tree, const char *fname_src, +NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src, const char *fname_dst) { - return cli_link_internal(tree, fname_src, fname_dst, False); + return smbcli_link_internal(tree, fname_src, fname_dst, False); } /**************************************************************************** Hard a file (UNIX extensions). ****************************************************************************/ -NTSTATUS cli_unix_hardlink(struct cli_tree *tree, const char *fname_src, +NTSTATUS smbcli_unix_hardlink(struct smbcli_tree *tree, const char *fname_src, const char *fname_dst) { - return cli_link_internal(tree, fname_src, fname_dst, True); + return smbcli_link_internal(tree, fname_src, fname_dst, True); } /**************************************************************************** Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ -static NTSTATUS cli_unix_chmod_chown_internal(struct cli_tree *tree, +static NTSTATUS smbcli_unix_chmod_chown_internal(struct smbcli_tree *tree, const char *fname, uint32_t mode, uint32_t uid, uint32_t gid) @@ -121,9 +121,9 @@ static NTSTATUS cli_unix_chmod_chown_internal(struct cli_tree *tree, chmod a file (UNIX extensions). ****************************************************************************/ -NTSTATUS cli_unix_chmod(struct cli_tree *tree, const char *fname, mode_t mode) +NTSTATUS smbcli_unix_chmod(struct smbcli_tree *tree, const char *fname, mode_t mode) { - return cli_unix_chmod_chown_internal(tree, fname, + return smbcli_unix_chmod_chown_internal(tree, fname, unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); @@ -132,10 +132,10 @@ NTSTATUS cli_unix_chmod(struct cli_tree *tree, const char *fname, mode_t mode) /**************************************************************************** chown a file (UNIX extensions). ****************************************************************************/ -NTSTATUS cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, +NTSTATUS smbcli_unix_chown(struct smbcli_tree *tree, const char *fname, uid_t uid, gid_t gid) { - return cli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE, + return smbcli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE, (uint32_t)uid, (uint32_t)gid); } @@ -143,7 +143,7 @@ NTSTATUS cli_unix_chown(struct cli_tree *tree, const char *fname, uid_t uid, /**************************************************************************** Rename a file. ****************************************************************************/ -NTSTATUS cli_rename(struct cli_tree *tree, const char *fname_src, +NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src, const char *fname_dst) { union smb_rename parms; @@ -160,7 +160,7 @@ NTSTATUS cli_rename(struct cli_tree *tree, const char *fname_src, /**************************************************************************** Delete a file. ****************************************************************************/ -NTSTATUS cli_unlink(struct cli_tree *tree, const char *fname) +NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname) { struct smb_unlink parms; @@ -177,7 +177,7 @@ NTSTATUS cli_unlink(struct cli_tree *tree, const char *fname) /**************************************************************************** Create a directory. ****************************************************************************/ -NTSTATUS cli_mkdir(struct cli_tree *tree, const char *dname) +NTSTATUS smbcli_mkdir(struct smbcli_tree *tree, const char *dname) { union smb_mkdir parms; @@ -191,7 +191,7 @@ NTSTATUS cli_mkdir(struct cli_tree *tree, const char *dname) /**************************************************************************** Remove a directory. ****************************************************************************/ -NTSTATUS cli_rmdir(struct cli_tree *tree, const char *dname) +NTSTATUS smbcli_rmdir(struct smbcli_tree *tree, const char *dname) { struct smb_rmdir parms; @@ -204,7 +204,7 @@ NTSTATUS cli_rmdir(struct cli_tree *tree, const char *dname) /**************************************************************************** Set or clear the delete on close flag. ****************************************************************************/ -NTSTATUS cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) +NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum, BOOL flag) { union smb_setfileinfo parms; NTSTATUS status; @@ -223,7 +223,7 @@ NTSTATUS cli_nt_delete_on_close(struct cli_tree *tree, int fnum, BOOL flag) Create/open a file - exposing the full horror of the NT API :-). Used in CIFS-on-CIFS NTVFS. ****************************************************************************/ -int cli_nt_create_full(struct cli_tree *tree, const char *fname, +int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname, uint32_t CreatFlags, uint32_t DesiredAccess, uint32_t FileAttributes, uint32_t ShareAccess, uint32_t CreateDisposition, uint32_t CreateOptions, @@ -264,7 +264,7 @@ int cli_nt_create_full(struct cli_tree *tree, const char *fname, Open a file (using SMBopenx) WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ -int cli_open(struct cli_tree *tree, const char *fname, int flags, +int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode) { union smb_open open_parms; @@ -330,7 +330,7 @@ int cli_open(struct cli_tree *tree, const char *fname, int flags, /**************************************************************************** Close a file. ****************************************************************************/ -NTSTATUS cli_close(struct cli_tree *tree, int fnum) +NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum) { union smb_close close_parms; NTSTATUS status; @@ -346,7 +346,7 @@ NTSTATUS cli_close(struct cli_tree *tree, int fnum) send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ -NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, +NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len, int timeout, uint8_t locktype) { @@ -374,7 +374,7 @@ NTSTATUS cli_locktype(struct cli_tree *tree, int fnum, /**************************************************************************** Lock a file. ****************************************************************************/ -NTSTATUS cli_lock(struct cli_tree *tree, int fnum, +NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type) { @@ -402,7 +402,7 @@ NTSTATUS cli_lock(struct cli_tree *tree, int fnum, /**************************************************************************** Unlock a file. ****************************************************************************/ -NTSTATUS cli_unlock(struct cli_tree *tree, int fnum, uint32_t offset, uint32_t len) +NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len) { union smb_lock parms; struct smb_lock_entry lock[1]; @@ -427,7 +427,7 @@ NTSTATUS cli_unlock(struct cli_tree *tree, int fnum, uint32_t offset, uint32_t l /**************************************************************************** Lock a file with 64 bit offsets. ****************************************************************************/ -NTSTATUS cli_lock64(struct cli_tree *tree, int fnum, +NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, SMB_OFF_T offset, SMB_OFF_T len, int timeout, enum brl_type lock_type) { @@ -437,7 +437,7 @@ NTSTATUS cli_lock64(struct cli_tree *tree, int fnum, NTSTATUS status; if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) { - return cli_lock(tree, fnum, offset, len, timeout, lock_type); + return smbcli_lock(tree, fnum, offset, len, timeout, lock_type); } parms.lockx.level = RAW_LOCK_LOCKX; @@ -463,7 +463,7 @@ NTSTATUS cli_lock64(struct cli_tree *tree, int fnum, /**************************************************************************** Unlock a file with 64 bit offsets. ****************************************************************************/ -NTSTATUS cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, +NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, SMB_OFF_T offset, SMB_OFF_T len) { union smb_lock parms; @@ -471,7 +471,7 @@ NTSTATUS cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, NTSTATUS status; if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) { - return cli_unlock(tree, fnum, offset, len); + return smbcli_unlock(tree, fnum, offset, len); } parms.lockx.level = RAW_LOCK_LOCKX; @@ -494,7 +494,7 @@ NTSTATUS cli_unlock64(struct cli_tree *tree, int fnum, SMB_OFF_T offset, /**************************************************************************** Do a SMBgetattrE call. ****************************************************************************/ -NTSTATUS cli_getattrE(struct cli_tree *tree, int fnum, +NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum, uint16_t *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { @@ -535,7 +535,7 @@ NTSTATUS cli_getattrE(struct cli_tree *tree, int fnum, /**************************************************************************** Do a SMBgetatr call ****************************************************************************/ -NTSTATUS cli_getatr(struct cli_tree *tree, const char *fname, +NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname, uint16_t *attr, size_t *size, time_t *t) { union smb_fileinfo parms; @@ -569,7 +569,7 @@ NTSTATUS cli_getatr(struct cli_tree *tree, const char *fname, /**************************************************************************** Do a SMBsetatr call. ****************************************************************************/ -NTSTATUS cli_setatr(struct cli_tree *tree, const char *fname, uint16_t mode, +NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mode, time_t t) { union smb_setfileinfo parms; @@ -589,7 +589,7 @@ NTSTATUS cli_setatr(struct cli_tree *tree, const char *fname, uint16_t mode, /**************************************************************************** Check for existence of a dir. ****************************************************************************/ -NTSTATUS cli_chkpath(struct cli_tree *tree, const char *path) +NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path) { struct smb_chkpath parms; char *path2; @@ -615,13 +615,13 @@ NTSTATUS cli_chkpath(struct cli_tree *tree, const char *path) /**************************************************************************** Query disk space. ****************************************************************************/ -NTSTATUS cli_dskattr(struct cli_tree *tree, int *bsize, int *total, int *avail) +NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, int *bsize, int *total, int *avail) { union smb_fsinfo fsinfo_parms; TALLOC_CTX *mem_ctx; NTSTATUS status; - mem_ctx = talloc_init("cli_dskattr"); + mem_ctx = talloc_init("smbcli_dskattr"); fsinfo_parms.dskattr.level = RAW_QFS_DSKATTR; status = smb_raw_fsinfo(tree, mem_ctx, &fsinfo_parms); @@ -640,7 +640,7 @@ NTSTATUS cli_dskattr(struct cli_tree *tree, int *bsize, int *total, int *avail) /**************************************************************************** Create and open a temporary file. ****************************************************************************/ -int cli_ctemp(struct cli_tree *tree, const char *path, char **tmp_path) +int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path) { union smb_open open_parms; TALLOC_CTX *mem_ctx; diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 7dac7399a7..e2c267cc96 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -77,7 +77,7 @@ static BOOL interpret_long_filename(enum smb_search_level level, } /* callback function used for trans2 search */ -static BOOL cli_list_new_callback(void *private, union smb_search_data *file) +static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; file_info *tdl; @@ -101,7 +101,7 @@ static BOOL cli_list_new_callback(void *private, union smb_search_data *file) return True; } -int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, +int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, void (*fn)(file_info *, const char *, void *), void *caller_state) { @@ -118,7 +118,7 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, /* initialize state for search */ state.dirlist = NULL; - state.mem_ctx = talloc_init("cli_list_new"); + state.mem_ctx = talloc_init("smbcli_list_new"); state.dirlist_len = 0; state.total_received = 0; @@ -144,7 +144,7 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, status = smb_raw_search_first(tree, state.mem_ctx, &first_parms, - (void*)&state, cli_list_new_callback); + (void*)&state, smbcli_list_new_callback); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(state.mem_ctx); return -1; @@ -172,7 +172,7 @@ int cli_list_new(struct cli_tree *tree, const char *Mask, uint16_t attribute, state.mem_ctx, &next_parms, (void*)&state, - cli_list_new_callback); + smbcli_list_new_callback); if (!NT_STATUS_IS_OK(status)) { return -1; @@ -219,7 +219,7 @@ static BOOL interpret_short_filename(int level, } /* callback function used for smb_search */ -static BOOL cli_list_old_callback(void *private, union smb_search_data *file) +static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; file_info *tdl; @@ -243,7 +243,7 @@ static BOOL cli_list_old_callback(void *private, union smb_search_data *file) return True; } -int cli_list_old(struct cli_tree *tree, const char *Mask, uint16_t attribute, +int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, void (*fn)(file_info *, const char *, void *), void *caller_state) { @@ -259,7 +259,7 @@ int cli_list_old(struct cli_tree *tree, const char *Mask, uint16_t attribute, /* initialize state for search */ state.dirlist = NULL; - state.mem_ctx = talloc_init("cli_list_old"); + state.mem_ctx = talloc_init("smbcli_list_old"); state.dirlist_len = 0; state.total_received = 0; @@ -278,7 +278,7 @@ int cli_list_old(struct cli_tree *tree, const char *Mask, uint16_t attribute, status = smb_raw_search_first(tree, state.mem_ctx, &first_parms, (void*)&state, - cli_list_old_callback); + smbcli_list_old_callback); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(state.mem_ctx); @@ -299,7 +299,7 @@ int cli_list_old(struct cli_tree *tree, const char *Mask, uint16_t attribute, status = smb_raw_search_next(tree, state.mem_ctx, &next_parms, (void*)&state, - cli_list_old_callback); + smbcli_list_old_callback); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(state.mem_ctx); @@ -326,10 +326,10 @@ int cli_list_old(struct cli_tree *tree, const char *Mask, uint16_t attribute, This auto-switches between old and new style. ****************************************************************************/ -int cli_list(struct cli_tree *tree, const char *Mask,uint16_t attribute, +int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, void (*fn)(file_info *, const char *, void *), void *state) { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) - return cli_list_old(tree, Mask, attribute, fn, state); - return cli_list_new(tree, Mask, attribute, fn, state); + return smbcli_list_old(tree, Mask, attribute, fn, state); + return smbcli_list_new(tree, Mask, attribute, fn, state); } diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 6470f4c154..dde512159e 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -25,23 +25,23 @@ /**************************************************************************** start a message sequence ****************************************************************************/ -BOOL cli_message_start(struct cli_tree *tree, char *host, char *username, +BOOL smbcli_message_start(struct smbcli_tree *tree, char *host, char *username, int *grp) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsendstrt, 0, 0); - cli_req_append_string(req, username, STR_TERMINATE); - cli_req_append_string(req, host, STR_TERMINATE); - if (!cli_request_send(req) || - !cli_request_receive(req) || - cli_is_error(tree)) { - cli_request_destroy(req); + req = smbcli_request_setup(tree, SMBsendstrt, 0, 0); + smbcli_req_append_string(req, username, STR_TERMINATE); + smbcli_req_append_string(req, host, STR_TERMINATE); + if (!smbcli_request_send(req) || + !smbcli_request_receive(req) || + smbcli_is_error(tree)) { + smbcli_request_destroy(req); return False; } *grp = SVAL(req->in.vwv, VWV(0)); - cli_request_destroy(req); + smbcli_request_destroy(req); return True; } @@ -50,44 +50,44 @@ BOOL cli_message_start(struct cli_tree *tree, char *host, char *username, /**************************************************************************** send a message ****************************************************************************/ -BOOL cli_message_text(struct cli_tree *tree, char *msg, int len, int grp) +BOOL smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsendtxt, 1, 0); + req = smbcli_request_setup(tree, SMBsendtxt, 1, 0); SSVAL(req->out.vwv, VWV(0), grp); - cli_req_append_bytes(req, msg, len); + smbcli_req_append_bytes(req, msg, len); - if (!cli_request_send(req) || - !cli_request_receive(req) || - cli_is_error(tree)) { - cli_request_destroy(req); + if (!smbcli_request_send(req) || + !smbcli_request_receive(req) || + smbcli_is_error(tree)) { + smbcli_request_destroy(req); return False; } - cli_request_destroy(req); + smbcli_request_destroy(req); return True; } /**************************************************************************** end a message ****************************************************************************/ -BOOL cli_message_end(struct cli_tree *tree, int grp) +BOOL smbcli_message_end(struct smbcli_tree *tree, int grp) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsendend, 1, 0); + req = smbcli_request_setup(tree, SMBsendend, 1, 0); SSVAL(req->out.vwv, VWV(0), grp); - if (!cli_request_send(req) || - !cli_request_receive(req) || - cli_is_error(tree)) { - cli_request_destroy(req); + if (!smbcli_request_send(req) || + !smbcli_request_receive(req) || + smbcli_is_error(tree)) { + smbcli_request_destroy(req); return False; } - cli_request_destroy(req); + smbcli_request_destroy(req); return True; } diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index e9c8b80c4f..dd9f8d44cc 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -24,7 +24,7 @@ /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ -ssize_t cli_read(struct cli_tree *tree, int fnum, char *buf, off_t offset, +ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, char *buf, off_t offset, size_t size) { union smb_read parms; @@ -82,7 +82,7 @@ ssize_t cli_read(struct cli_tree *tree, int fnum, char *buf, off_t offset, 0x0004 use raw named pipe protocol 0x0008 start of message mode named pipe protocol ****************************************************************************/ -ssize_t cli_write(struct cli_tree *tree, +ssize_t smbcli_write(struct smbcli_tree *tree, int fnum, uint16_t write_mode, const char *buf, off_t offset, size_t size) { @@ -128,7 +128,7 @@ ssize_t cli_write(struct cli_tree *tree, /**************************************************************************** write to a file using a SMBwrite and not bypassing 0 byte writes ****************************************************************************/ -ssize_t cli_smbwrite(struct cli_tree *tree, +ssize_t smbcli_smbwrite(struct smbcli_tree *tree, int fnum, char *buf, off_t offset, size_t size1) { union smb_write parms; diff --git a/source4/libcli/clisecdesc.c b/source4/libcli/clisecdesc.c index 7f3ec0f6bf..4c8b49fc67 100644 --- a/source4/libcli/clisecdesc.c +++ b/source4/libcli/clisecdesc.c @@ -24,7 +24,7 @@ /**************************************************************************** query the security descriptor for a open file ****************************************************************************/ -SEC_DESC *cli_query_secdesc(struct cli_tree *tree, int fnum, +SEC_DESC *smbcli_query_secdesc(struct smbcli_tree *tree, int fnum, TALLOC_CTX *mem_ctx) { struct smb_nttrans parms; @@ -72,7 +72,7 @@ SEC_DESC *cli_query_secdesc(struct cli_tree *tree, int fnum, /**************************************************************************** set the security descriptor for a open file ****************************************************************************/ -BOOL cli_set_secdesc(struct cli_tree *tree, int fnum, SEC_DESC *sd) +BOOL smbcli_set_secdesc(struct smbcli_tree *tree, int fnum, SEC_DESC *sd) { struct smb_nttrans parms; char param[8]; @@ -82,7 +82,7 @@ BOOL cli_set_secdesc(struct cli_tree *tree, int fnum, SEC_DESC *sd) TALLOC_CTX *mem_ctx; NTSTATUS status; - mem_ctx = talloc_init("cli_set_secdesc"); + mem_ctx = talloc_init("smbcli_set_secdesc"); prs_init(&pd, 0, mem_ctx, MARSHALL); prs_give_memory(&pd, NULL, 0, True); diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index a83660685b..7a37df6e1f 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -23,7 +23,7 @@ /**************************************************************************** send a qpathinfo call ****************************************************************************/ -NTSTATUS cli_qpathinfo(struct cli_tree *tree, const char *fname, +NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16_t *mode) { @@ -31,7 +31,7 @@ NTSTATUS cli_qpathinfo(struct cli_tree *tree, const char *fname, TALLOC_CTX *mem_ctx; NTSTATUS status; - mem_ctx = talloc_init("cli_qpathinfo"); + mem_ctx = talloc_init("smbcli_qpathinfo"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.standard.level = RAW_FILEINFO_STANDARD; @@ -64,7 +64,7 @@ NTSTATUS cli_qpathinfo(struct cli_tree *tree, const char *fname, /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ -NTSTATUS cli_qpathinfo2(struct cli_tree *tree, const char *fname, +NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, size_t *size, uint16_t *mode, SMB_INO_T *ino) @@ -73,7 +73,7 @@ NTSTATUS cli_qpathinfo2(struct cli_tree *tree, const char *fname, TALLOC_CTX *mem_ctx; NTSTATUS status; - mem_ctx = talloc_init("cli_qfilename"); + mem_ctx = talloc_init("smbcli_qfilename"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; @@ -110,13 +110,13 @@ NTSTATUS cli_qpathinfo2(struct cli_tree *tree, const char *fname, /**************************************************************************** send a qfileinfo QUERY_FILE_NAME_INFO call ****************************************************************************/ -NTSTATUS cli_qfilename(struct cli_tree *tree, int fnum, const char **name) +NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; NTSTATUS status; - mem_ctx = talloc_init("cli_qfilename"); + mem_ctx = talloc_init("smbcli_qfilename"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.name_info.level = RAW_FILEINFO_NAME_INFO; @@ -140,7 +140,7 @@ NTSTATUS cli_qfilename(struct cli_tree *tree, int fnum, const char **name) /**************************************************************************** send a qfileinfo call ****************************************************************************/ -NTSTATUS cli_qfileinfo(struct cli_tree *tree, int fnum, +NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum, uint16_t *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) @@ -149,7 +149,7 @@ NTSTATUS cli_qfileinfo(struct cli_tree *tree, int fnum, TALLOC_CTX *mem_ctx; NTSTATUS status; - mem_ctx = talloc_init("cli_qfileinfo"); + mem_ctx = talloc_init("smbcli_qfileinfo"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; @@ -191,7 +191,7 @@ NTSTATUS cli_qfileinfo(struct cli_tree *tree, int fnum, /**************************************************************************** send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call ****************************************************************************/ -NTSTATUS cli_qpathinfo_alt_name(struct cli_tree *tree, const char *fname, +NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname, const char **alt_name) { union smb_fileinfo parms; @@ -201,14 +201,14 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_tree *tree, const char *fname, parms.alt_name_info.level = RAW_FILEINFO_ALT_NAME_INFO; parms.alt_name_info.in.fname = fname; - mem_ctx = talloc_init("cli_qpathinfo_alt_name"); + mem_ctx = talloc_init("smbcli_qpathinfo_alt_name"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; status = smb_raw_pathinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); *alt_name = NULL; - return cli_nt_error(tree); + return smbcli_nt_error(tree); } if (!parms.alt_name_info.out.fname.s) { diff --git a/source4/libcli/namequery_dc.c b/source4/libcli/namequery_dc.c index ffc64139e9..16e5282497 100644 --- a/source4/libcli/namequery_dc.c +++ b/source4/libcli/namequery_dc.c @@ -90,7 +90,7 @@ done: /* We have the netbios name and IP address of a domain controller. Ideally we should sent a SAMLOGON request to determine whether the DC is alive and kicking. If we can catch a dead DC before - performing a cli_connect() we can avoid a 30-second timeout. */ + performing a smbcli_connect() we can avoid a 30-second timeout. */ DEBUG(3, ("rpc_find_dc: Returning DC %s (%s) for domain %s\n", srv_name, inet_ntoa(dc_ip), domain)); diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index 29e44fc940..6ae21a08f4 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -23,12 +23,12 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ -BOOL cli_oplock_ack(struct cli_tree *tree, uint16_t fnum, uint16_t ack_level) +BOOL smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_level) { BOOL ret; - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBlockingX, 8, 0); + req = smbcli_request_setup(tree, SMBlockingX, 8, 0); SSVAL(req->out.vwv,VWV(0),0xFF); SSVAL(req->out.vwv,VWV(1),0); @@ -43,7 +43,7 @@ BOOL cli_oplock_ack(struct cli_tree *tree, uint16_t fnum, uint16_t ack_level) subsystem not to allocate an id for a reply */ req->one_way_request = 1; - ret = cli_request_send(req); + ret = smbcli_request_send(req); return ret; } @@ -52,8 +52,8 @@ BOOL cli_oplock_ack(struct cli_tree *tree, uint16_t fnum, uint16_t ack_level) /**************************************************************************** set the oplock handler for a connection ****************************************************************************/ -void cli_oplock_handler(struct cli_transport *transport, - BOOL (*handler)(struct cli_transport *, uint16_t, uint16_t, uint8_t, void *), +void smbcli_oplock_handler(struct smbcli_transport *transport, + BOOL (*handler)(struct smbcli_transport *, uint16_t, uint16_t, uint8_t, void *), void *private) { transport->oplock.handler = handler; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index d5373bc76f..b32d59f340 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -22,17 +22,17 @@ #include "includes.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ - req = cli_request_setup_session(session, cmd, wct, buflen); \ + req = smbcli_request_setup_session(session, cmd, wct, buflen); \ if (!req) return NULL; \ } while (0) /**************************************************************************** Initialize the session context ****************************************************************************/ -struct cli_session *cli_session_init(struct cli_transport *transport) +struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) { - struct cli_session *session; - TALLOC_CTX *mem_ctx = talloc_init("cli_session"); + struct smbcli_session *session; + TALLOC_CTX *mem_ctx = talloc_init("smbcli_session"); if (mem_ctx == NULL) { return NULL; } @@ -55,11 +55,11 @@ struct cli_session *cli_session_init(struct cli_transport *transport) /**************************************************************************** reduce reference_count and destroy is <= 0 ****************************************************************************/ -void cli_session_close(struct cli_session *session) +void smbcli_session_close(struct smbcli_session *session) { session->reference_count--; if (session->reference_count <= 0) { - cli_transport_close(session->transport); + smbcli_transport_close(session->transport); talloc_destroy(session->mem_ctx); } } @@ -67,9 +67,9 @@ void cli_session_close(struct cli_session *session) /**************************************************************************** Perform a session setup (async send) ****************************************************************************/ -struct cli_request *smb_raw_session_setup_send(struct cli_session *session, union smb_sesssetup *parms) +struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session, union smb_sesssetup *parms) { - struct cli_request *req; + struct smbcli_request *req; switch (parms->generic.level) { case RAW_SESSSETUP_GENERIC: @@ -85,11 +85,11 @@ struct cli_request *smb_raw_session_setup_send(struct cli_session *session, unio SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num); SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey); SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length); - cli_req_append_blob(req, &parms->old.in.password); - cli_req_append_string(req, parms->old.in.user, STR_TERMINATE); - cli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER); - cli_req_append_string(req, parms->old.in.os, STR_TERMINATE); - cli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE); + smbcli_req_append_blob(req, &parms->old.in.password); + smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE); + smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER); + smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE); + smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE); break; case RAW_SESSSETUP_NT1: @@ -104,12 +104,12 @@ struct cli_request *smb_raw_session_setup_send(struct cli_session *session, unio SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length); SIVAL(req->out.vwv, VWV(9), 0); /* reserved */ SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities); - cli_req_append_blob(req, &parms->nt1.in.password1); - cli_req_append_blob(req, &parms->nt1.in.password2); - cli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE); - cli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER); - cli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE); - cli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE); + smbcli_req_append_blob(req, &parms->nt1.in.password1); + smbcli_req_append_blob(req, &parms->nt1.in.password2); + smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE); + smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER); + smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE); + smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE); break; case RAW_SESSSETUP_SPNEGO: @@ -123,15 +123,15 @@ struct cli_request *smb_raw_session_setup_send(struct cli_session *session, unio SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length); SIVAL(req->out.vwv, VWV(8), 0); /* reserved */ SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities); - cli_req_append_blob(req, &parms->spnego.in.secblob); - cli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE); - cli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); - cli_req_append_string(req, parms->spnego.in.domain, STR_TERMINATE); + smbcli_req_append_blob(req, &parms->spnego.in.secblob); + smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE); + smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); + smbcli_req_append_string(req, parms->spnego.in.domain, STR_TERMINATE); break; } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -142,20 +142,20 @@ struct cli_request *smb_raw_session_setup_send(struct cli_session *session, unio /**************************************************************************** Perform a session setup (async recv) ****************************************************************************/ -NTSTATUS smb_raw_session_setup_recv(struct cli_request *req, +NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { uint16_t len; char *p; - if (!cli_request_receive(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req)) { + return smbcli_request_destroy(req); } if (!NT_STATUS_IS_OK(req->status) && !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return cli_request_destroy(req); + return smbcli_request_destroy(req); } switch (parms->generic.level) { @@ -164,35 +164,35 @@ NTSTATUS smb_raw_session_setup_recv(struct cli_request *req, return NT_STATUS_INVALID_LEVEL; case RAW_SESSSETUP_OLD: - CLI_CHECK_WCT(req, 3); + SMBCLI_CHECK_WCT(req, 3); ZERO_STRUCT(parms->old.out); parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID); parms->old.out.action = SVAL(req->in.vwv, VWV(2)); p = req->in.data; if (p) { - p += cli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE); - p += cli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE); - p += cli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE); } break; case RAW_SESSSETUP_NT1: - CLI_CHECK_WCT(req, 3); + SMBCLI_CHECK_WCT(req, 3); ZERO_STRUCT(parms->nt1.out); parms->nt1.out.vuid = SVAL(req->in.hdr, HDR_UID); parms->nt1.out.action = SVAL(req->in.vwv, VWV(2)); p = req->in.data; if (p) { - p += cli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE); - p += cli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE); if (p < (req->in.data + req->in.data_size)) { - p += cli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE); } } break; case RAW_SESSSETUP_SPNEGO: - CLI_CHECK_WCT(req, 4); + SMBCLI_CHECK_WCT(req, 4); ZERO_STRUCT(parms->spnego.out); parms->spnego.out.vuid = SVAL(req->in.hdr, HDR_UID); parms->spnego.out.action = SVAL(req->in.vwv, VWV(2)); @@ -202,16 +202,16 @@ NTSTATUS smb_raw_session_setup_recv(struct cli_request *req, break; } - parms->spnego.out.secblob = cli_req_pull_blob(req, mem_ctx, p, len); + parms->spnego.out.secblob = smbcli_req_pull_blob(req, mem_ctx, p, len); p += parms->spnego.out.secblob.length; - p += cli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE); - p += cli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); - p += cli_req_pull_string(req, mem_ctx, &parms->spnego.out.domain, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.domain, p, -1, STR_TERMINATE); break; } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /* @@ -239,7 +239,7 @@ static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) /* store the user session key for a transport */ -void cli_session_set_user_session_key(struct cli_session *session, +void smbcli_session_set_user_session_key(struct smbcli_session *session, const DATA_BLOB *session_key) { session->user_session_key = data_blob_talloc(session->mem_ctx, @@ -250,19 +250,19 @@ void cli_session_set_user_session_key(struct cli_session *session, /* setup signing for a NT1 style session setup */ -static void use_nt1_session_keys(struct cli_session *session, +static void use_nt1_session_keys(struct smbcli_session *session, const char *password, const DATA_BLOB *nt_response) { - struct cli_transport *transport = session->transport; + struct smbcli_transport *transport = session->transport; uint8_t nt_hash[16]; DATA_BLOB session_key = data_blob(NULL, 16); E_md4hash(password, nt_hash); SMBsesskeygen_ntv1(nt_hash, session_key.data); - cli_transport_simple_set_signing(transport, session_key, *nt_response); + smbcli_transport_simple_set_signing(transport, session_key, *nt_response); - cli_session_set_user_session_key(session, &session_key); + smbcli_session_set_user_session_key(session, &session_key); data_blob_free(&session_key); } @@ -270,7 +270,7 @@ static void use_nt1_session_keys(struct cli_session *session, Perform a session setup (sync interface) using generic interface and the old style sesssetup call ****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic_old(struct cli_session *session, +static NTSTATUS smb_raw_session_setup_generic_old(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { @@ -319,7 +319,7 @@ static NTSTATUS smb_raw_session_setup_generic_old(struct cli_session *session, Perform a session setup (sync interface) using generic interface and the NT1 style sesssetup call ****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, +static NTSTATUS smb_raw_session_setup_generic_nt1(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { @@ -375,7 +375,7 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session, Perform a session setup (sync interface) using generic interface and the SPNEGO style sesssetup call ****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session, +static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { @@ -396,7 +396,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session s2.spnego.in.lanman = "Samba"; s2.spnego.out.vuid = UID_FIELD_INVALID; - cli_temp_set_signing(session->transport); + smbcli_temp_set_signing(session->transport); status = gensec_client_start(&session->gensec); if (!NT_STATUS_IS_OK(status)) { @@ -455,7 +455,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session session_key_err = gensec_session_key(session->gensec, &session_key); } if (NT_STATUS_IS_OK(session_key_err)) { - cli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } session->vuid = s2.spnego.out.vuid; @@ -479,7 +479,7 @@ done: return session_key_err; } - cli_session_set_user_session_key(session, &session_key); + smbcli_session_set_user_session_key(session, &session_key); parms->generic.out.vuid = s2.spnego.out.vuid; parms->generic.out.os = s2.spnego.out.os; @@ -496,7 +496,7 @@ done: /**************************************************************************** Perform a session setup (sync interface) using generic interface ****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, +static NTSTATUS smb_raw_session_setup_generic(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { @@ -527,10 +527,10 @@ static NTSTATUS smb_raw_session_setup_generic(struct cli_session *session, this interface allows for RAW_SESSSETUP_GENERIC to auto-select session setup variant based on negotiated protocol options ****************************************************************************/ -NTSTATUS smb_raw_session_setup(struct cli_session *session, TALLOC_CTX *mem_ctx, +NTSTATUS smb_raw_session_setup(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { - struct cli_request *req; + struct smbcli_request *req; if (parms->generic.level == RAW_SESSSETUP_GENERIC) { NTSTATUS ret = smb_raw_session_setup_generic(session, mem_ctx, parms); @@ -555,17 +555,17 @@ NTSTATUS smb_raw_session_setup(struct cli_session *session, TALLOC_CTX *mem_ctx, /**************************************************************************** Send a uloggoff (async send) *****************************************************************************/ -struct cli_request *smb_raw_ulogoff_send(struct cli_session *session) +struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -575,24 +575,24 @@ struct cli_request *smb_raw_ulogoff_send(struct cli_session *session) /**************************************************************************** Send a uloggoff (sync interface) *****************************************************************************/ -NTSTATUS smb_raw_ulogoff(struct cli_session *session) +NTSTATUS smb_raw_ulogoff(struct smbcli_session *session) { - struct cli_request *req = smb_raw_ulogoff_send(session); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_ulogoff_send(session); + return smbcli_request_simple_recv(req); } /**************************************************************************** Send a SMBexit ****************************************************************************/ -NTSTATUS smb_raw_exit(struct cli_session *session) +NTSTATUS smb_raw_exit(struct smbcli_session *session) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup_session(session, SMBexit, 0, 0); + req = smbcli_request_setup_session(session, SMBexit, 0, 0); - if (cli_request_send(req)) { - cli_request_receive(req); + if (smbcli_request_send(req)) { + smbcli_request_receive(req); } - return cli_request_destroy(req); + return smbcli_request_destroy(req); } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index eb5d3c0342..78d37b9be1 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -23,14 +23,14 @@ /* - create a cli_socket context + create a smbcli_socket context */ -struct cli_socket *cli_sock_init(void) +struct smbcli_socket *smbcli_sock_init(void) { - struct cli_socket *sock; + struct smbcli_socket *sock; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("cli_socket"); + mem_ctx = talloc_init("smbcli_socket"); if (!mem_ctx) return NULL; sock = talloc_zero(mem_ctx, sizeof(*sock)); @@ -51,10 +51,10 @@ struct cli_socket *cli_sock_init(void) } /* - connect a cli_socket context to an IP/port pair + connect a smbcli_socket context to an IP/port pair if port is 0 then choose 445 then 139 */ -BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) +BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int port) { if (getenv("LIBSMB_PROG")) { sock->fd = sock_exec(getenv("LIBSMB_PROG")); @@ -62,8 +62,8 @@ BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) } if (port == 0) { - return cli_sock_connect(sock, ip, 445) || - cli_sock_connect(sock, ip, 139); + return smbcli_sock_connect(sock, ip, 445) || + smbcli_sock_connect(sock, ip, 139); } sock->dest_ip = *ip; @@ -85,7 +85,7 @@ BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) /**************************************************************************** mark the socket as dead ****************************************************************************/ -void cli_sock_dead(struct cli_socket *sock) +void smbcli_sock_dead(struct smbcli_socket *sock) { if (sock->fd != -1) { close(sock->fd); @@ -96,18 +96,18 @@ void cli_sock_dead(struct cli_socket *sock) /**************************************************************************** reduce socket reference count - if it becomes zero then close ****************************************************************************/ -void cli_sock_close(struct cli_socket *sock) +void smbcli_sock_close(struct smbcli_socket *sock) { sock->reference_count--; if (sock->reference_count <= 0) { - cli_sock_dead(sock); + smbcli_sock_dead(sock); } } /**************************************************************************** Set socket options on a open connection. ****************************************************************************/ -void cli_sock_set_options(struct cli_socket *sock, const char *options) +void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) { set_socket_options(sock->fd, options); } @@ -115,7 +115,7 @@ void cli_sock_set_options(struct cli_socket *sock, const char *options) /**************************************************************************** Write to socket. Return amount written. ****************************************************************************/ -ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) +ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t len) { if (sock->fd == -1) { errno = EIO; @@ -129,7 +129,7 @@ ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) /**************************************************************************** Read from socket. return amount read ****************************************************************************/ -ssize_t cli_sock_read(struct cli_socket *sock, char *data, size_t len) +ssize_t smbcli_sock_read(struct smbcli_socket *sock, char *data, size_t len) { if (sock->fd == -1) { errno = EIO; @@ -142,7 +142,7 @@ ssize_t cli_sock_read(struct cli_socket *sock, char *data, size_t len) /**************************************************************************** resolve a hostname and connect ****************************************************************************/ -BOOL cli_sock_connect_byname(struct cli_socket *sock, const char *host, int port) +BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, int port) { int name_type = 0x20; struct in_addr ip; @@ -155,7 +155,7 @@ BOOL cli_sock_connect_byname(struct cli_socket *sock, const char *host, int port return sock->fd != -1; } - mem_ctx = talloc_init("cli_sock_connect_byname"); + mem_ctx = talloc_init("smbcli_sock_connect_byname"); if (!mem_ctx) return False; name = talloc_strdup(mem_ctx, host); @@ -171,7 +171,7 @@ BOOL cli_sock_connect_byname(struct cli_socket *sock, const char *host, int port return False; } - ret = cli_sock_connect(sock, &ip, port); + ret = smbcli_sock_connect(sock, &ip, port); if (ret) { sock->hostname = talloc_steal(mem_ctx, sock->mem_ctx, name); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 3b3c10ed01..5290dd953d 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -24,24 +24,24 @@ /* an event has happened on the socket */ -static void cli_transport_event_handler(struct event_context *ev, struct fd_event *fde, +static void smbcli_transport_event_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags) { - struct cli_transport *transport = fde->private; + struct smbcli_transport *transport = fde->private; - cli_transport_process(transport); + smbcli_transport_process(transport); } /* create a transport structure based on an established socket */ -struct cli_transport *cli_transport_init(struct cli_socket *sock) +struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) { TALLOC_CTX *mem_ctx; - struct cli_transport *transport; + struct smbcli_transport *transport; struct fd_event fde; - mem_ctx = talloc_init("cli_transport"); + mem_ctx = talloc_init("smbcli_transport"); if (!mem_ctx) return NULL; transport = talloc_zero(mem_ctx, sizeof(*transport)); @@ -59,7 +59,7 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) transport->options.use_spnego = lp_use_spnego(); transport->negotiate.max_xmit = ~0; - cli_init_signing(transport); + smbcli_init_signing(transport); transport->socket->reference_count++; @@ -67,7 +67,7 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) fde.fd = sock->fd; fde.flags = EVENT_FD_READ; - fde.handler = cli_transport_event_handler; + fde.handler = smbcli_transport_event_handler; fde.private = transport; fde.ref_count = 1; @@ -80,11 +80,11 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) decrease reference count on a transport, and destroy if it becomes zero */ -void cli_transport_close(struct cli_transport *transport) +void smbcli_transport_close(struct smbcli_transport *transport) { transport->reference_count--; if (transport->reference_count <= 0) { - cli_sock_close(transport->socket); + smbcli_sock_close(transport->socket); event_remove_fd(transport->event.ctx, transport->event.fde); event_remove_timed(transport->event.ctx, transport->event.te); event_context_destroy(transport->event.ctx); @@ -95,14 +95,14 @@ void cli_transport_close(struct cli_transport *transport) /* mark the transport as dead */ -void cli_transport_dead(struct cli_transport *transport) +void smbcli_transport_dead(struct smbcli_transport *transport) { - cli_sock_dead(transport->socket); + smbcli_sock_dead(transport->socket); /* all pending sends become errors */ while (transport->pending_send) { - struct cli_request *req = transport->pending_send; - req->state = CLI_REQUEST_ERROR; + struct smbcli_request *req = transport->pending_send; + req->state = SMBCLI_REQUEST_ERROR; req->status = NT_STATUS_NET_WRITE_FAULT; DLIST_REMOVE(transport->pending_send, req); if (req->async.fn) { @@ -112,8 +112,8 @@ void cli_transport_dead(struct cli_transport *transport) /* as do all pending receives */ while (transport->pending_recv) { - struct cli_request *req = transport->pending_recv; - req->state = CLI_REQUEST_ERROR; + struct smbcli_request *req = transport->pending_recv; + req->state = SMBCLI_REQUEST_ERROR; req->status = NT_STATUS_NET_WRITE_FAULT; DLIST_REMOVE(transport->pending_recv, req); if (req->async.fn) { @@ -126,7 +126,7 @@ void cli_transport_dead(struct cli_transport *transport) /* enable select for write on a transport */ -static void cli_transport_write_enable(struct cli_transport *transport) +static void smbcli_transport_write_enable(struct smbcli_transport *transport) { transport->event.fde->flags |= EVENT_FD_WRITE; } @@ -134,7 +134,7 @@ static void cli_transport_write_enable(struct cli_transport *transport) /* disable select for write on a transport */ -static void cli_transport_write_disable(struct cli_transport *transport) +static void smbcli_transport_write_disable(struct smbcli_transport *transport) { transport->event.fde->flags &= ~EVENT_FD_WRITE; } @@ -142,13 +142,13 @@ static void cli_transport_write_disable(struct cli_transport *transport) /**************************************************************************** send a session request (if appropriate) ****************************************************************************/ -BOOL cli_transport_connect(struct cli_transport *transport, +BOOL smbcli_transport_connect(struct smbcli_transport *transport, struct nmb_name *calling, struct nmb_name *called) { char *p; int len = NBT_HDR_SIZE; - struct cli_request *req; + struct smbcli_request *req; if (called) { transport->called = *called; @@ -160,7 +160,7 @@ BOOL cli_transport_connect(struct cli_transport *transport, } /* allocate output buffer */ - req = cli_request_setup_nonsmb(transport, NBT_HDR_SIZE + 2*nbt_mangled_name_len()); + req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + 2*nbt_mangled_name_len()); /* put in the destination name */ p = req->out.buffer + NBT_HDR_SIZE; @@ -175,20 +175,20 @@ BOOL cli_transport_connect(struct cli_transport *transport, _smb_setlen(req->out.buffer,len-4); SCVAL(req->out.buffer,0,0x81); - if (!cli_request_send(req) || - !cli_request_receive(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req) || + !smbcli_request_receive(req)) { + smbcli_request_destroy(req); return False; } if (CVAL(req->in.buffer,0) != 0x82) { transport->error.etype = ETYPE_NBT; transport->error.e.nbt_error = CVAL(req->in.buffer,4); - cli_request_destroy(req); + smbcli_request_destroy(req); return False; } - cli_request_destroy(req); + smbcli_request_destroy(req); return True; } @@ -196,10 +196,10 @@ BOOL cli_transport_connect(struct cli_transport *transport, /**************************************************************************** get next mid in sequence ****************************************************************************/ -uint16_t cli_transport_next_mid(struct cli_transport *transport) +uint16_t smbcli_transport_next_mid(struct smbcli_transport *transport) { uint16_t mid; - struct cli_request *req; + struct smbcli_request *req; mid = transport->next_mid; @@ -225,7 +225,7 @@ again: static void idle_handler(struct event_context *ev, struct timed_event *te, time_t t) { - struct cli_transport *transport = te->private; + struct smbcli_transport *transport = te->private; te->next_event = t + transport->idle.period; transport->idle.func(transport, transport->idle.private); } @@ -234,8 +234,8 @@ static void idle_handler(struct event_context *ev, setup the idle handler for a transport the period is in seconds */ -void cli_transport_idle_handler(struct cli_transport *transport, - void (*idle_func)(struct cli_transport *, void *), +void smbcli_transport_idle_handler(struct smbcli_transport *transport, + void (*idle_func)(struct smbcli_transport *, void *), uint_t period, void *private) { @@ -257,27 +257,27 @@ void cli_transport_idle_handler(struct cli_transport *transport, /* process some pending sends */ -static void cli_transport_process_send(struct cli_transport *transport) +static void smbcli_transport_process_send(struct smbcli_transport *transport) { while (transport->pending_send) { - struct cli_request *req = transport->pending_send; + struct smbcli_request *req = transport->pending_send; ssize_t ret; - ret = cli_sock_write(transport->socket, req->out.buffer, req->out.size); + ret = smbcli_sock_write(transport->socket, req->out.buffer, req->out.size); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) { return; } - cli_transport_dead(transport); + smbcli_transport_dead(transport); } req->out.buffer += ret; req->out.size -= ret; if (req->out.size == 0) { DLIST_REMOVE(transport->pending_send, req); if (req->one_way_request) { - req->state = CLI_REQUEST_DONE; - cli_request_destroy(req); + req->state = SMBCLI_REQUEST_DONE; + smbcli_request_destroy(req); } else { - req->state = CLI_REQUEST_RECV; + req->state = SMBCLI_REQUEST_RECV; DLIST_ADD(transport->pending_recv, req); } } @@ -285,19 +285,19 @@ static void cli_transport_process_send(struct cli_transport *transport) /* we're out of requests to send, so don't wait for write events any more */ - cli_transport_write_disable(transport); + smbcli_transport_write_disable(transport); } /* we have a full request in our receive buffer - match it to a pending request and process */ -static void cli_transport_finish_recv(struct cli_transport *transport) +static void smbcli_transport_finish_recv(struct smbcli_transport *transport) { uint8_t *buffer, *hdr, *vwv; int len; uint16_t wct, mid = 0; - struct cli_request *req; + struct smbcli_request *req; buffer = transport->recv_buffer.buffer; len = transport->recv_buffer.req_size; @@ -355,14 +355,14 @@ static void cli_transport_finish_recv(struct cli_transport *transport) /* handle non-SMB replies */ if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) { - req->state = CLI_REQUEST_ERROR; + req->state = SMBCLI_REQUEST_ERROR; goto error; } if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { DEBUG(2,("bad reply size for mid %d\n", mid)); req->status = NT_STATUS_UNSUCCESSFUL; - req->state = CLI_REQUEST_ERROR; + req->state = SMBCLI_REQUEST_ERROR; goto error; } @@ -394,10 +394,10 @@ static void cli_transport_finish_recv(struct cli_transport *transport) req->status = transport->error.e.nt_status; } - if (!cli_request_check_sign_mac(req)) { + if (!smbcli_request_check_sign_mac(req)) { transport->error.etype = ETYPE_SOCKET; transport->error.e.socket_error = SOCKET_READ_BAD_SIG; - req->state = CLI_REQUEST_ERROR; + req->state = SMBCLI_REQUEST_ERROR; goto error; }; @@ -406,7 +406,7 @@ async: notify that the reply has been received. This might destroy the request so it must happen last */ DLIST_REMOVE(transport->pending_recv, req); - req->state = CLI_REQUEST_DONE; + req->state = SMBCLI_REQUEST_DONE; if (req->async.fn) { req->async.fn(req); } @@ -415,21 +415,21 @@ async: error: if (req) { DLIST_REMOVE(transport->pending_recv, req); - req->state = CLI_REQUEST_ERROR; + req->state = SMBCLI_REQUEST_ERROR; } } /* process some pending receives */ -static void cli_transport_process_recv(struct cli_transport *transport) +static void smbcli_transport_process_recv(struct smbcli_transport *transport) { /* a incoming packet goes through 2 stages - first we read the 4 byte header, which tells us how much more is coming. Then we read the rest */ if (transport->recv_buffer.received < NBT_HDR_SIZE) { ssize_t ret; - ret = cli_sock_read(transport->socket, + ret = smbcli_sock_read(transport->socket, transport->recv_buffer.header + transport->recv_buffer.received, NBT_HDR_SIZE - transport->recv_buffer.received); @@ -437,7 +437,7 @@ static void cli_transport_process_recv(struct cli_transport *transport) if (errno == EINTR || errno == EAGAIN) { return; } - cli_transport_dead(transport); + smbcli_transport_dead(transport); return; } @@ -449,7 +449,7 @@ static void cli_transport_process_recv(struct cli_transport *transport) transport->recv_buffer.buffer = talloc(transport->mem_ctx, NBT_HDR_SIZE+transport->recv_buffer.req_size); if (transport->recv_buffer.buffer == NULL) { - cli_transport_dead(transport); + smbcli_transport_dead(transport); return; } memcpy(transport->recv_buffer.buffer, transport->recv_buffer.header, NBT_HDR_SIZE); @@ -458,7 +458,7 @@ static void cli_transport_process_recv(struct cli_transport *transport) if (transport->recv_buffer.received < transport->recv_buffer.req_size) { ssize_t ret; - ret = cli_sock_read(transport->socket, + ret = smbcli_sock_read(transport->socket, transport->recv_buffer.buffer + transport->recv_buffer.received, transport->recv_buffer.req_size - @@ -467,7 +467,7 @@ static void cli_transport_process_recv(struct cli_transport *transport) if (errno == EINTR || errno == EAGAIN) { return; } - cli_transport_dead(transport); + smbcli_transport_dead(transport); return; } transport->recv_buffer.received += ret; @@ -475,7 +475,7 @@ static void cli_transport_process_recv(struct cli_transport *transport) if (transport->recv_buffer.received != 0 && transport->recv_buffer.received == transport->recv_buffer.req_size) { - cli_transport_finish_recv(transport); + smbcli_transport_finish_recv(transport); } } @@ -483,10 +483,10 @@ static void cli_transport_process_recv(struct cli_transport *transport) process some read/write requests that are pending return False if the socket is dead */ -BOOL cli_transport_process(struct cli_transport *transport) +BOOL smbcli_transport_process(struct smbcli_transport *transport) { - cli_transport_process_send(transport); - cli_transport_process_recv(transport); + smbcli_transport_process_send(transport); + smbcli_transport_process_recv(transport); if (transport->socket->fd == -1) { return False; } @@ -498,19 +498,19 @@ BOOL cli_transport_process(struct cli_transport *transport) /* put a request into the send queue */ -void cli_transport_send(struct cli_request *req) +void smbcli_transport_send(struct smbcli_request *req) { /* check if the transport is dead */ if (req->transport->socket->fd == -1) { - req->state = CLI_REQUEST_ERROR; + req->state = SMBCLI_REQUEST_ERROR; req->status = NT_STATUS_NET_WRITE_FAULT; return; } /* put it on the outgoing socket queue */ - req->state = CLI_REQUEST_SEND; - DLIST_ADD_END(req->transport->pending_send, req, struct cli_request *); + req->state = SMBCLI_REQUEST_SEND; + DLIST_ADD_END(req->transport->pending_send, req, struct smbcli_request *); /* make sure we look for write events */ - cli_transport_write_enable(req->transport); + smbcli_transport_write_enable(req->transport); } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index a580ded010..b9d572fd56 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -22,7 +22,7 @@ #include "includes.h" #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ - req = cli_request_setup(tree, cmd, wct, buflen); \ + req = smbcli_request_setup(tree, cmd, wct, buflen); \ if (!req) return NULL; \ } while (0) @@ -30,10 +30,10 @@ /**************************************************************************** Initialize the tree context ****************************************************************************/ -struct cli_tree *cli_tree_init(struct cli_session *session) +struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) { - struct cli_tree *tree; - TALLOC_CTX *mem_ctx = talloc_init("cli_tree"); + struct smbcli_tree *tree; + TALLOC_CTX *mem_ctx = talloc_init("smbcli_tree"); if (mem_ctx == NULL) { return NULL; } @@ -54,12 +54,12 @@ struct cli_tree *cli_tree_init(struct cli_session *session) /**************************************************************************** reduce reference count on a tree and destroy if <= 0 ****************************************************************************/ -void cli_tree_close(struct cli_tree *tree) +void smbcli_tree_close(struct smbcli_tree *tree) { if (!tree) return; tree->reference_count--; if (tree->reference_count <= 0) { - cli_session_close(tree->session); + smbcli_session_close(tree->session); talloc_destroy(tree->mem_ctx); } } @@ -68,16 +68,16 @@ void cli_tree_close(struct cli_tree *tree) /**************************************************************************** Send a tconX (async send) ****************************************************************************/ -struct cli_request *smb_tree_connect_send(struct cli_tree *tree, union smb_tcon *parms) +struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, union smb_tcon *parms) { - struct cli_request *req; + struct smbcli_request *req; switch (parms->tcon.level) { case RAW_TCON_TCON: SETUP_REQUEST_TREE(SMBtcon, 0, 0); - cli_req_append_ascii4(req, parms->tcon.in.service, STR_ASCII); - cli_req_append_ascii4(req, parms->tcon.in.password,STR_ASCII); - cli_req_append_ascii4(req, parms->tcon.in.dev, STR_ASCII); + smbcli_req_append_ascii4(req, parms->tcon.in.service, STR_ASCII); + smbcli_req_append_ascii4(req, parms->tcon.in.password,STR_ASCII); + smbcli_req_append_ascii4(req, parms->tcon.in.dev, STR_ASCII); break; case RAW_TCON_TCONX: @@ -86,14 +86,14 @@ struct cli_request *smb_tree_connect_send(struct cli_tree *tree, union smb_tcon SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->tconx.in.flags); SSVAL(req->out.vwv, VWV(3), parms->tconx.in.password.length); - cli_req_append_blob(req, &parms->tconx.in.password); - cli_req_append_string(req, parms->tconx.in.path, STR_TERMINATE | STR_UPPER); - cli_req_append_string(req, parms->tconx.in.device, STR_TERMINATE | STR_ASCII); + smbcli_req_append_blob(req, &parms->tconx.in.password); + smbcli_req_append_string(req, parms->tconx.in.path, STR_TERMINATE | STR_UPPER); + smbcli_req_append_string(req, parms->tconx.in.device, STR_TERMINATE | STR_ASCII); break; } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -103,18 +103,18 @@ struct cli_request *smb_tree_connect_send(struct cli_tree *tree, union smb_tcon /**************************************************************************** Send a tconX (async recv) ****************************************************************************/ -NTSTATUS smb_tree_connect_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_tcon *parms) +NTSTATUS smb_tree_connect_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_tcon *parms) { char *p; - if (!cli_request_receive(req) || - cli_request_is_error(req)) { + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { goto failed; } switch (parms->tcon.level) { case RAW_TCON_TCON: - CLI_CHECK_WCT(req, 2); + SMBCLI_CHECK_WCT(req, 2); parms->tcon.out.max_xmit = SVAL(req->in.vwv, VWV(0)); parms->tcon.out.cnum = SVAL(req->in.vwv, VWV(1)); break; @@ -130,23 +130,23 @@ NTSTATUS smb_tree_connect_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, uni p = req->in.data; if (!p) break; - p += cli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type, + p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type, p, -1, STR_ASCII | STR_TERMINATE); - p += cli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type, + p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type, p, -1, STR_TERMINATE); break; } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** Send a tconX (sync interface) ****************************************************************************/ -NTSTATUS smb_tree_connect(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_tcon *parms) +NTSTATUS smb_tree_connect(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_tcon *parms) { - struct cli_request *req = smb_tree_connect_send(tree, parms); + struct smbcli_request *req = smb_tree_connect_send(tree, parms); return smb_tree_connect_recv(req, mem_ctx, parms); } @@ -154,35 +154,35 @@ NTSTATUS smb_tree_connect(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_ /**************************************************************************** Send a tree disconnect. ****************************************************************************/ -NTSTATUS smb_tree_disconnect(struct cli_tree *tree) +NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) { - struct cli_request *req; + struct smbcli_request *req; if (!tree) return NT_STATUS_OK; - req = cli_request_setup(tree, SMBtdis, 0, 0); + req = smbcli_request_setup(tree, SMBtdis, 0, 0); - if (cli_request_send(req)) { - cli_request_receive(req); + if (smbcli_request_send(req)) { + smbcli_request_receive(req); } - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /* - a convenient function to establish a cli_tree from scratch, using reasonable default + a convenient function to establish a smbcli_tree from scratch, using reasonable default parameters */ -NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, +NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, const char *my_name, const char *dest_host, int port, const char *service, const char *service_type, const char *user, const char *domain, const char *password) { - struct cli_socket *sock; - struct cli_transport *transport; - struct cli_session *session; - struct cli_tree *tree; + struct smbcli_socket *sock; + struct smbcli_transport *transport; + struct smbcli_session *session; + struct smbcli_tree *tree; NTSTATUS status; struct nmb_name calling; struct nmb_name called; @@ -193,20 +193,20 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, *ret_tree = NULL; - sock = cli_sock_init(); + sock = smbcli_sock_init(); if (!sock) { return NT_STATUS_NO_MEMORY; } /* open a TCP socket to the server */ - if (!cli_sock_connect_byname(sock, dest_host, port)) { + if (!smbcli_sock_connect_byname(sock, dest_host, port)) { DEBUG(2,("Failed to establish socket connection - %s\n", strerror(errno))); return NT_STATUS_UNSUCCESSFUL; } - transport = cli_transport_init(sock); + transport = smbcli_transport_init(sock); if (!transport) { - cli_sock_close(sock); + smbcli_sock_close(sock); return NT_STATUS_NO_MEMORY; } @@ -214,8 +214,8 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called, dest_host, 0x20); - if (!cli_transport_connect(transport, &calling, &called)) { - cli_transport_close(transport); + if (!smbcli_transport_connect(transport, &calling, &called)) { + smbcli_transport_close(transport); return NT_STATUS_UNSUCCESSFUL; } @@ -223,13 +223,13 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, /* negotiate protocol options with the server */ status = smb_raw_negotiate(transport); if (!NT_STATUS_IS_OK(status)) { - cli_transport_close(transport); + smbcli_transport_close(transport); return status; } - session = cli_session_init(transport); + session = smbcli_session_init(transport); if (!session) { - cli_transport_close(transport); + smbcli_transport_close(transport); return NT_STATUS_NO_MEMORY; } @@ -255,16 +255,16 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, status = smb_raw_session_setup(session, mem_ctx, &setup); if (!NT_STATUS_IS_OK(status)) { - cli_session_close(session); + smbcli_session_close(session); talloc_destroy(mem_ctx); return status; } session->vuid = setup.generic.out.vuid; - tree = cli_tree_init(session); + tree = smbcli_tree_init(session); if (!tree) { - cli_session_close(session); + smbcli_session_close(session); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -288,7 +288,7 @@ NTSTATUS cli_tree_full_connection(struct cli_tree **ret_tree, SAFE_FREE(in_path); if (!NT_STATUS_IS_OK(status)) { - cli_tree_close(tree); + smbcli_tree_close(tree); talloc_destroy(mem_ctx); return status; } diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index ca93591597..77374ae8b9 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -23,7 +23,7 @@ /**************************************************************************** fetch file ACL (async send) ****************************************************************************/ -struct cli_request *smb_raw_query_secdesc_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, struct smb_query_secdesc *query) { struct smb_nttrans nt; @@ -52,7 +52,7 @@ struct cli_request *smb_raw_query_secdesc_send(struct cli_tree *tree, /**************************************************************************** fetch file ACL (async recv) ****************************************************************************/ -NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, +NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_query_secdesc *query) { @@ -91,11 +91,11 @@ NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req, /**************************************************************************** fetch file ACL (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_query_secdesc(struct cli_tree *tree, +NTSTATUS smb_raw_query_secdesc(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_query_secdesc *query) { - struct cli_request *req = smb_raw_query_secdesc_send(tree, query); + struct smbcli_request *req = smb_raw_query_secdesc_send(tree, query); return smb_raw_query_secdesc_recv(req, mem_ctx, query); } @@ -104,13 +104,13 @@ NTSTATUS smb_raw_query_secdesc(struct cli_tree *tree, /**************************************************************************** set file ACL (async send) ****************************************************************************/ -struct cli_request *smb_raw_set_secdesc_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, struct smb_set_secdesc *set) { struct smb_nttrans nt; uint8_t params[8]; struct ndr_push *ndr; - struct cli_request *req; + struct smbcli_request *req; NTSTATUS status; nt.in.max_setup = 0; diff --git a/source4/libcli/raw/rawdate.c b/source4/libcli/raw/rawdate.c index 3b731d653b..bfb7465bd5 100644 --- a/source4/libcli/raw/rawdate.c +++ b/source4/libcli/raw/rawdate.c @@ -26,7 +26,7 @@ put a dos date into a buffer (time/date format) This takes GMT time and puts local time for zone_offset in the buffer ********************************************************************/ -void raw_push_dos_date(struct cli_transport *transport, +void raw_push_dos_date(struct smbcli_transport *transport, uint8_t *buf, int offset, time_t unixdate) { push_dos_date(buf, offset, unixdate, transport->negotiate.server_zone); @@ -36,7 +36,7 @@ void raw_push_dos_date(struct cli_transport *transport, put a dos date into a buffer (date/time format) This takes GMT time and puts local time in the buffer ********************************************************************/ -void raw_push_dos_date2(struct cli_transport *transport, +void raw_push_dos_date2(struct smbcli_transport *transport, char *buf, int offset, time_t unixdate) { push_dos_date2(buf, offset, unixdate, transport->negotiate.server_zone); @@ -46,7 +46,7 @@ void raw_push_dos_date2(struct cli_transport *transport, put a dos 32 bit "unix like" date into a buffer. This routine takes GMT and converts it to LOCAL time in zone_offset before putting it ********************************************************************/ -void raw_push_dos_date3(struct cli_transport *transport, +void raw_push_dos_date3(struct smbcli_transport *transport, char *buf, int offset, time_t unixdate) { push_dos_date3(buf, offset, unixdate, transport->negotiate.server_zone); @@ -55,7 +55,7 @@ void raw_push_dos_date3(struct cli_transport *transport, /******************************************************************* convert a dos date ********************************************************************/ -time_t raw_pull_dos_date(struct cli_transport *transport, +time_t raw_pull_dos_date(struct smbcli_transport *transport, const uint8_t *date_ptr) { return pull_dos_date(date_ptr, transport->negotiate.server_zone); @@ -64,7 +64,7 @@ time_t raw_pull_dos_date(struct cli_transport *transport, /******************************************************************* like raw_pull_dos_date() but the words are reversed ********************************************************************/ -time_t raw_pull_dos_date2(struct cli_transport *transport, +time_t raw_pull_dos_date2(struct smbcli_transport *transport, const uint8_t *date_ptr) { return pull_dos_date2(date_ptr, transport->negotiate.server_zone); @@ -74,7 +74,7 @@ time_t raw_pull_dos_date2(struct cli_transport *transport, create a unix GMT date from a dos date in 32 bit "unix like" format these arrive in server zone, with corresponding DST ******************************************************************/ -time_t raw_pull_dos_date3(struct cli_transport *transport, +time_t raw_pull_dos_date3(struct smbcli_transport *transport, const uint8_t *date_ptr) { return pull_dos_date3(date_ptr, transport->negotiate.server_zone); diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 0d00ffcca6..8bd8e5d8af 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -23,7 +23,7 @@ #include "includes.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ - req = cli_request_setup(tree, cmd, wct, buflen); \ + req = smbcli_request_setup(tree, cmd, wct, buflen); \ if (!req) return NULL; \ } while (0) @@ -31,17 +31,17 @@ /**************************************************************************** Rename a file - async interface ****************************************************************************/ -struct cli_request *smb_raw_rename_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree, union smb_rename *parms) { - struct cli_request *req; + struct smbcli_request *req; switch (parms->generic.level) { case RAW_RENAME_RENAME: SETUP_REQUEST(SMBmv, 1, 0); SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib); - cli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE); - cli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE); break; case RAW_RENAME_NTRENAME: @@ -49,13 +49,13 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib); SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags); SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size); - cli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); - cli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); break; } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -65,29 +65,29 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, /**************************************************************************** Rename a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_rename(struct cli_tree *tree, +NTSTATUS smb_raw_rename(struct smbcli_tree *tree, union smb_rename *parms) { - struct cli_request *req = smb_raw_rename_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_rename_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** Delete a file - async interface ****************************************************************************/ -struct cli_request *smb_raw_unlink_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree, struct smb_unlink *parms) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST(SMBunlink, 1, 0); SSVAL(req->out.vwv, VWV(0), parms->in.attrib); - cli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } return req; @@ -96,24 +96,24 @@ struct cli_request *smb_raw_unlink_send(struct cli_tree *tree, /* delete a file - sync interface */ -NTSTATUS smb_raw_unlink(struct cli_tree *tree, +NTSTATUS smb_raw_unlink(struct smbcli_tree *tree, struct smb_unlink *parms) { - struct cli_request *req = smb_raw_unlink_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_unlink_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** create a directory using TRANSACT2_MKDIR - async interface ****************************************************************************/ -static struct cli_request *smb_raw_t2mkdir_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, union smb_mkdir *parms) { struct smb_trans2 t2; uint16_t setup = TRANSACT2_MKDIR; TALLOC_CTX *mem_ctx; - struct cli_request *req; + struct smbcli_request *req; uint16_t data_total; mem_ctx = talloc_init("t2mkdir"); @@ -132,7 +132,7 @@ static struct cli_request *smb_raw_t2mkdir_send(struct cli_tree *tree, SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */ - cli_blob_append_string(tree->session, mem_ctx, + smbcli_blob_append_string(tree->session, mem_ctx, &t2.in.params, parms->t2mkdir.in.path, 0); ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); @@ -147,10 +147,10 @@ static struct cli_request *smb_raw_t2mkdir_send(struct cli_tree *tree, /**************************************************************************** Create a directory - async interface ****************************************************************************/ -struct cli_request *smb_raw_mkdir_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_mkdir_send(struct smbcli_tree *tree, union smb_mkdir *parms) { - struct cli_request *req; + struct smbcli_request *req; if (parms->generic.level == RAW_MKDIR_T2MKDIR) { return smb_raw_t2mkdir_send(tree, parms); @@ -162,9 +162,9 @@ struct cli_request *smb_raw_mkdir_send(struct cli_tree *tree, SETUP_REQUEST(SMBmkdir, 0, 0); - cli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE); - if (!cli_request_send(req)) { + if (!smbcli_request_send(req)) { return NULL; } @@ -174,27 +174,27 @@ struct cli_request *smb_raw_mkdir_send(struct cli_tree *tree, /**************************************************************************** Create a directory - sync interface ****************************************************************************/ -NTSTATUS smb_raw_mkdir(struct cli_tree *tree, +NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree, union smb_mkdir *parms) { - struct cli_request *req = smb_raw_mkdir_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_mkdir_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** Remove a directory - async interface ****************************************************************************/ -struct cli_request *smb_raw_rmdir_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_rmdir_send(struct smbcli_tree *tree, struct smb_rmdir *parms) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST(SMBrmdir, 0, 0); - cli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -204,24 +204,24 @@ struct cli_request *smb_raw_rmdir_send(struct cli_tree *tree, /**************************************************************************** Remove a directory - sync interface ****************************************************************************/ -NTSTATUS smb_raw_rmdir(struct cli_tree *tree, +NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree, struct smb_rmdir *parms) { - struct cli_request *req = smb_raw_rmdir_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_rmdir_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** Open a file using TRANSACT2_OPEN - async send ****************************************************************************/ -static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, union smb_open *parms) { struct smb_trans2 t2; uint16_t setup = TRANSACT2_OPEN; TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open"); - struct cli_request *req; + struct smbcli_request *req; uint16_t list_size; list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas); @@ -248,7 +248,7 @@ static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, SIVAL(t2.in.params.data, VWV(11), 0); SSVAL(t2.in.params.data, VWV(13), 0); - cli_blob_append_string(tree->session, mem_ctx, + smbcli_blob_append_string(tree->session, mem_ctx, &t2.in.params, parms->t2open.in.fname, STR_TERMINATE); @@ -265,9 +265,9 @@ static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, /**************************************************************************** Open a file using TRANSACT2_OPEN - async recv ****************************************************************************/ -static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) +static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) { - struct cli_transport *transport = req?req->transport:NULL; + struct smbcli_transport *transport = req?req->transport:NULL; struct smb_trans2 t2; NTSTATUS status; @@ -294,10 +294,10 @@ static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx /**************************************************************************** Open a file - async send ****************************************************************************/ -struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *parms) +struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms) { int len; - struct cli_request *req = NULL; + struct smbcli_request *req = NULL; switch (parms->open.level) { case RAW_OPEN_T2OPEN: @@ -307,7 +307,7 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SETUP_REQUEST(SMBopen, 2, 0); SSVAL(req->out.vwv, VWV(0), parms->open.in.flags); SSVAL(req->out.vwv, VWV(1), parms->open.in.search_attrs); - cli_req_append_ascii4(req, parms->open.in.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->open.in.fname, STR_TERMINATE); break; case RAW_OPEN_OPENX: @@ -324,7 +324,7 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SIVAL(req->out.vwv, VWV(9), parms->openx.in.size); SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout); SIVAL(req->out.vwv, VWV(13),0); /* reserved */ - cli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE); + smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE); break; case RAW_OPEN_MKNEW: @@ -332,7 +332,7 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->mknew.in.write_time); - cli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE); break; case RAW_OPEN_CREATE: @@ -340,7 +340,7 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->create.in.write_time); - cli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE); break; case RAW_OPEN_CTEMP: @@ -348,7 +348,7 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->ctemp.in.write_time); - cli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE); break; case RAW_OPEN_SPLOPEN: @@ -373,13 +373,13 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation); SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags); - cli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len); + smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len); SSVAL(req->out.vwv, 5, len); break; } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -389,10 +389,10 @@ struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *par /**************************************************************************** Open a file - async recv ****************************************************************************/ -NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) +NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { goto failed; } @@ -401,7 +401,7 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s return smb_raw_t2open_recv(req, mem_ctx, parms); case RAW_OPEN_OPEN: - CLI_CHECK_WCT(req, 7); + SMBCLI_CHECK_WCT(req, 7); parms->open.out.fnum = SVAL(req->in.vwv, VWV(0)); parms->open.out.attrib = SVAL(req->in.vwv, VWV(1)); parms->open.out.write_time = raw_pull_dos_date3(req->transport, @@ -411,7 +411,7 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s break; case RAW_OPEN_OPENX: - CLI_CHECK_MIN_WCT(req, 15); + SMBCLI_CHECK_MIN_WCT(req, 15); parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2)); parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3)); parms->openx.out.write_time = raw_pull_dos_date3(req->transport, @@ -432,35 +432,35 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s break; case RAW_OPEN_MKNEW: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_CREATE: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->create.out.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_CTEMP: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0)); - cli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); + smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); break; case RAW_OPEN_SPLOPEN: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_NTCREATEX: - CLI_CHECK_MIN_WCT(req, 34); + SMBCLI_CHECK_MIN_WCT(req, 34); parms->ntcreatex.out.oplock_level = CVAL(req->in.vwv, 4); parms->ntcreatex.out.fnum = SVAL(req->in.vwv, 5); parms->ntcreatex.out.create_action = IVAL(req->in.vwv, 7); - parms->ntcreatex.out.create_time = cli_pull_nttime(req->in.vwv, 11); - parms->ntcreatex.out.access_time = cli_pull_nttime(req->in.vwv, 19); - parms->ntcreatex.out.write_time = cli_pull_nttime(req->in.vwv, 27); - parms->ntcreatex.out.change_time = cli_pull_nttime(req->in.vwv, 35); + parms->ntcreatex.out.create_time = smbcli_pull_nttime(req->in.vwv, 11); + parms->ntcreatex.out.access_time = smbcli_pull_nttime(req->in.vwv, 19); + parms->ntcreatex.out.write_time = smbcli_pull_nttime(req->in.vwv, 27); + parms->ntcreatex.out.change_time = smbcli_pull_nttime(req->in.vwv, 35); parms->ntcreatex.out.attrib = IVAL(req->in.vwv, 43); parms->ntcreatex.out.alloc_size = BVAL(req->in.vwv, 47); parms->ntcreatex.out.size = BVAL(req->in.vwv, 55); @@ -471,16 +471,16 @@ NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union s } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** Open a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_open(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms) +NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms) { - struct cli_request *req = smb_raw_open_send(tree, parms); + struct smbcli_request *req = smb_raw_open_send(tree, parms); return smb_raw_open_recv(req, mem_ctx, parms); } @@ -488,9 +488,9 @@ NTSTATUS smb_raw_open(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open /**************************************************************************** Close a file - async send ****************************************************************************/ -struct cli_request *smb_raw_close_send(struct cli_tree *tree, union smb_close *parms) +struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms) { - struct cli_request *req; + struct smbcli_request *req; switch (parms->generic.level) { case RAW_CLOSE_GENERIC: @@ -512,8 +512,8 @@ struct cli_request *smb_raw_close_send(struct cli_tree *tree, union smb_close *p if (!req) return NULL; - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -524,19 +524,19 @@ struct cli_request *smb_raw_close_send(struct cli_tree *tree, union smb_close *p /**************************************************************************** Close a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_close(struct cli_tree *tree, union smb_close *parms) +NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms) { - struct cli_request *req = smb_raw_close_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_close_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** Locking calls - async interface ****************************************************************************/ -struct cli_request *smb_raw_lock_send(struct cli_tree *tree, union smb_lock *parms) +struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_lock *parms) { - struct cli_request *req; + struct smbcli_request *req; switch (parms->generic.level) { case RAW_LOCK_GENERIC: @@ -590,8 +590,8 @@ struct cli_request *smb_raw_lock_send(struct cli_tree *tree, union smb_lock *par } } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -601,26 +601,26 @@ struct cli_request *smb_raw_lock_send(struct cli_tree *tree, union smb_lock *par /**************************************************************************** Locking calls - sync interface ****************************************************************************/ -NTSTATUS smb_raw_lock(struct cli_tree *tree, union smb_lock *parms) +NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms) { - struct cli_request *req = smb_raw_lock_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_lock_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** Check for existence of a dir - async send ****************************************************************************/ -struct cli_request *smb_raw_chkpath_send(struct cli_tree *tree, struct smb_chkpath *parms) +struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb_chkpath *parms) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST(SMBchkpth, 0, 0); - cli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -630,10 +630,10 @@ struct cli_request *smb_raw_chkpath_send(struct cli_tree *tree, struct smb_chkpa /**************************************************************************** Check for existence of a dir - sync interface ****************************************************************************/ -NTSTATUS smb_raw_chkpath(struct cli_tree *tree, struct smb_chkpath *parms) +NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, struct smb_chkpath *parms) { - struct cli_request *req = smb_raw_chkpath_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_chkpath_send(tree, parms); + return smbcli_request_simple_recv(req); } @@ -643,15 +643,15 @@ NTSTATUS smb_raw_chkpath(struct cli_tree *tree, struct smb_chkpath *parms) flush a file - async send a flush to fnum 0xFFFF will flush all files ****************************************************************************/ -struct cli_request *smb_raw_flush_send(struct cli_tree *tree, struct smb_flush *parms) +struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_flush *parms) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST(SMBflush, 1, 0); SSVAL(req->out.vwv, VWV(0), parms->in.fnum); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -662,20 +662,20 @@ struct cli_request *smb_raw_flush_send(struct cli_tree *tree, struct smb_flush * /**************************************************************************** flush a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_flush(struct cli_tree *tree, struct smb_flush *parms) +NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms) { - struct cli_request *req = smb_raw_flush_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_flush_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** seek a file - async send ****************************************************************************/ -struct cli_request *smb_raw_seek_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree, struct smb_seek *parms) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST(SMBlseek, 4, 0); @@ -683,8 +683,8 @@ struct cli_request *smb_raw_seek_send(struct cli_tree *tree, SSVAL(req->out.vwv, VWV(1), parms->in.mode); SIVALS(req->out.vwv, VWV(2), parms->in.offset); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } return req; @@ -693,27 +693,27 @@ struct cli_request *smb_raw_seek_send(struct cli_tree *tree, /**************************************************************************** seek a file - async receive ****************************************************************************/ -NTSTATUS smb_raw_seek_recv(struct cli_request *req, +NTSTATUS smb_raw_seek_recv(struct smbcli_request *req, struct smb_seek *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } - CLI_CHECK_WCT(req, 2); + SMBCLI_CHECK_WCT(req, 2); parms->out.offset = IVAL(req->in.vwv, VWV(0)); failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /* seek a file - sync interface */ -NTSTATUS smb_raw_seek(struct cli_tree *tree, +NTSTATUS smb_raw_seek(struct smbcli_tree *tree, struct smb_seek *parms) { - struct cli_request *req = smb_raw_seek_send(tree, parms); + struct smbcli_request *req = smb_raw_seek_send(tree, parms); return smb_raw_seek_recv(req, parms); } diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index f27a0d7281..8dc220b0b4 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -36,7 +36,7 @@ /**************************************************************************** Handle qfileinfo/qpathinfo trans2 backend. ****************************************************************************/ -static NTSTATUS smb_raw_info_backend(struct cli_session *session, +static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms, DATA_BLOB *blob) @@ -95,10 +95,10 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, if (blob->length != 36) { FINFO_CHECK_SIZE(40); } - parms->basic_info.out.create_time = cli_pull_nttime(blob->data, 0); - parms->basic_info.out.access_time = cli_pull_nttime(blob->data, 8); - parms->basic_info.out.write_time = cli_pull_nttime(blob->data, 16); - parms->basic_info.out.change_time = cli_pull_nttime(blob->data, 24); + parms->basic_info.out.create_time = smbcli_pull_nttime(blob->data, 0); + parms->basic_info.out.access_time = smbcli_pull_nttime(blob->data, 8); + parms->basic_info.out.write_time = smbcli_pull_nttime(blob->data, 16); + parms->basic_info.out.change_time = smbcli_pull_nttime(blob->data, 24); parms->basic_info.out.attrib = IVAL(blob->data, 32); return NT_STATUS_OK; @@ -121,17 +121,17 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, case RAW_FILEINFO_NAME_INFO: case RAW_FILEINFO_NAME_INFORMATION: FINFO_CHECK_MIN_SIZE(4); - cli_blob_pull_string(session, mem_ctx, blob, + smbcli_blob_pull_string(session, mem_ctx, blob, &parms->name_info.out.fname, 0, 4, STR_UNICODE); return NT_STATUS_OK; case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: FINFO_CHECK_MIN_SIZE(72); - parms->all_info.out.create_time = cli_pull_nttime(blob->data, 0); - parms->all_info.out.access_time = cli_pull_nttime(blob->data, 8); - parms->all_info.out.write_time = cli_pull_nttime(blob->data, 16); - parms->all_info.out.change_time = cli_pull_nttime(blob->data, 24); + parms->all_info.out.create_time = smbcli_pull_nttime(blob->data, 0); + parms->all_info.out.access_time = smbcli_pull_nttime(blob->data, 8); + parms->all_info.out.write_time = smbcli_pull_nttime(blob->data, 16); + parms->all_info.out.change_time = smbcli_pull_nttime(blob->data, 24); parms->all_info.out.attrib = IVAL(blob->data, 32); parms->all_info.out.alloc_size = BVAL(blob->data, 40); parms->all_info.out.size = BVAL(blob->data, 48); @@ -139,14 +139,14 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, parms->all_info.out.delete_pending = CVAL(blob->data, 60); parms->all_info.out.directory = CVAL(blob->data, 61); parms->all_info.out.ea_size = IVAL(blob->data, 64); - cli_blob_pull_string(session, mem_ctx, blob, + smbcli_blob_pull_string(session, mem_ctx, blob, &parms->all_info.out.fname, 68, 72, STR_UNICODE); return NT_STATUS_OK; case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: FINFO_CHECK_MIN_SIZE(4); - cli_blob_pull_string(session, mem_ctx, blob, + smbcli_blob_pull_string(session, mem_ctx, blob, &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE); return NT_STATUS_OK; @@ -166,7 +166,7 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, } parms->stream_info.out.streams[n].size = BVAL(blob->data, ofs + 8); parms->stream_info.out.streams[n].alloc_size = BVAL(blob->data, ofs + 16); - cli_blob_pull_string(session, mem_ctx, blob, + smbcli_blob_pull_string(session, mem_ctx, blob, &parms->stream_info.out.streams[n].stream_name, ofs+4, ofs+24, STR_UNICODE); parms->stream_info.out.num_streams++; @@ -218,9 +218,9 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, FINFO_CHECK_SIZE(100); parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0); parms->unix_basic_info.out.num_bytes = BVAL(blob->data, 8); - parms->unix_basic_info.out.status_change_time = cli_pull_nttime(blob->data, 16); - parms->unix_basic_info.out.access_time = cli_pull_nttime(blob->data, 24); - parms->unix_basic_info.out.change_time = cli_pull_nttime(blob->data, 32); + parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16); + parms->unix_basic_info.out.access_time = smbcli_pull_nttime(blob->data, 24); + parms->unix_basic_info.out.change_time = smbcli_pull_nttime(blob->data, 32); parms->unix_basic_info.out.uid = BVAL(blob->data, 40); parms->unix_basic_info.out.gid = BVAL(blob->data, 48); parms->unix_basic_info.out.file_type = IVAL(blob->data, 52); @@ -232,16 +232,16 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, return NT_STATUS_OK; case RAW_FILEINFO_UNIX_LINK: - cli_blob_pull_string(session, mem_ctx, blob, + smbcli_blob_pull_string(session, mem_ctx, blob, &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE); return NT_STATUS_OK; case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: FINFO_CHECK_SIZE(56); - parms->network_open_information.out.create_time = cli_pull_nttime(blob->data, 0); - parms->network_open_information.out.access_time = cli_pull_nttime(blob->data, 8); - parms->network_open_information.out.write_time = cli_pull_nttime(blob->data, 16); - parms->network_open_information.out.change_time = cli_pull_nttime(blob->data, 24); + parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data, 0); + parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data, 8); + parms->network_open_information.out.write_time = smbcli_pull_nttime(blob->data, 16); + parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24); parms->network_open_information.out.alloc_size = BVAL(blob->data, 32); parms->network_open_information.out.size = BVAL(blob->data, 40); parms->network_open_information.out.attrib = IVAL(blob->data, 48); @@ -260,12 +260,12 @@ static NTSTATUS smb_raw_info_backend(struct cli_session *session, /**************************************************************************** Very raw query file info - returns param/data blobs - (async send) ****************************************************************************/ -static struct cli_request *smb_raw_fileinfo_blob_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree, uint16_t fnum, uint16_t info_level) { struct smb_trans2 tp; uint16_t setup = TRANSACT2_QFILEINFO; - struct cli_request *req; + struct smbcli_request *req; TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo"); tp.in.max_setup = 0; @@ -297,7 +297,7 @@ static struct cli_request *smb_raw_fileinfo_blob_send(struct cli_tree *tree, /**************************************************************************** Very raw query file info - returns param/data blobs - (async recv) ****************************************************************************/ -static NTSTATUS smb_raw_fileinfo_blob_recv(struct cli_request *req, +static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) { @@ -312,13 +312,13 @@ static NTSTATUS smb_raw_fileinfo_blob_recv(struct cli_request *req, /**************************************************************************** Very raw query path info - returns param/data blobs (async send) ****************************************************************************/ -static struct cli_request *smb_raw_pathinfo_blob_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree, const char *fname, uint16_t info_level) { struct smb_trans2 tp; uint16_t setup = TRANSACT2_QPATHINFO; - struct cli_request *req; + struct smbcli_request *req; TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo"); tp.in.max_setup = 0; @@ -338,7 +338,7 @@ static struct cli_request *smb_raw_pathinfo_blob_send(struct cli_tree *tree, SSVAL(tp.in.params.data, 0, info_level); SIVAL(tp.in.params.data, 2, 0); - cli_blob_append_string(tree->session, mem_ctx, &tp.in.params, + smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, fname, STR_TERMINATE); req = smb_raw_trans2_send(tree, &tp); @@ -351,18 +351,18 @@ static struct cli_request *smb_raw_pathinfo_blob_send(struct cli_tree *tree, /**************************************************************************** send a SMBgetatr (async send) ****************************************************************************/ -static struct cli_request *smb_raw_getattr_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBgetatr, 0, 0); + req = smbcli_request_setup(tree, SMBgetatr, 0, 0); if (!req) return NULL; - cli_req_append_ascii4(req, parms->getattr.in.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->getattr.in.fname, STR_TERMINATE); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -372,39 +372,39 @@ static struct cli_request *smb_raw_getattr_send(struct cli_tree *tree, /**************************************************************************** send a SMBgetatr (async recv) ****************************************************************************/ -static NTSTATUS smb_raw_getattr_recv(struct cli_request *req, +static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req, union smb_fileinfo *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } - CLI_CHECK_WCT(req, 10); + SMBCLI_CHECK_WCT(req, 10); parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0)); parms->getattr.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(1)); parms->getattr.out.size = IVAL(req->in.vwv, VWV(3)); failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** Handle SMBgetattrE (async send) ****************************************************************************/ -static struct cli_request *smb_raw_getattrE_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBgetattrE, 1, 0); + req = smbcli_request_setup(tree, SMBgetattrE, 1, 0); if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), parms->getattre.in.fnum); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -414,15 +414,15 @@ static struct cli_request *smb_raw_getattrE_send(struct cli_tree *tree, /**************************************************************************** Handle SMBgetattrE (async send) ****************************************************************************/ -static NTSTATUS smb_raw_getattrE_recv(struct cli_request *req, +static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req, union smb_fileinfo *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } - CLI_CHECK_WCT(req, 11); + SMBCLI_CHECK_WCT(req, 11); parms->getattre.out.create_time = raw_pull_dos_date2(req->transport, req->in.vwv + VWV(0)); parms->getattre.out.access_time = raw_pull_dos_date2(req->transport, @@ -434,14 +434,14 @@ static NTSTATUS smb_raw_getattrE_recv(struct cli_request *req, parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10)); failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** Query file info (async send) ****************************************************************************/ -struct cli_request *smb_raw_fileinfo_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { /* pass off the non-trans2 level to specialised functions */ @@ -460,13 +460,13 @@ struct cli_request *smb_raw_fileinfo_send(struct cli_tree *tree, /**************************************************************************** Query file info (async recv) ****************************************************************************/ -NTSTATUS smb_raw_fileinfo_recv(struct cli_request *req, +NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { DATA_BLOB blob; NTSTATUS status; - struct cli_session *session = req?req->session:NULL; + struct smbcli_session *session = req?req->session:NULL; if (parms->generic.level == RAW_FILEINFO_GETATTRE) { return smb_raw_getattrE_recv(req, parms); @@ -486,18 +486,18 @@ NTSTATUS smb_raw_fileinfo_recv(struct cli_request *req, /**************************************************************************** Query file info (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_fileinfo(struct cli_tree *tree, +NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { - struct cli_request *req = smb_raw_fileinfo_send(tree, parms); + struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms); return smb_raw_fileinfo_recv(req, mem_ctx, parms); } /**************************************************************************** Query path info (async send) ****************************************************************************/ -struct cli_request *smb_raw_pathinfo_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { if (parms->generic.level == RAW_FILEINFO_GETATTR) { @@ -514,7 +514,7 @@ struct cli_request *smb_raw_pathinfo_send(struct cli_tree *tree, /**************************************************************************** Query path info (async recv) ****************************************************************************/ -NTSTATUS smb_raw_pathinfo_recv(struct cli_request *req, +NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { @@ -525,10 +525,10 @@ NTSTATUS smb_raw_pathinfo_recv(struct cli_request *req, /**************************************************************************** Query path info (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_pathinfo(struct cli_tree *tree, +NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { - struct cli_request *req = smb_raw_pathinfo_send(tree, parms); + struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms); return smb_raw_pathinfo_recv(req, mem_ctx, parms); } diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index faf375deb0..aefe8e3085 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -25,15 +25,15 @@ /**************************************************************************** Query FS Info - SMBdskattr call (async send) ****************************************************************************/ -static struct cli_request *smb_raw_dskattr_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_dskattr_send(struct smbcli_tree *tree, union smb_fsinfo *fsinfo) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBdskattr, 0, 0); + req = smbcli_request_setup(tree, SMBdskattr, 0, 0); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -43,29 +43,29 @@ static struct cli_request *smb_raw_dskattr_send(struct cli_tree *tree, /**************************************************************************** Query FS Info - SMBdskattr call (async recv) ****************************************************************************/ -static NTSTATUS smb_raw_dskattr_recv(struct cli_request *req, +static NTSTATUS smb_raw_dskattr_recv(struct smbcli_request *req, union smb_fsinfo *fsinfo) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { goto failed; } - CLI_CHECK_WCT(req, 5); + SMBCLI_CHECK_WCT(req, 5); fsinfo->dskattr.out.units_total = SVAL(req->in.vwv, VWV(0)); fsinfo->dskattr.out.blocks_per_unit = SVAL(req->in.vwv, VWV(1)); fsinfo->dskattr.out.block_size = SVAL(req->in.vwv, VWV(2)); fsinfo->dskattr.out.units_free = SVAL(req->in.vwv, VWV(3)); failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** RAW_QFS_ trans2 interface via blobs (async send) ****************************************************************************/ -static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_qfsinfo_send(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, uint16_t info_level) { @@ -94,7 +94,7 @@ static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree, /**************************************************************************** RAW_QFS_ trans2 interface via blobs (async recv) ****************************************************************************/ -static NTSTATUS smb_raw_qfsinfo_blob_recv(struct cli_request *req, +static NTSTATUS smb_raw_qfsinfo_blob_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) { @@ -129,7 +129,7 @@ static NTSTATUS smb_raw_qfsinfo_blob_recv(struct cli_request *req, /**************************************************************************** Query FSInfo raw interface (async send) ****************************************************************************/ -struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_fsinfo_send(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo) { @@ -153,14 +153,14 @@ struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree, /**************************************************************************** Query FSInfo raw interface (async recv) ****************************************************************************/ -NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req, +NTSTATUS smb_raw_fsinfo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo) { DATA_BLOB blob; NTSTATUS status; int i; - struct cli_session *session = req?req->session:NULL; + struct smbcli_session *session = req?req->session:NULL; if (fsinfo->generic.level == RAW_QFS_DSKATTR) { return smb_raw_dskattr_recv(req, fsinfo); @@ -190,7 +190,7 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req, case RAW_QFS_VOLUME: QFS_CHECK_MIN_SIZE(5); fsinfo->volume.out.serial_number = IVAL(blob.data, 0); - cli_blob_pull_string(session, mem_ctx, &blob, + smbcli_blob_pull_string(session, mem_ctx, &blob, &fsinfo->volume.out.volume_name, 4, 5, STR_LEN8BIT | STR_NOALIGN); break; @@ -198,9 +198,9 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req, case RAW_QFS_VOLUME_INFO: case RAW_QFS_VOLUME_INFORMATION: QFS_CHECK_MIN_SIZE(18); - fsinfo->volume_info.out.create_time = cli_pull_nttime(blob.data, 0); + fsinfo->volume_info.out.create_time = smbcli_pull_nttime(blob.data, 0); fsinfo->volume_info.out.serial_number = IVAL(blob.data, 8); - cli_blob_pull_string(session, mem_ctx, &blob, + smbcli_blob_pull_string(session, mem_ctx, &blob, &fsinfo->volume_info.out.volume_name, 12, 18, STR_UNICODE); break; @@ -226,7 +226,7 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req, QFS_CHECK_MIN_SIZE(12); fsinfo->attribute_info.out.fs_attr = IVAL(blob.data, 0); fsinfo->attribute_info.out.max_file_component_length = IVAL(blob.data, 4); - cli_blob_pull_string(session, mem_ctx, &blob, + smbcli_blob_pull_string(session, mem_ctx, &blob, &fsinfo->attribute_info.out.fs_type, 8, 12, STR_UNICODE); break; @@ -274,10 +274,10 @@ failed: /**************************************************************************** Query FSInfo raw interface (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_fsinfo(struct cli_tree *tree, +NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo) { - struct cli_request *req = smb_raw_fsinfo_send(tree, mem_ctx, fsinfo); + struct smbcli_request *req = smb_raw_fsinfo_send(tree, mem_ctx, fsinfo); return smb_raw_fsinfo_recv(req, mem_ctx, fsinfo); } diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 271758c65c..798300451b 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -22,25 +22,25 @@ #include "includes.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ - req = cli_request_setup(tree, cmd, wct, buflen); \ + req = smbcli_request_setup(tree, cmd, wct, buflen); \ if (!req) return NULL; \ } while (0) /* send a raw smb ioctl - async send */ -static struct cli_request *smb_raw_smbioctl_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_smbioctl_send(struct smbcli_tree *tree, union smb_ioctl *parms) { - struct cli_request *req; + struct smbcli_request *req; SETUP_REQUEST(SMBioctl, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->ioctl.in.fnum); SIVAL(req->out.vwv, VWV(1), parms->ioctl.in.request); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -50,17 +50,17 @@ static struct cli_request *smb_raw_smbioctl_send(struct cli_tree *tree, /* send a raw smb ioctl - async recv */ -static NTSTATUS smb_raw_smbioctl_recv(struct cli_request *req, +static NTSTATUS smb_raw_smbioctl_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } - parms->ioctl.out.blob = cli_req_pull_blob(req, mem_ctx, req->in.data, -1); - return cli_request_destroy(req); + parms->ioctl.out.blob = smbcli_req_pull_blob(req, mem_ctx, req->in.data, -1); + return smbcli_request_destroy(req); } @@ -68,7 +68,7 @@ static NTSTATUS smb_raw_smbioctl_recv(struct cli_request *req, /**************************************************************************** NT ioctl (async send) ****************************************************************************/ -static struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, union smb_ioctl *parms) { struct smb_nttrans nt; @@ -93,26 +93,26 @@ static struct cli_request *smb_raw_ntioctl_send(struct cli_tree *tree, /**************************************************************************** NT ioctl (async recv) ****************************************************************************/ -static NTSTATUS smb_raw_ntioctl_recv(struct cli_request *req, +static NTSTATUS smb_raw_ntioctl_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } - parms->ntioctl.out.blob = cli_req_pull_blob(req, mem_ctx, req->in.data, -1); - return cli_request_destroy(req); + parms->ntioctl.out.blob = smbcli_req_pull_blob(req, mem_ctx, req->in.data, -1); + return smbcli_request_destroy(req); } /* send a raw ioctl - async send */ -struct cli_request *smb_raw_ioctl_send(struct cli_tree *tree, union smb_ioctl *parms) +struct smbcli_request *smb_raw_ioctl_send(struct smbcli_tree *tree, union smb_ioctl *parms) { - struct cli_request *req = NULL; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_IOCTL_IOCTL: @@ -130,7 +130,7 @@ struct cli_request *smb_raw_ioctl_send(struct cli_tree *tree, union smb_ioctl *p /* recv a raw ioctl - async recv */ -NTSTATUS smb_raw_ioctl_recv(struct cli_request *req, +NTSTATUS smb_raw_ioctl_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { switch (parms->generic.level) { @@ -146,10 +146,10 @@ NTSTATUS smb_raw_ioctl_recv(struct cli_request *req, /* send a raw ioctl - sync interface */ -NTSTATUS smb_raw_ioctl(struct cli_tree *tree, +NTSTATUS smb_raw_ioctl(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { - struct cli_request *req; + struct smbcli_request *req; req = smb_raw_ioctl_send(tree, parms); return smb_raw_ioctl_recv(req, mem_ctx, parms); } diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 6bf35fb26d..9b00aa6121 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -41,13 +41,13 @@ static const struct { /**************************************************************************** Send a negprot command. ****************************************************************************/ -struct cli_request *smb_negprot_send(struct cli_transport *transport, int maxprotocol) +struct smbcli_request *smb_negprot_send(struct smbcli_transport *transport, int maxprotocol) { - struct cli_request *req; + struct smbcli_request *req; int i; uint16_t flags2 = 0; - req = cli_request_setup_transport(transport, SMBnegprot, 0, 0); + req = smbcli_request_setup_transport(transport, SMBnegprot, 0, 0); if (!req) { return NULL; } @@ -66,12 +66,12 @@ struct cli_request *smb_negprot_send(struct cli_transport *transport, int maxpro /* setup the protocol strings */ for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) { - cli_req_append_bytes(req, "\2", 1); - cli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII); + smbcli_req_append_bytes(req, "\2", 1); + smbcli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII); } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -81,9 +81,9 @@ struct cli_request *smb_negprot_send(struct cli_transport *transport, int maxpro /**************************************************************************** Send a negprot command. ****************************************************************************/ -NTSTATUS smb_raw_negotiate(struct cli_transport *transport) +NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) { - struct cli_request *req; + struct smbcli_request *req; int protocol; req = smb_negprot_send(transport, PROTOCOL_NT1); @@ -91,18 +91,18 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) return NT_STATUS_UNSUCCESSFUL; } - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } - CLI_CHECK_MIN_WCT(req, 1); + SMBCLI_CHECK_MIN_WCT(req, 1); protocol = SVALS(req->in.vwv, VWV(0)); if (protocol >= ARRAY_SIZE(prots) || protocol < 0) { req->status = NT_STATUS_UNSUCCESSFUL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } transport->negotiate.protocol = prots[protocol].prot; @@ -111,7 +111,7 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) NTTIME ntt; /* NT protocol */ - CLI_CHECK_WCT(req, 17); + SMBCLI_CHECK_WCT(req, 17); transport->negotiate.sec_mode = CVAL(req->in.vwv,VWV(1)); transport->negotiate.max_mux = SVAL(req->in.vwv,VWV(1)+1); transport->negotiate.max_xmit = IVAL(req->in.vwv,VWV(3)+1); @@ -119,7 +119,7 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); /* this time arrives in real GMT */ - ntt = cli_pull_nttime(req->in.vwv, VWV(11)+1); + ntt = smbcli_pull_nttime(req->in.vwv, VWV(11)+1); transport->negotiate.server_time = nt_time_to_unix(ntt); transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60; transport->negotiate.key_len = CVAL(req->in.vwv,VWV(16)+1); @@ -128,14 +128,14 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) if (req->in.data_size < 16) { goto failed; } - transport->negotiate.server_guid = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, 16); - transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data + 16, req->in.data_size - 16); + transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data, 16); + transport->negotiate.secblob = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data + 16, req->in.data_size - 16); } else { if (req->in.data_size < (transport->negotiate.key_len)) { goto failed; } - transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, req->in.data, transport->negotiate.key_len); - cli_req_pull_string(req, transport->mem_ctx, &transport->negotiate.server_domain, + transport->negotiate.secblob = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data, transport->negotiate.key_len); + smbcli_req_pull_string(req, transport->mem_ctx, &transport->negotiate.server_domain, req->in.data+transport->negotiate.key_len, req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN); /* here comes the server name */ @@ -146,7 +146,7 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) transport->negotiate.writebraw_supported = True; } } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) { - CLI_CHECK_WCT(req, 13); + SMBCLI_CHECK_WCT(req, 13); transport->negotiate.sec_mode = SVAL(req->in.vwv,VWV(1)); transport->negotiate.max_xmit = SVAL(req->in.vwv,VWV(2)); transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(6)); @@ -161,7 +161,7 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) { transport->negotiate.writebraw_supported = 1; } - transport->negotiate.secblob = cli_req_pull_blob(req, transport->mem_ctx, + transport->negotiate.secblob = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data, req->in.data_size); } else { /* the old core protocol */ @@ -172,10 +172,10 @@ NTSTATUS smb_raw_negotiate(struct cli_transport *transport) } /* a way to force ascii SMB */ - if (getenv("CLI_FORCE_ASCII")) { + if (getenv("SMBCLI_FORCE_ASCII")) { transport->negotiate.capabilities &= ~CAP_UNICODE; } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index a9215fee10..47553e735e 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -23,7 +23,7 @@ /**************************************************************************** change notify (async send) ****************************************************************************/ -struct cli_request *smb_raw_changenotify_send(struct cli_tree *tree, struct smb_notify *parms) +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struct smb_notify *parms) { struct smb_nttrans nt; uint16_t setup[4]; @@ -46,13 +46,13 @@ struct cli_request *smb_raw_changenotify_send(struct cli_tree *tree, struct smb_ /**************************************************************************** change notify (async recv) ****************************************************************************/ -NTSTATUS smb_raw_changenotify_recv(struct cli_request *req, +NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_notify *parms) { struct smb_nttrans nt; NTSTATUS status; uint32_t ofs, i; - struct cli_session *session = req?req->session:NULL; + struct smbcli_session *session = req?req->session:NULL; status = smb_raw_nttrans_recv(req, mem_ctx, &nt); if (!NT_STATUS_IS_OK(status)) { @@ -80,7 +80,7 @@ NTSTATUS smb_raw_changenotify_recv(struct cli_request *req, for (i=ofs=0; iout.num_changes; i++) { parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); - cli_blob_pull_string(session, mem_ctx, &nt.out.params, + smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, &parms->out.changes[i].name, ofs+8, ofs+12, STR_UNICODE); ofs += IVAL(nt.out.params.data, ofs); @@ -95,11 +95,11 @@ NTSTATUS smb_raw_changenotify_recv(struct cli_request *req, used to cancel a pending change notify request note that this request does not expect a response! ****************************************************************************/ -NTSTATUS smb_raw_ntcancel(struct cli_request *oldreq) +NTSTATUS smb_raw_ntcancel(struct smbcli_request *oldreq) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup_transport(oldreq->transport, SMBntcancel, 0, 0); + req = smbcli_request_setup_transport(oldreq->transport, SMBntcancel, 0, 0); SSVAL(req->out.hdr, HDR_MID, SVAL(oldreq->out.hdr, HDR_MID)); SSVAL(req->out.hdr, HDR_PID, SVAL(oldreq->out.hdr, HDR_PID)); @@ -111,7 +111,7 @@ NTSTATUS smb_raw_ntcancel(struct cli_request *oldreq) req->sign_single_increment = 1; req->one_way_request = 1; - cli_request_send(req); + smbcli_request_send(req); return NT_STATUS_OK; } diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 3e3b29d252..f0a9a063ed 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -22,7 +22,7 @@ #include "includes.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ - req = cli_request_setup(tree, cmd, wct, buflen); \ + req = smbcli_request_setup(tree, cmd, wct, buflen); \ if (!req) return NULL; \ } while (0) @@ -30,10 +30,10 @@ /**************************************************************************** low level read operation (async send) ****************************************************************************/ -struct cli_request *smb_raw_read_send(struct cli_tree *tree, union smb_read *parms) +struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms) { BOOL bigoffset = False; - struct cli_request *req; + struct smbcli_request *req; switch (parms->generic.level) { case RAW_READ_GENERIC: @@ -90,8 +90,8 @@ struct cli_request *smb_raw_read_send(struct cli_tree *tree, union smb_read *par break; } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -107,10 +107,10 @@ struct cli_request *smb_raw_read_send(struct cli_tree *tree, union smb_read *par /**************************************************************************** low level read operation (async recv) ****************************************************************************/ -NTSTATUS smb_raw_read_recv(struct cli_request *req, union smb_read *parms) +NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { goto failed; } @@ -130,10 +130,10 @@ NTSTATUS smb_raw_read_recv(struct cli_request *req, union smb_read *parms) break; case RAW_READ_LOCKREAD: - CLI_CHECK_WCT(req, 5); + SMBCLI_CHECK_WCT(req, 5); parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0)); if (parms->lockread.out.nread > parms->lockread.in.count || - !cli_raw_pull_data(req, req->in.data+3, + !smbcli_raw_pull_data(req, req->in.data+3, parms->lockread.out.nread, parms->lockread.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; } @@ -141,10 +141,10 @@ NTSTATUS smb_raw_read_recv(struct cli_request *req, union smb_read *parms) case RAW_READ_READ: /* there are 4 reserved words in the reply */ - CLI_CHECK_WCT(req, 5); + SMBCLI_CHECK_WCT(req, 5); parms->read.out.nread = SVAL(req->in.vwv, VWV(0)); if (parms->read.out.nread > parms->read.in.count || - !cli_raw_pull_data(req, req->in.data+3, + !smbcli_raw_pull_data(req, req->in.data+3, parms->read.out.nread, parms->read.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; } @@ -152,12 +152,12 @@ NTSTATUS smb_raw_read_recv(struct cli_request *req, union smb_read *parms) case RAW_READ_READX: /* there are 5 reserved words in the reply */ - CLI_CHECK_WCT(req, 12); + SMBCLI_CHECK_WCT(req, 12); parms->readx.out.remaining = SVAL(req->in.vwv, VWV(2)); parms->readx.out.compaction_mode = SVAL(req->in.vwv, VWV(3)); parms->readx.out.nread = SVAL(req->in.vwv, VWV(5)); if (parms->readx.out.nread > MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt) || - !cli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), + !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), parms->readx.out.nread, parms->readx.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; @@ -166,15 +166,15 @@ NTSTATUS smb_raw_read_recv(struct cli_request *req, union smb_read *parms) } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** low level read operation (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_read(struct cli_tree *tree, union smb_read *parms) +NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms) { - struct cli_request *req = smb_raw_read_send(tree, parms); + struct smbcli_request *req = smb_raw_read_send(tree, parms); return smb_raw_read_recv(req, parms); } @@ -182,10 +182,10 @@ NTSTATUS smb_raw_read(struct cli_tree *tree, union smb_read *parms) /**************************************************************************** raw write interface (async send) ****************************************************************************/ -struct cli_request *smb_raw_write_send(struct cli_tree *tree, union smb_write *parms) +struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms) { BOOL bigoffset = False; - struct cli_request *req; + struct smbcli_request *req; switch (parms->generic.level) { case RAW_WRITE_GENERIC: @@ -264,8 +264,8 @@ struct cli_request *smb_raw_write_send(struct cli_tree *tree, union smb_write *p break; } - if (!cli_request_send(req)) { -cli_request_destroy(req); + if (!smbcli_request_send(req)) { +smbcli_request_destroy(req); return NULL; } @@ -276,10 +276,10 @@ cli_request_destroy(req); /**************************************************************************** raw write interface (async recv) ****************************************************************************/ -NTSTATUS smb_raw_write_recv(struct cli_request *req, union smb_write *parms) +NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms) { - if (!cli_request_receive(req) || - cli_request_is_error(req)) { + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { goto failed; } @@ -287,19 +287,19 @@ NTSTATUS smb_raw_write_recv(struct cli_request *req, union smb_write *parms) case RAW_WRITE_GENERIC: break; case RAW_WRITE_WRITEUNLOCK: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->writeunlock.out.nwritten = SVAL(req->in.vwv, VWV(0)); break; case RAW_WRITE_WRITE: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->write.out.nwritten = SVAL(req->in.vwv, VWV(0)); break; case RAW_WRITE_WRITECLOSE: - CLI_CHECK_WCT(req, 1); + SMBCLI_CHECK_WCT(req, 1); parms->writeclose.out.nwritten = SVAL(req->in.vwv, VWV(0)); break; case RAW_WRITE_WRITEX: - CLI_CHECK_WCT(req, 6); + SMBCLI_CHECK_WCT(req, 6); parms->writex.out.nwritten = SVAL(req->in.vwv, VWV(2)); parms->writex.out.nwritten += (CVAL(req->in.vwv, VWV(4)) << 16); parms->writex.out.remaining = SVAL(req->in.vwv, VWV(3)); @@ -309,14 +309,14 @@ NTSTATUS smb_raw_write_recv(struct cli_request *req, union smb_write *parms) } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** raw write interface (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_write(struct cli_tree *tree, union smb_write *parms) +NTSTATUS smb_raw_write(struct smbcli_tree *tree, union smb_write *parms) { - struct cli_request *req = smb_raw_write_send(tree, parms); + struct smbcli_request *req = smb_raw_write_send(tree, parms); return smb_raw_write_recv(req, parms); } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 38b8f71f57..4143cb12ca 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -20,7 +20,7 @@ */ /* - this file implements functions for manipulating the 'struct cli_request' structure in libsmb + this file implements functions for manipulating the 'struct smbcli_request' structure in libsmb */ #include "includes.h" @@ -32,7 +32,7 @@ #define MAX_BYTES_PER_CHAR 3 /* destroy a request structure and return final status */ -NTSTATUS cli_request_destroy(struct cli_request *req) +NTSTATUS smbcli_request_destroy(struct smbcli_request *req) { NTSTATUS status; @@ -58,28 +58,28 @@ NTSTATUS cli_request_destroy(struct cli_request *req) low-level function to setup a request buffer for a non-SMB packet at the transport level */ -struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, uint_t size) +struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, uint_t size) { - struct cli_request *req; + struct smbcli_request *req; TALLOC_CTX *mem_ctx; /* each request gets its own talloc context. The request structure itself is also allocated inside this context, so we need to allocate it before we construct the request */ - mem_ctx = talloc_init("cli_request"); + mem_ctx = talloc_init("smbcli_request"); if (!mem_ctx) { return NULL; } - req = talloc(mem_ctx, sizeof(struct cli_request)); + req = talloc(mem_ctx, sizeof(struct smbcli_request)); if (!req) { return NULL; } ZERO_STRUCTP(req); /* setup the request context */ - req->state = CLI_REQUEST_INIT; + req->state = SMBCLI_REQUEST_INIT; req->mem_ctx = mem_ctx; req->transport = transport; req->session = NULL; @@ -103,12 +103,12 @@ struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, ui /* setup a SMB packet at transport level */ -struct cli_request *cli_request_setup_transport(struct cli_transport *transport, +struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport, uint8_t command, uint_t wct, uint_t buflen) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen); + req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen); if (!req) return NULL; @@ -129,7 +129,7 @@ struct cli_request *cli_request_setup_transport(struct cli_transport *transport, SSVAL(req->out.hdr,HDR_FLG2, 0); /* assign a mid */ - req->mid = cli_transport_next_mid(transport); + req->mid = smbcli_transport_next_mid(transport); /* copy the pid, uid and mid to the request */ SSVAL(req->out.hdr, HDR_PID, 0); @@ -146,17 +146,17 @@ struct cli_request *cli_request_setup_transport(struct cli_transport *transport, /* setup a reply in req->out with the given word count and initial data buffer size. the caller will then fill in the command words and - data before calling cli_request_send() to send the reply on its + data before calling smbcli_request_send() to send the reply on its way. This interface is used before a session is setup. */ -struct cli_request *cli_request_setup_session(struct cli_session *session, +struct smbcli_request *smbcli_request_setup_session(struct smbcli_session *session, uint8_t command, uint_t wct, uint_t buflen) { - struct cli_request *req; + struct smbcli_request *req; uint16_t flags2; uint32_t capabilities; - req = cli_request_setup_transport(session->transport, command, wct, buflen); + req = smbcli_request_setup_transport(session->transport, command, wct, buflen); if (!req) return NULL; @@ -189,13 +189,13 @@ struct cli_request *cli_request_setup_session(struct cli_session *session, /* setup a request for tree based commands */ -struct cli_request *cli_request_setup(struct cli_tree *tree, +struct smbcli_request *smbcli_request_setup(struct smbcli_tree *tree, uint8_t command, uint_t wct, uint_t buflen) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup_session(tree->session, command, wct, buflen); + req = smbcli_request_setup_session(tree->session, command, wct, buflen); if (req) { req->tree = tree; SSVAL(req->out.hdr,HDR_TID,tree->tid); @@ -211,7 +211,7 @@ struct cli_request *cli_request_setup(struct cli_tree *tree, To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ -static void cli_req_grow_allocation(struct cli_request *req, uint_t new_size) +static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_size) { int delta; char *buf2; @@ -252,11 +252,11 @@ static void cli_req_grow_allocation(struct cli_request *req, uint_t new_size) To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ -static void cli_req_grow_data(struct cli_request *req, uint_t new_size) +static void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) { int delta; - cli_req_grow_allocation(req, new_size); + smbcli_req_grow_allocation(req, new_size); delta = new_size - req->out.data_size; @@ -271,15 +271,15 @@ static void cli_req_grow_data(struct cli_request *req, uint_t new_size) /* send a message */ -BOOL cli_request_send(struct cli_request *req) +BOOL smbcli_request_send(struct smbcli_request *req) { if (IVAL(req->out.buffer, 0) == 0) { _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); } - cli_request_calculate_sign_mac(req); + smbcli_request_calculate_sign_mac(req); - cli_transport_send(req); + smbcli_transport_send(req); return True; } @@ -288,14 +288,14 @@ BOOL cli_request_send(struct cli_request *req) /* receive a response to a packet */ -BOOL cli_request_receive(struct cli_request *req) +BOOL smbcli_request_receive(struct smbcli_request *req) { /* req can be NULL when a send has failed. This eliminates lots of NULL checks in each module */ if (!req) return False; /* keep receiving packets until this one is replied to */ - while (req->state <= CLI_REQUEST_RECV) { + while (req->state <= SMBCLI_REQUEST_RECV) { event_loop_once(req->transport->event.ctx); } @@ -307,12 +307,12 @@ BOOL cli_request_receive(struct cli_request *req) receive another reply to a request - this is used for requests that have multi-part replies (such as SMBtrans2) */ -BOOL cli_request_receive_more(struct cli_request *req) +BOOL smbcli_request_receive_more(struct smbcli_request *req) { - req->state = CLI_REQUEST_RECV; + req->state = SMBCLI_REQUEST_RECV; DLIST_ADD(req->transport->pending_recv, req); - return cli_request_receive(req); + return smbcli_request_receive(req); } @@ -320,7 +320,7 @@ BOOL cli_request_receive_more(struct cli_request *req) handle oplock break requests from the server - return True if the request was an oplock break */ -BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char *hdr, const char *vwv) +BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const char *hdr, const char *vwv) { /* we must be very fussy about what we consider an oplock break to avoid matching readbraw replies */ @@ -347,15 +347,15 @@ BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char wait for a reply to be received for a packet that just returns an error code and nothing more */ -NTSTATUS cli_request_simple_recv(struct cli_request *req) +NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req) { - cli_request_receive(req); - return cli_request_destroy(req); + smbcli_request_receive(req); + return smbcli_request_destroy(req); } /* Return true if the last packet was in error */ -BOOL cli_request_is_error(struct cli_request *req) +BOOL smbcli_request_is_error(struct smbcli_request *req) { return NT_STATUS_IS_ERR(req->status); } @@ -365,7 +365,7 @@ BOOL cli_request_is_error(struct cli_request *req) return the number of bytes added to the packet */ -size_t cli_req_append_string(struct cli_request *req, const char *str, uint_t flags) +size_t smbcli_req_append_string(struct smbcli_request *req, const char *str, uint_t flags) { size_t len; @@ -376,17 +376,17 @@ size_t cli_req_append_string(struct cli_request *req, const char *str, uint_t fl len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; - cli_req_grow_allocation(req, len + req->out.data_size); + smbcli_req_grow_allocation(req, len + req->out.data_size); len = push_string(NULL, req->out.data + req->out.data_size, str, len, flags); - cli_req_grow_data(req, len + req->out.data_size); + smbcli_req_grow_data(req, len + req->out.data_size); return len; } /* - this is like cli_req_append_string but it also return the + this is like smbcli_req_append_string but it also return the non-terminated string byte length, which can be less than the number of bytes consumed in the packet for 2 reasons: @@ -396,7 +396,7 @@ size_t cli_req_append_string(struct cli_request *req, const char *str, uint_t fl this is used in places where the non-terminated string byte length is placed in the packet as a separate field */ -size_t cli_req_append_string_len(struct cli_request *req, const char *str, uint_t flags, int *len) +size_t smbcli_req_append_string_len(struct smbcli_request *req, const char *str, uint_t flags, int *len) { int diff = 0; size_t ret; @@ -412,7 +412,7 @@ size_t cli_req_append_string_len(struct cli_request *req, const char *str, uint_ } /* do the hard work */ - ret = cli_req_append_string(req, str, flags); + ret = smbcli_req_append_string(req, str, flags); /* see if we need to subtract the termination */ if (flags & STR_TERMINATE) { @@ -437,11 +437,11 @@ size_t cli_req_append_string_len(struct cli_request *req, const char *str, uint_ if dest_len is -1 then no limit applies */ -size_t cli_req_append_ascii4(struct cli_request *req, const char *str, uint_t flags) +size_t smbcli_req_append_ascii4(struct smbcli_request *req, const char *str, uint_t flags) { size_t size; - cli_req_append_bytes(req, (const uint8_t *)"\4", 1); - size = cli_req_append_string(req, str, flags); + smbcli_req_append_bytes(req, (const uint8_t *)"\4", 1); + size = smbcli_req_append_string(req, str, flags); return size + 1; } @@ -452,11 +452,11 @@ size_t cli_req_append_ascii4(struct cli_request *req, const char *str, uint_t fl if dest is NULL, then put the blob at the end of the data portion of the packet */ -size_t cli_req_append_blob(struct cli_request *req, const DATA_BLOB *blob) +size_t smbcli_req_append_blob(struct smbcli_request *req, const DATA_BLOB *blob) { - cli_req_grow_allocation(req, req->out.data_size + blob->length); + smbcli_req_grow_allocation(req, req->out.data_size + blob->length); memcpy(req->out.data + req->out.data_size, blob->data, blob->length); - cli_req_grow_data(req, req->out.data_size + blob->length); + smbcli_req_grow_data(req, req->out.data_size + blob->length); return blob->length; } @@ -464,11 +464,11 @@ size_t cli_req_append_blob(struct cli_request *req, const DATA_BLOB *blob) append raw bytes into the data portion of the request packet return the number of bytes added */ -size_t cli_req_append_bytes(struct cli_request *req, const uint8_t *bytes, size_t byte_len) +size_t smbcli_req_append_bytes(struct smbcli_request *req, const uint8_t *bytes, size_t byte_len) { - cli_req_grow_allocation(req, byte_len + req->out.data_size); + smbcli_req_grow_allocation(req, byte_len + req->out.data_size); memcpy(req->out.data + req->out.data_size, bytes, byte_len); - cli_req_grow_data(req, byte_len + req->out.data_size); + smbcli_req_grow_data(req, byte_len + req->out.data_size); return byte_len; } @@ -476,15 +476,15 @@ size_t cli_req_append_bytes(struct cli_request *req, const uint8_t *bytes, size_ append variable block (type 5 buffer) into the data portion of the request packet return the number of bytes added */ -size_t cli_req_append_var_block(struct cli_request *req, const uint8_t *bytes, uint16_t byte_len) +size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *bytes, uint16_t byte_len) { - cli_req_grow_allocation(req, byte_len + 3 + req->out.data_size); + smbcli_req_grow_allocation(req, byte_len + 3 + req->out.data_size); SCVAL(req->out.data + req->out.data_size, 0, 5); SSVAL(req->out.data + req->out.data_size, 1, byte_len); /* add field length */ if (byte_len > 0) { memcpy(req->out.data + req->out.data_size + 3, bytes, byte_len); } - cli_req_grow_data(req, byte_len + 3 + req->out.data_size); + smbcli_req_grow_data(req, byte_len + 3 + req->out.data_size); return byte_len + 3; } @@ -502,7 +502,7 @@ size_t cli_req_append_var_block(struct cli_request *req, const uint8_t *bytes, u on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx, +static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx, char **dest, const char *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; @@ -559,7 +559,7 @@ static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx, on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -size_t cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx, +size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, char **dest, const char *src, int byte_len, uint_t flags) { int src_len, src_len2; @@ -602,15 +602,15 @@ size_t cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx, on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -size_t cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx, +size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, char **dest, const char *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { - return cli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags); + return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags); } - return cli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags); + return smbcli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags); } @@ -620,7 +620,7 @@ size_t cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx, if byte_len is -1 then limit the blob only by packet size */ -DATA_BLOB cli_req_pull_blob(struct cli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len) +DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len) { int src_len; @@ -639,7 +639,7 @@ DATA_BLOB cli_req_pull_blob(struct cli_request *req, TALLOC_CTX *mem_ctx, const /* check that a lump of data in a request is within the bounds of the data section of the packet */ -static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32_t count) +static BOOL smbcli_req_data_oob(struct smbcli_request *req, const char *ptr, uint32_t count) { /* be careful with wraparound! */ if (ptr < req->in.data || @@ -656,11 +656,11 @@ static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32_t return False if any part is outside the data portion of the packet */ -BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char *dest) +BOOL smbcli_raw_pull_data(struct smbcli_request *req, const char *src, int len, char *dest) { if (len == 0) return True; - if (cli_req_data_oob(req, src, len)) { + if (smbcli_req_data_oob(req, src, len)) { return False; } @@ -672,7 +672,7 @@ BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char * /* put a NTTIME into a packet */ -void cli_push_nttime(void *base, uint16_t offset, NTTIME t) +void smbcli_push_nttime(void *base, uint16_t offset, NTTIME t) { SBVAL(base, offset, t); } @@ -680,7 +680,7 @@ void cli_push_nttime(void *base, uint16_t offset, NTTIME t) /* pull a NTTIME from a packet */ -NTTIME cli_pull_nttime(void *base, uint16_t offset) +NTTIME smbcli_pull_nttime(void *base, uint16_t offset) { NTTIME ret = BVAL(base, offset); return ret; @@ -699,7 +699,7 @@ NTTIME cli_pull_nttime(void *base, uint16_t offset) on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the blob is returned */ -static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, +static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, DATA_BLOB *blob, const char **dest, const char *src, int byte_len, uint_t flags) { @@ -758,7 +758,7 @@ static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the blob is returned */ -static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx, +static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **dest, const char *src, int byte_len, uint_t flags) { @@ -804,7 +804,7 @@ static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx, on failure zero is returned and dest->s is set to NULL, otherwise the number of bytes consumed in the blob is returned */ -size_t cli_blob_pull_string(struct cli_session *session, +size_t smbcli_blob_pull_string(struct smbcli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, WIRE_STRING *dest, @@ -834,7 +834,7 @@ size_t cli_blob_pull_string(struct cli_session *session, if (flags & STR_LEN_NOTERM) { extra = 2; } - return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, &dest->s, + return align + extra + smbcli_blob_pull_ucs2(mem_ctx, blob, &dest->s, blob->data+str_offset+align, dest->private_length, flags); } @@ -843,7 +843,7 @@ size_t cli_blob_pull_string(struct cli_session *session, extra = 1; } - return extra + cli_blob_pull_ascii(mem_ctx, blob, &dest->s, + return extra + smbcli_blob_pull_ascii(mem_ctx, blob, &dest->s, blob->data+str_offset, dest->private_length, flags); } @@ -859,7 +859,7 @@ size_t cli_blob_pull_string(struct cli_session *session, on failure zero is returned and dest->s is set to NULL, otherwise the number of bytes consumed in the blob is returned */ -size_t cli_blob_pull_unix_string(struct cli_session *session, +size_t smbcli_blob_pull_unix_string(struct smbcli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **dest, @@ -879,7 +879,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session, if (flags & STR_LEN_NOTERM) { extra = 2; } - return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, dest, + return align + extra + smbcli_blob_pull_ucs2(mem_ctx, blob, dest, blob->data+str_offset+align, -1, flags); } @@ -888,7 +888,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session, extra = 1; } - return extra + cli_blob_pull_ascii(mem_ctx, blob, dest, + return extra + smbcli_blob_pull_ascii(mem_ctx, blob, dest, blob->data+str_offset, -1, flags); } @@ -896,7 +896,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session, /* append a string into a blob */ -size_t cli_blob_append_string(struct cli_session *session, +size_t smbcli_blob_append_string(struct smbcli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *str, uint_t flags) { diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index a4ba8e8696..67410283ed 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -23,7 +23,7 @@ /**************************************************************************** Old style search backend - process output. ****************************************************************************/ -static void smb_raw_search_backend(struct cli_request *req, +static void smb_raw_search_backend(struct smbcli_request *req, TALLOC_CTX *mem_ctx, uint16_t count, void *private, @@ -42,12 +42,12 @@ static void smb_raw_search_backend(struct cli_request *req, p = req->in.data + 3; for (i=0; i < count; i++) { - search_data.search.search_id = cli_req_pull_blob(req, mem_ctx, p, 21); + search_data.search.search_id = smbcli_req_pull_blob(req, mem_ctx, p, 21); search_data.search.attrib = CVAL(p, 21); search_data.search.write_time = raw_pull_dos_date(req->transport, p + 22); search_data.search.size = IVAL(p, 26); - cli_req_pull_ascii(req, mem_ctx, &search_data.search.name, p+30, 13, STR_ASCII); + smbcli_req_pull_ascii(req, mem_ctx, &search_data.search.name, p+30, 13, STR_ASCII); if (!callback(private, &search_data)) { break; } @@ -58,27 +58,27 @@ static void smb_raw_search_backend(struct cli_request *req, /**************************************************************************** Old style search first. ****************************************************************************/ -static NTSTATUS smb_raw_search_first_old(struct cli_tree *tree, +static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsearch, 2, 0); + req = smbcli_request_setup(tree, SMBsearch, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->search_first.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_first.in.search_attrib); - cli_req_append_ascii4(req, io->search_first.in.pattern, STR_TERMINATE); - cli_req_append_var_block(req, NULL, 0); + smbcli_req_append_ascii4(req, io->search_first.in.pattern, STR_TERMINATE); + smbcli_req_append_var_block(req, NULL, 0); - if (!cli_request_send(req) || - !cli_request_receive(req)) { - return cli_request_destroy(req); + if (!smbcli_request_send(req) || + !smbcli_request_receive(req)) { + return smbcli_request_destroy(req); } if (NT_STATUS_IS_OK(req->status)) { @@ -86,33 +86,33 @@ static NTSTATUS smb_raw_search_first_old(struct cli_tree *tree, smb_raw_search_backend(req, mem_ctx, io->search_first.out.count, private, callback); } - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** Old style search next. ****************************************************************************/ -static NTSTATUS smb_raw_search_next_old(struct cli_tree *tree, +static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsearch, 2, 0); + req = smbcli_request_setup(tree, SMBsearch, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->search_next.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_next.in.search_attrib); - cli_req_append_ascii4(req, "", STR_TERMINATE); - cli_req_append_var_block(req, io->search_next.in.search_id.data, 21); + smbcli_req_append_ascii4(req, "", STR_TERMINATE); + smbcli_req_append_var_block(req, io->search_next.in.search_id.data, 21); - if (!cli_request_send(req) || - !cli_request_receive(req)) { - return cli_request_destroy(req); + if (!smbcli_request_send(req) || + !smbcli_request_receive(req)) { + return smbcli_request_destroy(req); } if (NT_STATUS_IS_OK(req->status)) { @@ -120,13 +120,13 @@ static NTSTATUS smb_raw_search_next_old(struct cli_tree *tree, smb_raw_search_backend(req, mem_ctx, io->search_next.out.count, private, callback); } - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /**************************************************************************** Very raw search first - returns param/data blobs. ****************************************************************************/ -static NTSTATUS smb_raw_search_first_blob(struct cli_tree *tree, +static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, /* used to allocate output blobs */ union smb_search_first *io, uint16_t info_level, @@ -157,7 +157,7 @@ static NTSTATUS smb_raw_search_first_blob(struct cli_tree *tree, SSVAL(tp.in.params.data, 6, info_level); SIVAL(tp.in.params.data, 8, io->t2ffirst.in.storage_type); - cli_blob_append_string(tree->session, mem_ctx, &tp.in.params, + smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, io->t2ffirst.in.pattern, STR_TERMINATE); status = smb_raw_trans2(tree, mem_ctx, &tp); @@ -178,7 +178,7 @@ static NTSTATUS smb_raw_search_first_blob(struct cli_tree *tree, Very raw search first - returns param/data blobs. Used in CIFS-on-CIFS NTVFS. ****************************************************************************/ -static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, +static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, uint16_t info_level, @@ -209,7 +209,7 @@ static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, SIVAL(tp.in.params.data, 6, io->t2fnext.in.resume_key); SSVAL(tp.in.params.data, 10, io->t2fnext.in.flags); - cli_blob_append_string(tree->session, mem_ctx, &tp.in.params, + smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, io->t2fnext.in.last_name, STR_TERMINATE); @@ -233,7 +233,7 @@ static NTSTATUS smb_raw_search_next_blob(struct cli_tree *tree, return 0 for success with end of list return -1 for a parse error */ -static int parse_trans2_search(struct cli_tree *tree, +static int parse_trans2_search(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, enum smb_search_level level, uint16_t flags, @@ -265,7 +265,7 @@ static int parse_trans2_search(struct cli_tree *tree, data->standard.size = IVAL(blob->data, 12); data->standard.alloc_size = IVAL(blob->data, 16); data->standard.attrib = SVAL(blob->data, 20); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->standard.name, 22, 23, STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM); return len + 23; @@ -288,7 +288,7 @@ static int parse_trans2_search(struct cli_tree *tree, data->ea_size.alloc_size = IVAL(blob->data, 16); data->ea_size.attrib = SVAL(blob->data, 20); data->ea_size.ea_size = IVAL(blob->data, 22); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->ea_size.name, 26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN); return len + 27 + 1; @@ -297,14 +297,14 @@ static int parse_trans2_search(struct cli_tree *tree, if (blob->length < 65) return -1; ofs = IVAL(blob->data, 0); data->directory_info.file_index = IVAL(blob->data, 4); - data->directory_info.create_time = cli_pull_nttime(blob->data, 8); - data->directory_info.access_time = cli_pull_nttime(blob->data, 16); - data->directory_info.write_time = cli_pull_nttime(blob->data, 24); - data->directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->directory_info.size = BVAL(blob->data, 40); data->directory_info.alloc_size = BVAL(blob->data, 48); data->directory_info.attrib = IVAL(blob->data, 56); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->directory_info.name, 60, 64, 0); if (ofs != 0 && ofs < 64+len) { @@ -316,15 +316,15 @@ static int parse_trans2_search(struct cli_tree *tree, if (blob->length < 69) return -1; ofs = IVAL(blob->data, 0); data->full_directory_info.file_index = IVAL(blob->data, 4); - data->full_directory_info.create_time = cli_pull_nttime(blob->data, 8); - data->full_directory_info.access_time = cli_pull_nttime(blob->data, 16); - data->full_directory_info.write_time = cli_pull_nttime(blob->data, 24); - data->full_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->full_directory_info.size = BVAL(blob->data, 40); data->full_directory_info.alloc_size = BVAL(blob->data, 48); data->full_directory_info.attrib = IVAL(blob->data, 56); data->full_directory_info.ea_size = IVAL(blob->data, 64); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->full_directory_info.name, 60, 68, 0); if (ofs != 0 && ofs < 68+len) { @@ -336,7 +336,7 @@ static int parse_trans2_search(struct cli_tree *tree, if (blob->length < 13) return -1; ofs = IVAL(blob->data, 0); data->name_info.file_index = IVAL(blob->data, 4); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->name_info.name, 8, 12, 0); if (ofs != 0 && ofs < 12+len) { @@ -349,18 +349,18 @@ static int parse_trans2_search(struct cli_tree *tree, if (blob->length < 95) return -1; ofs = IVAL(blob->data, 0); data->both_directory_info.file_index = IVAL(blob->data, 4); - data->both_directory_info.create_time = cli_pull_nttime(blob->data, 8); - data->both_directory_info.access_time = cli_pull_nttime(blob->data, 16); - data->both_directory_info.write_time = cli_pull_nttime(blob->data, 24); - data->both_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->both_directory_info.size = BVAL(blob->data, 40); data->both_directory_info.alloc_size = BVAL(blob->data, 48); data->both_directory_info.attrib = IVAL(blob->data, 56); data->both_directory_info.ea_size = IVAL(blob->data, 64); - cli_blob_pull_string(tree->session, mem_ctx, blob, + smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->both_directory_info.short_name, 68, 70, STR_LEN8BIT | STR_UNICODE); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->both_directory_info.name, 60, 94, 0); if (ofs != 0 && ofs < 94+len) { @@ -373,16 +373,16 @@ static int parse_trans2_search(struct cli_tree *tree, if (blob->length < 81) return -1; ofs = IVAL(blob->data, 0); data->id_full_directory_info.file_index = IVAL(blob->data, 4); - data->id_full_directory_info.create_time = cli_pull_nttime(blob->data, 8); - data->id_full_directory_info.access_time = cli_pull_nttime(blob->data, 16); - data->id_full_directory_info.write_time = cli_pull_nttime(blob->data, 24); - data->id_full_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->id_full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->id_full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->id_full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->id_full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->id_full_directory_info.size = BVAL(blob->data, 40); data->id_full_directory_info.alloc_size = BVAL(blob->data, 48); data->id_full_directory_info.attrib = IVAL(blob->data, 56); data->id_full_directory_info.ea_size = IVAL(blob->data, 64); data->id_full_directory_info.file_id = BVAL(blob->data, 72); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->id_full_directory_info.name, 60, 80, 0); if (ofs != 0 && ofs < 80+len) { @@ -394,19 +394,19 @@ static int parse_trans2_search(struct cli_tree *tree, if (blob->length < 105) return -1; ofs = IVAL(blob->data, 0); data->id_both_directory_info.file_index = IVAL(blob->data, 4); - data->id_both_directory_info.create_time = cli_pull_nttime(blob->data, 8); - data->id_both_directory_info.access_time = cli_pull_nttime(blob->data, 16); - data->id_both_directory_info.write_time = cli_pull_nttime(blob->data, 24); - data->id_both_directory_info.change_time = cli_pull_nttime(blob->data, 32); + data->id_both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->id_both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->id_both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->id_both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->id_both_directory_info.size = BVAL(blob->data, 40); data->id_both_directory_info.alloc_size = BVAL(blob->data, 48); data->id_both_directory_info.attrib = SVAL(blob->data, 56); data->id_both_directory_info.ea_size = IVAL(blob->data, 64); - cli_blob_pull_string(tree->session, mem_ctx, blob, + smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->id_both_directory_info.short_name, 68, 70, STR_LEN8BIT | STR_UNICODE); data->id_both_directory_info.file_id = BVAL(blob->data, 96); - len = cli_blob_pull_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->id_both_directory_info.name, 60, 104, 0); if (ofs != 0 && ofs < 104+len) { @@ -420,9 +420,9 @@ static int parse_trans2_search(struct cli_tree *tree, data->unix_info.file_index = IVAL(blob->data, 4); data->unix_info.size = BVAL(blob->data, 8); data->unix_info.alloc_size = BVAL(blob->data, 16); - data->unix_info.status_change_time = cli_pull_nttime(blob->data, 24); - data->unix_info.access_time = cli_pull_nttime(blob->data, 32); - data->unix_info.change_time = cli_pull_nttime(blob->data, 40); + data->unix_info.status_change_time = smbcli_pull_nttime(blob->data, 24); + data->unix_info.access_time = smbcli_pull_nttime(blob->data, 32); + data->unix_info.change_time = smbcli_pull_nttime(blob->data, 40); data->unix_info.uid = IVAL(blob->data, 48); data->unix_info.gid = IVAL(blob->data, 56); data->unix_info.file_type = IVAL(blob->data, 64); @@ -432,7 +432,7 @@ static int parse_trans2_search(struct cli_tree *tree, data->unix_info.permissions = IVAL(blob->data, 92); data->unix_info.nlink = IVAL(blob->data, 100); /* There is no length field for this name but we know it's null terminated. */ - len = cli_blob_pull_unix_string(tree->session, mem_ctx, blob, + len = smbcli_blob_pull_unix_string(tree->session, mem_ctx, blob, &data->unix_info.name, 108, 0); if (ofs != 0 && ofs < 108+len) { return -1; @@ -447,7 +447,7 @@ static int parse_trans2_search(struct cli_tree *tree, /**************************************************************************** Trans2 search backend - process output. ****************************************************************************/ -static NTSTATUS smb_raw_t2search_backend(struct cli_tree *tree, +static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, enum smb_search_level level, uint16_t flags, @@ -490,7 +490,7 @@ static NTSTATUS smb_raw_t2search_backend(struct cli_tree *tree, /* Implements trans2findfirst2 and old search */ -NTSTATUS smb_raw_search_first(struct cli_tree *tree, +NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) @@ -534,7 +534,7 @@ NTSTATUS smb_raw_search_first(struct cli_tree *tree, /* Implements trans2findnext2 and old smbsearch */ -NTSTATUS smb_raw_search_next(struct cli_tree *tree, +NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) @@ -578,21 +578,21 @@ NTSTATUS smb_raw_search_next(struct cli_tree *tree, /* Implements trans2findclose2 */ -NTSTATUS smb_raw_search_close(struct cli_tree *tree, +NTSTATUS smb_raw_search_close(struct smbcli_tree *tree, union smb_search_close *io) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBfindclose, 1, 0); + req = smbcli_request_setup(tree, SMBfindclose, 1, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->findclose.in.handle); - if (cli_request_send(req)) { - cli_request_receive(req); + if (smbcli_request_send(req)) { + smbcli_request_receive(req); } - return cli_request_destroy(req); + return smbcli_request_destroy(req); } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 3dcda401f5..b1667db50f 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -24,7 +24,7 @@ /**************************************************************************** Handle setfileinfo/setpathinfo trans2 backend. ****************************************************************************/ -static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, +static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_setfileinfo *parms, DATA_BLOB *blob) @@ -61,10 +61,10 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: NEED_BLOB(40); - cli_push_nttime(blob->data, 0, parms->basic_info.in.create_time); - cli_push_nttime(blob->data, 8, parms->basic_info.in.access_time); - cli_push_nttime(blob->data, 16, parms->basic_info.in.write_time); - cli_push_nttime(blob->data, 24, parms->basic_info.in.change_time); + smbcli_push_nttime(blob->data, 0, parms->basic_info.in.create_time); + smbcli_push_nttime(blob->data, 8, parms->basic_info.in.access_time); + smbcli_push_nttime(blob->data, 16, parms->basic_info.in.write_time); + smbcli_push_nttime(blob->data, 24, parms->basic_info.in.change_time); SIVAL(blob->data, 32, parms->basic_info.in.attrib); SIVAL(blob->data, 36, 0); /* padding */ return True; @@ -73,9 +73,9 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, NEED_BLOB(92); SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file); SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes); - cli_push_nttime(blob->data, 16, parms->unix_basic.in.status_change_time); - cli_push_nttime(blob->data, 24, parms->unix_basic.in.access_time); - cli_push_nttime(blob->data, 32, parms->unix_basic.in.change_time); + smbcli_push_nttime(blob->data, 16, parms->unix_basic.in.status_change_time); + smbcli_push_nttime(blob->data, 24, parms->unix_basic.in.access_time); + smbcli_push_nttime(blob->data, 32, parms->unix_basic.in.change_time); SBVAL(blob->data, 40, parms->unix_basic.in.uid); SBVAL(blob->data, 48, parms->unix_basic.in.gid); SIVAL(blob->data, 56, parms->unix_basic.in.file_type); @@ -107,7 +107,7 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, NEED_BLOB(12); SIVAL(blob->data, 0, parms->rename_information.in.overwrite); SIVAL(blob->data, 4, parms->rename_information.in.root_fid); - len = cli_blob_append_string(tree->session, mem_ctx, blob, + len = smbcli_blob_append_string(tree->session, mem_ctx, blob, parms->rename_information.in.new_name, STR_UNICODE|STR_TERMINATE); SIVAL(blob->data, 8, len - 2); @@ -130,7 +130,7 @@ static BOOL smb_raw_setinfo_backend(struct cli_tree *tree, /**************************************************************************** Very raw set file info - takes data blob (async send) ****************************************************************************/ -static struct cli_request *smb_raw_setfileinfo_blob_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_setfileinfo_blob_send(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, uint16_t fnum, uint16_t info_level, @@ -163,7 +163,7 @@ static struct cli_request *smb_raw_setfileinfo_blob_send(struct cli_tree *tree, /**************************************************************************** Very raw set path info - takes data blob ****************************************************************************/ -static struct cli_request *smb_raw_setpathinfo_blob_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_setpathinfo_blob_send(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, const char *fname, uint16_t info_level, @@ -186,7 +186,7 @@ static struct cli_request *smb_raw_setpathinfo_blob_send(struct cli_tree *tree, } SSVAL(tp.in.params.data, 0, info_level); SSVAL(tp.in.params.data, 2, 0); - cli_blob_append_string(tree->session, mem_ctx, + smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, fname, STR_TERMINATE); @@ -198,23 +198,23 @@ static struct cli_request *smb_raw_setpathinfo_blob_send(struct cli_tree *tree, /**************************************************************************** Handle setattr (async send) ****************************************************************************/ -static struct cli_request *smb_raw_setattr_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_setattr_send(struct smbcli_tree *tree, union smb_setfileinfo *parms) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsetatr, 8, 0); + req = smbcli_request_setup(tree, SMBsetatr, 8, 0); if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), parms->setattr.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->setattr.in.write_time); memset(req->out.vwv + VWV(3), 0, 10); /* reserved */ - cli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE); - cli_req_append_ascii4(req, "", STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, "", STR_TERMINATE); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -224,12 +224,12 @@ static struct cli_request *smb_raw_setattr_send(struct cli_tree *tree, /**************************************************************************** Handle setattrE. (async send) ****************************************************************************/ -static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree, +static struct smbcli_request *smb_raw_setattrE_send(struct smbcli_tree *tree, union smb_setfileinfo *parms) { - struct cli_request *req; + struct smbcli_request *req; - req = cli_request_setup(tree, SMBsetattrE, 7, 0); + req = smbcli_request_setup(tree, SMBsetattrE, 7, 0); if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), parms->setattre.file.fnum); @@ -240,8 +240,8 @@ static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree, raw_push_dos_date2(tree->session->transport, req->out.vwv, VWV(5), parms->setattre.in.write_time); - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -251,12 +251,12 @@ static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree, /**************************************************************************** Set file info (async send) ****************************************************************************/ -struct cli_request *smb_raw_setfileinfo_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree, union smb_setfileinfo *parms) { DATA_BLOB blob; TALLOC_CTX *mem_ctx; - struct cli_request *req; + struct smbcli_request *req; if (parms->generic.level == RAW_SFILEINFO_SETATTRE) { return smb_raw_setattrE_send(tree, parms); @@ -287,23 +287,23 @@ struct cli_request *smb_raw_setfileinfo_send(struct cli_tree *tree, /**************************************************************************** Set file info (async send) ****************************************************************************/ -NTSTATUS smb_raw_setfileinfo(struct cli_tree *tree, +NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree, union smb_setfileinfo *parms) { - struct cli_request *req = smb_raw_setfileinfo_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_setfileinfo_send(tree, parms); + return smbcli_request_simple_recv(req); } /**************************************************************************** Set path info (async send) ****************************************************************************/ -struct cli_request *smb_raw_setpathinfo_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, union smb_setfileinfo *parms) { DATA_BLOB blob; TALLOC_CTX *mem_ctx; - struct cli_request *req; + struct smbcli_request *req; if (parms->generic.level == RAW_SFILEINFO_SETATTR) { return smb_raw_setattr_send(tree, parms); @@ -334,9 +334,9 @@ struct cli_request *smb_raw_setpathinfo_send(struct cli_tree *tree, /**************************************************************************** Set path info (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_setpathinfo(struct cli_tree *tree, +NTSTATUS smb_raw_setpathinfo(struct smbcli_tree *tree, union smb_setfileinfo *parms) { - struct cli_request *req = smb_raw_setpathinfo_send(tree, parms); - return cli_request_simple_recv(req); + struct smbcli_request *req = smb_raw_setpathinfo_send(tree, parms); + return smbcli_request_simple_recv(req); } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 5dde753368..0c39abe880 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -25,7 +25,7 @@ /* check out of bounds for incoming data */ -static BOOL raw_trans_oob(struct cli_request *req, +static BOOL raw_trans_oob(struct smbcli_request *req, uint_t offset, uint_t count) { char *ptr; @@ -49,7 +49,7 @@ static BOOL raw_trans_oob(struct cli_request *req, /**************************************************************************** receive a SMB trans or trans2 response allocating the necessary memory ****************************************************************************/ -NTSTATUS smb_raw_trans2_recv(struct cli_request *req, +NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { @@ -63,8 +63,8 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, parms->out.params.length = 0; parms->out.params.data = NULL; - if (!cli_request_receive(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req)) { + return smbcli_request_destroy(req); } /* @@ -73,10 +73,10 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, * be treated as such. */ if (NT_STATUS_IS_ERR(req->status)) { - return cli_request_destroy(req); + return smbcli_request_destroy(req); } - CLI_CHECK_MIN_WCT(req, 10); + SMBCLI_CHECK_MIN_WCT(req, 10); /* parse out the lengths */ total_data = SVAL(req->in.vwv, VWV(1)); @@ -88,7 +88,7 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, if (!tdata) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); req->status = NT_STATUS_NO_MEMORY; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } parms->out.data.data = tdata; } @@ -98,20 +98,20 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, if (!tparam) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); req->status = NT_STATUS_NO_MEMORY; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } parms->out.params.data = tparam; } parms->out.setup_count = SVAL(req->in.vwv, VWV(9)); - CLI_CHECK_WCT(req, 10 + parms->out.setup_count); + SMBCLI_CHECK_WCT(req, 10 + parms->out.setup_count); if (parms->out.setup_count > 0) { int i; parms->out.setup = talloc(mem_ctx, 2 * parms->out.setup_count); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } for (i=0;iout.setup_count;i++) { parms->out.setup[i] = SVAL(req->in.vwv, VWV(10+i)); @@ -132,7 +132,7 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, /* they must *only* shrink */ DEBUG(1,("smb_raw_receive_trans: data/params expanded!\n")); req->status = NT_STATUS_BUFFER_TOO_SMALL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } total_data = total_data2; @@ -151,7 +151,7 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, param_count + param_disp > total_param) { DEBUG(1,("smb_raw_receive_trans: Buffer overflow\n")); req->status = NT_STATUS_BUFFER_TOO_SMALL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /* check the server isn't being nasty */ @@ -159,7 +159,7 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, raw_trans_oob(req, data_ofs, data_count)) { DEBUG(1,("smb_raw_receive_trans: out of bounds parameters!\n")); req->status = NT_STATUS_BUFFER_TOO_SMALL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } if (data_count) { @@ -180,17 +180,17 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, if (total_data <= parms->out.data.length && total_param <= parms->out.params.length) break; - if (!cli_request_receive_more(req)) { + if (!smbcli_request_receive_more(req)) { req->status = NT_STATUS_UNSUCCESSFUL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } -NTSTATUS smb_raw_trans_recv(struct cli_request *req, +NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { @@ -201,12 +201,12 @@ NTSTATUS smb_raw_trans_recv(struct cli_request *req, trans/trans2 raw async interface - only BLOBs used in this interface. note that this doesn't yet support multi-part requests ****************************************************************************/ -struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, +struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, struct smb_trans2 *parms, uint8_t command) { int wct = 14 + parms->in.setup_count; - struct cli_request *req; + struct smbcli_request *req; char *outdata,*outparam; int i; int padding; @@ -217,7 +217,7 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, else padding = 3; - req = cli_request_setup(tree, command, wct, padding); + req = smbcli_request_setup(tree, command, wct, padding); if (!req) { return NULL; } @@ -230,7 +230,7 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, memset(req->out.data, 0, padding); if (command == SMBtrans && parms->in.trans_name) { - namelen = cli_req_append_string(req, parms->in.trans_name, + namelen = smbcli_req_append_string(req, parms->in.trans_name, STR_TERMINATE); } @@ -252,14 +252,14 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, SSVAL(req->out.vwv,VWV(14)+i*2,parms->in.setup[i]); } if (parms->in.params.data) { - cli_req_append_blob(req, &parms->in.params); + smbcli_req_append_blob(req, &parms->in.params); } if (parms->in.data.data) { - cli_req_append_blob(req, &parms->in.data); + smbcli_req_append_blob(req, &parms->in.data); } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -271,13 +271,13 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree, note that this doesn't yet support multi-part requests ****************************************************************************/ -struct cli_request *smb_raw_trans_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, struct smb_trans2 *parms) { return smb_raw_trans_send_backend(tree, parms, SMBtrans); } -struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree, struct smb_trans2 *parms) { return smb_raw_trans_send_backend(tree, parms, SMBtrans2); @@ -286,11 +286,11 @@ struct cli_request *smb_raw_trans2_send(struct cli_tree *tree, /* trans2 synchronous blob interface */ -NTSTATUS smb_raw_trans2(struct cli_tree *tree, +NTSTATUS smb_raw_trans2(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { - struct cli_request *req; + struct smbcli_request *req; req = smb_raw_trans2_send(tree, parms); if (!req) return NT_STATUS_UNSUCCESSFUL; return smb_raw_trans2_recv(req, mem_ctx, parms); @@ -300,11 +300,11 @@ NTSTATUS smb_raw_trans2(struct cli_tree *tree, /* trans synchronous blob interface */ -NTSTATUS smb_raw_trans(struct cli_tree *tree, +NTSTATUS smb_raw_trans(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { - struct cli_request *req; + struct smbcli_request *req; req = smb_raw_trans_send(tree, parms); if (!req) return NT_STATUS_UNSUCCESSFUL; return smb_raw_trans_recv(req, mem_ctx, parms); @@ -313,16 +313,16 @@ NTSTATUS smb_raw_trans(struct cli_tree *tree, /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ -NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, +NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_nttrans *parms) { uint32_t total_data, recvd_data=0; uint32_t total_param, recvd_param=0; - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } /* sanity check */ @@ -331,10 +331,10 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, "SMBnttrans", CVAL(req->in.hdr,HDR_COM))); req->status = NT_STATUS_UNSUCCESSFUL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } - CLI_CHECK_MIN_WCT(req, 18); + SMBCLI_CHECK_MIN_WCT(req, 18); /* parse out the lengths */ total_param = IVAL(req->in.vwv, 3); @@ -346,18 +346,18 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, if (parms->out.data.length != total_data || parms->out.params.length != total_param) { req->status = NT_STATUS_NO_MEMORY; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } parms->out.setup_count = CVAL(req->in.vwv, 35); - CLI_CHECK_WCT(req, 18 + parms->out.setup_count); + SMBCLI_CHECK_WCT(req, 18 + parms->out.setup_count); if (parms->out.setup_count > 0) { int i; parms->out.setup = talloc(mem_ctx, 2 * parms->out.setup_count); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } for (i=0;iout.setup_count;i++) { parms->out.setup[i] = SVAL(req->in.vwv, VWV(18+i)); @@ -379,7 +379,7 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, /* they must *only* shrink */ DEBUG(1,("smb_raw_receive_nttrans: data/params expanded!\n")); req->status = NT_STATUS_BUFFER_TOO_SMALL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } total_data = total_data2; @@ -400,7 +400,7 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, param_count + param_disp > total_param) { DEBUG(1,("smb_raw_receive_nttrans: Buffer overflow\n")); req->status = NT_STATUS_BUFFER_TOO_SMALL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } /* check the server isn't being nasty */ @@ -408,7 +408,7 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, raw_trans_oob(req, data_ofs, data_count)) { DEBUG(1,("smb_raw_receive_nttrans: out of bounds parameters!\n")); req->status = NT_STATUS_BUFFER_TOO_SMALL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } if (data_count) { @@ -431,9 +431,9 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, break; } - if (!cli_request_receive(req) || - cli_request_is_error(req)) { - return cli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + return smbcli_request_destroy(req); } /* sanity check */ @@ -441,12 +441,12 @@ NTSTATUS smb_raw_nttrans_recv(struct cli_request *req, DEBUG(0,("smb_raw_receive_nttrans: Expected nttranss, got command 0x%02x\n", CVAL(req->in.hdr, HDR_COM))); req->status = NT_STATUS_UNSUCCESSFUL; - return cli_request_destroy(req); + return smbcli_request_destroy(req); } } failed: - return cli_request_destroy(req); + return smbcli_request_destroy(req); } @@ -454,10 +454,10 @@ failed: nttrans raw - only BLOBs used in this interface. at the moment we only handle a single primary request ****************************************************************************/ -struct cli_request *smb_raw_nttrans_send(struct cli_tree *tree, +struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, struct smb_nttrans *parms) { - struct cli_request *req; + struct smbcli_request *req; char *outdata, *outparam; int i; int align = 0; @@ -467,7 +467,7 @@ struct cli_request *smb_raw_nttrans_send(struct cli_tree *tree, align = 3; } - req = cli_request_setup(tree, SMBnttrans, + req = smbcli_request_setup(tree, SMBnttrans, 19 + parms->in.setup_count, align + parms->in.params.length + @@ -502,8 +502,8 @@ struct cli_request *smb_raw_nttrans_send(struct cli_tree *tree, memcpy(outparam, parms->in.data.data, parms->in.data.length); } - if (!cli_request_send(req)) { - cli_request_destroy(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); return NULL; } @@ -514,11 +514,11 @@ struct cli_request *smb_raw_nttrans_send(struct cli_tree *tree, /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ -NTSTATUS smb_raw_nttrans(struct cli_tree *tree, +NTSTATUS smb_raw_nttrans(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_nttrans *parms) { - struct cli_request *req; + struct smbcli_request *req; req = smb_raw_nttrans_send(tree, parms); if (!req) { diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 9c02fe50ec..ddde58fd88 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -30,7 +30,7 @@ struct smb_basic_signing_context { /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL set_smb_signing_common(struct cli_transport *transport) +static BOOL set_smb_signing_common(struct smbcli_transport *transport) { if (!(transport->negotiate.sec_mode & (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) { @@ -58,7 +58,7 @@ static BOOL set_smb_signing_common(struct cli_transport *transport) /*********************************************************** SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL set_smb_signing_real_common(struct cli_transport *transport) +static BOOL set_smb_signing_real_common(struct smbcli_transport *transport) { if (transport->negotiate.sign_info.mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -77,7 +77,7 @@ static void mark_packet_signed(struct request_buffer *out) SSVAL(out->hdr, HDR_FLG2, flags2); } -static BOOL signing_good(struct cli_request *req, unsigned int seq, BOOL good) +static BOOL signing_good(struct smbcli_request *req, unsigned int seq, BOOL good) { if (good) { if (!req->transport->negotiate.sign_info.doing_signing) { @@ -96,7 +96,7 @@ static BOOL signing_good(struct cli_request *req, unsigned int seq, BOOL good) req->transport->negotiate.sign_info.doing_signing = False; if (req->transport->negotiate.sign_info.free_signing_context) req->transport->negotiate.sign_info.free_signing_context(req->transport); - cli_null_set_signing(req->transport); + smbcli_null_set_signing(req->transport); return True; } else { /* bad packet after signing started - fail and disconnect. */ @@ -206,7 +206,7 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key /*********************************************************** SMB signing - Simple implementation - calculate a MAC to send. ************************************************************/ -static void cli_request_simple_sign_outgoing_message(struct cli_request *req) +static void smbcli_request_simple_sign_outgoing_message(struct smbcli_request *req) { struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; @@ -233,7 +233,7 @@ static void cli_request_simple_sign_outgoing_message(struct cli_request *req) /*********************************************************** SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) +static BOOL smbcli_request_simple_check_incoming_message(struct smbcli_request *req) { struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; @@ -249,7 +249,7 @@ static BOOL cli_request_simple_check_incoming_message(struct cli_request *req) /*********************************************************** SMB signing - Simple implementation - free signing context ************************************************************/ -static void cli_transport_simple_free_signing_context(struct cli_transport *transport) +static void smbcli_transport_simple_free_signing_context(struct smbcli_transport *transport) { struct smb_basic_signing_context *data = transport->negotiate.sign_info.signing_context; @@ -263,7 +263,7 @@ static void cli_transport_simple_free_signing_context(struct cli_transport *tran /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_transport_simple_set_signing(struct cli_transport *transport, +BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, const DATA_BLOB user_session_key, const DATA_BLOB response) { @@ -293,9 +293,9 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, /* Initialise the sequence number */ data->next_seq_num = 0; - transport->negotiate.sign_info.sign_outgoing_message = cli_request_simple_sign_outgoing_message; - transport->negotiate.sign_info.check_incoming_message = cli_request_simple_check_incoming_message; - transport->negotiate.sign_info.free_signing_context = cli_transport_simple_free_signing_context; + transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_simple_sign_outgoing_message; + transport->negotiate.sign_info.check_incoming_message = smbcli_request_simple_check_incoming_message; + transport->negotiate.sign_info.free_signing_context = smbcli_transport_simple_free_signing_context; return True; } @@ -304,7 +304,7 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport, /*********************************************************** SMB signing - NULL implementation - calculate a MAC to send. ************************************************************/ -static void cli_request_null_sign_outgoing_message(struct cli_request *req) +static void smbcli_request_null_sign_outgoing_message(struct smbcli_request *req) { /* we can't zero out the sig, as we might be trying to send a transport request - which is NBT-level, not SMB level and doesn't @@ -315,7 +315,7 @@ static void cli_request_null_sign_outgoing_message(struct cli_request *req) /*********************************************************** SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_request_null_check_incoming_message(struct cli_request *req) +static BOOL smbcli_request_null_check_incoming_message(struct smbcli_request *req) { return True; } @@ -324,7 +324,7 @@ static BOOL cli_request_null_check_incoming_message(struct cli_request *req) /*********************************************************** SMB signing - NULL implementation - free signing context ************************************************************/ -static void cli_null_free_signing_context(struct cli_transport *transport) +static void smbcli_null_free_signing_context(struct smbcli_transport *transport) { } @@ -334,13 +334,13 @@ static void cli_null_free_signing_context(struct cli_transport *transport) @note Used as an initialisation only - it will not correctly shut down a real signing mechanism */ -BOOL cli_null_set_signing(struct cli_transport *transport) +BOOL smbcli_null_set_signing(struct smbcli_transport *transport) { transport->negotiate.sign_info.signing_context = NULL; - transport->negotiate.sign_info.sign_outgoing_message = cli_request_null_sign_outgoing_message; - transport->negotiate.sign_info.check_incoming_message = cli_request_null_check_incoming_message; - transport->negotiate.sign_info.free_signing_context = cli_null_free_signing_context; + transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_null_sign_outgoing_message; + transport->negotiate.sign_info.check_incoming_message = smbcli_request_null_check_incoming_message; + transport->negotiate.sign_info.free_signing_context = smbcli_null_free_signing_context; return True; } @@ -348,7 +348,7 @@ BOOL cli_null_set_signing(struct cli_transport *transport) /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ -static void cli_request_temp_sign_outgoing_message(struct cli_request *req) +static void smbcli_request_temp_sign_outgoing_message(struct smbcli_request *req) { /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(&req->out); @@ -363,7 +363,7 @@ static void cli_request_temp_sign_outgoing_message(struct cli_request *req) /*********************************************************** SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_request_temp_check_incoming_message(struct cli_request *req) +static BOOL smbcli_request_temp_check_incoming_message(struct smbcli_request *req) { return True; } @@ -371,7 +371,7 @@ static BOOL cli_request_temp_check_incoming_message(struct cli_request *req) /*********************************************************** SMB signing - NULL implementation - free signing context ************************************************************/ -static void cli_temp_free_signing_context(struct cli_transport *transport) +static void smbcli_temp_free_signing_context(struct smbcli_transport *transport) { return; } @@ -382,7 +382,7 @@ static void cli_temp_free_signing_context(struct cli_transport *transport) @note Used as an initialisation only - it will not correctly shut down a real signing mechanism */ -BOOL cli_temp_set_signing(struct cli_transport *transport) +BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) { if (!set_smb_signing_common(transport)) { return False; @@ -390,9 +390,9 @@ BOOL cli_temp_set_signing(struct cli_transport *transport) transport->negotiate.sign_info.signing_context = NULL; - transport->negotiate.sign_info.sign_outgoing_message = cli_request_temp_sign_outgoing_message; - transport->negotiate.sign_info.check_incoming_message = cli_request_temp_check_incoming_message; - transport->negotiate.sign_info.free_signing_context = cli_temp_free_signing_context; + transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_temp_sign_outgoing_message; + transport->negotiate.sign_info.check_incoming_message = smbcli_request_temp_check_incoming_message; + transport->negotiate.sign_info.free_signing_context = smbcli_temp_free_signing_context; return True; } @@ -400,20 +400,20 @@ BOOL cli_temp_set_signing(struct cli_transport *transport) /** * Free the signing context */ -void cli_transport_free_signing_context(struct cli_transport *transport) +void smbcli_transport_free_signing_context(struct smbcli_transport *transport) { if (transport->negotiate.sign_info.free_signing_context) { transport->negotiate.sign_info.free_signing_context(transport); } - cli_null_set_signing(transport); + smbcli_null_set_signing(transport); } /** * Sign a packet with the current mechanism */ -void cli_request_calculate_sign_mac(struct cli_request *req) +void smbcli_request_calculate_sign_mac(struct smbcli_request *req) { req->transport->negotiate.sign_info.sign_outgoing_message(req); } @@ -424,7 +424,7 @@ void cli_request_calculate_sign_mac(struct cli_request *req) * @return False if we had an established signing connection * which had a back checksum, True otherwise */ -BOOL cli_request_check_sign_mac(struct cli_request *req) +BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) { BOOL good; @@ -442,9 +442,9 @@ BOOL cli_request_check_sign_mac(struct cli_request *req) } -BOOL cli_init_signing(struct cli_transport *transport) +BOOL smbcli_init_signing(struct smbcli_transport *transport) { - if (!cli_null_set_signing(transport)) { + if (!smbcli_null_set_signing(transport)) { return False; } diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index d852cd0d21..e7e413bbcb 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -25,7 +25,7 @@ /*************************************************************************** Return an error message from the last response ****************************************************************************/ -const char *cli_errstr(struct cli_tree *tree) +const char *smbcli_errstr(struct smbcli_tree *tree) { switch (tree->session->transport->error.etype) { case ETYPE_DOS: @@ -49,7 +49,7 @@ const char *cli_errstr(struct cli_tree *tree) /* Return the 32-bit NT status code from the last packet */ -NTSTATUS cli_nt_error(struct cli_tree *tree) +NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) { switch (tree->session->transport->error.etype) { case ETYPE_NT: @@ -75,7 +75,7 @@ NTSTATUS cli_nt_error(struct cli_tree *tree) /* Return the DOS error from the last packet - an error class and an error code. */ -void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode) +void smbcli_dos_error(struct smbcli_state *cli, uint8_t *eclass, uint32_t *ecode) { if (cli->transport->error.etype == ETYPE_DOS) { ntstatus_to_dos(cli->transport->error.e.nt_status, @@ -89,13 +89,13 @@ void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode) /* Return true if the last packet was an error */ -BOOL cli_is_error(struct cli_tree *tree) +BOOL smbcli_is_error(struct smbcli_tree *tree) { - return NT_STATUS_IS_ERR(cli_nt_error(tree)); + return NT_STATUS_IS_ERR(smbcli_nt_error(tree)); } /* Return true if the last error was a DOS error */ -BOOL cli_is_dos_error(struct cli_tree *tree) +BOOL smbcli_is_dos_error(struct smbcli_tree *tree) { return tree->session->transport->error.etype == ETYPE_DOS; } diff --git a/source4/libcli/util/cliutil.c b/source4/libcli/util/cliutil.c index 56dee7381a..3efa1dbbc9 100644 --- a/source4/libcli/util/cliutil.c +++ b/source4/libcli/util/cliutil.c @@ -29,7 +29,7 @@ of the ".." name. *******************************************************************/ -BOOL mask_match(struct cli_state *cli, const char *string, char *pattern, BOOL is_case_sensitive) +BOOL mask_match(struct smbcli_state *cli, const char *string, char *pattern, BOOL is_case_sensitive) { fstring p2, s2; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index a02fdaa38b..a50b4edc88 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -190,20 +190,20 @@ void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) /* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uint8_t kr[16], const DATA_BLOB *srv_chal, - const DATA_BLOB *cli_chal, + const DATA_BLOB *smbcli_chal, uint8_t resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); - hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); + hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx); hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); + DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n")); dump_data(100, srv_chal->data, srv_chal->length); - dump_data(100, cli_chal->data, cli_chal->length); + dump_data(100, smbcli_chal->data, smbcli_chal->length); dump_data(100, resp_buf, 16); #endif } -- cgit From 3ef16b2679bed40041483b8f862463fb30f426dc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 9 Aug 2004 20:47:31 +0000 Subject: r1674: fixed a bug in the handling of STR_LEN8BIT flagged strings (This used to be commit 17a331529706266bd53b2d1c7b873cf4bbd7aaa7) --- source4/libcli/raw/rawrequest.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 4143cb12ca..70e924a99f 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -814,12 +814,15 @@ size_t smbcli_blob_pull_string(struct smbcli_session *session, int extra; dest->s = NULL; - if (len_offset > blob->length-4) { - return 0; - } if (flags & STR_LEN8BIT) { + if (len_offset > blob->length-1) { + return 0; + } dest->private_length = CVAL(blob->data, len_offset); } else { + if (len_offset > blob->length-4) { + return 0; + } dest->private_length = IVAL(blob->data, len_offset); } extra = 0; -- cgit From 9c41274ace0a1dd88b113ce2bf84b33b0c528efa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 9 Aug 2004 20:51:16 +0000 Subject: r1676: - improved the handling of username/password in locktest and gentest - use lp_maxprotocol() in the libcli/raw/ negotiate code, so we obey the smb.conf "max protocol" option - better handling of -M option in masktest (This used to be commit 8685a584c92ab73a35b29a8c719f1ec207562837) --- source4/libcli/raw/rawnegotiate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 9b00aa6121..dab7b38939 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -86,7 +86,7 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) struct smbcli_request *req; int protocol; - req = smb_negprot_send(transport, PROTOCOL_NT1); + req = smb_negprot_send(transport, lp_maxprotocol()); if (!req) { return NT_STATUS_UNSUCCESSFUL; } -- cgit From 06cf56bc1dd75bc3fd47ec7c100c42a8aa4b23ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 Aug 2004 04:28:00 +0000 Subject: r1685: Add the ability to lookup RPC auth types for the RPC-MGMT torture test. Andrew Bartlett (This used to be commit 0e4e3647e848605416fe79c742ac84d84dc4357c) --- source4/libcli/auth/gensec.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index e91497bee4..d635378117 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -212,6 +212,17 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, return gensec_start_mech(gensec_security); } +const char *gensec_get_name_by_authtype(uint8_t authtype) +{ + const struct gensec_security_ops *ops; + ops = gensec_security_by_authtype(authtype); + if (ops) { + return ops->name; + } + return NULL; +} + + /** * Start a GENSEC sub-mechanism by OID, used in SPNEGO * -- cgit From 6ffaf57fe715419bf3aa677027548161b642d17e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 Aug 2004 04:38:03 +0000 Subject: r1686: Don't use a void* for the context inside the SMB signing code. Andrew Bartlett (This used to be commit 64fcd8ecebabdd09fed6b65e3c436bffc1da9de7) --- source4/libcli/raw/smb_signing.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index ddde58fd88..ffbecb85fc 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -22,11 +22,6 @@ #include "includes.h" -struct smb_basic_signing_context { - DATA_BLOB mac_key; - uint32_t next_seq_num; -}; - /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ -- cgit From 7a523b2bc443c7031336d5afd6b6a884ba0e0fab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Aug 2004 23:06:59 +0000 Subject: r1712: this should fix a bug with a spinning client when a server dies unexpectedly. bug found by abartlett. (This used to be commit 566b7a9ce986cdfeabb69f17c472782fc7494d43) --- source4/libcli/raw/clitransport.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 5290dd953d..784a6f1798 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -433,6 +433,10 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) transport->recv_buffer.header + transport->recv_buffer.received, NBT_HDR_SIZE - transport->recv_buffer.received); + if (ret == 0) { + smbcli_transport_dead(transport); + return; + } if (ret == -1) { if (errno == EINTR || errno == EAGAIN) { return; -- cgit From 8ed563cfbbe3921a7a07479a50de85fcf71cd41a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Aug 2004 16:09:54 +0000 Subject: r1723: Make sure we bail out on error in reading a OID. Andrew Bartlett (This used to be commit 6da7b65851aa4932aab56d1ab0f8fc67ccb62cdf) --- source4/libcli/util/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index da51340774..dcafb261ee 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -354,7 +354,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) oid = talloc_asprintf(mem_ctx, "%u", b/40); oid = talloc_asprintf_append(mem_ctx, oid, " %u", b%40); - while (asn1_tag_remaining(data) > 0) { + while (!data->has_error && asn1_tag_remaining(data) > 0) { uint_t v = 0; do { asn1_read_uint8(data, &b); -- cgit From 1bcd36ed8ac4cb748f80d75c3f3b9c33fb474a8d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Aug 2004 16:13:25 +0000 Subject: r1724: Add a new function to return the list of available OIDs. (Used in our SPNEGO code). Andrew Bartlett (This used to be commit c91d6b6f9b53e64069fd5860f677bc1b4c250f0c) --- source4/libcli/auth/gensec.c | 48 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index d635378117..3db6002639 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -25,12 +25,12 @@ /* the list of currently registered GENSEC backends */ const static struct gensec_security_ops **generic_security_ops; -static int num_backends; +static int gensec_num_backends; static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) { int i; - for (i=0; i < num_backends; i++) { + for (i=0; i < gensec_num_backends; i++) { if (generic_security_ops[i]->auth_type == auth_type) { return generic_security_ops[i]; } @@ -42,7 +42,7 @@ static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t aut static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_string) { int i; - for (i=0; i < num_backends; i++) { + for (i=0; i < gensec_num_backends; i++) { if (generic_security_ops[i]->oid && (strcmp(generic_security_ops[i]->oid, oid_string) == 0)) { return generic_security_ops[i]; @@ -55,7 +55,7 @@ static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_ static const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) { int i; - for (i=0; i < num_backends; i++) { + for (i=0; i < gensec_num_backends; i++) { if (generic_security_ops[i]->sasl_name && (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) { return generic_security_ops[i]; @@ -68,7 +68,7 @@ static const struct gensec_security_ops *gensec_security_by_sasl_name(const char static const struct gensec_security_ops *gensec_security_by_name(const char *name) { int i; - for (i=0; i < num_backends; i++) { + for (i=0; i < gensec_num_backends; i++) { if (generic_security_ops[i]->name && (strcmp(generic_security_ops[i]->name, name) == 0)) { return generic_security_ops[i]; @@ -80,10 +80,40 @@ static const struct gensec_security_ops *gensec_security_by_name(const char *nam const struct gensec_security_ops **gensec_security_all(int *num_backends_out) { - *num_backends_out = num_backends; + *num_backends_out = gensec_num_backends; return generic_security_ops; } +const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) +{ + int i, j = 0; + const char **oid_list; + int num_backends; + const struct gensec_security_ops **ops = gensec_security_all(&num_backends); + if (!ops) { + return NULL; + } + oid_list = talloc_array_p(mem_ctx, const char *, num_backends + 1); + if (!oid_list) { + return NULL; + } + + for (i=0; ioid) { + continue; + } + + if (skip && strcmp(skip, ops[i]->oid)==0) { + continue; + } + + oid_list[j] = ops[i]->oid; + j++; + } + oid_list[j] = NULL; + return oid_list; +} + static NTSTATUS gensec_start(struct gensec_security **gensec_security) { TALLOC_CTX *mem_ctx; @@ -643,14 +673,14 @@ static NTSTATUS gensec_register(const void *_ops) return NT_STATUS_OBJECT_NAME_COLLISION; } - generic_security_ops = Realloc(generic_security_ops, sizeof(generic_security_ops[0]) * (num_backends+1)); + generic_security_ops = Realloc(generic_security_ops, sizeof(generic_security_ops[0]) * (gensec_num_backends+1)); if (!generic_security_ops) { smb_panic("out of memory in gensec_register"); } - generic_security_ops[num_backends] = ops; + generic_security_ops[gensec_num_backends] = ops; - num_backends++; + gensec_num_backends++; DEBUG(3,("GENSEC backend '%s' registered\n", ops->name)); -- cgit From 5a79e6cf484cd27092217a8e739e6d79bb8b12e9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Aug 2004 16:15:21 +0000 Subject: r1725: Remove a silly 'utility' function. Andrew Bartlett (This used to be commit 4d563d7e4afad1c5f583aca3f42087bfff0fb895) --- source4/libcli/raw/smb_signing.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index ffbecb85fc..b65513ebce 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -50,20 +50,6 @@ static BOOL set_smb_signing_common(struct smbcli_transport *transport) return True; } -/*********************************************************** - SMB signing - Common code for 'real' implementations -************************************************************/ -static BOOL set_smb_signing_real_common(struct smbcli_transport *transport) -{ - if (transport->negotiate.sign_info.mandatory_signing) { - DEBUG(5, ("Mandatory SMB signing enabled!\n")); - } - - DEBUG(5, ("SMB signing enabled!\n")); - - return True; -} - static void mark_packet_signed(struct request_buffer *out) { uint16_t flags2; @@ -268,10 +254,12 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, return False; } - if (!set_smb_signing_real_common(transport)) { - return False; + if (transport->negotiate.sign_info.mandatory_signing) { + DEBUG(5, ("Mandatory SMB signing enabled!\n")); } + DEBUG(5, ("SMB signing enabled!\n")); + data = smb_xmalloc(sizeof(*data)); transport->negotiate.sign_info.signing_context = data; -- cgit From d9ff454a87410d4756cd61612bfb4aa768301be5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Aug 2004 18:05:30 +0000 Subject: r1729: Make the SMB signing code more generic (to share more between client and servers). Andrew Bartlett (This used to be commit b90b04e84bc8add235cf9ee7797a608ff48c4ca0) --- source4/libcli/raw/smb_signing.c | 99 +++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 42 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index b65513ebce..c1fad1eaf8 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -41,7 +41,8 @@ static BOOL set_smb_signing_common(struct smbcli_transport *transport) } if (transport->negotiate.sign_info.free_signing_context) - transport->negotiate.sign_info.free_signing_context(transport); + transport->negotiate.sign_info + .free_signing_context(&transport->negotiate.sign_info); /* These calls are INCOMPATIBLE with SMB signing */ transport->negotiate.readbraw_supported = False; @@ -58,26 +59,27 @@ static void mark_packet_signed(struct request_buffer *out) SSVAL(out->hdr, HDR_FLG2, flags2); } -static BOOL signing_good(struct smbcli_request *req, unsigned int seq, BOOL good) +static BOOL signing_good(struct smb_signing_context *sign_info, + unsigned int seq, BOOL good) { if (good) { - if (!req->transport->negotiate.sign_info.doing_signing) { - req->transport->negotiate.sign_info.doing_signing = True; + if (!sign_info->doing_signing) { + sign_info->doing_signing = True; } - if (!req->transport->negotiate.sign_info.seen_valid) { - req->transport->negotiate.sign_info.seen_valid = True; + if (!sign_info->seen_valid) { + sign_info->seen_valid = True; } } else { - if (!req->transport->negotiate.sign_info.seen_valid) { + if (!sign_info->seen_valid) { /* If we have never seen a good packet, just turn it off */ DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); - req->transport->negotiate.sign_info.negotiated_smb_signing = False; - req->transport->negotiate.sign_info.allow_smb_signing = False; - req->transport->negotiate.sign_info.doing_signing = False; - if (req->transport->negotiate.sign_info.free_signing_context) - req->transport->negotiate.sign_info.free_signing_context(req->transport); - smbcli_null_set_signing(req->transport); + sign_info->negotiated_smb_signing = False; + sign_info->allow_smb_signing = False; + sign_info->doing_signing = False; + if (sign_info->free_signing_context) + sign_info->free_signing_context(sign_info); + smbcli_null_set_signing(sign_info); return True; } else { /* bad packet after signing started - fail and disconnect. */ @@ -223,45 +225,41 @@ static BOOL smbcli_request_simple_check_incoming_message(struct smbcli_request * &data->mac_key, req->seq_num+1); - return signing_good(req, req->seq_num+1, good); + return signing_good(&req->transport->negotiate.sign_info, + req->seq_num+1, good); } /*********************************************************** SMB signing - Simple implementation - free signing context ************************************************************/ -static void smbcli_transport_simple_free_signing_context(struct smbcli_transport *transport) +static void smbcli_transport_simple_free_signing_context(struct smb_signing_context *sign_info) { - struct smb_basic_signing_context *data = transport->negotiate.sign_info.signing_context; + struct smb_basic_signing_context *data = sign_info->signing_context; data_blob_free(&data->mac_key); - SAFE_FREE(transport->negotiate.sign_info.signing_context); + SAFE_FREE(sign_info->signing_context); return; } - /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, - const DATA_BLOB user_session_key, - const DATA_BLOB response) +BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, + const DATA_BLOB user_session_key, + const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!set_smb_signing_common(transport)) { - return False; - } - - if (transport->negotiate.sign_info.mandatory_signing) { + if (sign_info->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); } DEBUG(5, ("SMB signing enabled!\n")); data = smb_xmalloc(sizeof(*data)); - transport->negotiate.sign_info.signing_context = data; + sign_info->signing_context = data; data->mac_key = data_blob(NULL, response.length + user_session_key.length); @@ -276,14 +274,31 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, /* Initialise the sequence number */ data->next_seq_num = 0; - transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_simple_sign_outgoing_message; - transport->negotiate.sign_info.check_incoming_message = smbcli_request_simple_check_incoming_message; - transport->negotiate.sign_info.free_signing_context = smbcli_transport_simple_free_signing_context; + sign_info->sign_outgoing_message = smbcli_request_simple_sign_outgoing_message; + sign_info->check_incoming_message = smbcli_request_simple_check_incoming_message; + sign_info->free_signing_context = smbcli_transport_simple_free_signing_context; return True; } +/*********************************************************** + SMB signing - Simple implementation - setup the MAC key. +************************************************************/ +BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, + const DATA_BLOB user_session_key, + const DATA_BLOB response) +{ + if (!set_smb_signing_common(transport)) { + return False; + } + + return smbcli_simple_set_signing(&transport->negotiate.sign_info, + user_session_key, + response); +} + + /*********************************************************** SMB signing - NULL implementation - calculate a MAC to send. ************************************************************/ @@ -307,7 +322,7 @@ static BOOL smbcli_request_null_check_incoming_message(struct smbcli_request *re /*********************************************************** SMB signing - NULL implementation - free signing context ************************************************************/ -static void smbcli_null_free_signing_context(struct smbcli_transport *transport) +static void smbcli_null_free_signing_context(struct smb_signing_context *sign_info) { } @@ -317,13 +332,13 @@ static void smbcli_null_free_signing_context(struct smbcli_transport *transport) @note Used as an initialisation only - it will not correctly shut down a real signing mechanism */ -BOOL smbcli_null_set_signing(struct smbcli_transport *transport) +BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) { - transport->negotiate.sign_info.signing_context = NULL; + sign_info->signing_context = NULL; - transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_null_sign_outgoing_message; - transport->negotiate.sign_info.check_incoming_message = smbcli_request_null_check_incoming_message; - transport->negotiate.sign_info.free_signing_context = smbcli_null_free_signing_context; + sign_info->sign_outgoing_message = smbcli_request_null_sign_outgoing_message; + sign_info->check_incoming_message = smbcli_request_null_check_incoming_message; + sign_info->free_signing_context = smbcli_null_free_signing_context; return True; } @@ -354,7 +369,7 @@ static BOOL smbcli_request_temp_check_incoming_message(struct smbcli_request *re /*********************************************************** SMB signing - NULL implementation - free signing context ************************************************************/ -static void smbcli_temp_free_signing_context(struct smbcli_transport *transport) +static void smbcli_temp_free_signing_context(struct smb_signing_context *sign_info) { return; } @@ -383,13 +398,13 @@ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) /** * Free the signing context */ -void smbcli_transport_free_signing_context(struct smbcli_transport *transport) +void smbcli_transport_free_signing_context(struct smb_signing_context *sign_info) { - if (transport->negotiate.sign_info.free_signing_context) { - transport->negotiate.sign_info.free_signing_context(transport); + if (sign_info->free_signing_context) { + sign_info->free_signing_context(sign_info); } - smbcli_null_set_signing(transport); + smbcli_null_set_signing(sign_info); } @@ -427,7 +442,7 @@ BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) BOOL smbcli_init_signing(struct smbcli_transport *transport) { - if (!smbcli_null_set_signing(transport)) { + if (!smbcli_null_set_signing(&transport->negotiate.sign_info)) { return False; } -- cgit From 1c9216f36cc451156d6c65f0e971ce48f05da3e5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Aug 2004 18:09:40 +0000 Subject: r1731: Add server-side SPNEGO support to Samba (disabled, until SMB signing is reworked). Andrew Bartlett (This used to be commit 73ee549b8c54e93556ff0105941996e0d4de8303) --- source4/libcli/auth/spnego.c | 310 +++++++++++++++++++++++++++++-------------- 1 file changed, 207 insertions(+), 103 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 23f0b1c070..6a8b858f91 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -66,6 +66,28 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi return NT_STATUS_OK; } +static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_security) +{ + struct spnego_state *spnego_state; + TALLOC_CTX *mem_ctx = talloc_init("gensec_spnego_server_start"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + spnego_state = talloc_p(mem_ctx, struct spnego_state); + + if (!spnego_state) { + return NT_STATUS_NO_MEMORY; + } + + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; + spnego_state->state_position = SPNEGO_SERVER_START; + spnego_state->mem_ctx = mem_ctx; + spnego_state->sub_sec_security = NULL; + + gensec_security->private_data = spnego_state; + return NT_STATUS_OK; +} + /* wrappers for the spnego_*() functions */ @@ -146,6 +168,18 @@ static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_securit session_key); } +static NTSTATUS gensec_spnego_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info) +{ + struct spnego_state *spnego_state = gensec_security->private_data; + if (!spnego_state->sub_sec_security) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_session_info(spnego_state->sub_sec_security, + session_info); +} + /** Fallback to another GENSEC mechanism, based on magic strings * * This is the 'fallback' case, where we don't get SPNEGO, and have to @@ -191,22 +225,69 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec } -/** create a client netTokenInit +static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_security, + struct spnego_state *spnego_state, + TALLOC_CTX *out_mem_ctx, + const char **mechType, + const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) +{ + int i; + NTSTATUS nt_status; + DATA_BLOB null_data_blob = data_blob(NULL,0); + + for (i=0; mechType && mechType[i]; i++) { + nt_status = gensec_subcontext_start(gensec_security, + &spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + break; + } + /* select the sub context */ + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechType[i]); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); + continue; + } + + if (i == 0) { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + unwrapped_in, + unwrapped_out); + } else { + /* only get the helping start blob for the first OID */ + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + unwrapped_out); + } + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { + DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + gensec_end(&spnego_state->sub_sec_security); + } else { + break; + } + } + if (!mechType || !mechType[i]) { + DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + } + return nt_status; +} + +/** create a client negTokenInit * * This is the case, where the client is the first one who sends data */ -static NTSTATUS gensec_spnego_client_netTokenInit(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec_security, struct spnego_state *spnego_state, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { NTSTATUS nt_status; - int i; int num_ops; - char **mechTypes = NULL; - const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); - DATA_BLOB null_data_blob = data_blob(NULL,0); + const char **mechTypes = NULL; DATA_BLOB unwrapped_out = data_blob(NULL,0); if (num_ops < 1) { @@ -214,31 +295,13 @@ static NTSTATUS gensec_spnego_client_netTokenInit(struct gensec_security *gensec return NT_STATUS_INVALID_PARAMETER; } - /* build a mechTypes list we want to offer */ - for (i=0; i < num_ops; i++) { - if (!all_ops[i]->oid) { - continue; - } - - /* skip SPNEGO itself */ - if (strcmp(OID_SPNEGO,all_ops[i]->oid)==0) { - continue; - } - - mechTypes = talloc_realloc_p(out_mem_ctx, mechTypes, char *, i+2); - if (!mechTypes) { - DEBUG(1, ("talloc_realloc_p(out_mem_ctx, mechTypes, char *, i+1) failed\n")); - return NT_STATUS_NO_MEMORY; - } - - mechTypes[i] = all_ops[i]->oid; - mechTypes[i+1] = NULL; - } + mechTypes = gensec_security_oids(out_mem_ctx, OID_SPNEGO); if (!mechTypes) { DEBUG(1, ("no GENSEC OID backends available\n")); return NT_STATUS_INVALID_PARAMETER; } + DATA_BLOB null_data_blob = data_blob(NULL,0); nt_status = gensec_subcontext_start(gensec_security, &spnego_state->sub_sec_security); @@ -278,6 +341,53 @@ static NTSTATUS gensec_spnego_client_netTokenInit(struct gensec_security *gensec return NT_STATUS_INVALID_PARAMETER; } + +/** create a client negTokenTarg + * + * This is the case, where the client is the first one who sends data +*/ + +static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec_security, + struct spnego_state *spnego_state, + TALLOC_CTX *out_mem_ctx, + NTSTATUS nt_status, + const DATA_BLOB unwrapped_out, DATA_BLOB *out) +{ + struct spnego_data spnego_out; + DATA_BLOB null_data_blob = data_blob(NULL, 0); + + /* compose reply */ + spnego_out.type = SPNEGO_NEG_TOKEN_TARG; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; + spnego_out.negTokenTarg.responseToken = unwrapped_out; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; + + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego_state->state_position = SPNEGO_SERVER_TARG; + } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; + spnego_state->state_position = SPNEGO_DONE; + } else { + spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; + DEBUG(1, ("SPNEGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); + spnego_state->state_position = SPNEGO_DONE; + } + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + + return nt_status; +} + + static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { @@ -289,6 +399,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA ssize_t len; + *out = data_blob(NULL, 0); + if (!out_mem_ctx) { out_mem_ctx = spnego_state->mem_ctx; } @@ -302,30 +414,72 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA case SPNEGO_SERVER_START: { if (in.length) { + NTSTATUS nt_status; + len = spnego_read_data(in, &spnego); if (len == -1) { return gensec_spnego_server_try_fallback(gensec_security, spnego_state, out_mem_ctx, in, out); - } else { - /* client sent NegTargetInit */ } + /* client sent NegTargetInit, we send NegTokenTarg */ + + /* OK, so it's real SPNEGO, check the packet's the one we expect */ + if (spnego.type != spnego_state->expected_packet) { + DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, + spnego_state->expected_packet)); + dump_data(1, (const char *)in.data, in.length); + spnego_free_data(&spnego); + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_spnego_parse_negTokenInit(gensec_security, + spnego_state, + out_mem_ctx, + spnego.negTokenInit.mechTypes, + spnego.negTokenInit.mechToken, + &unwrapped_out); + + nt_status = gensec_spnego_server_negTokenTarg(gensec_security, + spnego_state, + out_mem_ctx, + nt_status, + unwrapped_out, + out); + + spnego_free_data(&spnego); + + return nt_status; } else { - /* server needs to send NegTargetInit */ + const char **mechlist = gensec_security_oids(out_mem_ctx, OID_SPNEGO); + + spnego_out.type = SPNEGO_NEG_TOKEN_INIT; + spnego_out.negTokenInit.mechTypes = mechlist; + spnego_out.negTokenInit.reqFlags = 0; + spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechToken = unwrapped_out; + + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { + DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* set next state */ + spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->state_position = SPNEGO_SERVER_TARG; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; } - return NT_STATUS_INVALID_PARAMETER; } case SPNEGO_CLIENT_START: { /* The server offers a list of mechanisms */ - char **mechType; char *my_mechs[] = {NULL, NULL}; - int i; NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; if (!in.length) { /* client to produce negTokenInit */ - return gensec_spnego_client_netTokenInit(gensec_security, spnego_state, out_mem_ctx, in, out); + return gensec_spnego_client_negTokenInit(gensec_security, spnego_state, out_mem_ctx, in, out); } len = spnego_read_data(in, &spnego); @@ -354,50 +508,17 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } } - mechType = spnego.negTokenInit.mechTypes; - for (i=0; mechType && mechType[i]; i++) { - nt_status = gensec_subcontext_start(gensec_security, - &spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - break; - } - /* select the sub context */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechType[i]); - if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); - continue; - } - - if (i == 0) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenInit.mechToken, - &unwrapped_out); - } else { - /* only get the helping start blob for the first OID */ - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - &unwrapped_out); - } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", - spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - gensec_end(&spnego_state->sub_sec_security); - } else { - break; - } - } - if (!mechType || !mechType[i]) { - DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); - } - - spnego_free_data(&spnego); + nt_status = gensec_spnego_parse_negTokenInit(gensec_security, + spnego_state, + out_mem_ctx, + spnego.negTokenInit.mechTypes, + spnego.negTokenInit.mechToken, + &unwrapped_out); + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { return nt_status; } - + /* compose reply */ my_mechs[0] = spnego_state->sub_sec_security->ops->oid; @@ -441,40 +562,21 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } - + nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, - spnego.negTokenTarg.responseToken, + spnego.negTokenTarg.responseToken, &unwrapped_out); - + + nt_status = gensec_spnego_server_negTokenTarg(gensec_security, + spnego_state, + out_mem_ctx, + nt_status, + unwrapped_out, + out); + spnego_free_data(&spnego); - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_state->state_position = SPNEGO_SERVER_TARG; - } else if (NT_STATUS_IS_OK(nt_status)) { - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; - spnego_state->state_position = SPNEGO_DONE; - } else { - spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; - DEBUG(1, ("SPNEGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); - spnego_state->state_position = SPNEGO_DONE; - } - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } - return nt_status; } case SPNEGO_CLIENT_TARG: @@ -584,12 +686,14 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .auth_type = DCERPC_AUTH_TYPE_SPNEGO, .oid = OID_SPNEGO, .client_start = gensec_spnego_client_start, + .server_start = gensec_spnego_server_start, .update = gensec_spnego_update, .seal_packet = gensec_spnego_seal_packet, .sign_packet = gensec_spnego_sign_packet, .check_packet = gensec_spnego_check_packet, .unseal_packet = gensec_spnego_unseal_packet, .session_key = gensec_spnego_session_key, + .session_info = gensec_spnego_session_info, .end = gensec_spnego_end }; -- cgit From ca72bdfecbea2e332821bc292b4bb34f6c96ac2e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Aug 2004 19:29:22 +0000 Subject: r1735: Clean up SMB signing - we don't have more than one 'real' way to sign a packet, so don't pretend we do... Andrew Bartlett (This used to be commit 68a6d5aeb35e8972182fffbb6cc506f89584b2d5) --- source4/libcli/raw/smb_signing.c | 45 +++++++++++++--------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index c1fad1eaf8..adfccda65a 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -74,7 +74,6 @@ static BOOL signing_good(struct smb_signing_context *sign_info, /* If we have never seen a good packet, just turn it off */ DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); - sign_info->negotiated_smb_signing = False; sign_info->allow_smb_signing = False; sign_info->doing_signing = False; if (sign_info->free_signing_context) @@ -191,25 +190,25 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key ************************************************************/ static void smbcli_request_simple_sign_outgoing_message(struct smbcli_request *req) { - struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context; - #if 0 /* enable this when packet signing is preventing you working out why valgrind says that data is uninitialised */ file_save("pkt.dat", req->out.buffer, req->out.size); #endif - req->seq_num = data->next_seq_num; + req->seq_num = req->transport->negotiate.sign_info.next_seq_num; /* some requests (eg. NTcancel) are one way, and the sequence number should be increased by 1 not 2 */ if (req->sign_single_increment) { - data->next_seq_num += 1; + req->transport->negotiate.sign_info.next_seq_num += 1; } else { - data->next_seq_num += 2; + req->transport->negotiate.sign_info.next_seq_num += 2; } - sign_outgoing_message(&req->out, &data->mac_key, req->seq_num); + sign_outgoing_message(&req->out, + &req->transport->negotiate.sign_info.mac_key, + req->seq_num); } @@ -218,11 +217,8 @@ static void smbcli_request_simple_sign_outgoing_message(struct smbcli_request *r ************************************************************/ static BOOL smbcli_request_simple_check_incoming_message(struct smbcli_request *req) { - struct smb_basic_signing_context *data - = req->transport->negotiate.sign_info.signing_context; - BOOL good = check_signed_incoming_message(&req->in, - &data->mac_key, + &req->transport->negotiate.sign_info.mac_key, req->seq_num+1); return signing_good(&req->transport->negotiate.sign_info, @@ -235,11 +231,7 @@ static BOOL smbcli_request_simple_check_incoming_message(struct smbcli_request * ************************************************************/ static void smbcli_transport_simple_free_signing_context(struct smb_signing_context *sign_info) { - struct smb_basic_signing_context *data = sign_info->signing_context; - - data_blob_free(&data->mac_key); - SAFE_FREE(sign_info->signing_context); - + data_blob_free(&sign_info->mac_key); return; } @@ -250,29 +242,24 @@ BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, const DATA_BLOB user_session_key, const DATA_BLOB response) { - struct smb_basic_signing_context *data; - if (sign_info->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); } DEBUG(5, ("SMB signing enabled!\n")); - data = smb_xmalloc(sizeof(*data)); - sign_info->signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); + sign_info->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); + memcpy(&sign_info->mac_key.data[0], user_session_key.data, user_session_key.length); if (response.length) { - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + memcpy(&sign_info->mac_key.data[user_session_key.length],response.data, response.length); } - dump_data_pw("Started Signing with key:\n", data->mac_key.data, data->mac_key.length); + dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length); /* Initialise the sequence number */ - data->next_seq_num = 0; + sign_info->next_seq_num = 0; sign_info->sign_outgoing_message = smbcli_request_simple_sign_outgoing_message; sign_info->check_incoming_message = smbcli_request_simple_check_incoming_message; @@ -334,8 +321,6 @@ static void smbcli_null_free_signing_context(struct smb_signing_context *sign_in */ BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) { - sign_info->signing_context = NULL; - sign_info->sign_outgoing_message = smbcli_request_null_sign_outgoing_message; sign_info->check_incoming_message = smbcli_request_null_check_incoming_message; sign_info->free_signing_context = smbcli_null_free_signing_context; @@ -344,7 +329,7 @@ BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) } /*********************************************************** - SMB signing - TEMP implementation - calculate a MAC to send. + SMB signing - TEMP implementation (send BSRSPYL during SPNEGO) - calculate a MAC to send. ************************************************************/ static void smbcli_request_temp_sign_outgoing_message(struct smbcli_request *req) { @@ -386,8 +371,6 @@ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) return False; } - transport->negotiate.sign_info.signing_context = NULL; - transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_temp_sign_outgoing_message; transport->negotiate.sign_info.check_incoming_message = smbcli_request_temp_check_incoming_message; transport->negotiate.sign_info.free_signing_context = smbcli_temp_free_signing_context; -- cgit From daa4a722f9623e057981c01efdb9d831a174a53c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Aug 2004 21:06:11 +0000 Subject: r1737: don't segfault when a mech don't have a session_info hook metze (This used to be commit 68f3e538265b59ec818917b914678485585795a6) --- source4/libcli/auth/gensec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 3db6002639..24c2c18877 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -355,6 +355,9 @@ NTSTATUS gensec_session_key(struct gensec_security *gensec_security, NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info) { + if (!gensec_security->ops->session_info) { + return NT_STATUS_NOT_IMPLEMENTED; + } return gensec_security->ops->session_info(gensec_security, session_info); } -- cgit From b3e7722a88cec3ffdc937effbeff149b8353df72 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 11 Aug 2004 21:09:36 +0000 Subject: r1738: honor the "unicode=yes/no" option in the SMB client library (This used to be commit b6664bdd0f4125a483620b76a87ea69cad866d6a) --- source4/libcli/raw/rawnegotiate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index dab7b38939..5ec827eebb 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -53,7 +53,9 @@ struct smbcli_request *smb_negprot_send(struct smbcli_transport *transport, int } flags2 |= FLAGS2_32_BIT_ERROR_CODES; - flags2 |= FLAGS2_UNICODE_STRINGS; + if (lp_unicode()) { + flags2 |= FLAGS2_UNICODE_STRINGS; + } flags2 |= FLAGS2_EXTENDED_ATTRIBUTES; flags2 |= FLAGS2_LONG_PATH_COMPONENTS; flags2 |= FLAGS2_IS_LONG_NAME; @@ -172,7 +174,7 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) } /* a way to force ascii SMB */ - if (getenv("SMBCLI_FORCE_ASCII")) { + if (!lp_unicode() || getenv("SMBCLI_FORCE_ASCII")) { transport->negotiate.capabilities &= ~CAP_UNICODE; } -- cgit From 44e04cdb11a87ae78cabd76c61e11ae1f283dfaa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 11 Aug 2004 21:10:16 +0000 Subject: r1739: fixed the padding in setpathinfo, noticed when forcing negotiated ascii strings (This used to be commit fc75dc49025f4beb0f1df656cfe4ec497e693dcc) --- source4/libcli/raw/rawsetfileinfo.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index b1667db50f..2b525f2661 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -164,10 +164,10 @@ static struct smbcli_request *smb_raw_setfileinfo_blob_send(struct smbcli_tree * Very raw set path info - takes data blob ****************************************************************************/ static struct smbcli_request *smb_raw_setpathinfo_blob_send(struct smbcli_tree *tree, - TALLOC_CTX *mem_ctx, - const char *fname, - uint16_t info_level, - DATA_BLOB *blob) + TALLOC_CTX *mem_ctx, + const char *fname, + uint16_t info_level, + DATA_BLOB *blob) { struct smb_trans2 tp; uint16_t setup = TRANSACT2_SETPATHINFO; @@ -180,15 +180,15 @@ static struct smbcli_request *smb_raw_setpathinfo_blob_send(struct smbcli_tree * tp.in.max_data = 0; tp.in.setup = &setup; - tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); + tp.in.params = data_blob_talloc(mem_ctx, NULL, 6); if (!tp.in.params.data) { return NULL; } SSVAL(tp.in.params.data, 0, info_level); - SSVAL(tp.in.params.data, 2, 0); + SIVAL(tp.in.params.data, 2, 0); smbcli_blob_append_string(tree->session, mem_ctx, - &tp.in.params, - fname, STR_TERMINATE); + &tp.in.params, + fname, STR_TERMINATE); tp.in.data = *blob; -- cgit From ffcfb97fb3d065e8c37d7f2de8b688d1e570a47b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Aug 2004 00:04:52 +0000 Subject: r1745: More work on cleaning up SMB signing. This removes the function pointer mess from the SMB signing code. Andrew Bartlett (This used to be commit 8830603e4bc821a11db87072a32a51b076a28e06) --- source4/libcli/raw/smb_signing.c | 288 +++++++++++++++------------------------ 1 file changed, 109 insertions(+), 179 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index adfccda65a..03794829c2 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -21,6 +21,8 @@ */ #include "includes.h" +static void smbcli_free_signing_context(struct smb_signing_context *sign_info); +static BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info); /*********************************************************** SMB signing - Common code before we set a new signing implementation @@ -40,9 +42,7 @@ static BOOL set_smb_signing_common(struct smbcli_transport *transport) return False; } - if (transport->negotiate.sign_info.free_signing_context) - transport->negotiate.sign_info - .free_signing_context(&transport->negotiate.sign_info); + smbcli_free_signing_context(&transport->negotiate.sign_info); /* These calls are INCOMPATIBLE with SMB signing */ transport->negotiate.readbraw_supported = False; @@ -74,10 +74,9 @@ static BOOL signing_good(struct smb_signing_context *sign_info, /* If we have never seen a good packet, just turn it off */ DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); - sign_info->allow_smb_signing = False; sign_info->doing_signing = False; - if (sign_info->free_signing_context) - sign_info->free_signing_context(sign_info); + smbcli_free_signing_context(sign_info); + smbcli_null_set_signing(sign_info); return True; } else { @@ -188,7 +187,7 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key /*********************************************************** SMB signing - Simple implementation - calculate a MAC to send. ************************************************************/ -static void smbcli_request_simple_sign_outgoing_message(struct smbcli_request *req) +void smbcli_request_calculate_sign_mac(struct smbcli_request *req) { #if 0 /* enable this when packet signing is preventing you working out why valgrind @@ -196,51 +195,121 @@ static void smbcli_request_simple_sign_outgoing_message(struct smbcli_request *r file_save("pkt.dat", req->out.buffer, req->out.size); #endif - req->seq_num = req->transport->negotiate.sign_info.next_seq_num; - - /* some requests (eg. NTcancel) are one way, and the sequence number - should be increased by 1 not 2 */ - if (req->sign_single_increment) { - req->transport->negotiate.sign_info.next_seq_num += 1; - } else { - req->transport->negotiate.sign_info.next_seq_num += 2; + switch (req->transport->negotiate.sign_info.signing_state) { + case SMB_SIGNING_ENGINE_OFF: + break; + + case SMB_SIGNING_ENGINE_BSRSPYL: + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(&req->out); + + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8); + break; + + case SMB_SIGNING_ENGINE_ON: + + req->seq_num = req->transport->negotiate.sign_info.next_seq_num; + + /* some requests (eg. NTcancel) are one way, and the sequence number + should be increased by 1 not 2 */ + if (req->sign_single_increment) { + req->transport->negotiate.sign_info.next_seq_num += 1; + } else { + req->transport->negotiate.sign_info.next_seq_num += 2; + } + + sign_outgoing_message(&req->out, + &req->transport->negotiate.sign_info.mac_key, + req->seq_num); + break; } - - sign_outgoing_message(&req->out, - &req->transport->negotiate.sign_info.mac_key, - req->seq_num); + return; } -/*********************************************************** - SMB signing - Simple implementation - check a MAC sent by server. -************************************************************/ -static BOOL smbcli_request_simple_check_incoming_message(struct smbcli_request *req) +/** + SMB signing - NULL implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ +static BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) { - BOOL good = check_signed_incoming_message(&req->in, - &req->transport->negotiate.sign_info.mac_key, - req->seq_num+1); - - return signing_good(&req->transport->negotiate.sign_info, - req->seq_num+1, good); + sign_info->mac_key = data_blob(NULL, 0); + sign_info->signing_state = SMB_SIGNING_ENGINE_OFF; + return True; } +/** + SMB signing - TEMP implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ +BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) +{ + if (!set_smb_signing_common(transport)) { + return False; + } + + transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); + transport->negotiate.sign_info.signing_state = SMB_SIGNING_ENGINE_BSRSPYL; + + return True; +} + +/** + * Free the signing context + */ +static void smbcli_free_signing_context(struct smb_signing_context *sign_info) +{ + data_blob_free(&sign_info->mac_key); + smbcli_null_set_signing(sign_info); +} /*********************************************************** - SMB signing - Simple implementation - free signing context + SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ -static void smbcli_transport_simple_free_signing_context(struct smb_signing_context *sign_info) +/** + * Check a packet supplied by the server. + * @return False if we had an established signing connection + * which had a back checksum, True otherwise + */ +BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) { - data_blob_free(&sign_info->mac_key); - return; + BOOL good; + + switch (req->transport->negotiate.sign_info.signing_state) + { + case SMB_SIGNING_ENGINE_OFF: + return True; + case SMB_SIGNING_ENGINE_BSRSPYL: + case SMB_SIGNING_ENGINE_ON: + { + if (req->in.size < (HDR_SS_FIELD + 8)) { + return False; + } else { + good = check_signed_incoming_message(&req->in, + &req->transport->negotiate.sign_info.mac_key, + req->seq_num+1); + + return signing_good(&req->transport->negotiate.sign_info, + req->seq_num+1, good); + } + } + } + return False; } + /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, - const DATA_BLOB user_session_key, - const DATA_BLOB response) +static BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, + const DATA_BLOB user_session_key, + const DATA_BLOB response) { if (sign_info->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -261,9 +330,7 @@ BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, /* Initialise the sequence number */ sign_info->next_seq_num = 0; - sign_info->sign_outgoing_message = smbcli_request_simple_sign_outgoing_message; - sign_info->check_incoming_message = smbcli_request_simple_check_incoming_message; - sign_info->free_signing_context = smbcli_transport_simple_free_signing_context; + sign_info->signing_state = SMB_SIGNING_ENGINE_ON; return True; } @@ -273,8 +340,8 @@ BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, SMB signing - Simple implementation - setup the MAC key. ************************************************************/ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, - const DATA_BLOB user_session_key, - const DATA_BLOB response) + const DATA_BLOB user_session_key, + const DATA_BLOB response) { if (!set_smb_signing_common(transport)) { return False; @@ -286,143 +353,6 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, } -/*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. -************************************************************/ -static void smbcli_request_null_sign_outgoing_message(struct smbcli_request *req) -{ - /* we can't zero out the sig, as we might be trying to send a - transport request - which is NBT-level, not SMB level and doesn't - have the field */ -} - - -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ -static BOOL smbcli_request_null_check_incoming_message(struct smbcli_request *req) -{ - return True; -} - - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ -static void smbcli_null_free_signing_context(struct smb_signing_context *sign_info) -{ -} - -/** - SMB signing - NULL implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ -BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) -{ - sign_info->sign_outgoing_message = smbcli_request_null_sign_outgoing_message; - sign_info->check_incoming_message = smbcli_request_null_check_incoming_message; - sign_info->free_signing_context = smbcli_null_free_signing_context; - - return True; -} - -/*********************************************************** - SMB signing - TEMP implementation (send BSRSPYL during SPNEGO) - calculate a MAC to send. -************************************************************/ -static void smbcli_request_temp_sign_outgoing_message(struct smbcli_request *req) -{ - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(&req->out); - - /* I wonder what BSRSPYL stands for - but this is what MS - actually sends! */ - memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8); - - return; -} - -/*********************************************************** - SMB signing - TEMP implementation - check a MAC sent by server. -************************************************************/ -static BOOL smbcli_request_temp_check_incoming_message(struct smbcli_request *req) -{ - return True; -} - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ -static void smbcli_temp_free_signing_context(struct smb_signing_context *sign_info) -{ - return; -} - -/** - SMB signing - TEMP implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ -BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) -{ - if (!set_smb_signing_common(transport)) { - return False; - } - - transport->negotiate.sign_info.sign_outgoing_message = smbcli_request_temp_sign_outgoing_message; - transport->negotiate.sign_info.check_incoming_message = smbcli_request_temp_check_incoming_message; - transport->negotiate.sign_info.free_signing_context = smbcli_temp_free_signing_context; - - return True; -} - -/** - * Free the signing context - */ -void smbcli_transport_free_signing_context(struct smb_signing_context *sign_info) -{ - if (sign_info->free_signing_context) { - sign_info->free_signing_context(sign_info); - } - - smbcli_null_set_signing(sign_info); -} - - -/** - * Sign a packet with the current mechanism - */ -void smbcli_request_calculate_sign_mac(struct smbcli_request *req) -{ - req->transport->negotiate.sign_info.sign_outgoing_message(req); -} - - -/** - * Check a packet with the current mechanism - * @return False if we had an established signing connection - * which had a back checksum, True otherwise - */ -BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) -{ - BOOL good; - - if (req->in.size < (HDR_SS_FIELD + 8)) { - good = False; - } else { - good = req->transport->negotiate.sign_info.check_incoming_message(req); - } - - if (!good && req->transport->negotiate.sign_info.doing_signing) { - return False; - } - - return True; -} - - BOOL smbcli_init_signing(struct smbcli_transport *transport) { if (!smbcli_null_set_signing(&transport->negotiate.sign_info)) { @@ -431,7 +361,7 @@ BOOL smbcli_init_signing(struct smbcli_transport *transport) switch (lp_client_signing()) { case SMB_SIGNING_OFF: - transport->negotiate.sign_info.allow_smb_signing = False; + transport->negotiate.sign_info.allow_smb_signing = False; break; case SMB_SIGNING_SUPPORTED: transport->negotiate.sign_info.allow_smb_signing = True; -- cgit From 912e79ade515451152be6b45cc3cc83a9d286827 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Aug 2004 00:37:01 +0000 Subject: r1746: Remove more cruft from the SMB signing code. Andrew Bartlett (This used to be commit b176151b7294b03534921a26db4fb4be1e5d617c) --- source4/libcli/raw/smb_signing.c | 56 ++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 03794829c2..09da8e9983 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -21,8 +21,7 @@ */ #include "includes.h" -static void smbcli_free_signing_context(struct smb_signing_context *sign_info); -static BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info); +static BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info); /*********************************************************** SMB signing - Common code before we set a new signing implementation @@ -42,8 +41,6 @@ static BOOL set_smb_signing_common(struct smbcli_transport *transport) return False; } - smbcli_free_signing_context(&transport->negotiate.sign_info); - /* These calls are INCOMPATIBLE with SMB signing */ transport->negotiate.readbraw_supported = False; transport->negotiate.writebraw_supported = False; @@ -74,10 +71,7 @@ static BOOL signing_good(struct smb_signing_context *sign_info, /* If we have never seen a good packet, just turn it off */ DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); - sign_info->doing_signing = False; - smbcli_free_signing_context(sign_info); - - smbcli_null_set_signing(sign_info); + smbcli_set_signing_off(sign_info); return True; } else { /* bad packet after signing started - fail and disconnect. */ @@ -162,25 +156,23 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - if (i == 0) { - if (!good) { - DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", seq_num + i)); - dump_data(5, calc_md5_mac, 8); - - DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", seq_num + i)); - dump_data(5, server_sent_mac, 8); - } else { - DEBUG(15, ("check_signed_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", seq_num + i)); - dump_data(5, server_sent_mac, 8); - } - } - if (good) break; } if (good && i != 0) { DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, seq_num)); } + + if (!good) { + DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", seq_num + i)); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", seq_num + i)); + dump_data(5, server_sent_mac, 8); + } else { + DEBUG(15, ("check_signed_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", seq_num + i)); + dump_data(5, server_sent_mac, 8); + } return good; } @@ -230,14 +222,15 @@ void smbcli_request_calculate_sign_mac(struct smbcli_request *req) /** - SMB signing - NULL implementation - setup the MAC key. + SMB signing - NULL implementation @note Used as an initialisation only - it will not correctly shut down a real signing mechanism */ -static BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) +static BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info) { - sign_info->mac_key = data_blob(NULL, 0); + sign_info->doing_signing = False; + data_blob_free(&sign_info->mac_key); sign_info->signing_state = SMB_SIGNING_ENGINE_OFF; return True; } @@ -245,14 +238,13 @@ static BOOL smbcli_null_set_signing(struct smb_signing_context *sign_info) /** SMB signing - TEMP implementation - setup the MAC key. - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism */ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) { if (!set_smb_signing_common(transport)) { return False; } + smbcli_set_signing_off(&transport->negotiate.sign_info); transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); transport->negotiate.sign_info.signing_state = SMB_SIGNING_ENGINE_BSRSPYL; @@ -260,15 +252,6 @@ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) return True; } -/** - * Free the signing context - */ -static void smbcli_free_signing_context(struct smb_signing_context *sign_info) -{ - data_blob_free(&sign_info->mac_key); - smbcli_null_set_signing(sign_info); -} - /*********************************************************** SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ @@ -355,7 +338,8 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, BOOL smbcli_init_signing(struct smbcli_transport *transport) { - if (!smbcli_null_set_signing(&transport->negotiate.sign_info)) { + transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); + if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) { return False; } -- cgit From 34b0a989ebdbd14c66665a493992d92452d53551 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 03:26:38 +0000 Subject: r1748: don't segfault if there's no ticket metze (This used to be commit b8985892964e84ca09d611540811d5a50a31232e) --- source4/libcli/auth/clikrb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index c4bab57996..0e4ec1f438 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -154,11 +154,11 @@ DATA_BLOB *auth_data, krb5_ticket *tkt) { #if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt->enc_part2) + if (tkt && tkt->enc_part2) *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); #else - if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + if (tkt && tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, tkt->ticket.authorization_data->val->ad_data.length); #endif -- cgit From 5a4845ff8b44ef32cdb6d34ba5fc3359f9e3ef15 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Aug 2004 03:35:38 +0000 Subject: r1752: Fix compile bugs on C (rather than C++) tolerant compilers. Andrew Bartlett (This used to be commit 0949b72645024a6810f447fe8acb643f98588ab3) --- source4/libcli/auth/spnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 6a8b858f91..ed938c4a11 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -285,6 +285,7 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { + DATA_BLOB null_data_blob = data_blob(NULL,0); NTSTATUS nt_status; int num_ops; const char **mechTypes = NULL; @@ -301,7 +302,6 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec DEBUG(1, ("no GENSEC OID backends available\n")); return NT_STATUS_INVALID_PARAMETER; } - DATA_BLOB null_data_blob = data_blob(NULL,0); nt_status = gensec_subcontext_start(gensec_security, &spnego_state->sub_sec_security); -- cgit From fa8d37adae70a5f479262b722e47aa7fc21aaf5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 04:55:59 +0000 Subject: r1756: merge volkers ldap client lib to samba4 for simo to start with the ldap server code it's not compiled in yet... metze (This used to be commit 48939adca1332ff90f9287311c0e9ff3e2e5917a) --- source4/libcli/ldap/config.m4 | 1 + source4/libcli/ldap/config.mk | 6 + source4/libcli/ldap/ldap.c | 1989 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap.h | 246 +++++ source4/libcli/util/asn1.c | 160 +++- 5 files changed, 2375 insertions(+), 27 deletions(-) create mode 100644 source4/libcli/ldap/config.m4 create mode 100644 source4/libcli/ldap/config.mk create mode 100644 source4/libcli/ldap/ldap.c create mode 100644 source4/libcli/ldap/ldap.h (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.m4 b/source4/libcli/ldap/config.m4 new file mode 100644 index 0000000000..01f78279bf --- /dev/null +++ b/source4/libcli/ldap/config.m4 @@ -0,0 +1 @@ +SMB_SUBSYSTEM_MK(LIBCLI_LDAP,libcli/ldap/config.mk) diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk new file mode 100644 index 0000000000..397cfe0b72 --- /dev/null +++ b/source4/libcli/ldap/config.mk @@ -0,0 +1,6 @@ +################################# +# Start SUBSYSTEM LIBCLI_LDAP +[SUBSYSTEM::LIBCLI_LDAP] +ADD_OBJ_FILES = libcli/ldap/ldap.o +# End SUBSYSTEM LIBCLI_LDAP +################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c new file mode 100644 index 0000000000..38fff7e357 --- /dev/null +++ b/source4/libcli/ldap/ldap.c @@ -0,0 +1,1989 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + + 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 "smb_ldap.h" + +/**************************************************************************** + * + * LDAP filter parser -- main routine is ldb_parse_filter + * + * Shamelessly stolen and adapted from Samba 4. + * + ***************************************************************************/ + +/* Hmm. A blob might be more appropriate here :-) */ + +struct ldb_val { + unsigned int length; + void *data; +}; + +enum ldb_parse_op {LDB_OP_SIMPLE, LDB_OP_AND, LDB_OP_OR, LDB_OP_NOT}; + +struct ldb_parse_tree { + enum ldb_parse_op operation; + union { + struct { + char *attr; + struct ldb_val value; + } simple; + struct { + unsigned int num_elements; + struct ldb_parse_tree **elements; + } list; + struct { + struct ldb_parse_tree *child; + } not; + } u; +}; + +#define LDB_ALL_SEP "()&|=!" + +/* + return next token element. Caller frees +*/ +static char *ldb_parse_lex(TALLOC_CTX *mem_ctx, const char **s, + const char *sep) +{ + const char *p = *s; + char *ret; + + while (isspace(*p)) { + p++; + } + *s = p; + + if (*p == 0) { + return NULL; + } + + if (strchr(sep, *p)) { + (*s) = p+1; + ret = talloc_strndup(mem_ctx, p, 1); + if (!ret) { + errno = ENOMEM; + } + return ret; + } + + while (*p && (isalnum(*p) || !strchr(sep, *p))) { + p++; + } + + if (p == *s) { + return NULL; + } + + ret = talloc_strndup(mem_ctx, *s, p - *s); + if (!ret) { + errno = ENOMEM; + } + + *s = p; + + return ret; +} + + +/* + find a matching close brace in a string +*/ +static const char *match_brace(const char *s) +{ + unsigned int count = 0; + while (*s && (count != 0 || *s != ')')) { + if (*s == '(') { + count++; + } + if (*s == ')') { + count--; + } + s++; + } + if (! *s) { + return NULL; + } + return s; +} + +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, + const char **s); + +/* + ::= +*/ +static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, + const char *s) +{ + char *eq, *val, *l; + struct ldb_parse_tree *ret; + + l = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + if (!l) { + return NULL; + } + + if (strchr("()&|=", *l)) + return NULL; + + eq = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + if (!eq || strcmp(eq, "=") != 0) + return NULL; + + val = ldb_parse_lex(mem_ctx, &s, ")"); + if (val && strchr("()&|", *val)) + return NULL; + + ret = talloc(mem_ctx, sizeof(*ret)); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = LDB_OP_SIMPLE; + ret->u.simple.attr = l; + ret->u.simple.value.data = val; + ret->u.simple.value.length = val?strlen(val):0; + + return ret; +} + + +/* + parse a filterlist + ::= '&' + ::= '|' + ::= | +*/ +static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, + enum ldb_parse_op op, + const char *s) +{ + struct ldb_parse_tree *ret, *next; + + ret = talloc(mem_ctx, sizeof(*ret)); + + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = op; + ret->u.list.num_elements = 1; + ret->u.list.elements = talloc(mem_ctx, sizeof(*ret->u.list.elements)); + if (!ret->u.list.elements) { + errno = ENOMEM; + return NULL; + } + + ret->u.list.elements[0] = ldb_parse_filter(mem_ctx, &s); + if (!ret->u.list.elements[0]) { + return NULL; + } + + while (isspace(*s)) s++; + + while (*s && (next = ldb_parse_filter(mem_ctx, &s))) { + struct ldb_parse_tree **e; + e = talloc_realloc(mem_ctx, ret->u.list.elements, + sizeof(struct ldb_parse_tree) * + (ret->u.list.num_elements+1)); + if (!e) { + errno = ENOMEM; + return NULL; + } + ret->u.list.elements = e; + ret->u.list.elements[ret->u.list.num_elements] = next; + ret->u.list.num_elements++; + while (isspace(*s)) s++; + } + + return ret; +} + + +/* + ::= '!' +*/ +static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) +{ + struct ldb_parse_tree *ret; + + ret = talloc(mem_ctx, sizeof(*ret)); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = LDB_OP_NOT; + ret->u.not.child = ldb_parse_filter(mem_ctx, &s); + if (!ret->u.not.child) + return NULL; + + return ret; +} + +/* + parse a filtercomp + ::= | | | +*/ +static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, + const char *s) +{ + while (isspace(*s)) s++; + + switch (*s) { + case '&': + return ldb_parse_filterlist(mem_ctx, LDB_OP_AND, s+1); + + case '|': + return ldb_parse_filterlist(mem_ctx, LDB_OP_OR, s+1); + + case '!': + return ldb_parse_not(mem_ctx, s+1); + + case '(': + case ')': + return NULL; + } + + return ldb_parse_simple(mem_ctx, s); +} + + +/* + ::= '(' ')' +*/ +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, + const char **s) +{ + char *l, *s2; + const char *p, *p2; + struct ldb_parse_tree *ret; + + l = ldb_parse_lex(mem_ctx, s, LDB_ALL_SEP); + if (!l) { + return NULL; + } + + if (strcmp(l, "(") != 0) { + return NULL; + } + + p = match_brace(*s); + if (!p) { + return NULL; + } + p2 = p + 1; + + s2 = talloc_strndup(mem_ctx, *s, p - *s); + if (!s2) { + errno = ENOMEM; + return NULL; + } + + ret = ldb_parse_filtercomp(mem_ctx, s2); + + *s = p2; + + return ret; +} + +/* + main parser entry point. Takes a search string and returns a parse tree + + expression ::= | +*/ +static struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +{ + while (isspace(*s)) s++; + + if (*s == '(') { + return ldb_parse_filter(mem_ctx, &s); + } + + return ldb_parse_simple(mem_ctx, s); +} + +static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) +{ + switch (tree->operation) { + case LDB_OP_SIMPLE: { + if ((tree->u.simple.value.length == 1) && + (((char *)(tree->u.simple.value.data))[0] == '*')) { + /* Just a presence test */ + asn1_push_tag(data, 0x87); + asn1_write(data, tree->u.simple.attr, + strlen(tree->u.simple.attr)); + asn1_pop_tag(data); + return !data->has_error; + } + + /* Equality is all we currently do... */ + asn1_push_tag(data, 0xa3); + asn1_write_OctetString(data, tree->u.simple.attr, + strlen(tree->u.simple.attr)); + asn1_write_OctetString(data, tree->u.simple.value.data, + tree->u.simple.value.length); + asn1_pop_tag(data); + break; + } + + case LDB_OP_AND: { + int i; + + asn1_push_tag(data, 0xa0); + for (i=0; iu.list.num_elements; i++) { + ldap_push_filter(data, tree->u.list.elements[i]); + } + asn1_pop_tag(data); + break; + } + + case LDB_OP_OR: { + int i; + + asn1_push_tag(data, 0xa1); + for (i=0; iu.list.num_elements; i++) { + ldap_push_filter(data, tree->u.list.elements[i]); + } + asn1_pop_tag(data); + break; + } + default: + return False; + } + return !data->has_error; +} + +/**************************************************************************** + * + * LDIF parser + * + * Shamelessly stolen and adapted from Samba 4. + * + ***************************************************************************/ + +/* + pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF + this routine removes any RFC2849 continuations and comments + + caller frees +*/ +static char *next_chunk(TALLOC_CTX *mem_ctx, + int (*fgetc_fn)(void *), void *private_data) +{ + size_t alloc_size=0, chunk_size = 0; + char *chunk = NULL; + int c; + int in_comment = 0; + + while ((c = fgetc_fn(private_data)) != EOF) { + if (chunk_size+1 >= alloc_size) { + char *c2; + alloc_size += 1024; + c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + if (!c2) { + errno = ENOMEM; + return NULL; + } + chunk = c2; + } + + if (in_comment) { + if (c == '\n') { + in_comment = 0; + } + continue; + } + + /* handle continuation lines - see RFC2849 */ + if (c == ' ' && chunk_size > 1 && + chunk[chunk_size-1] == '\n') { + chunk_size--; + continue; + } + + /* chunks are terminated by a double line-feed */ + if (c == '\n' && chunk_size > 0 && + chunk[chunk_size-1] == '\n') { + chunk[chunk_size-1] = 0; + return chunk; + } + + if (c == '#' && + (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { + in_comment = 1; + continue; + } + + /* ignore leading blank lines */ + if (chunk_size == 0 && c == '\n') { + continue; + } + + chunk[chunk_size++] = c; + } + + if (chunk) { + chunk[chunk_size] = 0; + } + + return chunk; +} + +/* simple ldif attribute parser */ +static int next_attr(char **s, const char **attr, struct ldb_val *value) +{ + char *p; + int base64_encoded = 0; + + if (strncmp(*s, "-\n", 2) == 0) { + value->length = 0; + *attr = "-"; + *s += 2; + return 0; + } + + p = strchr(*s, ':'); + if (!p) { + return -1; + } + + *p++ = 0; + + if (*p == ':') { + base64_encoded = 1; + p++; + } + + *attr = *s; + + while (isspace(*p)) { + p++; + } + + value->data = p; + + p = strchr(p, '\n'); + + if (!p) { + value->length = strlen((char *)value->data); + *s = ((char *)value->data) + value->length; + } else { + value->length = p - (char *)value->data; + *s = p+1; + *p = 0; + } + + if (base64_encoded) { + DATA_BLOB blob = base64_decode_data_blob(value->data); + memcpy(value->data, blob.data, blob.length); + value->length = blob.length; + ((char *)value->data)[value->length] = '\0'; + } + + return 0; +} + +static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldap_attribute *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, attrib->values, + sizeof(*attrib->values) * + (attrib->num_values+1)); + if (attrib->values == NULL) + return False; + + attrib->values[attrib->num_values] = + data_blob_talloc(mem_ctx, value->data, value->length); + attrib->num_values += 1; + return True; +} + +static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) +{ + struct ldap_AddRequest *r = &msg->r.AddRequest; + const char *attr_name; + struct ldb_val value; + + r->num_attributes = 0; + r->attributes = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + int i; + struct ldap_attribute *attrib = NULL; + + for (i=0; inum_attributes; i++) { + if (strequal(r->attributes[i].name, attr_name)) { + attrib = &r->attributes[i]; + break; + } + } + + if (attrib == NULL) { + r->attributes = talloc_realloc(msg->mem_ctx, + r->attributes, + sizeof(*r->attributes) * + (r->num_attributes+1)); + if (r->attributes == NULL) + return False; + + attrib = &(r->attributes[r->num_attributes]); + r->num_attributes += 1; + ZERO_STRUCTP(attrib); + attrib->name = talloc_strdup(msg->mem_ctx, + attr_name); + } + + if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) + return False; + } + return True; +} + +static BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, + sizeof(**mods) * ((*num_mods)+1)); + + if (*mods == NULL) + return False; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return True; +} + +static BOOL fill_mods(struct ldap_message *msg, char **chunk) +{ + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + const char *attr_name; + struct ldb_val value; + + r->num_mods = 0; + r->mods = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + + struct ldap_mod mod; + mod.type = LDAP_MODIFY_NONE; + + mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); + + if (strequal(attr_name, "add")) + mod.type = LDAP_MOD_ADD; + + if (strequal(attr_name, "delete")) + mod.type = LDAP_MOD_DELETE; + + if (strequal(attr_name, "replace")) + mod.type = LDAP_MOD_REPLACE; + + if (mod.type == LDAP_MODIFY_NONE) { + DEBUG(2, ("ldif modification type %s unsupported\n", + attr_name)); + return False; + } + + mod.attrib.num_values = 0; + mod.attrib.values = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + if (strequal(attr_name, "-")) + break; + if (!strequal(attr_name, mod.attrib.name)) { + DEBUG(3, ("attrib name %s does not " + "match %s\n", attr_name, + mod.attrib.name)); + return False; + } + if (!add_value_to_attrib(msg->mem_ctx, &value, + &mod.attrib)) { + DEBUG(3, ("Could not add value\n")); + return False; + } + } + + if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, + &r->num_mods)) + return False; + } + + return True; +} + +/* + read from a LDIF source, creating a ldap_message +*/ +static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), + void *private_data) +{ + struct ldap_message *msg; + const char *attr=NULL; + const char *dn; + char *chunk=NULL, *s; + struct ldb_val value; + + value.data = NULL; + + msg = new_ldap_message(); + if (msg == NULL) + return NULL; + + chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); + if (!chunk) { + goto failed; + } + + s = chunk; + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + /* first line must be a dn */ + if (!strequal(attr, "dn")) { + DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", + attr)); + goto failed; + } + + dn = talloc_strdup(msg->mem_ctx, value.data); + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + if (!strequal(attr, "changetype")) { + DEBUG(5, ("Error: Second line of ldif must be a changetype " + "not '%s'\n", attr)); + goto failed; + } + + if (strequal(value.data, "delete")) { + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; + return msg; + } + + if (strequal(value.data, "add")) { + msg->type = LDAP_TAG_AddRequest; + + msg->r.AddRequest.dn = dn; + + if (!fill_add_attributes(msg, &s)) + goto failed; + + return msg; + } + + if (strequal(value.data, "modify")) { + msg->type = LDAP_TAG_ModifyRequest; + + msg->r.ModifyRequest.dn = dn; + + if (!fill_mods(msg, &s)) + goto failed; + + return msg; + } + + DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); + +failed: + destroy_ldap_message(msg); + return NULL; +} + +/* + a wrapper around ldif_read() for reading from const char* +*/ +struct ldif_read_string_state { + const char *s; +}; + +static int fgetc_string(void *private_data) +{ + struct ldif_read_string_state *state = private_data; + if (state->s[0] != 0) { + return *state->s++; + } + return EOF; +} + +struct ldap_message *ldap_ldif2msg(const char *s) +{ + struct ldif_read_string_state state; + state.s = s; + return ldif_read(fgetc_string, &state); +} + +static void ldap_encode_response(enum ldap_request_tag tag, + struct ldap_Result *result, + ASN1_DATA *data) +{ + asn1_push_tag(data, ASN1_APPLICATION(tag)); + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral != NULL) + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); +} + +BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) +{ + ASN1_DATA data; + int i, j; + + ZERO_STRUCT(data); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_Integer(&data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_write_Integer(&data, r->version); + asn1_write_OctetString(&data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(&data, r->mechanism | 0x80); + asn1_write(&data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(&data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(&data, r->mechanism | 0xa0); + asn1_write_OctetString(&data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + asn1_write_OctetString(&data, r->creds.SASL.creds.data, + r->creds.SASL.creds.length); + asn1_pop_tag(&data); + break; + default: + return False; + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + ldap_encode_response(msg->type, &r->response, &data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(&data, r->scope); + asn1_write_enumerated(&data, r->deref); + asn1_write_Integer(&data, r->sizelimit); + asn1_write_Integer(&data, r->timelimit); + asn1_write_BOOLEAN2(&data, r->attributesonly); + + { + TALLOC_CTX *mem_ctx = talloc_init("ldb_parse_tree"); + struct ldb_parse_tree *tree; + + if (mem_ctx == NULL) + return False; + + tree = ldb_parse_tree(mem_ctx, r->filter); + + if (tree == NULL) + return False; + + ldap_push_filter(&data, tree); + + talloc_destroy(mem_ctx); + } + + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(&data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldap_attribute *attr = &r->attributes[i]; + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, attr->name, + strlen(attr->name)); + asn1_push_tag(&data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(&data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldap_attribute *attrib = &r->mods[i].attrib; + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(&data, r->mods[i].type); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(&data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(&data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldap_attribute *attrib = &r->attributes[i]; + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(&data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(&data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(&data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + asn1_write(&data, r->dn, strlen(r->dn)); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(&data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN2(&data, r->deleteolddn); + if (r->newsuperior != NULL) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(&data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_ModifyDNResponse: { +/* struct ldap_Result *r = &msg->r.ModifyDNResponse; */ + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(&data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(&data, r->value, + strlen(r->value)); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_CompareResponse: { +/* struct ldap_Result *r = &msg->r.CompareResponse; */ + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(&data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_write_Integer(&data, r->messageid); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_SearchResultReference: { +/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(&data, r->oid, strlen(r->oid)); + asn1_pop_tag(&data); + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(&data, r->value.data, r->value.length); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + ldap_encode_response(msg->type, &r->response, &data); + break; + } + default: + return False; + } + + asn1_pop_tag(&data); + *result = data_blob(data.data, data.length); + asn1_free(&data); + return True; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc(mem_ctx, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + ASN1_DATA *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, &string)) + return False; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return True; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + ASN1_DATA *data, + enum ldap_request_tag tag, + struct ldap_Result *result) +{ + asn1_start_tag(data, ASN1_APPLICATION(tag)); + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + else + result->referral = NULL; + asn1_end_tag(data); +} + +static BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldap_attribute *attrib, + struct ldap_attribute **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, *attribs, + sizeof(**attribs) * (*num_attribs+1)); + + if (*attribs == NULL) + return False; + + (*attribs)[*num_attribs] = *attrib; + *num_attribs += 1; + return True; +} + +static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, + char **filter) +{ + uint8 filter_tag, tag_desc; + + if (!asn1_peek_uint8(data, &filter_tag)) + return False; + + tag_desc = filter_tag; + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + tag_desc &= 0xe0; + + switch(filter_tag) { + case 0: { + /* AND of one or more filters */ + if (tag_desc != 0xa0) /* context compount */ + return False; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + *filter = talloc_strdup(mem_ctx, "(&"); + if (*filter == NULL) + return False; + + while (asn1_tag_remaining(data) > 0) { + char *subfilter; + if (!ldap_decode_filter(mem_ctx, data, &subfilter)) + return False; + *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, + subfilter); + if (*filter == NULL) + return False; + } + asn1_end_tag(data); + + *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + break; + } + case 1: { + /* OR of one or more filters */ + if (tag_desc != 0xa0) /* context compount */ + return False; + + asn1_start_tag(data, ASN1_CONTEXT(1)); + + *filter = talloc_strdup(mem_ctx, "(|"); + if (*filter == NULL) + return False; + + while (asn1_tag_remaining(data) > 0) { + char *subfilter; + if (!ldap_decode_filter(mem_ctx, data, &subfilter)) + return False; + *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, + subfilter); + if (*filter == NULL) + return False; + } + + asn1_end_tag(data); + + *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + break; + } + case 3: { + /* equalityMatch */ + const char *attrib, *value; + if (tag_desc != 0xa0) /* context compound */ + return False; + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString_talloc(mem_ctx, data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value == NULL)) + return False; + *filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + int attr_len; + char *attr_name; + if (tag_desc != 0x80) /* context simple */ + return False; + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) + return False; + attr_len = asn1_tag_remaining(data); + attr_name = malloc(attr_len+1); + if (attr_name == NULL) + return False; + asn1_read(data, attr_name, attr_len); + attr_name[attr_len] = '\0'; + *filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); + SAFE_FREE(attr_name); + asn1_end_tag(data); + break; + } + default: + return False; + } + if (*filter == NULL) + return False; + return True; +} + +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, + struct ldap_attribute *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + struct ldb_val value; + asn1_read_OctetString(data, &blob); + value.data = blob.data; + value.length = blob.length; + add_value_to_attrib(mem_ctx, &value, attrib); + data_blob_free(&blob); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, ASN1_DATA *data, + struct ldap_attribute **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldap_attribute attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } + asn1_end_tag(data); +} + +BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) +{ + uint8 tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return False; + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + if (asn1_peek_tag(data, 0x80)) { + int pwlen; + r->creds.password = ""; + /* Mechanism 0 (SIMPLE) */ + asn1_start_tag(data, 0x80); + pwlen = asn1_tag_remaining(data); + if (pwlen != 0) { + char *pw = talloc(msg->mem_ctx, pwlen+1); + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + ldap_decode_response(msg->mem_ctx, + data, LDAP_TAG_BindResponse, + &r->response); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN2(data, &r->attributesonly); + + /* Maybe create a TALLOC_CTX for the filter? This can waste + * quite a bit of memory recursing down. */ + ldap_decode_filter(msg->mem_ctx, data, &r->filter); + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + const char *attr; + if (!asn1_read_OctetString_talloc(msg->mem_ctx, data, + &attr)) + return False; + if (!add_string_to_array(msg->mem_ctx, attr, + &r->attributes, + &r->num_attributes)) + return False; + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_SearchResultDone, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { +/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + msg->type = LDAP_TAG_SearchResultReference; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &mod.type); + ldap_decode_attrib(msg->mem_ctx, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, + &r->mods, &r->num_mods)) + break; + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_ModifyResponse *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_ModifyResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_AddResponse *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_AddResponse, r); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + dn = talloc(msg->mem_ctx, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_DelResponse *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_DelResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { +/* struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; */ + msg->type = LDAP_TAG_ModifyDNRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_ModifyDNResponse *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_ModifyDNResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { +/* struct ldap_CompareRequest *r = &msg->r.CompareRequest; */ + msg->type = LDAP_TAG_CompareRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_CompareResponse *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_CompareResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AbandonRequest): { +/* struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; */ + msg->type = LDAP_TAG_AbandonRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { +/* struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; */ + msg->type = LDAP_TAG_ExtendedRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + msg->type = LDAP_TAG_ExtendedResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_ExtendedResponse, &r->response); + /* I have to come across an operation that actually sends + * something back to really see what's going on. The currently + * needed pwdchange does not send anything back. */ + r->name = NULL; + r->value.data = NULL; + r->value.length = 0; + break; + } + + } + + asn1_end_tag(data); + return ((!data->has_error) && (data->nesting == NULL)); +} + +BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, + char **host, uint16 *port, BOOL *ldaps) +{ + int tmp_port = 0; + fstring protocol; + fstring tmp_host; + const char *p = url; + + /* skip leading "URL:" (if any) */ + if ( strnequal( p, "URL:", 4 ) ) { + p += 4; + } + + /* Paranoia check */ + SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); + + sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + + if (strequal(protocol, "ldap")) { + *port = 389; + *ldaps = False; + } else if (strequal(protocol, "ldaps")) { + *port = 636; + *ldaps = True; + } else { + DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); + return False; + } + + if (tmp_port != 0) + *port = tmp_port; + + *host = talloc_strdup(mem_ctx, tmp_host); + + return (*host != NULL); +} + +struct ldap_connection *new_ldap_connection(void) +{ + TALLOC_CTX *mem_ctx = talloc_init("ldap_connection"); + struct ldap_connection *result; + + if (mem_ctx == NULL) + return NULL; + + result = talloc(mem_ctx, sizeof(*result)); + + if (result == NULL) + return NULL; + + result->mem_ctx = mem_ctx; + result->next_msgid = 1; + result->outstanding = NULL; + result->searchid = 0; + result->search_entries = NULL; + return result; +} + +BOOL ldap_connect(struct ldap_connection *conn, const char *url) +{ + struct hostent *hp; + struct in_addr ip; + + if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, + &conn->port, &conn->ldaps)) + return False; + + hp = sys_gethostbyname(conn->host); + + if ((hp == NULL) || (hp->h_addr == NULL)) + return False; + + putip((char *)&ip, (char *)hp->h_addr); + + conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, 10000); + + return (conn->sock >= 0); +} + +BOOL ldap_set_simple_creds(struct ldap_connection *conn, + const char *dn, const char *password) +{ + conn->auth_dn = talloc_strdup(conn->mem_ctx, dn); + conn->simple_pw = talloc_strdup(conn->mem_ctx, password); + + return ((conn->auth_dn != NULL) && (conn->simple_pw != NULL)); +} + +struct ldap_message *new_ldap_message(void) +{ + TALLOC_CTX *mem_ctx = talloc_init("ldap_message"); + struct ldap_message *result; + + if (mem_ctx == NULL) + return NULL; + + result = talloc(mem_ctx, sizeof(*result)); + + if (result == NULL) + return NULL; + + result->mem_ctx = mem_ctx; + return result; +} + +void destroy_ldap_message(struct ldap_message *msg) +{ + if (msg != NULL) + talloc_destroy(msg->mem_ctx); +} + +BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + DATA_BLOB request; + BOOL result; + struct ldap_queue_entry *entry; + + msg->messageid = conn->next_msgid++; + + if (!ldap_encode(msg, &request)) + return False; + + result = (write_data_until(conn->sock, request.data, request.length, + endtime) == request.length); + + data_blob_free(&request); + + if (!result) + return result; + + /* abandon and unbind don't expect results */ + + if ((msg->type == LDAP_TAG_AbandonRequest) || + (msg->type == LDAP_TAG_UnbindRequest)) + return True; + + entry = malloc(sizeof(*entry)); + + if (entry == NULL) + return False; + + entry->msgid = msg->messageid; + entry->msg = NULL; + DLIST_ADD(conn->outstanding, entry); + + return True; +} + +BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + struct asn1_data data; + BOOL result; + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return False; + + result = ldap_decode(&data, msg); + + asn1_free(&data); + return result; +} + +static struct ldap_message *recv_from_queue(struct ldap_connection *conn, + int msgid) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + + if (e->msgid == msgid) { + struct ldap_message *result = e->msg; + DLIST_REMOVE(conn->outstanding, e); + SAFE_FREE(e); + return result; + } + } + + return NULL; +} + +static void add_search_entry(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e = malloc(sizeof *e); + struct ldap_queue_entry *tmp; + + if (e == NULL) + return; + + e->msg = msg; + DLIST_ADD_END(conn->search_entries, e, tmp); + return; +} + +static void fill_outstanding_request(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + if (e->msgid == msg->messageid) { + e->msg = msg; + return; + } + } + + /* This reply has not been expected, destroy the incoming msg */ + destroy_ldap_message(msg); + return; +} + +struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *result = recv_from_queue(conn, msgid); + + if (result != NULL) + return result; + + while (True) { + struct asn1_data data; + result = new_ldap_message(); + BOOL res; + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return NULL; + + res = ldap_decode(&data, result); + asn1_free(&data); + + if (!res) + return NULL; + + if (result->messageid == msgid) + return result; + + if (result->type == LDAP_TAG_SearchResultEntry) { + add_search_entry(conn, result); + } else { + fill_outstanding_request(conn, result); + } + } + + return NULL; +} + +struct ldap_message *ldap_transaction(struct ldap_connection *conn, + struct ldap_message *request) +{ + if (!ldap_send_msg(conn, request, NULL)) + return False; + + return ldap_receive(conn, request->messageid, NULL); +} + +BOOL ldap_setup_connection(struct ldap_connection *conn, + const char *url) +{ + struct ldap_message *msg = new_ldap_message(); + struct ldap_message *response; + BOOL result; + + if (msg == NULL) + return False; + + if (!ldap_connect(conn, url)) { + destroy_ldap_message(msg); + return False; + } + + msg->messageid = conn->next_msgid++; + msg->type = LDAP_TAG_BindRequest; + msg->r.BindRequest.version = 3; + msg->r.BindRequest.dn = conn->auth_dn; + msg->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + msg->r.BindRequest.creds.password = conn->simple_pw; + + if ((response = ldap_transaction(conn, msg)) == NULL) + return False; + + result = (response->r.BindResponse.response.resultcode == 0); + + destroy_ldap_message(msg); + destroy_ldap_message(response); + return result; +} + +static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *msg = new_ldap_message(); + BOOL result; + + if (msg == NULL) + return False; + + msg->type = LDAP_TAG_AbandonRequest; + msg->r.AbandonRequest.messageid = msgid; + + result = ldap_send_msg(conn, msg, endtime); + destroy_ldap_message(msg); + return result; +} + +struct ldap_message *new_ldap_search_message(const char *base, + enum ldap_scope scope, + char *filter, + int num_attributes, + const char **attributes) +{ + struct ldap_message *res = new_ldap_message(); + + if (res == NULL) + return NULL; + + res->type = LDAP_TAG_SearchRequest; + res->r.SearchRequest.basedn = base; + res->r.SearchRequest.scope = scope; + res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + res->r.SearchRequest.timelimit = 0; + res->r.SearchRequest.sizelimit = 0; + res->r.SearchRequest.attributesonly = False; + res->r.SearchRequest.filter = filter; + res->r.SearchRequest.num_attributes = num_attributes; + res->r.SearchRequest.attributes = attributes; + return res; +} + +struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw) +{ + struct ldap_message *res = new_ldap_message(); + + if (res == NULL) + return NULL; + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); + return res; +} + +BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + if ((conn->searchid != 0) && + (!ldap_abandon_message(conn, conn->searchid, endtime))) + return False; + + conn->searchid = conn->next_msgid; + return ldap_send_msg(conn, msg, endtime); +} + +struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_message *result; + + if (conn->search_entries != NULL) { + struct ldap_queue_entry *e = conn->search_entries; + + result = e->msg; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + return result; + } + + result = ldap_receive(conn, conn->searchid, endtime); + + if (result->type == LDAP_TAG_SearchResultEntry) + return result; + + if (result->type == LDAP_TAG_SearchResultDone) { + /* TODO: Handle Paged Results */ + destroy_ldap_message(result); + return NULL; + } + + /* TODO: Handle Search References here */ + return NULL; +} + +void ldap_endsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_queue_entry *e; + + e = conn->search_entries; + + while (e != NULL) { + struct ldap_queue_entry *next = e->next; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + e = next; + } +} + +struct ldap_message *ldap_searchone(struct ldap_connection *conn, + struct ldap_message *msg, + const struct timeval *endtime) +{ + struct ldap_message *res1, *res2 = NULL; + if (!ldap_setsearchent(conn, msg, endtime)) + return NULL; + + res1 = ldap_getsearchent(conn, endtime); + + if (res1 != NULL) + res2 = ldap_getsearchent(conn, endtime); + + ldap_endsearchent(conn, endtime); + + if (res1 == NULL) + return NULL; + + if (res2 != NULL) { + /* More than one entry */ + destroy_ldap_message(res1); + destroy_ldap_message(res2); + return NULL; + } + + return res1; +} + +BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, + DATA_BLOB *value) +{ + int i; + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + + if (msg->type != LDAP_TAG_SearchResultEntry) + return False; + + for (i=0; inum_attributes; i++) { + if (strequal(attr, r->attributes[i].name)) { + if (r->attributes[i].num_values != 1) + return False; + + *value = r->attributes[i].values[0]; + return True; + } + } + return False; +} + +BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, + TALLOC_CTX *mem_ctx, char **value) +{ + DATA_BLOB blob; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + *value = talloc(mem_ctx, blob.length+1); + + if (*value == NULL) + return False; + + memcpy(*value, blob.data, blob.length); + (*value)[blob.length] = '\0'; + return True; +} + +BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, + int *value) +{ + DATA_BLOB blob; + char *val; + int errno_save; + BOOL res; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + val = malloc(blob.length+1); + if (val == NULL) + return False; + + memcpy(val, blob.data, blob.length); + val[blob.length] = '\0'; + + errno_save = errno; + errno = 0; + + *value = strtol(val, NULL, 10); + + res = (errno == 0); + + free(val); + errno = errno_save; + + return res; +} + +int ldap_error(struct ldap_connection *conn) +{ + return 0; +} + +NTSTATUS ldap2nterror(int ldaperror) +{ + return NT_STATUS_OK; +} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h new file mode 100644 index 0000000000..96c1b82ca3 --- /dev/null +++ b/source4/libcli/ldap/ldap.h @@ -0,0 +1,246 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 2004 + + 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. + +*/ + +#ifndef _SMB_LDAP_H +#define _SMB_LDAP_H + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_attribute { + const char *name; + int num_values; + DATA_BLOB *values; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB creds; + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB credentials; + } SASL_Credentials; +}; + +struct ldap_UnbindRequest { +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32 timelimit; + uint32 sizelimit; + BOOL attributesonly; + char *filter; + int num_attributes; + const char **attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldap_attribute *attributes; +}; + +struct ldap_SearchResRef { + int num_referrals; + const char **referrals; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldap_attribute attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldap_attribute *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + BOOL deleteolddn; + const char *newsuperior; +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + const char *value; +}; + +struct ldap_AbandonRequest { + uint32 messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB value; +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *name; + DATA_BLOB value; +}; + +union ldap_Request { + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + +struct ldap_Control { + const char *oid; + BOOL critical; + DATA_BLOB value; +}; + +struct ldap_message { + TALLOC_CTX *mem_ctx; + uint32 messageid; + uint8 type; + union ldap_Request r; + int num_controls; + struct ldap_Control *controls; +}; + +struct ldap_queue_entry { + struct ldap_queue_entry *next, *prev; + int msgid; + struct ldap_message *msg; +}; + +struct ldap_connection { + TALLOC_CTX *mem_ctx; + int sock; + int next_msgid; + char *host; + uint16 port; + BOOL ldaps; + + const char *auth_dn; + const char *simple_pw; + + /* Current outstanding search entry */ + int searchid; + + /* List for incoming search entries */ + struct ldap_queue_entry *search_entries; + + /* Outstanding LDAP requests that have not yet been replied to */ + struct ldap_queue_entry *outstanding; +}; + +#endif diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index dcafb261ee..6ddce7882c 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -184,6 +184,14 @@ BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) return !data->has_error; } +BOOL asn1_read_BOOLEAN2(ASN1_DATA *data, BOOL *v) +{ + asn1_start_tag(data, ASN1_BOOLEAN); + asn1_read_uint8(data, (uint8 *)v); + asn1_end_tag(data); + return !data->has_error; +} + /* check a BOOLEAN */ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) { @@ -216,51 +224,52 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) return True; } -/* read from a ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_read(ASN1_DATA *data, void *p, int len) +/* Peek into an ASN1 buffer, not advancing the pointer */ +BOOL asn1_peek(ASN1_DATA *data, void *p, int len) { - if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { - data->has_error = True; + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) return False; - } - if (data->ofs + len > data->length) { - data->has_error = True; + if (data->ofs + len > data->length) return False; - } + memcpy(p, data->data + data->ofs, len); - data->ofs += len; return True; } -/* read a uint8_t from a ASN1 buffer */ -BOOL asn1_read_uint8(ASN1_DATA *data, uint8_t *v) -{ - return asn1_read(data, v, 1); -} - /* read from a ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_peek(ASN1_DATA *data, void *p, int len) +BOOL asn1_read(ASN1_DATA *data, void *p, int len) { - if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { + if (!asn1_peek(data, p, len)) { data->has_error = True; return False; } - if (data->ofs + len > data->length) { - data->has_error = True; - return False; - } - memcpy(p, data->data + data->ofs, len); + data->ofs += len; return True; } /* read a uint8_t from a ASN1 buffer */ +BOOL asn1_read_uint8(ASN1_DATA *data, uint8_t *v) +{ + return asn1_read(data, v, 1); +} + BOOL asn1_peek_uint8(ASN1_DATA *data, uint8_t *v) { return asn1_peek(data, v, 1); } +BOOL asn1_peek_tag(ASN1_DATA *data, uint8_t tag) +{ + uint8_t b; + + if (!asn1_peek(data, &b, sizeof(b))) + return False; + + return (b == tag); +} + /* start reading a nested asn1 structure */ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) { @@ -304,6 +313,89 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) return !data->has_error; } +#if 0 +static BOOL read_one_uint8(int sock, uint8_t *result, ASN1_DATA *data, + const struct timeval *endtime) +{ + if (read_data_until(sock, result, 1, endtime) != 1) + return False; + + return asn1_write(data, result, 1); +} + +/* Read a complete ASN sequence (ie LDAP result) from a socket */ +BOOL asn1_read_sequence_until(int sock, ASN1_DATA *data, + const struct timeval *endtime) +{ + uint8_t b; + size_t len; + char *buf; + + ZERO_STRUCTP(data); + + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + + if (b != 0x30) { + data->has_error = True; + return False; + } + + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + + if (b & 0x80) { + int n = b & 0x7f; + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + len = b; + while (n > 1) { + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + len = (len<<8) | b; + n--; + } + } else { + len = b; + } + + buf = malloc(len); + if (buf == NULL) + return False; + + if (read_data_until(sock, buf, len, endtime) != len) + return False; + + if (!asn1_write(data, buf, len)) + return False; + + free(buf); + + data->ofs = 0; + + return True; +} +#endif + +/* Get the length to be expected in buf */ +BOOL asn1_object_length(uint8_t *buf, size_t buf_length, + uint8_t tag, size_t *result) +{ + ASN1_DATA data; + + /* Fake the asn1_load to avoid the memdup, this is just to be able to + * re-use the length-reading in asn1_start_tag */ + ZERO_STRUCT(data); + data.data = buf; + data.length = buf_length; + if (!asn1_start_tag(&data, tag)) + return False; + *result = asn1_tag_remaining(&data)+data.ofs; + /* We can't use asn1_end_tag here, as we did not consume the complete + * tag, so asn1_end_tag would flag an error and not free nesting */ + free(data.nesting); + return True; +} /* stop reading a tag */ BOOL asn1_end_tag(ASN1_DATA *data) @@ -342,7 +434,7 @@ int asn1_tag_remaining(ASN1_DATA *data) BOOL asn1_read_OID(ASN1_DATA *data, char **OID) { uint8_t b; - char *oid = NULL; + char *tmp_oid = NULL; TALLOC_CTX *mem_ctx = talloc_init("asn1_read_OID"); if (!mem_ctx) { return False; @@ -351,8 +443,8 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) if (!asn1_start_tag(data, ASN1_OID)) return False; asn1_read_uint8(data, &b); - oid = talloc_asprintf(mem_ctx, "%u", b/40); - oid = talloc_asprintf_append(mem_ctx, oid, " %u", b%40); + tmp_oid = talloc_asprintf(mem_ctx, "%u", b/40); + tmp_oid = talloc_asprintf_append(mem_ctx, tmp_oid, " %u", b%40); while (!data->has_error && asn1_tag_remaining(data) > 0) { uint_t v = 0; @@ -360,12 +452,12 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); - oid = talloc_asprintf_append(mem_ctx, oid, " %u", v); + tmp_oid = talloc_asprintf_append(mem_ctx, tmp_oid, " %u", v); } asn1_end_tag(data); - *OID = strdup(oid); + *OID = strdup(tmp_oid); talloc_destroy(mem_ctx); return (*OID && !data->has_error); @@ -439,6 +531,20 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) } +/* read an interger */ +BOOL asn1_read_enumerated(ASN1_DATA *data, int *v) +{ + *v = 0; + + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; + while (asn1_tag_remaining(data)>0) { + uint8_t b; + asn1_read_uint8(data, &b); + *v = (*v << 8) + b; + } + return asn1_end_tag(data); +} + /* check a enumarted value is correct */ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) { -- cgit From 2b51ce3ca44943758f70017c7553dd2bb0bb977c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 06:37:12 +0000 Subject: r1761: start porting valuable volker's work on ldap from trunk all ldb functions has been renamed to ldap_ as we don't really want to include ldb functions here, let's keep ldap and ldb separate. (This used to be commit f9d7b731c910b530a0a6c0f0c09c809f3e7b4167) --- source4/libcli/ldap/ldap.c | 126 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 64 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 38fff7e357..ef1d43022f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -22,48 +22,47 @@ */ #include "includes.h" -#include "smb_ldap.h" /**************************************************************************** * - * LDAP filter parser -- main routine is ldb_parse_filter + * LDAP filter parser -- main routine is ldap_parse_filter * - * Shamelessly stolen and adapted from Samba 4. + * Shamelessly stolen and adapted from ldb. * ***************************************************************************/ /* Hmm. A blob might be more appropriate here :-) */ -struct ldb_val { +struct ldap_val { unsigned int length; void *data; }; -enum ldb_parse_op {LDB_OP_SIMPLE, LDB_OP_AND, LDB_OP_OR, LDB_OP_NOT}; +enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; -struct ldb_parse_tree { - enum ldb_parse_op operation; +struct ldap_parse_tree { + enum ldap_parse_op operation; union { struct { char *attr; - struct ldb_val value; + struct ldap_val value; } simple; struct { unsigned int num_elements; - struct ldb_parse_tree **elements; + struct ldap_parse_tree **elements; } list; struct { - struct ldb_parse_tree *child; + struct ldap_parse_tree *child; } not; } u; }; -#define LDB_ALL_SEP "()&|=!" +#define LDAP_ALL_SEP "()&|=!" /* return next token element. Caller frees */ -static char *ldb_parse_lex(TALLOC_CTX *mem_ctx, const char **s, +static char *ldap_parse_lex(TALLOC_CTX *mem_ctx, const char **s, const char *sep) { const char *p = *s; @@ -127,19 +126,19 @@ static const char *match_brace(const char *s) return s; } -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, const char **s); /* ::= */ -static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, const char *s) { char *eq, *val, *l; - struct ldb_parse_tree *ret; + struct ldap_parse_tree *ret; - l = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + l = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); if (!l) { return NULL; } @@ -147,11 +146,11 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, if (strchr("()&|=", *l)) return NULL; - eq = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + eq = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); if (!eq || strcmp(eq, "=") != 0) return NULL; - val = ldb_parse_lex(mem_ctx, &s, ")"); + val = ldap_parse_lex(mem_ctx, &s, ")"); if (val && strchr("()&|", *val)) return NULL; @@ -161,7 +160,7 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, return NULL; } - ret->operation = LDB_OP_SIMPLE; + ret->operation = LDAP_OP_SIMPLE; ret->u.simple.attr = l; ret->u.simple.value.data = val; ret->u.simple.value.length = val?strlen(val):0; @@ -176,11 +175,11 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, ::= '|' ::= | */ -static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, - enum ldb_parse_op op, +static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, + enum ldap_parse_op op, const char *s) { - struct ldb_parse_tree *ret, *next; + struct ldap_parse_tree *ret, *next; ret = talloc(mem_ctx, sizeof(*ret)); @@ -197,17 +196,17 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, return NULL; } - ret->u.list.elements[0] = ldb_parse_filter(mem_ctx, &s); + ret->u.list.elements[0] = ldap_parse_filter(mem_ctx, &s); if (!ret->u.list.elements[0]) { return NULL; } while (isspace(*s)) s++; - while (*s && (next = ldb_parse_filter(mem_ctx, &s))) { - struct ldb_parse_tree **e; + while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { + struct ldap_parse_tree **e; e = talloc_realloc(mem_ctx, ret->u.list.elements, - sizeof(struct ldb_parse_tree) * + sizeof(struct ldap_parse_tree) * (ret->u.list.num_elements+1)); if (!e) { errno = ENOMEM; @@ -226,9 +225,9 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, /* ::= '!' */ -static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) +static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s) { - struct ldb_parse_tree *ret; + struct ldap_parse_tree *ret; ret = talloc(mem_ctx, sizeof(*ret)); if (!ret) { @@ -236,8 +235,8 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) return NULL; } - ret->operation = LDB_OP_NOT; - ret->u.not.child = ldb_parse_filter(mem_ctx, &s); + ret->operation = LDAP_OP_NOT; + ret->u.not.child = ldap_parse_filter(mem_ctx, &s); if (!ret->u.not.child) return NULL; @@ -248,41 +247,41 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) parse a filtercomp ::= | | | */ -static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_filtercomp(TALLOC_CTX *mem_ctx, const char *s) { while (isspace(*s)) s++; switch (*s) { case '&': - return ldb_parse_filterlist(mem_ctx, LDB_OP_AND, s+1); + return ldap_parse_filterlist(mem_ctx, LDAP_OP_AND, s+1); case '|': - return ldb_parse_filterlist(mem_ctx, LDB_OP_OR, s+1); + return ldap_parse_filterlist(mem_ctx, LDAP_OP_OR, s+1); case '!': - return ldb_parse_not(mem_ctx, s+1); + return ldap_parse_not(mem_ctx, s+1); case '(': case ')': return NULL; } - return ldb_parse_simple(mem_ctx, s); + return ldap_parse_simple(mem_ctx, s); } /* ::= '(' ')' */ -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, const char **s) { char *l, *s2; const char *p, *p2; - struct ldb_parse_tree *ret; + struct ldap_parse_tree *ret; - l = ldb_parse_lex(mem_ctx, s, LDB_ALL_SEP); + l = ldap_parse_lex(mem_ctx, s, LDAP_ALL_SEP); if (!l) { return NULL; } @@ -303,7 +302,7 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, return NULL; } - ret = ldb_parse_filtercomp(mem_ctx, s2); + ret = ldap_parse_filtercomp(mem_ctx, s2); *s = p2; @@ -315,21 +314,21 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, expression ::= | */ -static struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char *s) { while (isspace(*s)) s++; if (*s == '(') { - return ldb_parse_filter(mem_ctx, &s); + return ldap_parse_filter(mem_ctx, &s); } - return ldb_parse_simple(mem_ctx, s); + return ldap_parse_simple(mem_ctx, s); } -static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) +static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) { switch (tree->operation) { - case LDB_OP_SIMPLE: { + case LDAP_OP_SIMPLE: { if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -350,7 +349,7 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) break; } - case LDB_OP_AND: { + case LDAP_OP_AND: { int i; asn1_push_tag(data, 0xa0); @@ -361,7 +360,7 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) break; } - case LDB_OP_OR: { + case LDAP_OP_OR: { int i; asn1_push_tag(data, 0xa1); @@ -454,7 +453,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, } /* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldb_val *value) +static int next_attr(char **s, const char **attr, struct ldap_val *value) { char *p; int base64_encoded = 0; @@ -507,7 +506,7 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value) return 0; } -static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, +static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, struct ldap_attribute *attrib) { attrib->values = talloc_realloc(mem_ctx, attrib->values, @@ -526,7 +525,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) { struct ldap_AddRequest *r = &msg->r.AddRequest; const char *attr_name; - struct ldb_val value; + struct ldap_val value; r->num_attributes = 0; r->attributes = NULL; @@ -583,7 +582,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; const char *attr_name; - struct ldb_val value; + struct ldap_val value; r->num_mods = 0; r->mods = NULL; @@ -647,7 +646,7 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), const char *attr=NULL; const char *dn; char *chunk=NULL, *s; - struct ldb_val value; + struct ldap_val value; value.data = NULL; @@ -822,13 +821,13 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_BOOLEAN2(&data, r->attributesonly); { - TALLOC_CTX *mem_ctx = talloc_init("ldb_parse_tree"); - struct ldb_parse_tree *tree; + TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); + struct ldap_parse_tree *tree; if (mem_ctx == NULL) return False; - tree = ldb_parse_tree(mem_ctx, r->filter); + tree = ldap_parse_tree(mem_ctx, r->filter); if (tree == NULL) return False; @@ -872,7 +871,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) break; } case LDAP_TAG_SearchResultDone: { - struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + struct ldap_Result *r = &msg->r.SearchResultDone; ldap_encode_response(msg->type, r, &data); break; } @@ -1195,7 +1194,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldb_val value; + struct ldap_val value; asn1_read_OctetString(data, &blob); value.data = blob.data; value.length = blob.length; @@ -1323,7 +1322,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + struct ldap_Result *r = &msg->r.SearchResultDone; msg->type = LDAP_TAG_SearchResultDone; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_SearchResultDone, r); @@ -1364,7 +1363,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_ModifyResponse *r = &msg->r.ModifyResponse; + struct ldap_Result *r = &msg->r.ModifyResponse; msg->type = LDAP_TAG_ModifyResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_ModifyResponse, r); @@ -1387,7 +1386,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_AddResponse *r = &msg->r.AddResponse; + struct ldap_Result *r = &msg->r.AddResponse; msg->type = LDAP_TAG_AddResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_AddResponse, r); @@ -1413,7 +1412,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_DelResponse *r = &msg->r.DelResponse; + struct ldap_Result *r = &msg->r.DelResponse; msg->type = LDAP_TAG_DelResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_DelResponse, r); @@ -1427,7 +1426,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_ModifyDNResponse *r = &msg->r.ModifyDNResponse; + struct ldap_Result *r = &msg->r.ModifyDNResponse; msg->type = LDAP_TAG_ModifyDNResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_ModifyDNResponse, r); @@ -1441,7 +1440,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_CompareResponse *r = &msg->r.CompareResponse; + struct ldap_Result *r = &msg->r.CompareResponse; msg->type = LDAP_TAG_CompareResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_CompareResponse, r); @@ -1666,13 +1665,12 @@ static void add_search_entry(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_queue_entry *e = malloc(sizeof *e); - struct ldap_queue_entry *tmp; if (e == NULL) return; e->msg = msg; - DLIST_ADD_END(conn->search_entries, e, tmp); + DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); return; } -- cgit From f387277b7fa3dc190a6345394aaf79399b88851f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Aug 2004 07:26:42 +0000 Subject: r1768: Add some debugs to assist in SMB signing debugging. Andrew Bartlett (This used to be commit 32b45fc9e8ff1d0b73bbec1eb1d249af3ec52e46) --- source4/libcli/raw/smb_signing.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 09da8e9983..0b9c2864d3 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -30,14 +30,17 @@ static BOOL set_smb_signing_common(struct smbcli_transport *transport) { if (!(transport->negotiate.sec_mode & (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) { + DEBUG(5, ("SMB Signing is not negotiated by the peer\n")); return False; } if (transport->negotiate.sign_info.doing_signing) { + DEBUG(5, ("SMB Signing already in progress, so we don't start it again\n")); return False; } if (!transport->negotiate.sign_info.allow_smb_signing) { + DEBUG(5, ("SMB Signing has been locally disabled\n")); return False; } @@ -61,9 +64,11 @@ static BOOL signing_good(struct smb_signing_context *sign_info, { if (good) { if (!sign_info->doing_signing) { + DEBUG(5, ("Seen valid packet, so turning signing on\n")); sign_info->doing_signing = True; } if (!sign_info->seen_valid) { + DEBUG(5, ("Seen valid packet, so marking signing as 'seen valid'\n")); sign_info->seen_valid = True; } } else { @@ -130,6 +135,11 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key return False; } + if (!mac_key->length) { + /* NO key yet */ + return False; + } + /* its quite bogus to be guessing sequence numbers, but very useful when debugging signing implementations */ for (i = 0-sign_range; i <= 0+sign_range; i++) { @@ -229,6 +239,7 @@ void smbcli_request_calculate_sign_mac(struct smbcli_request *req) */ static BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info) { + DEBUG(5, ("Shutdown SMB signing\n")); sign_info->doing_signing = False; data_blob_free(&sign_info->mac_key); sign_info->signing_state = SMB_SIGNING_ENGINE_OFF; @@ -244,6 +255,7 @@ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) if (!set_smb_signing_common(transport)) { return False; } + DEBUG(5, ("BSRSPYL SMB signing enabled\n")); smbcli_set_signing_off(&transport->negotiate.sign_info); transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); -- cgit From 63c5ca7d583691fae5ccf0b760f24b9d11a2141b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Aug 2004 07:29:49 +0000 Subject: r1769: Add a new torture test to check vuid properties, and SPNEGO/non-SPNEGO games. Andrew Bartlett (This used to be commit 90d70a63ee6d44172cec99a9115817f666b5d06d) --- source4/libcli/raw/clisession.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index b32d59f340..f46c238378 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -394,7 +394,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess s2.spnego.in.domain = parms->generic.in.domain; s2.spnego.in.os = "Unix"; s2.spnego.in.lanman = "Samba"; - s2.spnego.out.vuid = UID_FIELD_INVALID; + s2.spnego.out.vuid = session->vuid; smbcli_temp_set_signing(session->transport); -- cgit From 8a0f6c9c7909162a9669197bc0238d0636de69da Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 07:37:49 +0000 Subject: r1770: here's the krb5 server code, there're some cleanups needed and we need to verify the PAC correctly and create the auth_session_info correctly... metze (This used to be commit d8fe497097ee49611bb05c4a2fed36912d8e16b4) --- source4/libcli/auth/gensec_krb5.c | 264 +++++++++++++++++++++++++++++++++- source4/libcli/auth/kerberos.h | 7 +- source4/libcli/auth/kerberos_verify.c | 75 +++++++--- 3 files changed, 318 insertions(+), 28 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index f5f02d1421..260b256934 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -38,14 +38,167 @@ enum GENSEC_KRB5_STATE { struct gensec_krb5_state { TALLOC_CTX *mem_ctx; DATA_BLOB session_key; - DATA_BLOB pac; + struct PAC_LOGON_INFO logon_info; enum GENSEC_KRB5_STATE state_position; krb5_context krb5_context; krb5_auth_context krb5_auth_context; krb5_ccache krb5_ccache; krb5_data ticket; + krb5_keyblock krb5_keyblock; }; +static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, + struct PAC_SIGNATURE_DATA *sig, + struct gensec_krb5_state *gensec_krb5_state, + uint32 cksum_type) +{ + krb5_error_code ret; + krb5_crypto crypto; + Checksum cksum; + + cksum.cksumtype = (CKSUMTYPE)sig->type; + cksum.checksum.length = sizeof(sig->signature); + cksum.checksum.data = sig->signature; + + + ret = krb5_crypto_init(gensec_krb5_state->krb5_context, + &gensec_krb5_state->krb5_keyblock, + cksum_type, + &crypto); + if (ret) { + DEBUG(0,("krb5_crypto_init() failed\n")); + return NT_STATUS_FOOBAR; + } + + ret = krb5_verify_checksum(gensec_krb5_state->krb5_context, + crypto, + cksum_type, + pac_data.data, + pac_data.length, + &cksum); + + krb5_crypto_destroy(gensec_krb5_state->krb5_context, crypto); + + if (ret) { + DEBUG(0,("NOT verifying PAC checksums yet!\n")); + //return NT_STATUS_LOGON_FAILURE; + } else { + DEBUG(0,("PAC checksums verified!\n")); + } + + return NT_STATUS_OK; +} + +NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, + struct PAC_LOGON_INFO *logon_info_out, + DATA_BLOB blob, + struct gensec_krb5_state *gensec_krb5_state) +{ + NTSTATUS status; + struct PAC_SIGNATURE_DATA srv_sig; + uint8_t *srv_key = NULL; + struct PAC_SIGNATURE_DATA kdc_sig; + uint8_t *kdc_key = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; + struct PAC_DATA pac_data; + DATA_BLOB tmp_blob; + int i; + + status = ndr_pull_struct_blob(&blob, mem_ctx, &pac_data, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("can't parse the PAC\n")); + return status; + } + + if (pac_data.num_buffers < 3) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("less than 3 PAC buffers\n")); + return NT_STATUS_FOOBAR; + } + + for (i=0; i < pac_data.num_buffers; i++) { + switch (pac_data.buffers[i].type) { + case PAC_TYPE_LOGON_INFO: + if (!pac_data.buffers[i].info) { + break; + } + logon_info = &pac_data.buffers[i].info->logon_info; + break; + case PAC_TYPE_SRV_CHECKSUM: + if (!pac_data.buffers[i].info) { + break; + } + srv_key = (uint8_t *)&pac_data.buffers[i].info->srv_cksum.signature; + srv_sig = pac_data.buffers[i].info->srv_cksum; + break; + case PAC_TYPE_KDC_CHECKSUM: + if (!pac_data.buffers[i].info) { + break; + } + kdc_key = (uint8_t *)&pac_data.buffers[i].info->kdc_cksum.signature; + kdc_sig = pac_data.buffers[i].info->kdc_cksum; + break; + case PAC_TYPE_UNKNOWN_10: + break; + default: + break; + } + } + + if (!logon_info) { + DEBUG(0,("PAC no logon_info\n")); + return NT_STATUS_FOOBAR; + } + + if (!srv_key) { + DEBUG(0,("PAC no srv_key\n")); + return NT_STATUS_FOOBAR; + } + + if (!kdc_key) { + DEBUG(0,("PAC no kdc_key\n")); + return NT_STATUS_FOOBAR; + } + + /* clear the kdc_key */ + memset(kdc_key , '\0', 16); + + status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, + (ndr_push_flags_fn_t)ndr_push_PAC_DATA); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* verify by kdc_key */ + status = gensec_krb5_pac_checksum(tmp_blob, &kdc_sig, gensec_krb5_state, 0); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* clear the service_key */ + memset(srv_key , '\0', 16); + + status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, + (ndr_push_flags_fn_t)ndr_push_PAC_DATA); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* verify by servie_key */ + status = gensec_krb5_pac_checksum(tmp_blob, &srv_sig, gensec_krb5_state, 0); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + DEBUG(0,("account_name: %s [%s]\n",logon_info->account_name.string, logon_info->full_name.string)); + *logon_info_out = *logon_info; + + return status; +} + static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state; @@ -334,7 +487,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL } return nt_status; } - + case GENSEC_KRB5_SERVER_START: { char *principal; @@ -348,19 +501,25 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context, lp_realm(), &in, - &principal, &pac, &unwrapped_out); + &principal, &pac, &unwrapped_out, + &gensec_krb5_state->krb5_keyblock); } else { /* TODO: check the tok_id */ nt_status = ads_verify_ticket(out_mem_ctx, gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context, lp_realm(), &unwrapped_in, - &principal, &pac, &unwrapped_out); + &principal, &pac, &unwrapped_out, + &gensec_krb5_state->krb5_keyblock); } - gensec_krb5_state->pac = data_blob_talloc_steal(out_mem_ctx, gensec_krb5_state->mem_ctx, - &pac); - /* TODO: parse the pac */ + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + /* decode and verify the pac */ + nt_status = gensec_krb5_decode_pac(gensec_krb5_state->mem_ctx, &gensec_krb5_state->logon_info, pac, + gensec_krb5_state); if (NT_STATUS_IS_OK(nt_status)) { gensec_krb5_state->state_position = GENSEC_KRB5_DONE; @@ -413,6 +572,95 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, return NT_STATUS_NO_USER_SESSION_KEY; } } +/* +struct gensec_krb5_state { + TALLOC_CTX *mem_ctx; + DATA_BLOB session_key; + struct PAC_LOGON_INFO logon_info; + enum GENSEC_KRB5_STATE state_position; + krb5_context krb5_context; + krb5_auth_context krb5_auth_context; + krb5_ccache krb5_ccache; + krb5_data ticket; + krb5_keyblock krb5_keyblock; +}; +struct auth_session_info +{ + TALLOC_CTX *mem_ctx; + + int refcount; + + NT_USER_TOKEN *nt_user_token; + + struct auth_serversupplied_info *server_info; + + DATA_BLOB session_key; + + const char *workstation; +}; +*/ +static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info_out) +{ + struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + TALLOC_CTX *mem_ctx; + struct auth_session_info *session_info = NULL; + struct PAC_LOGON_INFO *logon_info = &gensec_krb5_state->logon_info; + struct nt_user_token *ptoken; + struct dom_sid *sid; + + *session_info_out = NULL; + + mem_ctx = talloc_init("krb5: session_info"); + + session_info = talloc_p(mem_ctx, struct auth_session_info); + if (!session_info) { + return NT_STATUS_NO_MEMORY; + } + + session_info->mem_ctx = mem_ctx; + session_info->refcount = 1; + session_info->server_info = NULL; + + ptoken = talloc_p(session_info->mem_ctx, struct nt_user_token); + if (!ptoken) { + return NT_STATUS_NO_MEMORY; + } + + ptoken->num_sids = 0; + + ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, logon_info->groups_count + 2); + if (!ptoken->user_sids) { + return NT_STATUS_NO_MEMORY; + } + + + sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); + ptoken->user_sids[0] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->user_rid); + ptoken->num_sids++; + sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); + ptoken->user_sids[1] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->group_rid); + ptoken->num_sids++; + + for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) { + sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); + ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->groups[ptoken->num_sids - 2].rid); + } + + debug_nt_user_token(DBGC_AUTH, 0, ptoken); + + session_info->nt_user_token = ptoken; + + session_info->session_key = data_blob_talloc(session_info->mem_ctx, + gensec_krb5_state->session_key.data, + gensec_krb5_state->session_key.length); + + session_info->workstation = NULL; + + *session_info_out = session_info; + + return NT_STATUS_OK; +} static const struct gensec_security_ops gensec_krb5_security_ops = { @@ -423,6 +671,7 @@ static const struct gensec_security_ops gensec_krb5_security_ops = { .server_start = gensec_krb5_server_start, .update = gensec_krb5_update, .session_key = gensec_krb5_session_key, + .session_info = gensec_krb5_session_info, .end = gensec_krb5_end }; @@ -434,6 +683,7 @@ static const struct gensec_security_ops gensec_ms_krb5_security_ops = { .server_start = gensec_krb5_server_start, .update = gensec_krb5_update, .session_key = gensec_krb5_session_key, + .session_info = gensec_krb5_session_info, .end = gensec_krb5_end }; diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index ca796d0c86..e35079a4ee 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -47,6 +47,10 @@ krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_con void krb5_free_unparsed_name(krb5_context ctx, char *val); #endif +#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) +const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ); +#endif + /* Samba wrapper function for krb5 functionality. */ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr); int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); @@ -68,7 +72,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_auth_context auth_context, const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep); + DATA_BLOB *ap_rep, + krb5_keyblock *keyblock); int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, const char *principal, const char *password, time_t *expire_time, time_t *kdc_time); #endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 5cd22b3749..d1f0433ccc 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -26,6 +26,33 @@ #ifdef HAVE_KRB5 +static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) +{ + DATA_BLOB out; + DATA_BLOB pac_contents = data_blob(NULL, 0); + ASN1_DATA data; + int data_type; + + asn1_load(&data, *auth_data); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_Integer(&data, &data_type); + asn1_end_tag(&data); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_read_OctetString(&data, &pac_contents); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_free(&data); + + out = data_blob_talloc(mem_ctx, pac_contents.data, pac_contents.length); + + data_blob_free(&pac_contents); + + return out; +} + /********************************************************************************** Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so it's more like what microsoft does... see comment in utils/net_ads.c in the @@ -33,7 +60,8 @@ ***********************************************************************************/ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, + krb5_keyblock *keyblock) { krb5_error_code ret = 0; BOOL auth_ok = False; @@ -46,6 +74,8 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut ZERO_STRUCT(kt_entry); ZERO_STRUCT(cursor); + ZERO_STRUCTP(keyblock); + ret = krb5_kt_default(context, &keytab); if (ret) { DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret))); @@ -75,17 +105,22 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut p_packet->length = ticket->length; p_packet->data = (krb5_pointer)ticket->data; - if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { + ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt); + if (!ret) { unsigned int keytype; krb5_free_unparsed_name(context, princ_name); princ_name = NULL; #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK keytype = (unsigned int) kt_entry.keyblock.keytype; + copy_EncryptionKey(&kt_entry.keyblock, keyblock); #else keytype = (unsigned int) kt_entry.key.enctype; + /* I'not sure if that works --metze*/ + copy_EncryptionKey(&kt_entry.key, keyblock); #endif DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", keytype)); + auth_ok = True; break; } @@ -124,7 +159,8 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, krb5_principal host_princ, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, + krb5_keyblock *keyblock) { krb5_error_code ret = 0; BOOL auth_ok = False; @@ -133,6 +169,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_enctype *enctypes = NULL; int i; + ZERO_STRUCTP(keyblock); + if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); return False; @@ -160,30 +198,24 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { - krb5_keyblock *key = NULL; - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - goto out; - } - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { - SAFE_FREE(key); + if (create_kerberos_key_from_string(context, host_princ, &password, keyblock, enctypes[i])) { continue; } - krb5_auth_con_setuseruserkey(context, auth_context, key); - - krb5_free_keyblock(context, key); + krb5_auth_con_setuseruserkey(context, auth_context, keyblock); - if (!(ret = krb5_rd_req(context, &auth_context, p_packet, + ret = krb5_rd_req(context, &auth_context, p_packet, NULL, - NULL, NULL, pp_tkt))) { + NULL, NULL, pp_tkt); + if (!ret) { DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); auth_ok = True; break; } - + + free_EncryptionKey(keyblock); + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", (unsigned int)enctypes[i], error_message(ret))); @@ -207,7 +239,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_auth_context auth_context, const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep) + DATA_BLOB *ap_rep, + krb5_keyblock *keyblock) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_data packet; @@ -267,10 +300,10 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au goto out; } - auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt); + auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, keyblock); if (!auth_ok) { auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &packet, &tkt); + ticket, &packet, &tkt, keyblock); } release_server_mutex(); @@ -299,6 +332,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au get_auth_data_from_tkt(mem_ctx, auth_data, tkt); + *auth_data = unwrap_pac(mem_ctx, auth_data); + #if 0 if (tkt->enc_part2) { file_save("/tmp/authdata.dat", -- cgit From 2e28edd233964f54b46fde10217f93f571ed1d6d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 08:00:45 +0000 Subject: r1771: OK Let's add tests for ldap. Thanks to Metze and Volker for their unvaluable support :) (This used to be commit e6a6c0737ab94d58930c0d4e1ef0bb4d99510833) --- source4/libcli/ldap/ldap.c | 17 ++++++++++++++--- source4/libcli/util/asn1.c | 2 -- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index ef1d43022f..63dd7d4c7b 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -58,6 +58,7 @@ struct ldap_parse_tree { }; #define LDAP_ALL_SEP "()&|=!" +#define LDAP_CONNECTION_TIMEOUT 10000 /* return next token element. Caller frees @@ -1534,6 +1535,8 @@ struct ldap_connection *new_ldap_connection(void) result->outstanding = NULL; result->searchid = 0; result->search_entries = NULL; + result->auth_dn = NULL; + result->simple_pw = NULL; return result; } @@ -1553,7 +1556,7 @@ BOOL ldap_connect(struct ldap_connection *conn, const char *url) putip((char *)&ip, (char *)hp->h_addr); - conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, 10000); + conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); return (conn->sock >= 0); } @@ -1753,9 +1756,17 @@ BOOL ldap_setup_connection(struct ldap_connection *conn, msg->messageid = conn->next_msgid++; msg->type = LDAP_TAG_BindRequest; msg->r.BindRequest.version = 3; - msg->r.BindRequest.dn = conn->auth_dn; + if (conn->auth_dn) { + msg->r.BindRequest.dn = conn->auth_dn; + } else { + msg->r.BindRequest.dn = ""; + } msg->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - msg->r.BindRequest.creds.password = conn->simple_pw; + if (conn->simple_pw) { + msg->r.BindRequest.creds.password = conn->simple_pw; + } else { + msg->r.BindRequest.creds.password = ""; + } if ((response = ldap_transaction(conn, msg)) == NULL) return False; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 6ddce7882c..6dc459d59d 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -313,7 +313,6 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) return !data->has_error; } -#if 0 static BOOL read_one_uint8(int sock, uint8_t *result, ASN1_DATA *data, const struct timeval *endtime) { @@ -375,7 +374,6 @@ BOOL asn1_read_sequence_until(int sock, ASN1_DATA *data, return True; } -#endif /* Get the length to be expected in buf */ BOOL asn1_object_length(uint8_t *buf, size_t buf_length, -- cgit From 425caa9b78e76d943988fcc53e1b2e38cdaa18be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 18:43:35 +0000 Subject: r1784: a few minor changes and debug the decoded PAC_DATA metze (This used to be commit 250485b69fbdd494bfd6c69bae94662e24fb0117) --- source4/libcli/auth/gensec_krb5.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 260b256934..18053b5ded 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -96,9 +96,9 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, { NTSTATUS status; struct PAC_SIGNATURE_DATA srv_sig; - uint8_t *srv_key = NULL; + struct PAC_SIGNATURE_DATA *srv_sig_ptr; struct PAC_SIGNATURE_DATA kdc_sig; - uint8_t *kdc_key = NULL; + struct PAC_SIGNATURE_DATA *kdc_sig_ptr; struct PAC_LOGON_INFO *logon_info = NULL; struct PAC_DATA pac_data; DATA_BLOB tmp_blob; @@ -111,6 +111,8 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, return status; } + NDR_PRINT_DEBUG(PAC_DATA, &pac_data); + if (pac_data.num_buffers < 3) { /* we need logon_ingo, service_key and kdc_key */ DEBUG(0,("less than 3 PAC buffers\n")); @@ -129,14 +131,14 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, if (!pac_data.buffers[i].info) { break; } - srv_key = (uint8_t *)&pac_data.buffers[i].info->srv_cksum.signature; + srv_sig_ptr = &pac_data.buffers[i].info->srv_cksum; srv_sig = pac_data.buffers[i].info->srv_cksum; break; case PAC_TYPE_KDC_CHECKSUM: if (!pac_data.buffers[i].info) { break; } - kdc_key = (uint8_t *)&pac_data.buffers[i].info->kdc_cksum.signature; + kdc_sig_ptr = &pac_data.buffers[i].info->kdc_cksum; kdc_sig = pac_data.buffers[i].info->kdc_cksum; break; case PAC_TYPE_UNKNOWN_10: @@ -151,18 +153,18 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, return NT_STATUS_FOOBAR; } - if (!srv_key) { + if (!srv_sig_ptr) { DEBUG(0,("PAC no srv_key\n")); return NT_STATUS_FOOBAR; } - if (!kdc_key) { + if (!kdc_sig_ptr) { DEBUG(0,("PAC no kdc_key\n")); return NT_STATUS_FOOBAR; } /* clear the kdc_key */ - memset(kdc_key , '\0', 16); + memset((void *)kdc_sig_ptr , '\0', sizeof(*kdc_sig_ptr)); status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, (ndr_push_flags_fn_t)ndr_push_PAC_DATA); @@ -178,7 +180,7 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, } /* clear the service_key */ - memset(srv_key , '\0', 16); + memset((void *)srv_sig_ptr , '\0', sizeof(*srv_sig_ptr)); status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, (ndr_push_flags_fn_t)ndr_push_PAC_DATA); -- cgit From 28ea8b8785e5e8e3b3f3ddf0c12c0c8c69ea77c5 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 19:29:52 +0000 Subject: r1785: remove unneeded dependencies on openldap client libraries (This used to be commit 44083e317855f6d8a0b4a81002a3376e8775df28) --- source4/libcli/ldap/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 63dd7d4c7b..5afd595293 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -596,13 +596,13 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); if (strequal(attr_name, "add")) - mod.type = LDAP_MOD_ADD; + mod.type = LDAP_MODIFY_ADD; if (strequal(attr_name, "delete")) - mod.type = LDAP_MOD_DELETE; + mod.type = LDAP_MODIFY_DELETE; if (strequal(attr_name, "replace")) - mod.type = LDAP_MOD_REPLACE; + mod.type = LDAP_MODIFY_REPLACE; if (mod.type == LDAP_MODIFY_NONE) { DEBUG(2, ("ldif modification type %s unsupported\n", @@ -1537,6 +1537,7 @@ struct ldap_connection *new_ldap_connection(void) result->search_entries = NULL; result->auth_dn = NULL; result->simple_pw = NULL; + return result; } -- cgit From 2a574e22453161b8aa9578a6b512e05e5f7720a3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 21:15:35 +0000 Subject: r1790: a few updates on krb5 PAC... metze (This used to be commit 5a3a10c004ee2c94c42f08d52b36c75b413bdb79) --- source4/libcli/auth/gensec_krb5.c | 40 +++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 18053b5ded..0effed2198 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -50,7 +50,7 @@ struct gensec_krb5_state { static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, struct PAC_SIGNATURE_DATA *sig, struct gensec_krb5_state *gensec_krb5_state, - uint32 cksum_type) + uint32 keyusage) { krb5_error_code ret; krb5_crypto crypto; @@ -63,20 +63,27 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, ret = krb5_crypto_init(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_keyblock, - cksum_type, + 0, &crypto); if (ret) { DEBUG(0,("krb5_crypto_init() failed\n")); return NT_STATUS_FOOBAR; } - +{ +int i; +for (i=0; i < 40; i++) { + keyusage = i; ret = krb5_verify_checksum(gensec_krb5_state->krb5_context, crypto, - cksum_type, + keyusage, pac_data.data, pac_data.length, &cksum); - + if (!ret) { + DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage)); + break; + } +}} krb5_crypto_destroy(gensec_krb5_state->krb5_context, crypto); if (ret) { @@ -89,7 +96,7 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, return NT_STATUS_OK; } -NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, +static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, struct PAC_LOGON_INFO *logon_info_out, DATA_BLOB blob, struct gensec_krb5_state *gensec_krb5_state) @@ -101,7 +108,7 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, struct PAC_SIGNATURE_DATA *kdc_sig_ptr; struct PAC_LOGON_INFO *logon_info = NULL; struct PAC_DATA pac_data; - DATA_BLOB tmp_blob; + DATA_BLOB tmp_blob = data_blob(NULL, 0); int i; status = ndr_pull_struct_blob(&blob, mem_ctx, &pac_data, @@ -110,7 +117,6 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, DEBUG(0,("can't parse the PAC\n")); return status; } - NDR_PRINT_DEBUG(PAC_DATA, &pac_data); if (pac_data.num_buffers < 3) { @@ -164,13 +170,20 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, } /* clear the kdc_key */ - memset((void *)kdc_sig_ptr , '\0', sizeof(*kdc_sig_ptr)); +/* memset((void *)kdc_sig_ptr , '\0', sizeof(*kdc_sig_ptr));*/ status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, (ndr_push_flags_fn_t)ndr_push_PAC_DATA); if (!NT_STATUS_IS_OK(status)) { return status; } + status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("can't parse the PAC\n")); + return status; + } + /*NDR_PRINT_DEBUG(PAC_DATA, &pac_data);*/ /* verify by kdc_key */ status = gensec_krb5_pac_checksum(tmp_blob, &kdc_sig, gensec_krb5_state, 0); @@ -180,13 +193,20 @@ NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, } /* clear the service_key */ - memset((void *)srv_sig_ptr , '\0', sizeof(*srv_sig_ptr)); +/* memset((void *)srv_sig_ptr , '\0', sizeof(*srv_sig_ptr));*/ status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, (ndr_push_flags_fn_t)ndr_push_PAC_DATA); if (!NT_STATUS_IS_OK(status)) { return status; } + status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("can't parse the PAC\n")); + return status; + } + NDR_PRINT_DEBUG(PAC_DATA, &pac_data); /* verify by servie_key */ status = gensec_krb5_pac_checksum(tmp_blob, &srv_sig, gensec_krb5_state, 0); -- cgit From 16c52f7a0786a2583c32fb44ee12ff4f1863f355 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 22:23:57 +0000 Subject: r1792: split ldap_setup_connection() and provide an ldap_bind_simple() function (This used to be commit d9f8f97c9eaa8078f411adf0a8db607365082197) --- source4/libcli/ldap/ldap.c | 64 ++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 22 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5afd595293..d7c24e8c03 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1739,42 +1739,62 @@ struct ldap_message *ldap_transaction(struct ldap_connection *conn, return ldap_receive(conn, request->messageid, NULL); } -BOOL ldap_setup_connection(struct ldap_connection *conn, - const char *url) +struct ldap_message *ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) { - struct ldap_message *msg = new_ldap_message(); struct ldap_message *response; - BOOL result; + struct ldap_message *msg; + const char *dn, *pw; - if (msg == NULL) + if (conn == NULL || msg == NULL) return False; - if (!ldap_connect(conn, url)) { - destroy_ldap_message(msg); - return False; - } - - msg->messageid = conn->next_msgid++; - msg->type = LDAP_TAG_BindRequest; - msg->r.BindRequest.version = 3; - if (conn->auth_dn) { - msg->r.BindRequest.dn = conn->auth_dn; + if (userdn) { + dn = userdn; } else { - msg->r.BindRequest.dn = ""; + if (conn->auth_dn) { + dn = conn->auth_dn; + } else { + dn = ""; + } } - msg->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - if (conn->simple_pw) { - msg->r.BindRequest.creds.password = conn->simple_pw; + + if (password) { + pw = password; } else { - msg->r.BindRequest.creds.password = ""; + if (conn->simple_pw) { + pw = conn->simple_pw; + } else { + pw = ""; + } } - if ((response = ldap_transaction(conn, msg)) == NULL) + msg = new_ldap_simple_bind_msg(dn, pw); + if (!msg) return False; - result = (response->r.BindResponse.response.resultcode == 0); + response = ldap_transaction(conn, msg); destroy_ldap_message(msg); + return response; +} + +BOOL ldap_setup_connection(struct ldap_connection *conn, + const char *url, const char *userdn, const char *password) +{ + struct ldap_message *response; + BOOL result; + + if (!ldap_connect(conn, url)) { + return False; + } + + response = ldap_bind_simple(conn, userdn, password); + if (response == NULL) { + result = False; + } else { + result = (response->r.BindResponse.response.resultcode == 0); + } + destroy_ldap_message(response); return result; } -- cgit From 184bb1ab41b023b3953494ffdf0d334a55132d73 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 22:25:49 +0000 Subject: r1794: fix the build MIT krb5 metze (This used to be commit fe655d047434422eae77486e5fd7fa51eb942677) --- source4/libcli/auth/gensec_krb5.c | 6 ++++-- source4/libcli/auth/kerberos_verify.c | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 0effed2198..72def2d79e 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -47,6 +47,7 @@ struct gensec_krb5_state { krb5_keyblock krb5_keyblock; }; +#ifdef KRB5_DO_VERIFY_PAC static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, struct PAC_SIGNATURE_DATA *sig, struct gensec_krb5_state *gensec_krb5_state, @@ -95,6 +96,7 @@ for (i=0; i < 40; i++) { return NT_STATUS_OK; } +#endif static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, struct PAC_LOGON_INFO *logon_info_out, @@ -168,7 +170,7 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, DEBUG(0,("PAC no kdc_key\n")); return NT_STATUS_FOOBAR; } - +#ifdef KRB5_DO_VERIFY_PAC /* clear the kdc_key */ /* memset((void *)kdc_sig_ptr , '\0', sizeof(*kdc_sig_ptr));*/ @@ -214,7 +216,7 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { return status; } - +#endif DEBUG(0,("account_name: %s [%s]\n",logon_info->account_name.string, logon_info->full_name.string)); *logon_info_out = *logon_info; diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index d1f0433ccc..88bf391cfa 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -115,8 +115,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut copy_EncryptionKey(&kt_entry.keyblock, keyblock); #else keytype = (unsigned int) kt_entry.key.enctype; - /* I'not sure if that works --metze*/ - copy_EncryptionKey(&kt_entry.key, keyblock); + /* TODO: copy the keyblock on MIT krb5*/ #endif DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", keytype)); @@ -214,7 +213,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au break; } - free_EncryptionKey(keyblock); + krb5_free_keyblock(context, keyblock); DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", -- cgit From 7b088a8f654f34911928dcdf320ca3cf79592aed Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Aug 2004 00:16:57 +0000 Subject: r1796: Enable server-side SPNEGO, now that I have fixed the server-side SMB signing code to be able to cope. Andrew Bartlett (This used to be commit cb74d52b563730a50e33c92d868c45ee96a598e8) --- source4/libcli/raw/smb_signing.c | 109 ++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 43 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 0b9c2864d3..bd29abe3e6 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -21,26 +21,37 @@ */ #include "includes.h" -static BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info); /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL set_smb_signing_common(struct smbcli_transport *transport) +BOOL set_smb_signing_common(struct smb_signing_context *sign_info) { - if (!(transport->negotiate.sec_mode & - (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) { - DEBUG(5, ("SMB Signing is not negotiated by the peer\n")); + if (sign_info->doing_signing) { + DEBUG(5, ("SMB Signing already in progress, so we don't start it again\n")); return False; } - if (transport->negotiate.sign_info.doing_signing) { - DEBUG(5, ("SMB Signing already in progress, so we don't start it again\n")); + if (!sign_info->allow_smb_signing) { + DEBUG(5, ("SMB Signing has been locally disabled\n")); return False; } - if (!transport->negotiate.sign_info.allow_smb_signing) { - DEBUG(5, ("SMB Signing has been locally disabled\n")); + return True; +} + +/*********************************************************** + SMB signing - Common code before we set a new signing implementation +************************************************************/ +static BOOL smbcli_set_smb_signing_common(struct smbcli_transport *transport) +{ + if (!set_smb_signing_common(&transport->negotiate.sign_info)) { + return False; + } + + if (!(transport->negotiate.sec_mode & + (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) { + DEBUG(5, ("SMB Signing is not negotiated by the peer\n")); return False; } @@ -51,7 +62,7 @@ static BOOL set_smb_signing_common(struct smbcli_transport *transport) return True; } -static void mark_packet_signed(struct request_buffer *out) +void mark_packet_signed(struct request_buffer *out) { uint16_t flags2; flags2 = SVAL(out->hdr, HDR_FLG2); @@ -59,7 +70,7 @@ static void mark_packet_signed(struct request_buffer *out) SSVAL(out->hdr, HDR_FLG2, flags2); } -static BOOL signing_good(struct smb_signing_context *sign_info, +BOOL signing_good(struct smb_signing_context *sign_info, unsigned int seq, BOOL good) { if (good) { @@ -166,6 +177,19 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (i == 0) { + if (!good) { + DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", seq_num + i)); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", seq_num + i)); + dump_data(5, server_sent_mac, 8); + } else { + DEBUG(15, ("check_signed_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", seq_num + i)); + dump_data(5, server_sent_mac, 8); + } + } + if (good) break; } @@ -173,17 +197,20 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, seq_num)); } - if (!good) { - DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", seq_num + i)); - dump_data(5, calc_md5_mac, 8); - - DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", seq_num + i)); - dump_data(5, server_sent_mac, 8); + return good; +} + +static void smbcli_req_allocate_seq_num(struct smbcli_request *req) +{ + req->seq_num = req->transport->negotiate.sign_info.next_seq_num; + + /* some requests (eg. NTcancel) are one way, and the sequence number + should be increased by 1 not 2 */ + if (req->sign_single_increment) { + req->transport->negotiate.sign_info.next_seq_num += 1; } else { - DEBUG(15, ("check_signed_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", seq_num + i)); - dump_data(5, server_sent_mac, 8); + req->transport->negotiate.sign_info.next_seq_num += 2; } - return good; } /*********************************************************** @@ -212,16 +239,7 @@ void smbcli_request_calculate_sign_mac(struct smbcli_request *req) case SMB_SIGNING_ENGINE_ON: - req->seq_num = req->transport->negotiate.sign_info.next_seq_num; - - /* some requests (eg. NTcancel) are one way, and the sequence number - should be increased by 1 not 2 */ - if (req->sign_single_increment) { - req->transport->negotiate.sign_info.next_seq_num += 1; - } else { - req->transport->negotiate.sign_info.next_seq_num += 2; - } - + smbcli_req_allocate_seq_num(req); sign_outgoing_message(&req->out, &req->transport->negotiate.sign_info.mac_key, req->seq_num); @@ -237,10 +255,11 @@ void smbcli_request_calculate_sign_mac(struct smbcli_request *req) @note Used as an initialisation only - it will not correctly shut down a real signing mechanism */ -static BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info) +BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info) { DEBUG(5, ("Shutdown SMB signing\n")); sign_info->doing_signing = False; + sign_info->next_seq_num = 0; data_blob_free(&sign_info->mac_key); sign_info->signing_state = SMB_SIGNING_ENGINE_OFF; return True; @@ -252,7 +271,7 @@ static BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info) */ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) { - if (!set_smb_signing_common(transport)) { + if (!smbcli_set_smb_signing_common(transport)) { return False; } DEBUG(5, ("BSRSPYL SMB signing enabled\n")); @@ -302,9 +321,9 @@ BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -static BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, - const DATA_BLOB user_session_key, - const DATA_BLOB response) +BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, + const DATA_BLOB *user_session_key, + const DATA_BLOB *response) { if (sign_info->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -312,12 +331,16 @@ static BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, DEBUG(5, ("SMB signing enabled!\n")); - sign_info->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&sign_info->mac_key.data[0], user_session_key.data, user_session_key.length); + if (response && response->length) { + sign_info->mac_key = data_blob(NULL, response->length + user_session_key->length); + } else { + sign_info->mac_key = data_blob(NULL, user_session_key->length); + } + + memcpy(&sign_info->mac_key.data[0], user_session_key->data, user_session_key->length); - if (response.length) { - memcpy(&sign_info->mac_key.data[user_session_key.length],response.data, response.length); + if (response && response->length) { + memcpy(&sign_info->mac_key.data[user_session_key->length],response->data, response->length); } dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length); @@ -338,13 +361,13 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, const DATA_BLOB user_session_key, const DATA_BLOB response) { - if (!set_smb_signing_common(transport)) { + if (!smbcli_set_smb_signing_common(transport)) { return False; } return smbcli_simple_set_signing(&transport->negotiate.sign_info, - user_session_key, - response); + &user_session_key, + &response); } -- cgit From 2129ba5082d10e3934b57074231a74150265fece Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 00:55:15 +0000 Subject: r1798: fix the build metze (This used to be commit a1bfc94ab35c426b75efedea0df21acec7d1eeed) --- source4/libcli/ldap/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index d7c24e8c03..16f775a451 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1705,9 +1705,10 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, while (True) { struct asn1_data data; - result = new_ldap_message(); BOOL res; + result = new_ldap_message(); + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) return NULL; -- cgit From 01b58ebf83eca8b3909f3ba5becd6615bb89039f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 13 Aug 2004 05:26:38 +0000 Subject: r1802: start to support SASL in our ldap libraries does not work yet but we are close currently we send the right data on wire and fail to decode the answer (This used to be commit 10baf585821bf1f10a3786045a0965000cdffd12) --- source4/libcli/ldap/ldap.c | 169 ++++++++++++++++++++++++++++++++++++++++----- source4/libcli/ldap/ldap.h | 15 +++- 2 files changed, 165 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 16f775a451..3048c94114 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -790,8 +790,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, r->mechanism | 0xa0); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); - asn1_write_OctetString(&data, r->creds.SASL.creds.data, - r->creds.SASL.creds.length); + asn1_write_OctetString(&data, r->creds.SASL.secblob.data, + r->creds.SASL.secblob.length); asn1_pop_tag(&data); break; default: @@ -1537,6 +1537,7 @@ struct ldap_connection *new_ldap_connection(void) result->search_entries = NULL; result->auth_dn = NULL; result->simple_pw = NULL; + result->gensec = NULL; return result; } @@ -1740,14 +1741,15 @@ struct ldap_message *ldap_transaction(struct ldap_connection *conn, return ldap_receive(conn, request->messageid, NULL); } -struct ldap_message *ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) +int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) { struct ldap_message *response; struct ldap_message *msg; const char *dn, *pw; + int result = LDAP_OTHER; - if (conn == NULL || msg == NULL) - return False; + if (conn == NULL) + return result; if (userdn) { dn = userdn; @@ -1771,33 +1773,152 @@ struct ldap_message *ldap_bind_simple(struct ldap_connection *conn, const char * msg = new_ldap_simple_bind_msg(dn, pw); if (!msg) - return False; + return result; response = ldap_transaction(conn, msg); + if (!response) { + destroy_ldap_message(msg); + return result; + } + + result = response->r.BindResponse.response.resultcode; destroy_ldap_message(msg); - return response; + destroy_ldap_message(response); + + return result; +} + +int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + struct ldap_message *response; + struct ldap_message *msg; + DATA_BLOB input = data_blob(NULL, 0); + DATA_BLOB output = data_blob(NULL, 0); + int result = LDAP_OTHER; + + if (conn == NULL) + return result; + + status = gensec_client_start(&conn->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); + return result; + } + + status = gensec_set_domain(conn->gensec, domain); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", + domain, nt_errstr(status))); + goto done; + } + + status = gensec_set_username(conn->gensec, username); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", + username, nt_errstr(status))); + goto done; + } + + status = gensec_set_password(conn->gensec, password); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto done; + } + + mem_ctx = talloc_init("ldap_bind_sasl"); + if (!mem_ctx) + goto done; + + status = gensec_update(conn->gensec, mem_ctx, + input, + &output); + + while(1) { + if (NT_STATUS_IS_OK(status) && output.length == 0) { + break; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { + break; + } + + msg = new_ldap_sasl_bind_msg("GSS-SPNEGO", &output); + if (!msg) + goto done; + + response = ldap_transaction(conn, msg); + destroy_ldap_message(msg); + + result = response->r.BindResponse.response.resultcode; + + if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + break; + } + + status = gensec_update(conn->gensec, mem_ctx, + response->r.BindResponse.SASL.creds, + &output); + + destroy_ldap_message(response); + } + +done: + if (conn->gensec) + gensec_end(&conn->gensec); + if (mem_ctx) + talloc_destroy(mem_ctx); + + return result; } BOOL ldap_setup_connection(struct ldap_connection *conn, const char *url, const char *userdn, const char *password) { - struct ldap_message *response; - BOOL result; + int result; if (!ldap_connect(conn, url)) { return False; } - response = ldap_bind_simple(conn, userdn, password); - if (response == NULL) { - result = False; - } else { - result = (response->r.BindResponse.response.resultcode == 0); + result = ldap_bind_simple(conn, userdn, password); + if (result == LDAP_SUCCESS) { + return True; } - destroy_ldap_message(response); - return result; + return False; +} + +BOOL ldap_setup_connection_with_sasl(struct ldap_connection *conn, const char *url, const char *username, const char *domain, const char *password) +{ + int result; + + if (!ldap_connect(conn, url)) { + return False; + } + + result = ldap_bind_sasl(conn, username, domain, password); + if (result == LDAP_SUCCESS) { + return True; + } + + return False; } static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, @@ -1856,6 +1977,22 @@ struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw) return res; } +struct ldap_message *new_ldap_sasl_bind_msg(const char *sasl_mechanism, DATA_BLOB *secblob) +{ + struct ldap_message *res = new_ldap_message(); + + if (res == NULL) + return NULL; + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = ""; + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); + res->r.BindRequest.creds.SASL.secblob = *secblob; + return res; +} + BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, const struct timeval *endtime) { diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 96c1b82ca3..fcd660f841 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -50,6 +50,12 @@ enum ldap_auth_mechanism { LDAP_AUTH_MECH_SASL = 3 }; +enum ldap_result_code { + LDAP_SUCCESS = 0, + LDAP_SASL_BIND_IN_PROGRESS = 0x0e, + LDAP_OTHER = 0x50 +}; + struct ldap_Result { int resultcode; const char *dn; @@ -71,7 +77,7 @@ struct ldap_BindRequest { const char *password; struct { const char *mechanism; - DATA_BLOB creds; + DATA_BLOB secblob; } SASL; } creds; }; @@ -79,8 +85,8 @@ struct ldap_BindRequest { struct ldap_BindResponse { struct ldap_Result response; union { - DATA_BLOB credentials; - } SASL_Credentials; + DATA_BLOB creds; + } SASL; }; struct ldap_UnbindRequest { @@ -241,6 +247,9 @@ struct ldap_connection { /* Outstanding LDAP requests that have not yet been replied to */ struct ldap_queue_entry *outstanding; + + /* Let's support SASL */ + struct gensec_security *gensec; }; #endif -- cgit From cd5421b8ab189a35fe4f546ed1a4893f20e24ab3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 06:27:02 +0000 Subject: r1803: more progress on sasl binds, but decoding the response still fails metze (This used to be commit f6c44201073df37881191509ffb7badee3baac71) --- source4/libcli/ldap/ldap.c | 30 +++++++++++++++++++++++++++--- source4/libcli/ldap/ldap.h | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 3048c94114..b17d5dc461 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1066,6 +1066,26 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_end_tag(data); } +static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, + ASN1_DATA *data, + enum ldap_request_tag tag, + struct ldap_BindResponse *BindResp) +{ + asn1_start_tag(data, ASN1_APPLICATION(tag)); + asn1_read_enumerated(data, &BindResp->response.resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.dn); + asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.errormessage); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, &tmp_blob); + BindResp->SASL.secblob = data_blob_talloc(mem_ctx, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + BindResp->SASL.secblob = data_blob(NULL, 0); + } + asn1_end_tag(data); +} + static BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldap_attribute *attrib, struct ldap_attribute **attribs, @@ -1261,9 +1281,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindResponse): { struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; - ldap_decode_response(msg->mem_ctx, + ldap_decode_BindResponse(msg->mem_ctx, data, LDAP_TAG_BindResponse, - &r->response); + r); break; } @@ -1866,6 +1886,10 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha response = ldap_transaction(conn, msg); destroy_ldap_message(msg); + if (!response) { + goto done; + } + result = response->r.BindResponse.response.resultcode; if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { @@ -1873,7 +1897,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha } status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.creds, + response->r.BindResponse.SASL.secblob, &output); destroy_ldap_message(response); diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index fcd660f841..af322e783a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -85,7 +85,7 @@ struct ldap_BindRequest { struct ldap_BindResponse { struct ldap_Result response; union { - DATA_BLOB creds; + DATA_BLOB secblob; } SASL; }; -- cgit From e0a6215cdfd7ea1aca95bc81c7ce4e40e5f545a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 07:04:45 +0000 Subject: r1804: get a bit closer to a sasl bind metze (This used to be commit d0278c6bef622feeda8da7a120e3d1abce4a74e5) --- source4/libcli/ldap/ldap.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b17d5dc461..5b22825da4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1066,6 +1066,23 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_end_tag(data); } +/* read a octet string blob */ +static BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) +{ + int len; + ZERO_STRUCTP(blob); + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return False; + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } + *blob = data_blob(NULL, len); + asn1_read(data, blob->data, len); + asn1_end_tag(data); + return !data->has_error; +} + static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, ASN1_DATA *data, enum ldap_request_tag tag, @@ -1075,9 +1092,9 @@ static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, asn1_read_enumerated(data, &BindResp->response.resultcode); asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.dn); asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.errormessage); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, &tmp_blob); + asn1_read_ContextSimple(data, 7, &tmp_blob); BindResp->SASL.secblob = data_blob_talloc(mem_ctx, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { -- cgit From 16757c52d626d324566f504774525641a4785cd9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 07:10:46 +0000 Subject: r1805: ...I just forgot to say that the sasl bind actually works now:-) metze (This used to be commit a2cd725681fa7b10a5cca337554be17f628465c0) --- source4/libcli/ldap/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5b22825da4..b6272f694e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -4,6 +4,8 @@ Copyright (C) Andrew Tridgell 2004 Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 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 -- cgit From 64082214337e2ab50f0a69ca7f9bcf56762129cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 14 Aug 2004 05:56:12 +0000 Subject: r1819: changed "smb ports" to be a LIST parameter type in loadparm (its a classic case for a list) (This used to be commit e53d32c65ab0751b3e01f4f699f5d0e1892369ae) --- source4/libcli/raw/clisocket.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 78d37b9be1..b09bebf133 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -62,8 +62,15 @@ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int por } if (port == 0) { - return smbcli_sock_connect(sock, ip, 445) || - smbcli_sock_connect(sock, ip, 139); + int i; + const char **ports = lp_smb_ports(); + for (i=0;ports[i];i++) { + int port = atoi(ports[i]); + if (port != 0 && smbcli_sock_connect(sock, ip, port)) { + return True; + } + } + return False; } sock->dest_ip = *ip; -- cgit From 39686072d5539003f8a2e2679311c5057ee82041 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 14 Aug 2004 18:24:33 +0000 Subject: r1824: nicer handling of NBT session replies, and handling of bad packets with the async SMB code (This used to be commit cef94978f43a8326b6cf1888c15ca8c568ebe9f8) --- source4/libcli/raw/clitransport.c | 6 ++++++ source4/libcli/raw/rawrequest.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 784a6f1798..03a0540be0 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -353,6 +353,12 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) req->in.size = len; req->in.allocated = req->in.size; + /* handle NBT session replies */ + if (req->in.buffer[0] != 0) { + req->status = NT_STATUS_OK; + goto async; + } + /* handle non-SMB replies */ if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) { req->state = SMBCLI_REQUEST_ERROR; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 70e924a99f..bc87af4297 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -252,7 +252,7 @@ static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_si To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ -static void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) +void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) { int delta; @@ -299,7 +299,7 @@ BOOL smbcli_request_receive(struct smbcli_request *req) event_loop_once(req->transport->event.ctx); } - return True; + return req->state == SMBCLI_REQUEST_DONE; } -- cgit From 69d643535837bc23d8f7274ce476cf803b45969b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Aug 2004 10:04:25 +0000 Subject: r1851: if we try to peek a subtag, check if the parent tag has remaining data metze (This used to be commit 01626ed381bdc9cab3e94e80220c916bb61acf30) --- source4/libcli/util/asn1.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 6dc459d59d..e7c38b2803 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -264,6 +264,10 @@ BOOL asn1_peek_tag(ASN1_DATA *data, uint8_t tag) { uint8_t b; + if (asn1_tag_remaining(data) <= 0) { + return False; + } + if (!asn1_peek(data, &b, sizeof(b))) return False; -- cgit From c074e30e2eacaacebb95efd755ad7de74a0970e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Aug 2004 11:22:44 +0000 Subject: r1856: - move asn1 functions to asn1.c - merge some stuff from trunk metze (This used to be commit 267edf1c0bb1ed73f1ba19148e6412b9a1c41979) --- source4/libcli/ldap/ldap.c | 90 ++++++++++++++++++++++++---------------------- source4/libcli/util/asn1.c | 24 +++++++++++++ 2 files changed, 71 insertions(+), 43 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b6272f694e..b319299b1e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -971,7 +971,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) break; } case LDAP_TAG_ModifyDNResponse: { -/* struct ldap_Result *r = &msg->r.ModifyDNResponse; */ + struct ldap_Result *r = &msg->r.ModifyDNResponse; + ldap_encode_response(msg->type, r, &data); break; } case LDAP_TAG_CompareRequest: { @@ -1061,46 +1062,12 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_read_enumerated(data, &result->resultcode); asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - else - result->referral = NULL; - asn1_end_tag(data); -} - -/* read a octet string blob */ -static BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) -{ - int len; - ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return False; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = True; - return False; - } - *blob = data_blob(NULL, len); - asn1_read(data, blob->data, len); - asn1_end_tag(data); - return !data->has_error; -} - -static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, - ASN1_DATA *data, - enum ldap_request_tag tag, - struct ldap_BindResponse *BindResp) -{ - asn1_start_tag(data, ASN1_APPLICATION(tag)); - asn1_read_enumerated(data, &BindResp->response.resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.dn); - asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - BindResp->SASL.secblob = data_blob_talloc(mem_ctx, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); + asn1_end_tag(data); } else { - BindResp->SASL.secblob = data_blob(NULL, 0); + result->referral = NULL; } asn1_end_tag(data); } @@ -1300,9 +1267,26 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindResponse): { struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; - ldap_decode_BindResponse(msg->mem_ctx, - data, LDAP_TAG_BindResponse, - r); + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindResponse)); + asn1_read_enumerated(data, &r->response.resultcode); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.dn); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.referral); + asn1_end_tag(data); + } else { + r->response.referral = NULL; + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = data_blob(NULL, 0); + } + asn1_end_tag(data); break; } @@ -1460,8 +1444,28 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { -/* struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; */ + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->newrdn); + asn1_read_BOOLEAN2(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + newsup = talloc(msg->mem_ctx, len+1); + if (newsup == NULL) + break; + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); break; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index e7c38b2803..1f04e1fe46 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -166,6 +166,14 @@ BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) return !data->has_error; } +BOOL asn1_write_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) +{ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); + asn1_write(data, blob->data, blob->length); + asn1_pop_tag(data); + return !data->has_error; +} + /* write a BOOLEAN */ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) { @@ -518,6 +526,22 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) return !data->has_error; } +BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) +{ + int len; + ZERO_STRUCTP(blob); + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return False; + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } + *blob = data_blob(NULL, len); + asn1_read(data, blob->data, len); + asn1_end_tag(data); + return !data->has_error; +} + /* read an interger */ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) { -- cgit From ebd696bd8c73d39a3f72624e25bf85965bdf93ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Aug 2004 14:34:01 +0000 Subject: r1862: add invalid_creds ldap error metze (This used to be commit 11c866d602fb4daefc1dced349606bd8ccd38ef2) --- source4/libcli/ldap/ldap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index af322e783a..b777bb5252 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -53,6 +53,7 @@ enum ldap_auth_mechanism { enum ldap_result_code { LDAP_SUCCESS = 0, LDAP_SASL_BIND_IN_PROGRESS = 0x0e, + LDAP_INVALID_CREDENTIALS = 0x31, LDAP_OTHER = 0x50 }; -- cgit From 46003a56a8508c0b15a763b5a723bb77eba32094 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Aug 2004 13:01:10 +0000 Subject: r1881: empty structs are not allowed by all compilers metze (This used to be commit 4c6c4d6bc8927b93f29beecf44aef5c228533a43) --- source4/libcli/ldap/ldap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index b777bb5252..da844afa3e 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -91,6 +91,7 @@ struct ldap_BindResponse { }; struct ldap_UnbindRequest { + uint8_t __dummy; }; enum ldap_scope { -- cgit From 7d032a99927d3d4ddfc5561e8a96d0315a28ed35 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Aug 2004 13:43:53 +0000 Subject: r1883: I don't know why this was broken... tridge: can you please check if this is correct, I have only compiled it, but haven'T run it. metze (This used to be commit d3123c2e7357d8db4dce9e0253ac405318d05c48) --- source4/libcli/raw/rawacl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 77374ae8b9..dde6b673a0 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -84,7 +84,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, } status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, query->out.sd); - return NT_STATUS_OK; + return status; } @@ -130,12 +130,12 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, ndr = ndr_push_init(); if (!ndr) return NULL; -// status = ndr_push_security_descriptor(ndr, set->in.sd); + status = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, set->in.sd); if (!NT_STATUS_IS_OK(status)) { ndr_push_free(ndr); return NULL; } - + nt.in.data = ndr_push_blob(ndr); req = smb_raw_nttrans_send(tree, &nt); -- cgit From 6e5a9a6fe4368748dae0c26bb7a019d848621e66 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 18 Aug 2004 14:11:11 +0000 Subject: r1886: Fix the build (This used to be commit 7be7f25a57422fea3e763479629e18dc9a204aba) --- source4/libcli/auth/ntlmssp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 9579f3612c..893e8520c2 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -932,7 +932,7 @@ NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | -// NTLMSSP_NEGOTIATE_NTLM2 | +/* NTLMSSP_NEGOTIATE_NTLM2 | */ NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL; @@ -965,7 +965,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, } if (ntlmssp_state->use_ntlmv2) { -// ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; +/* ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;*/ } /* generate the ntlmssp negotiate packet */ @@ -1287,7 +1287,7 @@ NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | -// NTLMSSP_NEGOTIATE_NTLM2 | +/* NTLMSSP_NEGOTIATE_NTLM2 |*/ NTLMSSP_NEGOTIATE_KEY_EXCH | /* * We need to set this to allow a later SetPassword -- cgit From acc885855ac17d3fafaa309ac2e6b7ac3c899f52 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 18 Aug 2004 18:31:23 +0000 Subject: r1893: add a commented out lump of code to implement the "by the SPEC" ALL_INFO queryfileinfo level. It is useful having it here as many non-Microsoft servers implement it this way, which breaks just about all the torture tests, so when testing against these broken systems just change this one #if line and recompile smbtorture. (This used to be commit cd8887293e7735d8ee1cc2daebda233673801775) --- source4/libcli/raw/rawfileinfo.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 8dc220b0b4..9b82bf6fa0 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -138,9 +138,24 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->all_info.out.nlink = IVAL(blob->data, 56); parms->all_info.out.delete_pending = CVAL(blob->data, 60); parms->all_info.out.directory = CVAL(blob->data, 61); +#if 1 parms->all_info.out.ea_size = IVAL(blob->data, 64); smbcli_blob_pull_string(session, mem_ctx, blob, &parms->all_info.out.fname, 68, 72, STR_UNICODE); +#else + /* this is what the CIFS spec says - and its totally + wrong, but its useful having it here so we can + quickly adapt to broken servers when running + tests */ + parms->all_info.out.ea_size = IVAL(blob->data, 72); + /* access flags 4 bytes at 76 + current_position 8 bytes at 80 + mode 4 bytes at 88 + alignment 4 bytes at 92 + */ + smbcli_blob_pull_string(session, mem_ctx, blob, + &parms->all_info.out.fname, 96, 100, STR_UNICODE); +#endif return NT_STATUS_OK; case RAW_FILEINFO_ALT_NAME_INFO: -- cgit From 5f1f1e5e5c52ec8c453b5ea688f87004541cc5bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 18 Aug 2004 20:07:44 +0000 Subject: r1896: stricter check on packet parsing for NBT session replies (This used to be commit 30ab38559e8c52ecdaf7ca9b124875ade82c5c66) --- source4/libcli/raw/clitransport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 03a0540be0..91f0f0f8f5 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -354,7 +354,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) req->in.allocated = req->in.size; /* handle NBT session replies */ - if (req->in.buffer[0] != 0) { + if (req->in.size >= 4 && req->in.buffer[0] != 0) { req->status = NT_STATUS_OK; goto async; } -- cgit From 1129c7808354dc04f7725be505fd23c0bf11a29d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 18 Aug 2004 20:13:08 +0000 Subject: r1897: added a choose_called_name() function that allows us to more sanely handle connections using the IP as the server name, while not trying for NBT name resolution on names like "192" and "192.168.1.2". also removed the ip address argument to smbcli_socket_connect() as it isn't used and doesn't really make sense. (This used to be commit 2ce4028842556328da4da0de9bee942bed02cc62) --- source4/libcli/cliconnect.c | 4 ++-- source4/libcli/nmblib.c | 29 +++++++++++++++++++++++++++++ source4/libcli/raw/clitree.c | 12 ++++++------ 3 files changed, 37 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 8753f26b5f..14f7d5a1b3 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -23,7 +23,7 @@ /* wrapper around smbcli_sock_connect() */ -BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server, struct in_addr *ip) +BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) { struct smbcli_socket *sock; @@ -163,7 +163,7 @@ NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, } status = smbcli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, - username, domain, password); + username, domain, password); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index e05eb7966e..5eeec48003 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -1285,3 +1285,32 @@ int name_len(char *s1) return(len); } /* name_len */ + + +/* + choose a name to use when calling a server in a NBT session request. + we use heuristics to see if the name we have been given is a IP + address, or a too-long name. If it is then use *SMBSERVER, or a + truncated name +*/ +void choose_called_name(struct nmb_name *n, const char *name, int type) +{ + if (is_ipaddress(name)) { + make_nmb_name(n, "*SMBSERVER", type); + return; + } + if (strlen(name) > 16) { + const char *p = strchr(name, '.'); + char name2[17]; + if (p - name > 16) { + make_nmb_name(n, "*SMBSERVER", type); + return; + } + strlcpy(name2, name, 1+(p-name)); + make_nmb_name(n, name2, type); + return; + } + + /* looks OK */ + make_nmb_name(n, name, type); +} diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index b9d572fd56..97c0910451 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -173,11 +173,11 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) parameters */ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, - const char *my_name, - const char *dest_host, int port, - const char *service, const char *service_type, - const char *user, const char *domain, - const char *password) + const char *my_name, + const char *dest_host, int port, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password) { struct smbcli_socket *sock; struct smbcli_transport *transport; @@ -212,7 +212,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, /* send a NBT session request, if applicable */ make_nmb_name(&calling, my_name, 0x0); - make_nmb_name(&called, dest_host, 0x20); + choose_called_name(&called, dest_host, 0x20); if (!smbcli_transport_connect(transport, &calling, &called)) { smbcli_transport_close(transport); -- cgit From f42f0612364045702cea7e66cacd24aa20ecb54e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Aug 2004 11:37:36 +0000 Subject: r1910: this should not be a local var in this block metze (This used to be commit 0164cac6df46ca5996aae30b8c48a602999f7e0b) --- source4/libcli/raw/clisocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index b09bebf133..343904999a 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -65,7 +65,7 @@ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int por int i; const char **ports = lp_smb_ports(); for (i=0;ports[i];i++) { - int port = atoi(ports[i]); + port = atoi(ports[i]); if (port != 0 && smbcli_sock_connect(sock, ip, port)) { return True; } -- cgit From 8d6e233f66616c97fcce935253e56cdd6117242e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 20 Aug 2004 00:03:13 +0000 Subject: r1941: - fixed an allocation error with querying security descriptors remotely - print the received security_descriptor in the smbclient "acl" command - make sure we zero the alignment data in nttrans packet sends (This used to be commit 8925b8b2193905d084e1bfaaa3235ed7f9d1eb55) --- source4/libcli/raw/rawacl.c | 2 +- source4/libcli/raw/rawtrans.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index dde6b673a0..20e6d6df31 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -78,7 +78,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, return NT_STATUS_INVALID_PARAMETER; } - query->out.sd = talloc(mem_ctx, sizeof(query->out.sd)); + query->out.sd = talloc_p(mem_ctx, struct security_descriptor); if (!query->out.sd) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 0c39abe880..53f8075822 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -480,6 +480,10 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, outparam = req->out.data + align; outdata = outparam + parms->in.params.length; + if (align != 0) { + memset(req->out.data, 0, align); + } + SCVAL(req->out.vwv, 0, parms->in.max_setup); SSVAL(req->out.vwv, 1, 0); /* reserved */ SIVAL(req->out.vwv, 3, parms->in.params.length); -- cgit From 333aaf01e8dc1aba8cb7bba3e8fa792ff136e647 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 20 Aug 2004 07:39:19 +0000 Subject: r1944: put ldif functions in a separate file (This used to be commit 8be31e5c854e4462163b97b897ff41de95f181c4) --- source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 411 ---------------------------------------- source4/libcli/ldap/ldap.h | 29 +++ source4/libcli/ldap/ldap_ldif.c | 409 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 440 insertions(+), 412 deletions(-) create mode 100644 source4/libcli/ldap/ldap_ldif.c (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 397cfe0b72..ac047214ca 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -ADD_OBJ_FILES = libcli/ldap/ldap.o +ADD_OBJ_FILES = libcli/ldap/ldap.o \ + libcli/ldap/ldap_ldif.o # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b319299b1e..123def9416 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -33,35 +33,6 @@ * ***************************************************************************/ -/* Hmm. A blob might be more appropriate here :-) */ - -struct ldap_val { - unsigned int length; - void *data; -}; - -enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; - -struct ldap_parse_tree { - enum ldap_parse_op operation; - union { - struct { - char *attr; - struct ldap_val value; - } simple; - struct { - unsigned int num_elements; - struct ldap_parse_tree **elements; - } list; - struct { - struct ldap_parse_tree *child; - } not; - } u; -}; - -#define LDAP_ALL_SEP "()&|=!" -#define LDAP_CONNECTION_TIMEOUT 10000 - /* return next token element. Caller frees */ @@ -379,372 +350,6 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) return !data->has_error; } -/**************************************************************************** - * - * LDIF parser - * - * Shamelessly stolen and adapted from Samba 4. - * - ***************************************************************************/ - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(TALLOC_CTX *mem_ctx, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, alloc_size); - if (!c2) { - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && - chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && - chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && - (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - -/* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldap_val *value) -{ - char *p; - int base64_encoded = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - *attr = *s; - - while (isspace(*p)) { - p++; - } - - value->data = p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - DATA_BLOB blob = base64_decode_data_blob(value->data); - memcpy(value->data, blob.data, blob.length); - value->length = blob.length; - ((char *)value->data)[value->length] = '\0'; - } - - return 0; -} - -static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, - struct ldap_attribute *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, attrib->values, - sizeof(*attrib->values) * - (attrib->num_values+1)); - if (attrib->values == NULL) - return False; - - attrib->values[attrib->num_values] = - data_blob_talloc(mem_ctx, value->data, value->length); - attrib->num_values += 1; - return True; -} - -static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) -{ - struct ldap_AddRequest *r = &msg->r.AddRequest; - const char *attr_name; - struct ldap_val value; - - r->num_attributes = 0; - r->attributes = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - int i; - struct ldap_attribute *attrib = NULL; - - for (i=0; inum_attributes; i++) { - if (strequal(r->attributes[i].name, attr_name)) { - attrib = &r->attributes[i]; - break; - } - } - - if (attrib == NULL) { - r->attributes = talloc_realloc(msg->mem_ctx, - r->attributes, - sizeof(*r->attributes) * - (r->num_attributes+1)); - if (r->attributes == NULL) - return False; - - attrib = &(r->attributes[r->num_attributes]); - r->num_attributes += 1; - ZERO_STRUCTP(attrib); - attrib->name = talloc_strdup(msg->mem_ctx, - attr_name); - } - - if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) - return False; - } - return True; -} - -static BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, - sizeof(**mods) * ((*num_mods)+1)); - - if (*mods == NULL) - return False; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return True; -} - -static BOOL fill_mods(struct ldap_message *msg, char **chunk) -{ - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - const char *attr_name; - struct ldap_val value; - - r->num_mods = 0; - r->mods = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - - struct ldap_mod mod; - mod.type = LDAP_MODIFY_NONE; - - mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); - - if (strequal(attr_name, "add")) - mod.type = LDAP_MODIFY_ADD; - - if (strequal(attr_name, "delete")) - mod.type = LDAP_MODIFY_DELETE; - - if (strequal(attr_name, "replace")) - mod.type = LDAP_MODIFY_REPLACE; - - if (mod.type == LDAP_MODIFY_NONE) { - DEBUG(2, ("ldif modification type %s unsupported\n", - attr_name)); - return False; - } - - mod.attrib.num_values = 0; - mod.attrib.values = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - if (strequal(attr_name, "-")) - break; - if (!strequal(attr_name, mod.attrib.name)) { - DEBUG(3, ("attrib name %s does not " - "match %s\n", attr_name, - mod.attrib.name)); - return False; - } - if (!add_value_to_attrib(msg->mem_ctx, &value, - &mod.attrib)) { - DEBUG(3, ("Could not add value\n")); - return False; - } - } - - if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, - &r->num_mods)) - return False; - } - - return True; -} - -/* - read from a LDIF source, creating a ldap_message -*/ -static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), - void *private_data) -{ - struct ldap_message *msg; - const char *attr=NULL; - const char *dn; - char *chunk=NULL, *s; - struct ldap_val value; - - value.data = NULL; - - msg = new_ldap_message(); - if (msg == NULL) - return NULL; - - chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - - s = chunk; - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (!strequal(attr, "dn")) { - DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", - attr)); - goto failed; - } - - dn = talloc_strdup(msg->mem_ctx, value.data); - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - if (!strequal(attr, "changetype")) { - DEBUG(5, ("Error: Second line of ldif must be a changetype " - "not '%s'\n", attr)); - goto failed; - } - - if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; - return msg; - } - - if (strequal(value.data, "add")) { - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = dn; - - if (!fill_add_attributes(msg, &s)) - goto failed; - - return msg; - } - - if (strequal(value.data, "modify")) { - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = dn; - - if (!fill_mods(msg, &s)) - goto failed; - - return msg; - } - - DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); - -failed: - destroy_ldap_message(msg); - return NULL; -} - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldap_message *ldap_ldif2msg(const char *s) -{ - struct ldif_read_string_state state; - state.s = s; - return ldif_read(fgetc_string, &state); -} - static void ldap_encode_response(enum ldap_request_tag tag, struct ldap_Result *result, ASN1_DATA *data) @@ -1072,22 +677,6 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_end_tag(data); } -static BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldap_attribute *attrib, - struct ldap_attribute **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, *attribs, - sizeof(**attribs) * (*num_attribs+1)); - - if (*attribs == NULL) - return False; - - (*attribs)[*num_attribs] = *attrib; - *num_attribs += 1; - return True; -} - static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, char **filter) { diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index da844afa3e..449be9e015 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -254,4 +254,33 @@ struct ldap_connection { struct gensec_security *gensec; }; +/* Hmm. A blob might be more appropriate here :-) */ + +struct ldap_val { + unsigned int length; + void *data; +}; + +enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; + +struct ldap_parse_tree { + enum ldap_parse_op operation; + union { + struct { + char *attr; + struct ldap_val value; + } simple; + struct { + unsigned int num_elements; + struct ldap_parse_tree **elements; + } list; + struct { + struct ldap_parse_tree *child; + } not; + } u; +}; + +#define LDAP_ALL_SEP "()&|=!" +#define LDAP_CONNECTION_TIMEOUT 10000 + #endif diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c new file mode 100644 index 0000000000..2f23dd16a6 --- /dev/null +++ b/source4/libcli/ldap/ldap_ldif.c @@ -0,0 +1,409 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + 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" + +/**************************************************************************** + * + * LDIF parser + * + * Shamelessly stolen and adapted from ldb. + * + ***************************************************************************/ + +/* + pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF + this routine removes any RFC2849 continuations and comments + + caller frees +*/ +static char *next_chunk(TALLOC_CTX *mem_ctx, + int (*fgetc_fn)(void *), void *private_data) +{ + size_t alloc_size=0, chunk_size = 0; + char *chunk = NULL; + int c; + int in_comment = 0; + + while ((c = fgetc_fn(private_data)) != EOF) { + if (chunk_size+1 >= alloc_size) { + char *c2; + alloc_size += 1024; + c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + if (!c2) { + errno = ENOMEM; + return NULL; + } + chunk = c2; + } + + if (in_comment) { + if (c == '\n') { + in_comment = 0; + } + continue; + } + + /* handle continuation lines - see RFC2849 */ + if (c == ' ' && chunk_size > 1 && + chunk[chunk_size-1] == '\n') { + chunk_size--; + continue; + } + + /* chunks are terminated by a double line-feed */ + if (c == '\n' && chunk_size > 0 && + chunk[chunk_size-1] == '\n') { + chunk[chunk_size-1] = 0; + return chunk; + } + + if (c == '#' && + (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { + in_comment = 1; + continue; + } + + /* ignore leading blank lines */ + if (chunk_size == 0 && c == '\n') { + continue; + } + + chunk[chunk_size++] = c; + } + + if (chunk) { + chunk[chunk_size] = 0; + } + + return chunk; +} + +/* simple ldif attribute parser */ +static int next_attr(char **s, const char **attr, struct ldap_val *value) +{ + char *p; + int base64_encoded = 0; + + if (strncmp(*s, "-\n", 2) == 0) { + value->length = 0; + *attr = "-"; + *s += 2; + return 0; + } + + p = strchr(*s, ':'); + if (!p) { + return -1; + } + + *p++ = 0; + + if (*p == ':') { + base64_encoded = 1; + p++; + } + + *attr = *s; + + while (isspace(*p)) { + p++; + } + + value->data = p; + + p = strchr(p, '\n'); + + if (!p) { + value->length = strlen((char *)value->data); + *s = ((char *)value->data) + value->length; + } else { + value->length = p - (char *)value->data; + *s = p+1; + *p = 0; + } + + if (base64_encoded) { + DATA_BLOB blob = base64_decode_data_blob(value->data); + memcpy(value->data, blob.data, blob.length); + value->length = blob.length; + ((char *)value->data)[value->length] = '\0'; + } + + return 0; +} + +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, + struct ldap_attribute *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, attrib->values, + sizeof(*attrib->values) * + (attrib->num_values+1)); + if (attrib->values == NULL) + return False; + + attrib->values[attrib->num_values] = + data_blob_talloc(mem_ctx, value->data, value->length); + attrib->num_values += 1; + return True; +} + +BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldap_attribute *attrib, + struct ldap_attribute **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, *attribs, + sizeof(**attribs) * (*num_attribs+1)); + + if (*attribs == NULL) + return False; + + (*attribs)[*num_attribs] = *attrib; + *num_attribs += 1; + return True; +} + +static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) +{ + struct ldap_AddRequest *r = &msg->r.AddRequest; + const char *attr_name; + struct ldap_val value; + + r->num_attributes = 0; + r->attributes = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + int i; + struct ldap_attribute *attrib = NULL; + + for (i=0; inum_attributes; i++) { + if (strequal(r->attributes[i].name, attr_name)) { + attrib = &r->attributes[i]; + break; + } + } + + if (attrib == NULL) { + r->attributes = talloc_realloc(msg->mem_ctx, + r->attributes, + sizeof(*r->attributes) * + (r->num_attributes+1)); + if (r->attributes == NULL) + return False; + + attrib = &(r->attributes[r->num_attributes]); + r->num_attributes += 1; + ZERO_STRUCTP(attrib); + attrib->name = talloc_strdup(msg->mem_ctx, + attr_name); + } + + if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) + return False; + } + return True; +} + +BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, + sizeof(**mods) * ((*num_mods)+1)); + + if (*mods == NULL) + return False; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return True; +} + +static BOOL fill_mods(struct ldap_message *msg, char **chunk) +{ + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + const char *attr_name; + struct ldap_val value; + + r->num_mods = 0; + r->mods = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + + struct ldap_mod mod; + mod.type = LDAP_MODIFY_NONE; + + mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); + + if (strequal(attr_name, "add")) + mod.type = LDAP_MODIFY_ADD; + + if (strequal(attr_name, "delete")) + mod.type = LDAP_MODIFY_DELETE; + + if (strequal(attr_name, "replace")) + mod.type = LDAP_MODIFY_REPLACE; + + if (mod.type == LDAP_MODIFY_NONE) { + DEBUG(2, ("ldif modification type %s unsupported\n", + attr_name)); + return False; + } + + mod.attrib.num_values = 0; + mod.attrib.values = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + if (strequal(attr_name, "-")) + break; + if (!strequal(attr_name, mod.attrib.name)) { + DEBUG(3, ("attrib name %s does not " + "match %s\n", attr_name, + mod.attrib.name)); + return False; + } + if (!add_value_to_attrib(msg->mem_ctx, &value, + &mod.attrib)) { + DEBUG(3, ("Could not add value\n")); + return False; + } + } + + if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, + &r->num_mods)) + return False; + } + + return True; +} + +/* + read from a LDIF source, creating a ldap_message +*/ +static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), + void *private_data) +{ + struct ldap_message *msg; + const char *attr=NULL; + const char *dn; + char *chunk=NULL, *s; + struct ldap_val value; + + value.data = NULL; + + msg = new_ldap_message(); + if (msg == NULL) + return NULL; + + chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); + if (!chunk) { + goto failed; + } + + s = chunk; + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + /* first line must be a dn */ + if (!strequal(attr, "dn")) { + DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", + attr)); + goto failed; + } + + dn = talloc_strdup(msg->mem_ctx, value.data); + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + if (!strequal(attr, "changetype")) { + DEBUG(5, ("Error: Second line of ldif must be a changetype " + "not '%s'\n", attr)); + goto failed; + } + + if (strequal(value.data, "delete")) { + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; + return msg; + } + + if (strequal(value.data, "add")) { + msg->type = LDAP_TAG_AddRequest; + + msg->r.AddRequest.dn = dn; + + if (!fill_add_attributes(msg, &s)) + goto failed; + + return msg; + } + + if (strequal(value.data, "modify")) { + msg->type = LDAP_TAG_ModifyRequest; + + msg->r.ModifyRequest.dn = dn; + + if (!fill_mods(msg, &s)) + goto failed; + + return msg; + } + + DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); + +failed: + destroy_ldap_message(msg); + return NULL; +} + +/* + a wrapper around ldif_read() for reading from const char* +*/ +struct ldif_read_string_state { + const char *s; +}; + +static int fgetc_string(void *private_data) +{ + struct ldif_read_string_state *state = private_data; + if (state->s[0] != 0) { + return *state->s++; + } + return EOF; +} + +struct ldap_message *ldap_ldif2msg(const char *s) +{ + struct ldif_read_string_state state; + state.s = s; + return ldif_read(fgetc_string, &state); +} + -- cgit From b83ba93eaeb2dcb0bf11615591d886fda84e4162 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 01:54:46 +0000 Subject: r1983: a completely new implementation of talloc This version does the following: 1) talloc_free(), talloc_realloc() and talloc_steal() lose their (redundent) first arguments 2) you can use _any_ talloc pointer as a talloc context to allocate more memory. This allows you to create complex data structures where the top level structure is the logical parent of the next level down, and those are the parents of the level below that. Then destroy either the lot with a single talloc_free() or destroy any sub-part with a talloc_free() of that part 3) you can name any pointer. Use talloc_named() which is just like talloc() but takes the printf style name argument as well as the parent context and the size. The whole thing ends up being a very simple piece of code, although some of the pointer walking gets hairy. So far, I'm just using the new talloc() like the old one. The next step is to actually take advantage of the new interface properly. Expect some new commits soon that simplify some common coding styles in samba4 by using the new talloc(). (This used to be commit e35bb094c52e550b3105dd1638d8d90de71d854f) --- source4/libcli/clilist.c | 8 ++++---- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_ldif.c | 11 +++++------ source4/libcli/raw/clisession.c | 2 +- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/raw/clitransport.c | 8 ++++---- source4/libcli/raw/clitree.c | 2 +- source4/libcli/raw/raweas.c | 2 +- source4/libcli/raw/rawfile.c | 6 +++--- source4/libcli/raw/rawfileinfo.c | 2 +- source4/libcli/raw/rawreadwrite.c | 4 ++-- source4/libcli/raw/rawrequest.c | 4 ++-- source4/libcli/raw/rawtrans.c | 4 ++-- 13 files changed, 28 insertions(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index e2c267cc96..0e2cdabc0a 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -83,8 +83,8 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) file_info *tdl; /* add file info to the dirlist pool */ - tdl = talloc_realloc(state->mem_ctx, state->dirlist, - state->dirlist_len + sizeof(struct file_info)); + tdl = talloc_realloc(state->dirlist, + state->dirlist_len + sizeof(struct file_info)); if (!tdl) { return False; @@ -225,8 +225,8 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) file_info *tdl; /* add file info to the dirlist pool */ - tdl = talloc_realloc(state->mem_ctx, state->dirlist, - state->dirlist_len + sizeof(struct file_info)); + tdl = talloc_realloc(state->dirlist, + state->dirlist_len + sizeof(struct file_info)); if (!tdl) { return False; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 123def9416..7e60e48293 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -179,7 +179,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { struct ldap_parse_tree **e; - e = talloc_realloc(mem_ctx, ret->u.list.elements, + e = talloc_realloc(ret->u.list.elements, sizeof(struct ldap_parse_tree) * (ret->u.list.num_elements+1)); if (!e) { diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 2f23dd16a6..2ec3b827ce 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -51,7 +51,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + c2 = talloc_realloc(chunk, alloc_size); if (!c2) { errno = ENOMEM; return NULL; @@ -158,7 +158,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, struct ldap_attribute *attrib) { - attrib->values = talloc_realloc(mem_ctx, attrib->values, + attrib->values = talloc_realloc(attrib->values, sizeof(*attrib->values) * (attrib->num_values+1)); if (attrib->values == NULL) @@ -175,7 +175,7 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_attribute **attribs, int *num_attribs) { - *attribs = talloc_realloc(mem_ctx, *attribs, + *attribs = talloc_realloc(*attribs, sizeof(**attribs) * (*num_attribs+1)); if (*attribs == NULL) @@ -207,8 +207,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc(msg->mem_ctx, - r->attributes, + r->attributes = talloc_realloc(r->attributes, sizeof(*r->attributes) * (r->num_attributes+1)); if (r->attributes == NULL) @@ -232,7 +231,7 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod **mods, int *num_mods) { - *mods = talloc_realloc(mem_ctx, *mods, + *mods = talloc_realloc(*mods, sizeof(**mods) * ((*num_mods)+1)); if (*mods == NULL) diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index f46c238378..0ee631a549 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -69,7 +69,7 @@ void smbcli_session_close(struct smbcli_session *session) ****************************************************************************/ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session, union smb_sesssetup *parms) { - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_SESSSETUP_GENERIC: diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 343904999a..2bb50d200f 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -181,7 +181,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in ret = smbcli_sock_connect(sock, &ip, port); if (ret) { - sock->hostname = talloc_steal(mem_ctx, sock->mem_ctx, name); + sock->hostname = talloc_steal(sock->mem_ctx, name); } talloc_destroy(mem_ctx); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 91f0f0f8f5..82939467ae 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -296,7 +296,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) { uint8_t *buffer, *hdr, *vwv; int len; - uint16_t wct, mid = 0; + uint16_t wct=0, mid = 0; struct smbcli_request *req; buffer = transport->recv_buffer.buffer; @@ -309,7 +309,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) /* see if it could be an oplock break request */ if (handle_oplock_break(transport, len, hdr, vwv)) { - talloc_free(transport->mem_ctx, buffer); + talloc_free(buffer); return; } @@ -325,7 +325,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) if (!req) goto error; req->in.buffer = buffer; - talloc_steal(transport->mem_ctx, req->mem_ctx, buffer); + talloc_steal(req->mem_ctx, buffer); req->in.size = len; req->in.allocated = req->in.size; goto async; @@ -349,7 +349,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) /* fill in the 'in' portion of the matching request */ req->in.buffer = buffer; - talloc_steal(transport->mem_ctx, req->mem_ctx, buffer); + talloc_steal(req->mem_ctx, buffer); req->in.size = len; req->in.allocated = req->in.size; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 97c0910451..57e322da32 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -70,7 +70,7 @@ void smbcli_tree_close(struct smbcli_tree *tree) ****************************************************************************/ struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, union smb_tcon *parms) { - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->tcon.level) { case RAW_TCON_TCON: diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index e07fbcd288..d78f10fe1a 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -128,7 +128,7 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, blob2.data = blob->data + ofs; blob2.length = ea_size - ofs; - *eas = talloc_realloc(mem_ctx, *eas, sizeof(**eas) * (n+1)); + *eas = talloc_realloc(*eas, sizeof(**eas) * (n+1)); if (! *eas) return NT_STATUS_NO_MEMORY; len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 8bd8e5d8af..1b858d489a 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -34,7 +34,7 @@ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree, union smb_rename *parms) { - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_RENAME_RENAME: @@ -490,7 +490,7 @@ NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_o ****************************************************************************/ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms) { - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_CLOSE_GENERIC: @@ -536,7 +536,7 @@ NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms) ****************************************************************************/ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_lock *parms) { - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_LOCK_GENERIC: diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 9b82bf6fa0..aac8f2657b 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -174,7 +174,7 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, while (blob->length - ofs >= 24) { uint_t n = parms->stream_info.out.num_streams; parms->stream_info.out.streams = - talloc_realloc(mem_ctx,parms->stream_info.out.streams, + talloc_realloc(parms->stream_info.out.streams, (n+1) * sizeof(parms->stream_info.out.streams[0])); if (!parms->stream_info.out.streams) { return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index f0a9a063ed..dbca6fb7a5 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -33,7 +33,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms) { BOOL bigoffset = False; - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_READ_GENERIC: @@ -185,7 +185,7 @@ NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms) struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms) { BOOL bigoffset = False; - struct smbcli_request *req; + struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_WRITE_GENERIC: diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index bc87af4297..20a389af4c 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -224,7 +224,7 @@ static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_si /* we need to realloc */ req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION; - buf2 = talloc_realloc(req->mem_ctx, req->out.buffer, req->out.allocated); + buf2 = talloc_realloc(req->out.buffer, req->out.allocated); if (buf2 == NULL) { smb_panic("out of memory in req_grow_allocation"); } @@ -915,7 +915,7 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, max_len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; - blob->data = talloc_realloc(mem_ctx, blob->data, blob->length + max_len); + blob->data = talloc_realloc(blob->data, blob->length + max_len); if (!blob->data) { return 0; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 53f8075822..49b43dd930 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -84,7 +84,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, /* allocate it */ if (total_data != 0) { - tdata = talloc_realloc(mem_ctx, parms->out.data.data,total_data); + tdata = talloc_realloc(parms->out.data.data,total_data); if (!tdata) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); req->status = NT_STATUS_NO_MEMORY; @@ -94,7 +94,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, } if (total_param != 0) { - tparam = talloc_realloc(mem_ctx, parms->out.params.data,total_param); + tparam = talloc_realloc(parms->out.params.data,total_param); if (!tparam) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); req->status = NT_STATUS_NO_MEMORY; -- cgit From b45f4ebbb880e41abf86abb54264123f3edbde05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 02:07:12 +0000 Subject: r1984: this change is what you should read to understand the new talloc() It simplifies our structure handling a lot, making the code shorter and easier to understand. Look at the diff carefully and see if you can understand it. If you're still confused then please ask. (This used to be commit 03c341aca7f09cb1f0d33ec65e074e6a00caa30f) --- source4/libcli/raw/clitransport.c | 4 ++-- source4/libcli/raw/rawrequest.c | 17 +++-------------- 2 files changed, 5 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 82939467ae..5766fde03a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -325,7 +325,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) if (!req) goto error; req->in.buffer = buffer; - talloc_steal(req->mem_ctx, buffer); + talloc_steal(req, buffer); req->in.size = len; req->in.allocated = req->in.size; goto async; @@ -349,7 +349,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) /* fill in the 'in' portion of the matching request */ req->in.buffer = buffer; - talloc_steal(req->mem_ctx, buffer); + talloc_steal(req, buffer); req->in.size = len; req->in.allocated = req->in.size; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 20a389af4c..87bbe5a31b 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -49,7 +49,7 @@ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) /* ahh, its so nice to destroy a complex structure in such a simple way! */ status = req->status; - talloc_destroy(req->mem_ctx); + talloc_free(req); return status; } @@ -61,18 +61,8 @@ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, uint_t size) { struct smbcli_request *req; - TALLOC_CTX *mem_ctx; - - /* each request gets its own talloc context. The request - structure itself is also allocated inside this context, - so we need to allocate it before we construct the request - */ - mem_ctx = talloc_init("smbcli_request"); - if (!mem_ctx) { - return NULL; - } - req = talloc(mem_ctx, sizeof(struct smbcli_request)); + req = talloc_named(NULL, sizeof(struct smbcli_request), "smcli_request"); if (!req) { return NULL; } @@ -80,7 +70,6 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran /* setup the request context */ req->state = SMBCLI_REQUEST_INIT; - req->mem_ctx = mem_ctx; req->transport = transport; req->session = NULL; req->tree = NULL; @@ -89,7 +78,7 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran /* over allocate by a small amount */ req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; - req->out.buffer = talloc(req->mem_ctx, req->out.allocated); + req->out.buffer = talloc(req, req->out.allocated); if (!req->out.buffer) { return NULL; } -- cgit From b7e1ea20dc873a753ff64653987130f03897a4e9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 07:43:29 +0000 Subject: r1985: take advantage of the new talloc in a few more places (This used to be commit 6ffdfd779936ce8c5ca49c5f444e8da2bbeee0a8) --- source4/libcli/cliconnect.c | 14 +++++--------- source4/libcli/raw/clisession.c | 13 ++++--------- source4/libcli/raw/clisocket.c | 23 +++++++---------------- source4/libcli/raw/clitransport.c | 15 ++++++--------- source4/libcli/raw/clitree.c | 15 +++++---------- source4/libcli/raw/rawnegotiate.c | 10 +++++----- 6 files changed, 32 insertions(+), 58 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 14f7d5a1b3..d89925eda5 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -195,13 +195,11 @@ NTSTATUS smbcli_tdis(struct smbcli_state *cli) struct smbcli_state *smbcli_state_init(void) { struct smbcli_state *cli; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("smbcli_state"); - if (!mem_ctx) return NULL; - cli = talloc_zero(mem_ctx, sizeof(*cli)); - cli->mem_ctx = mem_ctx; + cli = talloc_named(NULL, sizeof(*cli), "smbcli_state"); + if (cli) { + ZERO_STRUCTP(cli); + } return cli; } @@ -216,7 +214,5 @@ void smbcli_shutdown(struct smbcli_state *cli) cli->tree->reference_count++; smbcli_tree_close(cli->tree); } - if (cli->mem_ctx) { - talloc_destroy(cli->mem_ctx); - } + talloc_free(cli); } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 0ee631a549..af8a63328c 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -32,18 +32,13 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) { struct smbcli_session *session; - TALLOC_CTX *mem_ctx = talloc_init("smbcli_session"); - if (mem_ctx == NULL) { - return NULL; - } - session = talloc_zero(mem_ctx, sizeof(*session)); + session = talloc_named(NULL, sizeof(*session), "smbcli_session"); if (!session) { - talloc_destroy(mem_ctx); return NULL; } - session->mem_ctx = mem_ctx; + ZERO_STRUCTP(session); session->transport = transport; session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; @@ -60,7 +55,7 @@ void smbcli_session_close(struct smbcli_session *session) session->reference_count--; if (session->reference_count <= 0) { smbcli_transport_close(session->transport); - talloc_destroy(session->mem_ctx); + talloc_free(session); } } @@ -242,7 +237,7 @@ static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) void smbcli_session_set_user_session_key(struct smbcli_session *session, const DATA_BLOB *session_key) { - session->user_session_key = data_blob_talloc(session->mem_ctx, + session->user_session_key = data_blob_talloc(session, session_key->data, session_key->length); } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 2bb50d200f..94bb447f47 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -28,18 +28,13 @@ struct smbcli_socket *smbcli_sock_init(void) { struct smbcli_socket *sock; - TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("smbcli_socket"); - if (!mem_ctx) return NULL; - - sock = talloc_zero(mem_ctx, sizeof(*sock)); + sock = talloc_named(NULL, sizeof(*sock), "smbcli_socket"); if (!sock) { - talloc_destroy(mem_ctx); return NULL; } - sock->mem_ctx = mem_ctx; + ZERO_STRUCTP(sock); sock->fd = -1; sock->port = 0; /* 20 second default timeout */ @@ -153,7 +148,6 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in { int name_type = 0x20; struct in_addr ip; - TALLOC_CTX *mem_ctx; char *name, *p; BOOL ret; @@ -162,10 +156,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in return sock->fd != -1; } - mem_ctx = talloc_init("smbcli_sock_connect_byname"); - if (!mem_ctx) return False; - - name = talloc_strdup(mem_ctx, host); + name = talloc_strdup(sock, host); /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(name, '#'))) { @@ -173,18 +164,18 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in *p = 0; } - if (!resolve_name(mem_ctx, name, &ip, name_type)) { - talloc_destroy(mem_ctx); + if (!resolve_name(name, name, &ip, name_type)) { + talloc_free(name); return False; } ret = smbcli_sock_connect(sock, &ip, port); if (ret) { - sock->hostname = talloc_steal(sock->mem_ctx, name); + sock->hostname = talloc_steal(sock, name); } - talloc_destroy(mem_ctx); + talloc_destroy(name); return ret; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 5766fde03a..cae8e2a3be 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -37,23 +37,20 @@ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_e */ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) { - TALLOC_CTX *mem_ctx; struct smbcli_transport *transport; struct fd_event fde; - mem_ctx = talloc_init("smbcli_transport"); - if (!mem_ctx) return NULL; - - transport = talloc_zero(mem_ctx, sizeof(*transport)); + transport = talloc_named(NULL, sizeof(*transport), "smbcli_transport"); if (!transport) return NULL; + ZERO_STRUCTP(transport); + transport->event.ctx = event_context_init(); if (transport->event.ctx == NULL) { - talloc_destroy(mem_ctx); + talloc_destroy(transport); return NULL; } - transport->mem_ctx = mem_ctx; transport->socket = sock; transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(); @@ -88,7 +85,7 @@ void smbcli_transport_close(struct smbcli_transport *transport) event_remove_fd(transport->event.ctx, transport->event.fde); event_remove_timed(transport->event.ctx, transport->event.te); event_context_destroy(transport->event.ctx); - talloc_destroy(transport->mem_ctx); + talloc_free(transport); } } @@ -456,7 +453,7 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) if (transport->recv_buffer.received == NBT_HDR_SIZE) { /* we've got a full header */ transport->recv_buffer.req_size = smb_len(transport->recv_buffer.header) + NBT_HDR_SIZE; - transport->recv_buffer.buffer = talloc(transport->mem_ctx, + transport->recv_buffer.buffer = talloc(transport, NBT_HDR_SIZE+transport->recv_buffer.req_size); if (transport->recv_buffer.buffer == NULL) { smbcli_transport_dead(transport); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 57e322da32..2d642a9a8c 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -33,18 +33,13 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) { struct smbcli_tree *tree; - TALLOC_CTX *mem_ctx = talloc_init("smbcli_tree"); - if (mem_ctx == NULL) { - return NULL; - } - tree = talloc_zero(mem_ctx, sizeof(*tree)); + tree = talloc_named(NULL, sizeof(*tree), "smbcli_tree"); if (!tree) { - talloc_destroy(mem_ctx); return NULL; } - tree->mem_ctx = mem_ctx; + ZERO_STRUCTP(tree); tree->session = session; tree->session->reference_count++; @@ -60,7 +55,7 @@ void smbcli_tree_close(struct smbcli_tree *tree) tree->reference_count--; if (tree->reference_count <= 0) { smbcli_session_close(tree->session); - talloc_destroy(tree->mem_ctx); + talloc_free(tree); } } @@ -295,10 +290,10 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, tree->tid = tcon.tconx.out.cnum; if (tcon.tconx.out.dev_type) { - tree->device = talloc_strdup(tree->mem_ctx, tcon.tconx.out.dev_type); + tree->device = talloc_strdup(tree, tcon.tconx.out.dev_type); } if (tcon.tconx.out.fs_type) { - tree->fs_type = talloc_strdup(tree->mem_ctx, tcon.tconx.out.fs_type); + tree->fs_type = talloc_strdup(tree, tcon.tconx.out.fs_type); } talloc_destroy(mem_ctx); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 5ec827eebb..fdc1d0eb60 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -130,14 +130,14 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) if (req->in.data_size < 16) { goto failed; } - transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data, 16); - transport->negotiate.secblob = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data + 16, req->in.data_size - 16); + transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport, req->in.data, 16); + transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data + 16, req->in.data_size - 16); } else { if (req->in.data_size < (transport->negotiate.key_len)) { goto failed; } - transport->negotiate.secblob = smbcli_req_pull_blob(req, transport->mem_ctx, req->in.data, transport->negotiate.key_len); - smbcli_req_pull_string(req, transport->mem_ctx, &transport->negotiate.server_domain, + transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data, transport->negotiate.key_len); + smbcli_req_pull_string(req, transport, &transport->negotiate.server_domain, req->in.data+transport->negotiate.key_len, req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN); /* here comes the server name */ @@ -163,7 +163,7 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) { transport->negotiate.writebraw_supported = 1; } - transport->negotiate.secblob = smbcli_req_pull_blob(req, transport->mem_ctx, + transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data, req->in.data_size); } else { /* the old core protocol */ -- cgit From dcd43a4cbef3bee948bdbd65212361b6043aa4bd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 22 Aug 2004 05:33:07 +0000 Subject: r1990: Fix breakage caused by the recent talloc changes. (Failure to process an SPNEGO login from WinXP at least). talloc_asprintf_append() lost an argument, but because TALLOC_CTX is now a void*, this was not picked up by the compiler. I've tested the login (asn1), but not the registry/gtk changes. Andrew Bartlett (This used to be commit 4294be44057124568fe1d176702056bb62ad3214) --- source4/libcli/util/asn1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 1f04e1fe46..293213a2d0 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -454,7 +454,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); tmp_oid = talloc_asprintf(mem_ctx, "%u", b/40); - tmp_oid = talloc_asprintf_append(mem_ctx, tmp_oid, " %u", b%40); + tmp_oid = talloc_asprintf_append(tmp_oid, " %u", b%40); while (!data->has_error && asn1_tag_remaining(data) > 0) { uint_t v = 0; @@ -462,7 +462,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); - tmp_oid = talloc_asprintf_append(mem_ctx, tmp_oid, " %u", v); + tmp_oid = talloc_asprintf_append(tmp_oid, " %u", v); } asn1_end_tag(data); -- cgit From 7d1a0239bbfdd192a9fab01888d95263da722076 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Aug 2004 10:03:49 +0000 Subject: r2004: remove unused file metze (This used to be commit 46d5ce350aeae352a9a14b14b968c299f11272f2) --- source4/libcli/clisecdesc.c | 121 -------------------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 source4/libcli/clisecdesc.c (limited to 'source4/libcli') diff --git a/source4/libcli/clisecdesc.c b/source4/libcli/clisecdesc.c deleted file mode 100644 index 4c8b49fc67..0000000000 --- a/source4/libcli/clisecdesc.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - Unix SMB/CIFS implementation. - client security descriptor functions - Copyright (C) Andrew Tridgell 2000 - Copyright (C) James J Myers 2003 - - 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" - -/**************************************************************************** - query the security descriptor for a open file - ****************************************************************************/ -SEC_DESC *smbcli_query_secdesc(struct smbcli_tree *tree, int fnum, - TALLOC_CTX *mem_ctx) -{ - struct smb_nttrans parms; - char param[8]; - DATA_BLOB param_blob; - prs_struct pd; - SEC_DESC *psd = NULL; - NTSTATUS status; - - param_blob.length = 8; - param_blob.data = ¶m[0]; - - SIVAL(param, 0, fnum); - SSVAL(param, 4, 0x7); - - parms.in.max_param = 1024; - parms.in.max_data = 1024; - parms.in.max_setup = 0; - parms.in.setup_count = 18; - parms.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; - parms.in.params = param_blob; - parms.in.data = data_blob(NULL, 0); - - status = smb_raw_nttrans(tree, mem_ctx, &parms); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); - goto cleanup; - } - - prs_init(&pd, parms.out.data.length, mem_ctx, UNMARSHALL); - prs_copy_data_in(&pd, parms.out.data.data, parms.out.data.length); - prs_set_offset(&pd,0); - - if (!sec_io_desc("sd data", &psd, &pd, 1)) { - DEBUG(1,("Failed to parse secdesc\n")); - goto cleanup; - } - - cleanup: - prs_mem_free(&pd); - return psd; -} - -/**************************************************************************** - set the security descriptor for a open file - ****************************************************************************/ -BOOL smbcli_set_secdesc(struct smbcli_tree *tree, int fnum, SEC_DESC *sd) -{ - struct smb_nttrans parms; - char param[8]; - DATA_BLOB param_blob; - prs_struct pd; - BOOL ret = False; - TALLOC_CTX *mem_ctx; - NTSTATUS status; - - mem_ctx = talloc_init("smbcli_set_secdesc"); - - prs_init(&pd, 0, mem_ctx, MARSHALL); - prs_give_memory(&pd, NULL, 0, True); - - if (!sec_io_desc("sd data", &sd, &pd, 1)) { - DEBUG(1,("Failed to marshall secdesc\n")); - goto cleanup; - } - - param_blob.length = 8; - param_blob.data = ¶m[0]; - - SIVAL(param, 0, fnum); - SSVAL(param, 4, 0x7); - - parms.in.max_param = 1000; - parms.in.max_data = 1000; - parms.in.max_setup = 0; - parms.in.setup_count = 18; - parms.in.function = NT_TRANSACT_SET_SECURITY_DESC; - parms.in.params = param_blob; - parms.in.data = data_blob(NULL, 0); - - status = smb_raw_nttrans(tree, mem_ctx, &parms); - - if (NT_STATUS_IS_ERR(status)) { - DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); - goto cleanup; - } - ret = True; - - cleanup: - prs_mem_free(&pd); - talloc_destroy(mem_ctx); - return ret; -} -- cgit From bee751ed17223dc72f8972b014998c950e5bd794 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Aug 2004 15:43:57 +0000 Subject: r2019: fix compiler warnings metze (This used to be commit 699248fe821ffb738065002b5fef67cd59ca37f6) --- source4/libcli/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 0094cc26bb..de0f406209 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -1217,8 +1217,8 @@ BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_li /* If it's our domain then use the 'password server' parameter. */ if (strequal(domain, lp_workgroup())) { - char *p; - char *pserver = lp_passwordserver(); /* UNIX charset. */ + const char *p; + const char *pserver = lp_passwordserver(); /* UNIX charset. */ fstring name; int num_addresses = 0; int local_count, i, j; -- cgit From 36e52d5d9ab0f4ec972f3c8efae82db7ffe4dd1e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Aug 2004 15:48:14 +0000 Subject: r2020: fix compiler warnings metze (This used to be commit 17268837d21c2199b87bd78c1f62b49a37b86df8) --- source4/libcli/auth/ntlmssp_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 251effd7e1..bb835b367c 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -204,7 +204,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - ps = va_arg(ap, char **); + ps = (const char **)va_arg(ap, char **); if (len1 == 0 && len2 == 0) { *ps = ""; } else { @@ -238,7 +238,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - ps = va_arg(ap, char **); + ps = (const char **)va_arg(ap, char **); /* make sure its in the right format - be strict */ if (len1 == 0 && len2 == 0) { *ps = ""; -- cgit From bc5b92c0e0a6bbfc09fa7594ce968996eafdbfbf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2004 02:04:35 +0000 Subject: r2036: switched the spnego code to use talloc now that talloc_free() doesn't need to take a context ptr, there is no reason we can't use talloc everywhere that we currently use malloc(). (This used to be commit a2ad77fb3ac9638c5ef52494bf62083ec594b9f5) --- source4/libcli/auth/spnego_parse.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index d32fd65c4d..41c9ece5fd 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -47,12 +47,12 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = malloc(sizeof(*token->mechTypes)); + token->mechTypes = talloc(NULL, sizeof(*token->mechTypes)); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - realloc(token->mechTypes, (i + 2) * - sizeof(*token->mechTypes)); + talloc_realloc(token->mechTypes, (i + 2) * + sizeof(*token->mechTypes)); asn1_read_OID(asn1, token->mechTypes + i); } token->mechTypes[i] = NULL; @@ -347,9 +347,9 @@ BOOL spnego_free_data(struct spnego_data *spnego) if (spnego->negTokenInit.mechTypes) { int i; for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - free(spnego->negTokenInit.mechTypes[i]); + talloc_free(spnego->negTokenInit.mechTypes[i]); } - free(spnego->negTokenInit.mechTypes); + talloc_free(spnego->negTokenInit.mechTypes); } data_blob_free(&spnego->negTokenInit.mechToken); data_blob_free(&spnego->negTokenInit.mechListMIC); -- cgit From 35d65298d5892ad2709d9c5a628179ba48fd46ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2004 02:05:02 +0000 Subject: r2037: switched the asn.1 code to use talloc (This used to be commit c0862278cab106a441d1049c1da945fa11353f9f) --- source4/libcli/util/asn1.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 293213a2d0..6f613f398b 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -23,7 +23,7 @@ /* free an asn1 structure */ void asn1_free(ASN1_DATA *data) { - SAFE_FREE(data->data); + talloc_free(data->data); } /* write to the ASN1 buffer, advancing the buffer pointer */ @@ -32,9 +32,9 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) if (data->has_error) return False; if (data->length < data->ofs+len) { uint8_t *newp; - newp = Realloc(data->data, data->ofs+len); + newp = talloc_realloc(data->data, data->ofs+len); if (!newp) { - SAFE_FREE(data->data); + asn1_free(data); data->has_error = True; return False; } @@ -58,7 +58,7 @@ BOOL asn1_push_tag(ASN1_DATA *data, uint8_t tag) struct nesting *nesting; asn1_write_uint8(data, tag); - nesting = (struct nesting *)malloc(sizeof(struct nesting)); + nesting = talloc_p(NULL, struct nesting); if (!nesting) { data->has_error = True; return False; @@ -103,7 +103,7 @@ BOOL asn1_pop_tag(ASN1_DATA *data) } data->nesting = nesting->next; - free(nesting); + talloc_free(nesting); return True; } @@ -223,7 +223,7 @@ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) { ZERO_STRUCTP(data); - data->data = memdup(blob.data, blob.length); + data->data = talloc_memdup(NULL, blob.data, blob.length); if (!data->data) { data->has_error = True; return False; @@ -295,7 +295,7 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) data->has_error = True; return False; } - nesting = (struct nesting *)malloc(sizeof(struct nesting)); + nesting = talloc_p(NULL, struct nesting); if (!nesting) { data->has_error = True; return False; @@ -370,7 +370,7 @@ BOOL asn1_read_sequence_until(int sock, ASN1_DATA *data, len = b; } - buf = malloc(len); + buf = talloc(NULL, len); if (buf == NULL) return False; @@ -380,7 +380,7 @@ BOOL asn1_read_sequence_until(int sock, ASN1_DATA *data, if (!asn1_write(data, buf, len)) return False; - free(buf); + talloc_free(buf); data->ofs = 0; @@ -403,7 +403,7 @@ BOOL asn1_object_length(uint8_t *buf, size_t buf_length, *result = asn1_tag_remaining(&data)+data.ofs; /* We can't use asn1_end_tag here, as we did not consume the complete * tag, so asn1_end_tag would flag an error and not free nesting */ - free(data.nesting); + talloc_free(data.nesting); return True; } @@ -426,7 +426,7 @@ BOOL asn1_end_tag(ASN1_DATA *data) } data->nesting = nesting->next; - free(nesting); + talloc_free(nesting); return True; } @@ -445,15 +445,11 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) { uint8_t b; char *tmp_oid = NULL; - TALLOC_CTX *mem_ctx = talloc_init("asn1_read_OID"); - if (!mem_ctx) { - return False; - } if (!asn1_start_tag(data, ASN1_OID)) return False; asn1_read_uint8(data, &b); - tmp_oid = talloc_asprintf(mem_ctx, "%u", b/40); + tmp_oid = talloc_asprintf(NULL, "%u", b/40); tmp_oid = talloc_asprintf_append(tmp_oid, " %u", b%40); while (!data->has_error && asn1_tag_remaining(data) > 0) { @@ -467,8 +463,8 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_end_tag(data); - *OID = strdup(tmp_oid); - talloc_destroy(mem_ctx); + *OID = talloc_strdup(NULL, tmp_oid); + talloc_free(tmp_oid); return (*OID && !data->has_error); } @@ -484,7 +480,7 @@ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) data->has_error = True; return False; } - free(id); + talloc_free(id); return True; } @@ -498,7 +494,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) data->has_error = True; return False; } - *s = malloc(len+1); + *s = talloc(NULL, len+1); if (! *s) { data->has_error = True; return False; -- cgit From b13a9a8f98469fffe0db4cce7e077390d35984a3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2004 02:07:53 +0000 Subject: r2040: fixed a memory handling error in clisocket (caught with valgrind) (This used to be commit f6dc62bf119c294db060b0870b6ca80bc28bd4a5) --- source4/libcli/raw/clisocket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 94bb447f47..1004db4040 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -173,9 +173,9 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in if (ret) { sock->hostname = talloc_steal(sock, name); + } else { + talloc_free(name); } - talloc_destroy(name); - return ret; } -- cgit From fa5a99b7a6e4f9bffa82eed1393e8e5e1f6404dc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Aug 2004 02:25:20 +0000 Subject: r2041: Fix NTLMSSP RPC sealing, client -> win2k3 server. The bug (found by tridge) is that Win2k3 is being tighter about the NTLMSSP flags. If we don't negotiate sealing, we can't use it. We now have a way to indicate to the GENSEC implementation mechanisms what things we want for a connection. Andrew Bartlett (This used to be commit 86f61568ea44c5719f9b583beeeefb12e0c26f4c) --- source4/libcli/auth/gensec.c | 41 +++++++++++++++++++++++++++++++++--- source4/libcli/auth/gensec.h | 6 +++++- source4/libcli/auth/gensec_ntlmssp.c | 26 +++++++++++++++++++++++ source4/libcli/auth/ntlmssp.c | 22 ++++++++----------- source4/libcli/auth/ntlmssp_sign.c | 10 +++++++++ source4/libcli/raw/clisession.c | 2 ++ 6 files changed, 90 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 24c2c18877..8188701558 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -145,6 +145,7 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) (*gensec_security)->default_user.realm = talloc_strdup(mem_ctx, lp_realm()); (*gensec_security)->subcontext = False; + (*gensec_security)->want_features = 0; return NT_STATUS_OK; } @@ -232,13 +233,20 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) */ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, - uint8_t authtype) + uint8_t auth_type, uint8_t auth_level) { - gensec_security->ops = gensec_security_by_authtype(authtype); + gensec_security->ops = gensec_security_by_authtype(auth_type); if (!gensec_security->ops) { - DEBUG(3, ("Could not find GENSEC backend for authtype=%d\n", (int)authtype)); + DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type)); return NT_STATUS_INVALID_PARAMETER; } + if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { + gensec_want_feature(gensec_security, GENSEC_WANT_SIGN); + } + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + gensec_want_feature(gensec_security, GENSEC_WANT_SIGN); + gensec_want_feature(gensec_security, GENSEC_WANT_SEAL); + } return gensec_start_mech(gensec_security); } @@ -308,6 +316,10 @@ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->check_packet) { return NT_STATUS_NOT_IMPLEMENTED; } + if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, sig); } @@ -319,6 +331,10 @@ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->seal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } + if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, sig); } @@ -330,6 +346,10 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->sign_packet) { return NT_STATUS_NOT_IMPLEMENTED; } + if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, sig); } @@ -339,6 +359,10 @@ NTSTATUS gensec_session_key(struct gensec_security *gensec_security, if (!gensec_security->ops->session_key) { return NT_STATUS_NOT_IMPLEMENTED; } + if (!(gensec_security->want_features & GENSEC_WANT_SESSION_KEY)) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->ops->session_key(gensec_security, session_key); } @@ -392,6 +416,17 @@ void gensec_end(struct gensec_security **gensec_security) gensec_security = NULL; } +/** + * Set the requirement for a certain feature on the connection + * + */ + +void gensec_want_feature(struct gensec_security *gensec_security, + uint32 feature) +{ + gensec_security->want_features |= feature; +} + /** * Set a username on a GENSEC context - ensures it is talloc()ed * diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 880ee45265..73a5f6b463 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -36,7 +36,10 @@ struct gensec_target { const struct sock_addr *addr; const char *service; }; - + +#define GENSEC_WANT_SESSION_KEY 0x1 +#define GENSEC_WANT_SIGN 0x2 +#define GENSEC_WANT_SEAL 0x4 /* GENSEC mode */ enum gensec_role @@ -86,6 +89,7 @@ struct gensec_security { struct gensec_target target; enum gensec_role gensec_role; BOOL subcontext; + uint32 want_features; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 99247fb626..ae03bc88e6 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -179,6 +179,13 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur return nt_status; } + if (gensec_security->want_features & GENSEC_WANT_SIGN) { + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (gensec_security->want_features & GENSEC_WANT_SEAL) { + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) { return nt_status; @@ -211,6 +218,25 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur return status; } + if (gensec_security->want_features & GENSEC_WANT_SESSION_KEY) { + /* + * We need to set this to allow a later SetPassword + * via the SAMR pipe to succeed. Strange.... We could + * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. + * + * Without this, Windows will not create the master key + * that it thinks is only used for NTLMSSP signing and + * sealing. (It is actually pulled out and used directly) + */ + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (gensec_security->want_features & GENSEC_WANT_SIGN) { + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (gensec_security->want_features & GENSEC_WANT_SEAL) { + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, gensec_security->user.domain); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 893e8520c2..4d2dd6b576 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -375,6 +375,14 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } + if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; + } + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } @@ -933,9 +941,7 @@ NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | /* NTLMSSP_NEGOTIATE_NTLM2 | */ - NTLMSSP_NEGOTIATE_KEY_EXCH | - NTLMSSP_NEGOTIATE_SIGN | - NTLMSSP_NEGOTIATE_SEAL; + NTLMSSP_NEGOTIATE_KEY_EXCH; return NT_STATUS_OK; } @@ -1289,16 +1295,6 @@ NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) NTLMSSP_NEGOTIATE_NTLM | /* NTLMSSP_NEGOTIATE_NTLM2 |*/ NTLMSSP_NEGOTIATE_KEY_EXCH | - /* - * We need to set this to allow a later SetPassword - * via the SAMR pipe to succeed. Strange.... We could - * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - * - * Without this, Windows will not create the master key - * that it thinks is only used for NTLMSSP signing and - * sealing. (It is actually pulled out and used directly) - */ - NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; return NT_STATUS_OK; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 80ce1cccc0..6c770b87b9 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -178,6 +178,11 @@ NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_NO_USER_SESSION_KEY; } + if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, data, length, NTLMSSP_SEND, sig); @@ -268,6 +273,11 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_NO_USER_SESSION_KEY; } + if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index af8a63328c..32be6b68ed 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -399,6 +399,8 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess goto done; } + gensec_want_feature(session->gensec, GENSEC_WANT_SESSION_KEY); + status = gensec_set_domain(session->gensec, parms->generic.in.domain); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", -- cgit From 98875066fbb828803698f34ed33c52c0fa374732 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2004 02:25:48 +0000 Subject: r2042: missed a couple of places that should be talloc_free() (This used to be commit e1575a72a10252fdb88778f14bf3c44a65d72c5e) --- source4/libcli/auth/spnego_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 41c9ece5fd..047d17ce5a 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -353,11 +353,11 @@ BOOL spnego_free_data(struct spnego_data *spnego) } data_blob_free(&spnego->negTokenInit.mechToken); data_blob_free(&spnego->negTokenInit.mechListMIC); - SAFE_FREE(spnego->negTokenInit.targetPrincipal); + talloc_free(spnego->negTokenInit.targetPrincipal); break; case SPNEGO_NEG_TOKEN_TARG: if (spnego->negTokenTarg.supportedMech) { - free(spnego->negTokenTarg.supportedMech); + talloc_free(spnego->negTokenTarg.supportedMech); } data_blob_free(&spnego->negTokenTarg.responseToken); data_blob_free(&spnego->negTokenTarg.mechListMIC); -- cgit From fadc0e46f75ffd0b26bf159c182a08c979a7f569 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Aug 2004 07:13:01 +0000 Subject: r2053: All RPC sessions 'want' a session key. Of course, the key they currently get it bougs, but anyway... Andrew Bartlett (This used to be commit 46864dd9d778c008c2f1a3a6701360d4ca64a664) --- source4/libcli/auth/gensec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 8188701558..4b362b5305 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -247,6 +247,9 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, gensec_want_feature(gensec_security, GENSEC_WANT_SIGN); gensec_want_feature(gensec_security, GENSEC_WANT_SEAL); } + + gensec_want_feature(gensec_security, GENSEC_WANT_SESSION_KEY); + return gensec_start_mech(gensec_security); } -- cgit From 18797d8c70afc383aa7c67003646efb8ecfd7e4f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Aug 2004 07:13:53 +0000 Subject: r2054: Fix compile warnings/build failures on non-gcc. Andrew Bartlett (This used to be commit 2cbbf123d26081687a15eb7b82738e8187153ba4) --- source4/libcli/auth/gensec_krb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 72def2d79e..569fd81206 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -110,7 +110,9 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, struct PAC_SIGNATURE_DATA *kdc_sig_ptr; struct PAC_LOGON_INFO *logon_info = NULL; struct PAC_DATA pac_data; +#ifdef KRB5_DO_VERIFY_PAC DATA_BLOB tmp_blob = data_blob(NULL, 0); +#endif int i; status = ndr_pull_struct_blob(&blob, mem_ctx, &pac_data, @@ -325,7 +327,6 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } } else { krb5_data in_data; - in_data.length = 0; const char *hostname = gensec_get_target_hostname(gensec_security); if (!hostname) { DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); -- cgit From e5c4c4b108370277458992a8f6d156317163fbb9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Aug 2004 08:31:48 +0000 Subject: r2058: Merge heimdal krb5_locate_kdc-fix over from trunk/3_0 although krb5_locate_kdc is (yet) an unused function in Samba4. Guenther (This used to be commit fe93f58dfe208ec814f1e75efde4ececa2b2cb5f) --- source4/libcli/auth/clikrb5.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 0e4ec1f438..f6f8520b3c 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -181,6 +181,7 @@ krb5_error_code rc; int num_kdcs, i; struct sockaddr *sa; + struct addrinfo **ai; *addr_pp = NULL; *naddrs = 0; @@ -210,10 +211,19 @@ return -1; } + *addr_pp = malloc(sizeof(struct sockaddr) * num_kdcs); memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { - if (hinfo->ai->ai_family == AF_INET) + +#if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO) + rc = krb5_krbhst_get_addrinfo(ctx, hinfo, ai); + if (rc) { + DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc))); + return rc; + } +#endif + if (hinfo->ai && hinfo->ai->ai_family == AF_INET) memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); } -- cgit From 1685238339d61f5b0dfef9edc9d754fcd0947922 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 29 Aug 2004 11:28:31 +0000 Subject: r2096: Enable use of NTLM2 for connections that do not got on to be NTLMSSP signed or sealed. This allows NTLM2 for SMB connections, and NTLMSSP over HTTP for example. Andrew Bartlett (This used to be commit e509451538eb5fac5a288e2c429d8481dbfb355f) --- source4/libcli/auth/gensec_ntlmssp.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index ae03bc88e6..beee29a088 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -186,6 +186,14 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + /* IF we are not doing Signing or Sealing, we can actually do + * NTLM2. When we crack the crypto puzzle, then we can enable + * this always, in the constant flags */ + + if (!(gensec_security->want_features & GENSEC_WANT_SIGN) && !(gensec_security->want_features & GENSEC_WANT_SEAL)) { + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } + ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) { return nt_status; @@ -237,6 +245,14 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + /* IF we are not doing Signing or Sealing, we can actually do + * NTLM2. When we crack the crypto puzzle, then we can enable + * this always, in the constant flags */ + + if (!(gensec_security->want_features & GENSEC_WANT_SIGN) && !(gensec_security->want_features & GENSEC_WANT_SEAL)) { + gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } + status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, gensec_security->user.domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From 18bbab726884725ccf2f3264223866194855f320 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 30 Aug 2004 01:34:01 +0000 Subject: r2099: Get rid of another private ARCFOUR implementation from the codebase. Andrew Bartlett (This used to be commit 0237389ce765cbb6825b79de1b0727da0969efeb) --- source4/libcli/auth/ntlmssp.h | 8 +-- source4/libcli/auth/ntlmssp_sign.c | 135 ++++++++++++------------------------- source4/libcli/util/smbdes.c | 42 ++++++++---- 3 files changed, 77 insertions(+), 108 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index b7fc914b75..61285e472b 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -166,10 +166,10 @@ struct ntlmssp_state uint32_t ntlmssp_seq_num; /* ntlmv2 */ - char send_sign_key[16]; - char send_seal_key[16]; - char recv_sign_key[16]; - char recv_seal_key[16]; + DATA_BLOB send_sign_key; + DATA_BLOB send_seal_key; + DATA_BLOB recv_sign_key; + DATA_BLOB recv_seal_key; uint8_t send_seal_hash[258]; uint8_t recv_seal_hash[258]; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 6c770b87b9..ca3660eea7 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -27,57 +27,6 @@ #define SRV_SIGN "session key to server-to-client signing key magic constant" #define SRV_SEAL "session key to server-to-client sealing key magic constant" -static void NTLMSSPcalc_ap(uint8_t *hash, uint8_t *data, int len) -{ - uint8_t index_i = hash[256]; - uint8_t index_j = hash[257]; - int ind; - - for (ind = 0; ind < len; ind++) - { - uint8_t tc; - uint8_t t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - -static void calc_hash(uint8_t hash[258], const uint8 *key, size_t key_len) -{ - uint8_t j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - hash[ind] = (uint8_t)ind; - } - - for (ind = 0; ind < 256; ind++) - { - uint8_t tc; - - j += (hash[ind] + key[ind%key_len]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - hash[256] = 0; - hash[257] = 0; -} - /** * Some notes on then NTLM2 code: * @@ -94,16 +43,17 @@ static void calc_hash(uint8_t hash[258], const uint8 *key, size_t key_len) * */ -static void calc_ntlmv2_key(uint8_t subkey[16], +static void calc_ntlmv2_key(TALLOC_CTX *mem_ctx, + DATA_BLOB *subkey, DATA_BLOB session_key, const char *constant) { struct MD5Context ctx3; - + *subkey = data_blob_talloc(mem_ctx, NULL, 16); MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); MD5Update(&ctx3, constant, strlen(constant)+1); - MD5Final(subkey, &ctx3); + MD5Final(subkey->data, &ctx3); } enum ntlmssp_direction { @@ -120,31 +70,31 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - uint8_t seq_num[4]; uint8_t digest[16]; + uint8_t seq_num[4]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); switch (direction) { case NTLMSSP_SEND: - hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, - sizeof(ntlmssp_state->send_sign_key), &ctx); + hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key.data, + ntlmssp_state->send_sign_key.length, &ctx); break; case NTLMSSP_RECEIVE: - hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, - sizeof(ntlmssp_state->recv_sign_key), &ctx); + hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key.data, + ntlmssp_state->recv_sign_key.length, &ctx); break; } - hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_update(seq_num, sizeof(seq_num), &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { switch (direction) { case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, digest, 8); + arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, digest, 8); break; case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, digest, 8); + arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, digest, 8); break; } } @@ -160,7 +110,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat return NT_STATUS_NO_MEMORY; } - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); return NT_STATUS_OK; @@ -286,8 +236,8 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, uint8_t digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, - sizeof(ntlmssp_state->send_sign_key), &ctx); + hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key.data, + ntlmssp_state->send_sign_key.length, &ctx); hmac_md5_update(seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -296,10 +246,10 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, then seal the sequence number - this is becouse the send_seal_hash is not constant, but is is rather updated with each iteration */ - NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); + arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, digest, 8); + arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, digest, 8); } *sig = data_blob_talloc(sig_mem_ctx, NULL, 16); @@ -317,9 +267,9 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, then seal the sequence number - this is becouse the ntlmssp_hash is not constant, but is is rather updated with each iteration */ - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } dump_data_pw("ntlmssp signature\n", sig->data, sig->length); dump_data_pw("ntlmssp sealed data\n", data, length); @@ -347,9 +297,9 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length); + arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, data, length); } else { - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); } dump_data_pw("ntlmssp clear data\n", data, length); @@ -414,41 +364,43 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) weak_session_key.length); /* SEND */ - calc_ntlmv2_key(ntlmssp_state->send_sign_key, + calc_ntlmv2_key(ntlmssp_state->mem_ctx, + &ntlmssp_state->send_sign_key, ntlmssp_state->session_key, send_sign_const); dump_data_pw("NTLMSSP send sign key:\n", - ntlmssp_state->send_sign_key, - sizeof(ntlmssp_state->send_sign_key)); + ntlmssp_state->send_sign_key.data, + ntlmssp_state->send_sign_key.length); - calc_ntlmv2_key(ntlmssp_state->send_seal_key, + calc_ntlmv2_key(ntlmssp_state->mem_ctx, + &ntlmssp_state->send_seal_key, weak_session_key, send_seal_const); dump_data_pw("NTLMSSP send seal key:\n", - ntlmssp_state->send_seal_key, - sizeof(ntlmssp_state->send_seal_key)); + ntlmssp_state->send_seal_key.data, + ntlmssp_state->send_seal_key.length); - calc_hash(ntlmssp_state->send_seal_hash, - ntlmssp_state->send_seal_key, - sizeof(ntlmssp_state->send_seal_key)); + arcfour_init(ntlmssp_state->send_seal_hash, + &ntlmssp_state->send_seal_key); dump_data_pw("NTLMSSP send sesl hash:\n", ntlmssp_state->send_seal_hash, sizeof(ntlmssp_state->send_seal_hash)); /* RECV */ - calc_ntlmv2_key(ntlmssp_state->recv_sign_key, + calc_ntlmv2_key(ntlmssp_state->mem_ctx, + &ntlmssp_state->recv_sign_key, ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP recv sign key:\n", - ntlmssp_state->recv_sign_key, - sizeof(ntlmssp_state->recv_sign_key)); + ntlmssp_state->recv_sign_key.data, + ntlmssp_state->recv_sign_key.length); - calc_ntlmv2_key(ntlmssp_state->recv_seal_key, + calc_ntlmv2_key(ntlmssp_state->mem_ctx, + &ntlmssp_state->recv_seal_key, weak_session_key, recv_seal_const); dump_data_pw("NTLMSSP recv seal key:\n", - ntlmssp_state->recv_seal_key, - sizeof(ntlmssp_state->recv_seal_key)); - calc_hash(ntlmssp_state->recv_seal_hash, - ntlmssp_state->recv_seal_key, - sizeof(ntlmssp_state->recv_seal_key)); + ntlmssp_state->recv_seal_key.data, + ntlmssp_state->recv_seal_key.length); + arcfour_init(ntlmssp_state->recv_seal_hash, + &ntlmssp_state->recv_seal_key); dump_data_pw("NTLMSSP receive seal hash:\n", ntlmssp_state->recv_seal_hash, @@ -456,9 +408,8 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) } else { DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, - ntlmssp_state->session_key.data, - ntlmssp_state->session_key.length); + arcfour_init(ntlmssp_state->ntlmssp_hash, + &ntlmssp_state->session_key); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 99c2c00977..a7c8f760ea 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -364,30 +364,36 @@ void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int des_crypt56(out + 8, in + 8, key+7, forw); } -/* - arcfour encryption with a blob key -*/ -void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) +/* initialise the arcfour sbox with key */ +void arcfour_init(uint8_t s_box[256], const DATA_BLOB *key) { - uint8_t s_box[256]; - uint8_t index_i = 0; - uint8_t index_j = 0; - uint8_t j = 0; int ind; - + uint8_t j = 0; for (ind = 0; ind < 256; ind++) { s_box[ind] = (uint8_t)ind; } - + for (ind = 0; ind < 256; ind++) { uint8_t tc; - + j += (s_box[ind] + key->data[ind%key->length]); - + tc = s_box[ind]; s_box[ind] = s_box[j]; s_box[j] = tc; } + s_box[256] = 0; /* i */ + s_box[257] = 0; /* j */ + +} + +/* crypt the data with arcfour */ +void arcfour_crypt_sbox(uint8_t s_box[258], uint8_t *data, int len) +{ + uint8_t index_i = s_box[256]; + uint8_t index_j = s_box[257]; + int ind; + for (ind = 0; ind < len; ind++) { uint8_t tc; uint8_t t; @@ -402,6 +408,18 @@ void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) t = s_box[index_i] + s_box[index_j]; data[ind] = data[ind] ^ s_box[t]; } + s_box[256] = index_i; + s_box[257] = index_j; +} + +/* + arcfour encryption with a blob key +*/ +void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) +{ + uint8_t s_box[258]; + arcfour_init(s_box, key); + arcfour_crypt_sbox(s_box, data, len); } /* -- cgit From e64fce8b883a49a8ecb6f0e4d326d3b5f11d2282 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 30 Aug 2004 05:32:00 +0000 Subject: r2101: fixed a signed/unsigned char warning (This used to be commit f5fd90848d350ba1016282a6ee9ea3c83a6e4a63) --- source4/libcli/clireadwrite.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index dd9f8d44cc..45c99f4f89 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -83,8 +83,8 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, char *buf, off_t offset, 0x0008 start of message mode named pipe protocol ****************************************************************************/ ssize_t smbcli_write(struct smbcli_tree *tree, - int fnum, uint16_t write_mode, - const char *buf, off_t offset, size_t size) + int fnum, uint16_t write_mode, + const uint8_t *buf, off_t offset, size_t size) { union smb_write parms; int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; -- cgit From f3d946646975cc04c5abd6b41adaf547175d6aab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 30 Aug 2004 05:33:49 +0000 Subject: r2102: fixed a race condition when handling dos errors that are in our table. Should get rid of the static buffer completely at some point. (This used to be commit e0bda611121ed1f4afc2bfe83853e5521c494164) --- source4/libcli/util/doserr.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index c4ec869961..b8605864fc 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -22,13 +22,12 @@ #include "includes.h" -typedef const struct -{ +struct werror_code_struct { const char *dos_errstr; WERROR werror; -} werror_code_struct; +}; -werror_code_struct dos_errs[] = +static const struct werror_code_struct dos_errs[] = { { "WERR_OK", WERR_OK }, { "WERR_BADFILE", WERR_BADFILE }, @@ -79,8 +78,6 @@ const char *win_errstr(WERROR werror) static pstring msg; int idx = 0; - slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror)); - while (dos_errs[idx].dos_errstr != NULL) { if (W_ERROR_V(dos_errs[idx].werror) == W_ERROR_V(werror)) @@ -88,5 +85,7 @@ const char *win_errstr(WERROR werror) idx++; } + slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror)); + return msg; } -- cgit From 6fe8b2f60834a01af69f8247ff7934cee5fd1ebb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 Aug 2004 02:57:49 +0000 Subject: r2119: Noticed by jra: Clean up use of unitilaised variable. Andrew Bartlett (This used to be commit e8d0246882f0d70dc3c63208d0a990804f36a05d) --- source4/libcli/auth/spnego.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index ed938c4a11..de71814354 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -287,15 +287,9 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec { DATA_BLOB null_data_blob = data_blob(NULL,0); NTSTATUS nt_status; - int num_ops; const char **mechTypes = NULL; DATA_BLOB unwrapped_out = data_blob(NULL,0); - if (num_ops < 1) { - DEBUG(1, ("no GENSEC backends available\n")); - return NT_STATUS_INVALID_PARAMETER; - } - mechTypes = gensec_security_oids(out_mem_ctx, OID_SPNEGO); if (!mechTypes) { -- cgit From 776d90d801ee253157f9de90416a93bfc7bfd55e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Aug 2004 06:21:14 +0000 Subject: r2122: merge from trunk (-r 2120): Fix bug found by Love H?\195?\182rnquist ?\195?\133strand: asn1_write_Integer needs to push stuff little endian. (This used to be commit 79bee828fbb70e71ad3fbd45758bcc7775ea977b) --- source4/libcli/util/asn1.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 6f613f398b..756a33f77d 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -107,15 +107,23 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return True; } +static void push_int_littleendian(ASN1_DATA *data, int i) +{ + uint8_t lowest = i & 0xFF; + + i = i >> 8; + if (i != 0) + push_int_littleendian(data, i); + + asn1_write_uint8(data, lowest); +} + /* write an integer */ BOOL asn1_write_Integer(ASN1_DATA *data, int i) { if (!asn1_push_tag(data, ASN1_INTEGER)) return False; - do { - asn1_write_uint8(data, i); - i = i >> 8; - } while (i); + push_int_littleendian(data, i); return asn1_pop_tag(data); } -- cgit From 0575d5e0d2d1548ce2f6d133ccebe65a0b6b7745 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Aug 2004 07:14:34 +0000 Subject: r2124: merge from trunk (-r 2123): Argl. I could never get the naming right. Having the most significant byte at the lowest memory address is big endian, at least according to the google search for 'big endian'.... Volker (This used to be commit bc4c188362901423cc900fd4bdfa4a9ed6838f2b) --- source4/libcli/util/asn1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 756a33f77d..7025808a1e 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -107,13 +107,13 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return True; } -static void push_int_littleendian(ASN1_DATA *data, int i) +static void push_int_bigendian(ASN1_DATA *data, int i) { uint8_t lowest = i & 0xFF; i = i >> 8; if (i != 0) - push_int_littleendian(data, i); + push_int_bigendian(data, i); asn1_write_uint8(data, lowest); } @@ -123,7 +123,7 @@ static void push_int_littleendian(ASN1_DATA *data, int i) BOOL asn1_write_Integer(ASN1_DATA *data, int i) { if (!asn1_push_tag(data, ASN1_INTEGER)) return False; - push_int_littleendian(data, i); + push_int_bigendian(data, i); return asn1_pop_tag(data); } -- cgit From 31c1c7846f6b6e5848bc39a28a65118bfa98e35d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 1 Sep 2004 04:39:06 +0000 Subject: r2159: converted samba4 over to UTF-16. I had previously thought this was unnecessary, as windows doesn't use standards compliant UTF-16, and for filesystem operations treats bytes as UCS-2, but Bjoern Jacke has pointed out to me that this means we don't correctly store extended UTF-16 characters as UTF-8 on disk. This can be seen with (for example) the gothic characters with codepoints above 64k. This commit also adds a LOCAL-ICONV torture test that tests the first 1 million codepoints against the system iconv library, and tests 5 million random UTF-16LE buffers for identical error handling to the system iconv library. the lib/iconv.c changes need backporting to samba3 (This used to be commit 756f28ac95feaa84b42402723d5f7286865c78db) --- source4/libcli/raw/rawrequest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 87bbe5a31b..51c0c0b925 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -526,7 +526,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c return 0; } - ret = convert_string_talloc(mem_ctx, CH_UCS2, CH_UNIX, src, src_len2, (const void **)dest); + ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (const void **)dest); if (ret == -1) { *dest = NULL; return 0; @@ -725,7 +725,7 @@ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, src_len2 += 2; } - ret = convert_string_talloc(mem_ctx, CH_UCS2, CH_UNIX, src, src_len2, (const void **)dest); + ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (const void **)dest); if (ret == -1) { *dest = NULL; return 0; -- cgit From deb288d82e92644dcc2431806e214dfeac7b0e84 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Sep 2004 07:29:02 +0000 Subject: r2166: sync the asn1 stuff with trunk metze (This used to be commit 46762c9ee011e5c37f3d94a1b80ed7d679c55434) --- source4/libcli/util/asn1.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 7025808a1e..7e313bcd4a 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -107,23 +107,59 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return True; } -static void push_int_bigendian(ASN1_DATA *data, int i) +/* "i" is the one's complement representation, as is the normal result of an + * implicit signed->unsigned conversion */ + +static void push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) { uint8_t lowest = i & 0xFF; i = i >> 8; if (i != 0) - push_int_bigendian(data, i); + push_int_bigendian(data, i, negative); + + if (data->nesting->start+1 == data->ofs) { + + /* We did not write anything yet, looking at the highest + * valued byte */ + + if (negative) { + /* Don't write leading 0xff's */ + if (lowest == 0xFF) + return; + + if ((lowest & 0x80) == 0) { + /* The only exception for a leading 0xff is if + * the highest bit is 0, which would indicate + * a positive value */ + asn1_write_uint8(data, 0xff); + } + } else { + if (lowest & 0x80) { + /* The highest bit of a positive integer is 1, + * this would indicate a negative number. Push + * a 0 to indicate a positive one */ + asn1_write_uint8(data, 0); + } + } + } asn1_write_uint8(data, lowest); } - /* write an integer */ BOOL asn1_write_Integer(ASN1_DATA *data, int i) { if (!asn1_push_tag(data, ASN1_INTEGER)) return False; - push_int_bigendian(data, i); + if (i == -1) { + /* -1 is special as it consists of all-0xff bytes. In + push_int_bigendian this is the only case that is not + properly handled, as all 0xff bytes would be handled as + leading ones to be ignored. */ + asn1_write_uint8(data, 0xff); + } else { + push_int_bigendian(data, i, i<0); + } return asn1_pop_tag(data); } -- cgit From 3e454a5891b73c9b021406bdb662127e1a3180dc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 1 Sep 2004 14:49:43 +0000 Subject: r2173: Fix asn1 BOOLEANs. Thanks to Love Hornquist-Astrand. Volker (This used to be commit 53f58c053b643c8b45d2f9394faf8cfdd5005f6d) --- source4/libcli/ldap/ldap.c | 8 ++++---- source4/libcli/util/asn1.c | 13 ++----------- 2 files changed, 6 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7e60e48293..b7ae58f7f5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -426,7 +426,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_enumerated(&data, r->deref); asn1_write_Integer(&data, r->sizelimit); asn1_write_Integer(&data, r->timelimit); - asn1_write_BOOLEAN2(&data, r->attributesonly); + asn1_write_BOOLEAN(&data, r->attributesonly); { TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); @@ -565,7 +565,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN2(&data, r->deleteolddn); + asn1_write_BOOLEAN(&data, r->deleteolddn); if (r->newsuperior != NULL) { asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->newsuperior, @@ -893,7 +893,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) asn1_read_enumerated(data, (int *)&(r->deref)); asn1_read_Integer(data, &r->sizelimit); asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN2(data, &r->attributesonly); + asn1_read_BOOLEAN(data, &r->attributesonly); /* Maybe create a TALLOC_CTX for the filter? This can waste * quite a bit of memory recursing down. */ @@ -1039,7 +1039,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->newrdn); - asn1_read_BOOLEAN2(data, &r->deleteolddn); + asn1_read_BOOLEAN(data, &r->deleteolddn); r->newsuperior = NULL; if (asn1_tag_remaining(data) > 0) { int len; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 7e313bcd4a..b5db9b157e 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -220,23 +220,14 @@ BOOL asn1_write_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) /* write a BOOLEAN */ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) -{ - asn1_write_uint8(data, ASN1_BOOLEAN); - asn1_write_uint8(data, v); - return !data->has_error; -} - -/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the - above boolean is bogus. Need to check */ -BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) { asn1_push_tag(data, ASN1_BOOLEAN); - asn1_write_uint8(data, v); + asn1_write_uint8(data, v ? 0xFF : 0); asn1_pop_tag(data); return !data->has_error; } -BOOL asn1_read_BOOLEAN2(ASN1_DATA *data, BOOL *v) +BOOL asn1_read_BOOLEAN(ASN1_DATA *data, BOOL *v) { asn1_start_tag(data, ASN1_BOOLEAN); asn1_read_uint8(data, (uint8 *)v); -- cgit From b990e9a97b02cec9f012bacc6bb266a0403f6792 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Sep 2004 12:02:28 +0000 Subject: r2184: use the smb.conf socket options for client code too (This used to be commit 7256945b526a1ee68d18eb579e592f7389740c22) --- source4/libcli/raw/clisocket.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 1004db4040..9aea8624d0 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -79,6 +79,7 @@ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int por } set_blocking(sock->fd, False); + set_socket_options(sock->fd, lp_socket_options()); return True; } -- cgit From 8293df91bcec574fb4a2b290cc11dd83353264ae Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 8 Sep 2004 00:00:56 +0000 Subject: r2247: talloc_destroy -> talloc_free (This used to be commit 6c1a72c5d667245b1eec94f58e68acd22dd720ce) --- source4/libcli/cliconnect.c | 6 +++--- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/raw/clitree.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index d89925eda5..220a450433 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -92,7 +92,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, cli->session->vuid = setup.generic.out.vuid; - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -125,7 +125,7 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, cli->tree->tid = tcon.tconx.out.cnum; - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -176,7 +176,7 @@ NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, tree->reference_count++; done: - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index cae8e2a3be..2d29ba371f 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -47,7 +47,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) transport->event.ctx = event_context_init(); if (transport->event.ctx == NULL) { - talloc_destroy(transport); + talloc_free(transport); return NULL; } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 2d642a9a8c..03a49708b3 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -251,7 +251,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, status = smb_raw_session_setup(session, mem_ctx, &setup); if (!NT_STATUS_IS_OK(status)) { smbcli_session_close(session); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -260,7 +260,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, tree = smbcli_tree_init(session); if (!tree) { smbcli_session_close(session); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -284,7 +284,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, if (!NT_STATUS_IS_OK(status)) { smbcli_tree_close(tree); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -296,7 +296,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, tree->fs_type = talloc_strdup(tree, tcon.tconx.out.fs_type); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); *ret_tree = tree; return NT_STATUS_OK; -- cgit From 909c9b681a0718b8701e05addbad08c0aec87113 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Sep 2004 15:11:36 +0000 Subject: r2284: Thanks to some great detective work by tridge, NTLM2 signing now works. This means that 'require NTLMv2 session security' now works for RPC pipe signing. We don't yet have sealing, but it can't be much further. This is almost all tridge's code, munged into a form that can work with the GENSEC API. This commit also includes more lsakey fixes - that key is used for all DCE-RPC level authenticated connections, even over CIFS/ncacn_np. No doubt I missed something, but I'm going to get some sleep :-) Andrew Bartlett (This used to be commit a1fe175eec884280fb7e9ca8f528134cf4600beb) --- source4/libcli/auth/gensec.c | 32 +++++++-- source4/libcli/auth/gensec.h | 17 +++-- source4/libcli/auth/gensec_ntlmssp.c | 41 +++++++---- source4/libcli/auth/ntlmssp.c | 6 +- source4/libcli/auth/ntlmssp.h | 7 +- source4/libcli/auth/ntlmssp_sign.c | 135 ++++++++++++++++++++++------------- source4/libcli/auth/spnego.c | 62 +++++++++++----- 7 files changed, 203 insertions(+), 97 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 4b362b5305..a744f513dc 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -248,8 +248,6 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, gensec_want_feature(gensec_security, GENSEC_WANT_SEAL); } - gensec_want_feature(gensec_security, GENSEC_WANT_SESSION_KEY); - return gensec_start_mech(gensec_security); } @@ -303,17 +301,23 @@ NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, */ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig) + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { if (!gensec_security->ops->unseal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } - return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, data, length, sig); + return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); } NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { if (!gensec_security->ops->check_packet) { @@ -323,12 +327,13 @@ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, sig); + return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig); } NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { if (!gensec_security->ops->seal_packet) { @@ -338,12 +343,13 @@ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, sig); + return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig); } NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { if (!gensec_security->ops->sign_packet) { @@ -353,7 +359,19 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, sig); + return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig); +} + +size_t gensec_sig_size(struct gensec_security *gensec_security) +{ + if (!gensec_security->ops->sig_size) { + return 0; + } + if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) { + return 0; + } + + return gensec_security->ops->sig_size(gensec_security); } NTSTATUS gensec_session_key(struct gensec_security *gensec_security, diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 73a5f6b463..00c1c0dd0a 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -60,13 +60,22 @@ struct gensec_security_ops { NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out); NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig); + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig); NTSTATUS (*sign_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, DATA_BLOB *sig); + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig); + size_t (*sig_size)(struct gensec_security *gensec_security); NTSTATUS (*check_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, const DATA_BLOB *sig); + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig); NTSTATUS (*unseal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig); + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig); NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); NTSTATUS (*session_info)(struct gensec_security *gensec_security, struct auth_session_info **session_info); diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index beee29a088..0c96a783f1 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -287,42 +287,52 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur wrappers for the ntlmssp_*() functions */ static NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); } static NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); } static NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); } static NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); +} + +static size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security) +{ + return NTLMSSP_SIG_SIZE; } static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, @@ -413,6 +423,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .server_start = gensec_ntlmssp_server_start, .update = gensec_ntlmssp_update, .seal_packet = gensec_ntlmssp_seal_packet, + .sig_size = gensec_ntlmssp_sig_size, .sign_packet = gensec_ntlmssp_sign_packet, .check_packet = gensec_ntlmssp_check_packet, .unseal_packet = gensec_ntlmssp_unseal_packet, diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 4d2dd6b576..e6839e1fea 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -940,7 +940,7 @@ NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | -/* NTLMSSP_NEGOTIATE_NTLM2 | */ + NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH; return NT_STATUS_OK; @@ -971,7 +971,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, } if (ntlmssp_state->use_ntlmv2) { -/* ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;*/ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } /* generate the ntlmssp negotiate packet */ @@ -1293,7 +1293,7 @@ NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | -/* NTLMSSP_NEGOTIATE_NTLM2 |*/ + NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_REQUEST_TARGET; diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 61285e472b..153669f7b4 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -71,6 +71,8 @@ enum ntlmssp_message_type #define NTLMSSP_SIGN_VERSION 1 +#define NTLMSSP_SIG_SIZE 16 + struct ntlmssp_state { TALLOC_CTX *mem_ctx; @@ -162,8 +164,9 @@ struct ntlmssp_state const char *(*get_domain)(void); /* SMB Signing */ - - uint32_t ntlmssp_seq_num; + uint32_t ntlm_seq_num; + uint32_t ntlm2_send_seq_num; + uint32_t ntlm2_recv_seq_num; /* ntlmv2 */ DATA_BLOB send_sign_key; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index ca3660eea7..2ab54124e3 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -64,31 +64,40 @@ enum ntlmssp_direction { static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, enum ntlmssp_direction direction, - DATA_BLOB *sig) + DATA_BLOB *sig, BOOL encrypt_sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; uint8_t digest[16]; uint8_t seq_num[4]; - SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); + *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE); + if (!sig->data) { + return NT_STATUS_NO_MEMORY; + } + switch (direction) { case NTLMSSP_SEND: + SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num); + ntlmssp_state->ntlm2_send_seq_num++; hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key.data, ntlmssp_state->send_sign_key.length, &ctx); break; case NTLMSSP_RECEIVE: + SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num); + ntlmssp_state->ntlm2_recv_seq_num++; hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key.data, ntlmssp_state->recv_sign_key.length, &ctx); break; } hmac_md5_update(seq_num, sizeof(seq_num), &ctx); - hmac_md5_update(data, length, &ctx); + hmac_md5_update(whole_pdu, pdu_length, &ctx); hmac_md5_final(digest, &ctx); - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + if (encrypt_sig && ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { switch (direction) { case NTLMSSP_SEND: arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, digest, 8); @@ -98,7 +107,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat break; } } - *sig = data_blob_talloc(sig_mem_ctx, NULL, 16); + SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); memcpy(sig->data + 4, digest, 8); memcpy(sig->data + 12, seq_num, 4); @@ -106,11 +115,14 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat } else { uint32_t crc; crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlm_seq_num)) { return NT_STATUS_NO_MEMORY; } - - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + ntlmssp_state->ntlm_seq_num++; + + if (encrypt_sig) { + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + } } dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); return NT_STATUS_OK; @@ -119,26 +131,23 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { - NTSTATUS nt_status; - if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot check sign packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; } - + if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n")); return NT_STATUS_INVALID_PARAMETER; } - - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, - data, length, NTLMSSP_SEND, sig); - - /* increment counter on send */ - ntlmssp_state->ntlmssp_seq_num++; - return nt_status; + + return ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, + data, length, + whole_pdu, pdu_length, + NTLMSSP_SEND, sig, True); } /** @@ -149,6 +158,7 @@ NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { DATA_BLOB local_sig; @@ -164,17 +174,16 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, (unsigned long)sig->length)); } - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, data, - length, NTLMSSP_RECEIVE, &local_sig); + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, + data, length, + whole_pdu, pdu_length, + NTLMSSP_RECEIVE, &local_sig, True); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); return nt_status; } - /* increment counter on recv */ - ntlmssp_state->ntlmssp_seq_num++; - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { if (local_sig.length != sig->length || memcmp(local_sig.data, @@ -216,8 +225,10 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { + NTSTATUS nt_status; if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot seal packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; @@ -231,35 +242,20 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - HMACMD5Context ctx; - uint8_t seq_num[4]; - uint8_t digest[16]; - SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - - hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key.data, - ntlmssp_state->send_sign_key.length, &ctx); - hmac_md5_update(seq_num, 4, &ctx); - hmac_md5_update(data, length, &ctx); - hmac_md5_final(digest, &ctx); - /* The order of these two operations matters - we must first seal the packet, then seal the sequence number - this is becouse the send_seal_hash is not constant, but is is rather updated with each iteration */ arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, data, length); - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, digest, 8); - } - - *sig = data_blob_talloc(sig_mem_ctx, NULL, 16); - SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); - memcpy(sig->data + 4, digest, 8); - memcpy(sig->data + 12, seq_num, 4); + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, + data, length, + whole_pdu, pdu_length, + NTLMSSP_SEND, sig, True); } else { uint32_t crc; crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlm_seq_num)) { return NT_STATUS_NO_MEMORY; } @@ -270,14 +266,15 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + /* increment counter on send */ + ntlmssp_state->ntlm_seq_num++; + nt_status = NT_STATUS_OK; } dump_data_pw("ntlmssp signature\n", sig->data, sig->length); dump_data_pw("ntlmssp sealed data\n", data, length); - /* increment counter on send */ - ntlmssp_state->ntlmssp_seq_num++; - return NT_STATUS_OK; + return nt_status; } /** @@ -288,8 +285,11 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { + DATA_BLOB local_sig; + NTSTATUS nt_status; if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot unseal packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; @@ -297,13 +297,46 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + + /* We have to pass the data past the arcfour pad in + * the correct order, so we must encrypt the signature + * after we decrypt the main body. however, the + * signature is calculated over the encrypted data */ + + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, + data, length, + whole_pdu, pdu_length, + NTLMSSP_RECEIVE, &local_sig, False); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, data, length); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, local_sig.data + 4, 8); + } + + if (local_sig.length != sig->length || + memcmp(local_sig.data, + sig->data, sig->length) != 0) { + DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); + + DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); + return NT_STATUS_ACCESS_DENIED; + } + + dump_data_pw("ntlmssp clear data\n", data, length); + return NT_STATUS_OK; } else { arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); + dump_data_pw("ntlmssp clear data\n", data, length); + return ntlmssp_check_packet(ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); } - dump_data_pw("ntlmssp clear data\n", data, length); - - return ntlmssp_check_packet(ntlmssp_state, sig_mem_ctx, data, length, sig); } /** @@ -414,7 +447,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) sizeof(ntlmssp_state->ntlmssp_hash)); } - ntlmssp_state->ntlmssp_seq_num = 0; + ntlmssp_state->ntlm_seq_num = 0; + ntlmssp_state->ntlm2_send_seq_num = 0; + ntlmssp_state->ntlm2_recv_seq_num = 0; return NT_STATUS_OK; } diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index de71814354..f3ead5069d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -92,8 +92,10 @@ static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_securi wrappers for the spnego_*() functions */ static NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -103,13 +105,17 @@ static NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_secur } return gensec_unseal_packet(spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); } static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -120,13 +126,17 @@ static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_securi } return gensec_check_packet(spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); } static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -137,13 +147,17 @@ static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_securit } return gensec_seal_packet(spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); } static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - DATA_BLOB *sig) + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -153,11 +167,26 @@ static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_securit } return gensec_sign_packet(spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); +} + +static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security) +{ + struct spnego_state *spnego_state = gensec_security->private_data; + + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + return 0; + } + + return gensec_sig_size(spnego_state->sub_sec_security); } static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) + DATA_BLOB *session_key) { struct spnego_state *spnego_state = gensec_security->private_data; if (!spnego_state->sub_sec_security) { @@ -684,6 +713,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .update = gensec_spnego_update, .seal_packet = gensec_spnego_seal_packet, .sign_packet = gensec_spnego_sign_packet, + .sig_size = gensec_spnego_sig_size, .check_packet = gensec_spnego_check_packet, .unseal_packet = gensec_spnego_unseal_packet, .session_key = gensec_spnego_session_key, -- cgit From a06b88863d165d20123ee19f9313249b870ed2be Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Sep 2004 23:05:08 +0000 Subject: r2285: Remove more static data, fix spelling in a comment. (This used to be commit 2c701f59a7f232fed624f7cec62dd494dd32c2d9) --- source4/libcli/auth/ntlmssp.c | 4 ++-- source4/libcli/auth/ntlmssp.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index e6839e1fea..592656e880 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -107,8 +107,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags) static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) { - static uint8_t chal[8]; - generate_random_buffer(chal, sizeof(chal)); + uint8_t *chal = talloc(ntlmssp_state->mem_ctx, 8); + generate_random_buffer(chal, 8); return chal; } diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 153669f7b4..a318025650 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -120,7 +120,7 @@ struct ntlmssp_state * Callback to get the 'challenge' used for NTLM authentication. * * @param ntlmssp_state This structure - * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication + * @return 8 bytes of challenge data, determined by the server to be the challenge for NTLM authentication * */ const uint8_t *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); -- cgit From c0bea2aeb36d4a6b7ed8240d3ed479b2c5c34a16 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Sep 2004 23:09:26 +0000 Subject: r2286: Fixes towards krb5 logins into Samba's CIFS server. These fixes aim particularly at allowing PAC-less logins, as I don't yet generate a PAC in the lorikeet-heimdal KDC. This is for the benifit of a Kerbeors-enabled domain join, which seems to be progressing quite well! Andrew Bartlett (This used to be commit f5a381094dd5bcbd795a134bc4b8b89901b5e3eb) --- source4/libcli/auth/clikrb5.c | 15 ++-- source4/libcli/auth/gensec_krb5.c | 164 ++++++++++++++++++---------------- source4/libcli/auth/kerberos.h | 4 +- source4/libcli/auth/kerberos_verify.c | 19 +++- 4 files changed, 113 insertions(+), 89 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index f6f8520b3c..78492d2352 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -150,18 +150,23 @@ } #endif - void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, - DATA_BLOB *auth_data, krb5_ticket *tkt) + DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, + krb5_ticket *tkt) { + DATA_BLOB auth_data = data_blob(NULL, 0); #if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt && tkt->enc_part2) - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + if (tkt && tkt->enc_part2 + && tkt->enc_part2->authorization_data + && tkt->enc_part2->authorization_data[0] + && tkt->enc_part2->authorization_data[0]->length) + auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); #else if (tkt && tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) - *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, tkt->ticket.authorization_data->val->ad_data.length); #endif + return auth_data; } krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 569fd81206..4a97d51c40 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -38,13 +38,14 @@ enum GENSEC_KRB5_STATE { struct gensec_krb5_state { TALLOC_CTX *mem_ctx; DATA_BLOB session_key; - struct PAC_LOGON_INFO logon_info; + struct PAC_LOGON_INFO *logon_info; enum GENSEC_KRB5_STATE state_position; krb5_context krb5_context; krb5_auth_context krb5_auth_context; krb5_ccache krb5_ccache; krb5_data ticket; krb5_keyblock krb5_keyblock; + char *peer_principal; }; #ifdef KRB5_DO_VERIFY_PAC @@ -56,6 +57,7 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, krb5_error_code ret; krb5_crypto crypto; Checksum cksum; + int i; cksum.cksumtype = (CKSUMTYPE)sig->type; cksum.checksum.length = sizeof(sig->signature); @@ -70,21 +72,19 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, DEBUG(0,("krb5_crypto_init() failed\n")); return NT_STATUS_FOOBAR; } -{ -int i; -for (i=0; i < 40; i++) { - keyusage = i; - ret = krb5_verify_checksum(gensec_krb5_state->krb5_context, - crypto, - keyusage, - pac_data.data, - pac_data.length, - &cksum); - if (!ret) { - DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage)); - break; + for (i=0; i < 40; i++) { + keyusage = i; + ret = krb5_verify_checksum(gensec_krb5_state->krb5_context, + crypto, + keyusage, + pac_data.data, + pac_data.length, + &cksum); + if (!ret) { + DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage)); + break; + } } -}} krb5_crypto_destroy(gensec_krb5_state->krb5_context, crypto); if (ret) { @@ -99,7 +99,7 @@ for (i=0; i < 40; i++) { #endif static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, - struct PAC_LOGON_INFO *logon_info_out, + struct PAC_LOGON_INFO **logon_info_out, DATA_BLOB blob, struct gensec_krb5_state *gensec_krb5_state) { @@ -220,7 +220,7 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, } #endif DEBUG(0,("account_name: %s [%s]\n",logon_info->account_name.string, logon_info->full_name.string)); - *logon_info_out = *logon_info; + *logon_info_out = logon_info; return status; } @@ -542,16 +542,22 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL return nt_status; } - /* decode and verify the pac */ - nt_status = gensec_krb5_decode_pac(gensec_krb5_state->mem_ctx, &gensec_krb5_state->logon_info, pac, - gensec_krb5_state); + if (pac.data) { + /* decode and verify the pac */ + nt_status = gensec_krb5_decode_pac(gensec_krb5_state->mem_ctx, &gensec_krb5_state->logon_info, pac, + gensec_krb5_state); + } else { + /* NULL PAC, we might need to figure this information out the hard way */ + gensec_krb5_state->logon_info = NULL; + } if (NT_STATUS_IS_OK(nt_status)) { gensec_krb5_state->state_position = GENSEC_KRB5_DONE; /* wrap that up in a nice GSS-API wrapping */ *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REP); + + gensec_krb5_state->peer_principal = talloc_steal(gensec_krb5_state->mem_ctx, principal); } - SAFE_FREE(principal); return nt_status; } case GENSEC_KRB5_DONE: @@ -597,88 +603,88 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, return NT_STATUS_NO_USER_SESSION_KEY; } } -/* -struct gensec_krb5_state { - TALLOC_CTX *mem_ctx; - DATA_BLOB session_key; - struct PAC_LOGON_INFO logon_info; - enum GENSEC_KRB5_STATE state_position; - krb5_context krb5_context; - krb5_auth_context krb5_auth_context; - krb5_ccache krb5_ccache; - krb5_data ticket; - krb5_keyblock krb5_keyblock; -}; -struct auth_session_info -{ - TALLOC_CTX *mem_ctx; - int refcount; - - NT_USER_TOKEN *nt_user_token; - - struct auth_serversupplied_info *server_info; - - DATA_BLOB session_key; - - const char *workstation; -}; -*/ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info_out) { + NTSTATUS nt_status; struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; TALLOC_CTX *mem_ctx; + struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; - struct PAC_LOGON_INFO *logon_info = &gensec_krb5_state->logon_info; + struct PAC_LOGON_INFO *logon_info = gensec_krb5_state->logon_info; struct nt_user_token *ptoken; struct dom_sid *sid; + char *p; + char *principal; *session_info_out = NULL; - mem_ctx = talloc_init("krb5: session_info"); - - session_info = talloc_p(mem_ctx, struct auth_session_info); - if (!session_info) { - return NT_STATUS_NO_MEMORY; - } - - session_info->mem_ctx = mem_ctx; - session_info->refcount = 1; - session_info->server_info = NULL; - - ptoken = talloc_p(session_info->mem_ctx, struct nt_user_token); - if (!ptoken) { - return NT_STATUS_NO_MEMORY; + nt_status = make_server_info(&server_info, gensec_krb5_state->peer_principal); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } - ptoken->num_sids = 0; + server_info->guest = False; - ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, logon_info->groups_count + 2); - if (!ptoken->user_sids) { + principal = talloc_strdup(server_info->mem_ctx, gensec_krb5_state->peer_principal); + p = strchr(principal, '@'); + if (p) { + *p = '\0'; + } + server_info->account_name = principal; + server_info->domain = talloc_strdup(server_info->mem_ctx, p++); + if (!server_info->domain) { + free_server_info(&server_info); return NT_STATUS_NO_MEMORY; } + nt_status = make_session_info(server_info, &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + free_server_info(&server_info); + return nt_status; + } - sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); - ptoken->user_sids[0] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->user_rid); - ptoken->num_sids++; - sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); - ptoken->user_sids[1] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->group_rid); - ptoken->num_sids++; + /* IF we have the PAC - otherwise (TODO) we need to get this + * data from elsewere - local ldb, or lookup of some + * kind... */ - for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) { + if (logon_info) { + ptoken = talloc_p(session_info->mem_ctx, struct nt_user_token); + if (!ptoken) { + return NT_STATUS_NO_MEMORY; + } + + ptoken->num_sids = 0; + + ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, logon_info->groups_count + 2); + if (!ptoken->user_sids) { + return NT_STATUS_NO_MEMORY; + } + + + sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); + ptoken->user_sids[0] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->user_rid); + ptoken->num_sids++; sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); - ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->groups[ptoken->num_sids - 2].rid); + ptoken->user_sids[1] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->group_rid); + ptoken->num_sids++; + + for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) { + sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); + ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->groups[ptoken->num_sids - 2].rid); + } + + debug_nt_user_token(DBGC_AUTH, 0, ptoken); + + session_info->nt_user_token = ptoken; + } else { + session_info->nt_user_token = NULL; } - - debug_nt_user_token(DBGC_AUTH, 0, ptoken); - - session_info->nt_user_token = ptoken; session_info->session_key = data_blob_talloc(session_info->mem_ctx, - gensec_krb5_state->session_key.data, - gensec_krb5_state->session_key.length); + gensec_krb5_state->session_key.data, + gensec_krb5_state->session_key.length); session_info->workstation = NULL; diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index e35079a4ee..9d6a5e81ae 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -65,8 +65,8 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, const char *principal, krb5_ccache ccache, krb5_data *outbuf); -void get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, - DATA_BLOB *auth_data, krb5_ticket *tkt); +DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, + krb5_ticket *tkt); NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, krb5_auth_context auth_context, diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 88bf391cfa..843189c884 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -32,6 +32,9 @@ static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) DATA_BLOB pac_contents = data_blob(NULL, 0); ASN1_DATA data; int data_type; + if (!auth_data->length) { + return data_blob(NULL, 0); + } asn1_load(&data, *auth_data); asn1_start_tag(&data, ASN1_SEQUENCE(0)); @@ -95,7 +98,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } /* Look for a CIFS ticket */ - if (!StrnCaseCmp(princ_name, "cifs/", 5)) { + if (!StrnCaseCmp(princ_name, "cifs/", 5) || (!StrnCaseCmp(princ_name, "host/", 5))) { #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); #else @@ -254,6 +257,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au char *myname; BOOL auth_ok = False; + char *malloc_principal; + ZERO_STRUCT(packet); ZERO_STRUCTP(auth_data); ZERO_STRUCTP(ap_rep); @@ -329,7 +334,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - get_auth_data_from_tkt(mem_ctx, auth_data, tkt); + *auth_data = get_auth_data_from_tkt(mem_ctx, tkt); *auth_data = unwrap_pac(mem_ctx, auth_data); @@ -342,13 +347,21 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au #endif if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), - principal))) { + &malloc_principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } + *principal = talloc_strdup(mem_ctx, malloc_principal); + SAFE_FREE(malloc_principal); + if (!principal) { + DEBUG(3,("ads_verify_ticket: talloc_strdup() failed\n")); + sret = NT_STATUS_NO_MEMORY; + goto out; + } + sret = NT_STATUS_OK; out: -- cgit From 15a96c42985c9bb4778a16160290220a935d99bd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 12 Sep 2004 03:18:24 +0000 Subject: r2290: Fix 'lsakey' for the server-side, it is static for 'authenticated' connections. Fix kerberos session key issues - we need to call the routine for extracting the session key, not just read the cache. Andrew Bartlett (This used to be commit b80d849b6b586869fc7d3d4153db1a316f2867a9) --- source4/libcli/auth/gensec_krb5.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 4a97d51c40..5dbdf56b03 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -682,15 +682,13 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security session_info->nt_user_token = NULL; } - session_info->session_key = data_blob_talloc(session_info->mem_ctx, - gensec_krb5_state->session_key.data, - gensec_krb5_state->session_key.length); + nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key); session_info->workstation = NULL; *session_info_out = session_info; - return NT_STATUS_OK; + return nt_status; } -- cgit From f8f2630c0d65460435598f3b1db5672091df99e7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Sep 2004 06:38:00 +0000 Subject: r2294: this fixes the NTLM2 sign+seal combination. I have now tested: NTLM sign NTLM sign+seal NTLM2 sign NTLM2 sign+seal and all of the above both with and without key exchange the NTLM2 seal case is ugly and involves an extra data copy, which some API changes in gensec or the ndr layer might avoid in future. (This used to be commit fce7a4218b3136d880dd1a123e8525e3091bbed8) --- source4/libcli/auth/ntlmssp_sign.c | 40 ++++++++++++++------------------------ 1 file changed, 15 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 2ab54124e3..2b9659ae52 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -66,7 +66,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat const uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, enum ntlmssp_direction direction, - DATA_BLOB *sig, BOOL encrypt_sig) + DATA_BLOB *sig, BOOL encrypt_sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -120,9 +120,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat } ntlmssp_state->ntlm_seq_num++; - if (encrypt_sig) { - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); - } + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); return NT_STATUS_OK; @@ -245,13 +243,14 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, /* The order of these two operations matters - we must first seal the packet, then seal the sequence number - this is becouse the send_seal_hash is not constant, but is is rather updated with each iteration */ - - arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, data, length); - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, - NTLMSSP_SEND, sig, True); + NTLMSSP_SEND, sig, False); + arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, sig->data+4, 8); + } } else { uint32_t crc; crc = crc32_calc_buffer((const char *)data, length); @@ -259,12 +258,13 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_NO_MEMORY; } - /* The order of these two operations matters - we must first seal the packet, - then seal the sequence number - this is becouse the ntlmssp_hash is not - constant, but is is rather updated with each iteration */ - - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); + /* The order of these two operations matters - we must + first seal the packet, then seal the sequence + number - this is becouse the ntlmssp_hash is not + constant, but is is rather updated with each + iteration */ + arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); /* increment counter on send */ ntlmssp_state->ntlm_seq_num++; @@ -297,26 +297,16 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - - /* We have to pass the data past the arcfour pad in - * the correct order, so we must encrypt the signature - * after we decrypt the main body. however, the - * signature is calculated over the encrypted data */ + arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, data, length); nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, - NTLMSSP_RECEIVE, &local_sig, False); + NTLMSSP_RECEIVE, &local_sig, True); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } - arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, data, length); - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, local_sig.data + 4, 8); - } - if (local_sig.length != sig->length || memcmp(local_sig.data, sig->data, sig->length) != 0) { -- cgit From 922e17105fbf12db2da535fed29395c9bf7f60c4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Sep 2004 02:35:55 +0000 Subject: r2303: allow setting of many ntlmssp options from smb.conf or the command line. This makes testing much easier. (This used to be commit 0a4723d250ba13e6374700fc6e80854ec6a3eddc) --- source4/libcli/auth/ntlmssp.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 592656e880..f52f1ffbf9 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -938,10 +938,19 @@ NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->ref_count = 1; (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_NTLM2 | - NTLMSSP_NEGOTIATE_KEY_EXCH; + NTLMSSP_NEGOTIATE_NTLM; + + if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) { + (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128; + } + + if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) { + (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + } + + if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) { + (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } return NT_STATUS_OK; } @@ -1291,12 +1300,24 @@ NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) (*ntlmssp_state)->ref_count = 1; (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_NTLM2 | - NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_REQUEST_TARGET; + if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) { + (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128; + } + + if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) { + (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + } + + if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) { + (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } else { + /* apparently we can't do ntlmv2 if we don't do ntlm2 */ + (*ntlmssp_state)->use_ntlmv2 = False; + } + return NT_STATUS_OK; } -- cgit From d2c14a5dc6117d6593aa03090ce7fa4c9ebc3359 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 13 Sep 2004 04:28:10 +0000 Subject: r2307: Fix the use of 'raw' NTLMSSP to hosts that support extended security, but do not support SPNEGO (such as XP, when not joined to a domain). This is triggered by the presense or lack of a security blob in the negprot reply. Andrew Bartlett (This used to be commit 99f7a38c077725b22475f2ba68d0955114879c24) --- source4/libcli/auth/gensec.c | 11 +++++++++++ source4/libcli/auth/spnego.c | 5 +++-- source4/libcli/raw/clisession.c | 29 +++++++++++++++++++---------- 3 files changed, 33 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index a744f513dc..b7891ee53b 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -262,6 +262,17 @@ const char *gensec_get_name_by_authtype(uint8_t authtype) } +const char *gensec_get_name_by_oid(const char *oid) +{ + const struct gensec_security_ops *ops; + ops = gensec_security_by_oid(oid); + if (ops) { + return ops->name; + } + return NULL; +} + + /** * Start a GENSEC sub-mechanism by OID, used in SPNEGO * diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index f3ead5069d..696240f8d6 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -290,7 +290,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ null_data_blob, unwrapped_out); } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) + && (!NT_STATUS_IS_OK(nt_status))) { DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); gensec_end(&spnego_state->sub_sec_security); @@ -412,7 +413,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) + const DATA_BLOB in, DATA_BLOB *out) { struct spnego_state *spnego_state = gensec_security->private_data; DATA_BLOB null_data_blob = data_blob(NULL, 0); diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 32be6b68ed..dcf32c8485 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -379,6 +379,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess union smb_sesssetup s2; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); + const char *chosen_oid; s2.generic.level = RAW_SESSSETUP_SPNEGO; s2.spnego.in.bufsize = ~0; @@ -429,21 +430,25 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess goto done; } - status = gensec_start_mech_by_oid(session->gensec, OID_SPNEGO); + if (session->transport->negotiate.secblob.length) { + chosen_oid = OID_SPNEGO; + } else { + /* without a sec blob, means raw NTLMSSP */ + chosen_oid = OID_NTLMSSP; + } + + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", - nt_errstr(status))); + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); goto done; } - + status = gensec_update(session->gensec, mem_ctx, - session->transport->negotiate.secblob, - &s2.spnego.in.secblob); + session->transport->negotiate.secblob, + &s2.spnego.in.secblob); while(1) { - if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) { - break; - } if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { break; } @@ -455,6 +460,10 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } + if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) { + break; + } + session->vuid = s2.spnego.out.vuid; status = smb_raw_session_setup(session, mem_ctx, &s2); session->vuid = UID_FIELD_INVALID; @@ -483,7 +492,7 @@ done: parms->generic.out.lanman = s2.spnego.out.lanman; parms->generic.out.domain = s2.spnego.out.domain; } else { - DEBUG(1, ("Failed to login with SPNEGO: %s\n", nt_errstr(status))); + DEBUG(1, ("Failed to login with %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); return status; } -- cgit From 6de405f71ed8dec5b44d34e61a840ae33e1f92a5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Sep 2004 08:45:41 +0000 Subject: r2314: fix compiler warning metze (This used to be commit 75c3108955bab44ffda308406bae153e3a92cedf) --- source4/libcli/auth/gensec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index b7891ee53b..4470d6d21a 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -262,10 +262,10 @@ const char *gensec_get_name_by_authtype(uint8_t authtype) } -const char *gensec_get_name_by_oid(const char *oid) +const char *gensec_get_name_by_oid(const char *oid_string) { const struct gensec_security_ops *ops; - ops = gensec_security_by_oid(oid); + ops = gensec_security_by_oid(oid_string); if (ops) { return ops->name; } -- cgit From ceb43e86a71008716467ef0cb07adee64ddb7cd7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Sep 2004 08:46:38 +0000 Subject: r2315: change format metze (This used to be commit 9177cd4285315175913aa2c9359f1173fa7d6eb7) --- source4/libcli/auth/gensec.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 3d22632a3e..1894e1c136 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -1,4 +1,4 @@ -if test t$SMB_EXT_LIB_ENABLE_KRB5 = tYES; then +if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then /* enable this when krb5 is fully working */ SMB_MODULE_DEFAULT(gensec_krb5, NOT) fi -- cgit From ce694e7051dca90cdb5700e3865315d16931c3c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Sep 2004 14:17:41 +0000 Subject: r2328: add the start of a new system and protocol independent socket library. this is not used, but compiled currently there're maybe some api changes later... metze (This used to be commit de4447d7a57c614b80d0ac00dca900ea7e1c21ea) --- source4/libcli/libsmb.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/libsmb.m4 b/source4/libcli/libsmb.m4 index fe2a5b17ba..9293ea2038 100644 --- a/source4/libcli/libsmb.m4 +++ b/source4/libcli/libsmb.m4 @@ -9,4 +9,4 @@ SMB_SUBSYSTEM(LIBSMB,[], libcli/climessage.o libcli/clideltree.o], [], - [LIBCLI LIBRPC]) + [LIBCLI LIBRPC SOCKET]) -- cgit From d9d634ce97b2fd7d49410d26271eacd98660bbc4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Sep 2004 13:29:59 +0000 Subject: r2347: merge LDAP ASN.1 fixes from trunk metze (This used to be commit 492a00d909d6f3ff8305f102551f60d91d988ccd) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/util/asn1.c | 34 +++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b7ae58f7f5..7af9ca42c5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -602,7 +602,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); - asn1_write_Integer(&data, r->messageid); + asn1_write_implicit_Integer(&data, r->messageid); asn1_pop_tag(&data); break; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index b5db9b157e..ca62a0b574 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -110,13 +110,14 @@ BOOL asn1_pop_tag(ASN1_DATA *data) /* "i" is the one's complement representation, as is the normal result of an * implicit signed->unsigned conversion */ -static void push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) +static BOOL push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) { uint8_t lowest = i & 0xFF; i = i >> 8; if (i != 0) - push_int_bigendian(data, i, negative); + if (!push_int_bigendian(data, i, negative)) + return False; if (data->nesting->start+1 == data->ofs) { @@ -126,40 +127,51 @@ static void push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) if (negative) { /* Don't write leading 0xff's */ if (lowest == 0xFF) - return; + return True; if ((lowest & 0x80) == 0) { /* The only exception for a leading 0xff is if * the highest bit is 0, which would indicate * a positive value */ - asn1_write_uint8(data, 0xff); + if (!asn1_write_uint8(data, 0xff)) + return False; } } else { if (lowest & 0x80) { /* The highest bit of a positive integer is 1, * this would indicate a negative number. Push * a 0 to indicate a positive one */ - asn1_write_uint8(data, 0); + if (!asn1_write_uint8(data, 0)) + return False; } } } - asn1_write_uint8(data, lowest); + return asn1_write_uint8(data, lowest); } -/* write an integer */ -BOOL asn1_write_Integer(ASN1_DATA *data, int i) +/* write an Integer without the tag framing. Needed for example for the LDAP + * Abandon Operation */ + +BOOL asn1_write_implicit_Integer(ASN1_DATA *data, int i) { - if (!asn1_push_tag(data, ASN1_INTEGER)) return False; if (i == -1) { /* -1 is special as it consists of all-0xff bytes. In push_int_bigendian this is the only case that is not properly handled, as all 0xff bytes would be handled as leading ones to be ignored. */ - asn1_write_uint8(data, 0xff); + return asn1_write_uint8(data, 0xff); } else { - push_int_bigendian(data, i, i<0); + return push_int_bigendian(data, i, i<0); } +} + + +/* write an integer */ +BOOL asn1_write_Integer(ASN1_DATA *data, int i) +{ + if (!asn1_push_tag(data, ASN1_INTEGER)) return False; + if (!asn1_write_implicit_Integer(data, i)) return False; return asn1_pop_tag(data); } -- cgit From 64a727c6aa0903d0385e1f2482b63b48f0be07d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Sep 2004 06:33:19 +0000 Subject: r2376: added a way to disable krb5 on the command line. Just use --option 'gensec:krb5=no' or put "gensec:krb5 = no" in smb.conf Given the frustration I've had with kerberos I was very tempted to name this option --nfk, but resisted the temptation (This used to be commit 2d710a5eb5b36e46fa8f652305fa9ab2e09e02f3) --- source4/libcli/auth/gensec_krb5.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 5dbdf56b03..292c08f3f8 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -720,6 +720,11 @@ static const struct gensec_security_ops gensec_ms_krb5_security_ops = { NTSTATUS gensec_krb5_init(void) { NTSTATUS ret; + + if (!lp_parm_bool(-1, "gensec", "krb5", True)) { + return NT_STATUS_NOT_SUPPORTED; + } + ret = register_backend("gensec", &gensec_krb5_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", -- cgit From 3e3f7b0ed03baa1d97012a787f377fdca131d219 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Sep 2004 06:49:24 +0000 Subject: r2377: added a more generic way of disabling gensec subsystems. For example, "gensec:ntlmssp=no" will disable ntlmssp. (This used to be commit 66f88c7d89154155b27bf8b7839c580fb1cd1e7c) --- source4/libcli/auth/gensec.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 4470d6d21a..b47840dc65 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -736,6 +736,11 @@ static NTSTATUS gensec_register(const void *_ops) { const struct gensec_security_ops *ops = _ops; + if (!lp_parm_bool(-1, "gensec", ops->name, True)) { + DEBUG(2,("gensec subsystem %s is disabled\n", ops->name)); + return NT_STATUS_OK; + } + if (gensec_security_by_name(ops->name) != NULL) { /* its already registered! */ DEBUG(0,("GENSEC backend '%s' already registered\n", -- cgit From 9115d6cb975b944b453c43d17a657a6e7979ac37 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Sep 2004 11:26:30 +0000 Subject: r2385: the gensec:krb5 test is not needed here any more, as we do it in the registration code (This used to be commit bcf9d787d6bced4c4482fa3e51ccea258563d89e) --- source4/libcli/auth/gensec_krb5.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 292c08f3f8..c9e6d572db 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -721,10 +721,6 @@ NTSTATUS gensec_krb5_init(void) { NTSTATUS ret; - if (!lp_parm_bool(-1, "gensec", "krb5", True)) { - return NT_STATUS_NOT_SUPPORTED; - } - ret = register_backend("gensec", &gensec_krb5_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", -- cgit From c997a9018389c6eb164aa6ab8cb6494640b8fd9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Sep 2004 08:17:32 +0000 Subject: r2405: expose unix_perms_to_wire() for use by the posix backend, in supporting the UNIX extensions (This used to be commit a3fd9a911f8852372a57146cde04971263fac7c9) --- source4/libcli/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index d3ebe0bf72..e8b49f71df 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -51,7 +51,7 @@ static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, /**************************************************************************** Map standard UNIX permissions onto wire representations. ****************************************************************************/ -static uint32_t unix_perms_to_wire(mode_t perms) +uint32_t unix_perms_to_wire(mode_t perms) { uint_t ret = 0; -- cgit From defe32e9f47d9eca44533056b652f3b1c3f56c8e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Sep 2004 07:24:00 +0000 Subject: r2432: more string function updates. btw, the reason I want to use strncasecmp() instead of StrnCaseCmp() is that the Samba internal functions are built to deal with multi-byte, whereas in the cases I am converting we know we are dealing with solely ascii string constants, so going via the slow conversion libraries is pointless. (This used to be commit cef08d5789277bdaa25d5bf0e7cfca8615230f1b) --- source4/libcli/auth/kerberos_verify.c | 2 +- source4/libcli/ldap/ldap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 843189c884..9afc4caacc 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -98,7 +98,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } /* Look for a CIFS ticket */ - if (!StrnCaseCmp(princ_name, "cifs/", 5) || (!StrnCaseCmp(princ_name, "host/", 5))) { + if (!strncasecmp(princ_name, "cifs/", 5) || (!strncasecmp(princ_name, "host/", 5))) { #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); #else diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7af9ca42c5..72e8f605dc 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1121,7 +1121,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, const char *p = url; /* skip leading "URL:" (if any) */ - if ( strnequal( p, "URL:", 4 ) ) { + if (strncasecmp( p, "URL:", 4) == 0) { p += 4; } -- cgit From 6b9b169c2746c0223f249700d7ff8a70feb8da62 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Sep 2004 10:40:11 +0000 Subject: r2443: check return code of event_loop_once() to catch thet cases where the server closes the connetion and we got EBADF from select() and event_loop_once() fails metze (This used to be commit 9c0e50a6f3d628156b4543d5ded89e06be696f64) --- source4/libcli/raw/rawrequest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 51c0c0b925..6536af3072 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -285,7 +285,9 @@ BOOL smbcli_request_receive(struct smbcli_request *req) /* keep receiving packets until this one is replied to */ while (req->state <= SMBCLI_REQUEST_RECV) { - event_loop_once(req->transport->event.ctx); + if (event_loop_once(req->transport->event.ctx) != 0) { + return False; + } } return req->state == SMBCLI_REQUEST_DONE; -- cgit From ed4d10fb43ea462500dbaf690b8e04d910bfac4e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Sep 2004 04:41:17 +0000 Subject: r2463: make sure we don't send the password in a tconx unless we really have to (This used to be commit 3e84c06f4c76d62f4f2606b457d9a76b6c1a061d) --- source4/libcli/cliconnect.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 220a450433..f25f29f86e 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -99,7 +99,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, /* wrapper around smb_tree_connect() */ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, - const char *devtype, const char *password) + const char *devtype, const char *password) { union smb_tcon tcon; TALLOC_CTX *mem_ctx; @@ -110,17 +110,25 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, cli->tree->reference_count++; + mem_ctx = talloc_init("tcon"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + /* setup a tree connect */ tcon.generic.level = RAW_TCON_TCONX; tcon.tconx.in.flags = 0; - tcon.tconx.in.password = data_blob(password, strlen(password)+1); + if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { + tcon.tconx.in.password = data_blob(NULL, 0); + } else if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 16); + E_md4hash(password, tcon.tconx.in.password.data); + } else { + tcon.tconx.in.password = data_blob_talloc(mem_ctx, password, strlen(password)+1); + } tcon.tconx.in.path = sharename; tcon.tconx.in.device = devtype; - mem_ctx = talloc_init("tcon"); - if (!mem_ctx) - return NT_STATUS_NO_MEMORY; - status = smb_tree_connect(cli->tree, mem_ctx, &tcon); cli->tree->tid = tcon.tconx.out.cnum; -- cgit From 23ba434b017d61f397befe9808fa3214c3964355 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Sep 2004 08:46:47 +0000 Subject: r2469: complete overhaul of the old-style RAW_SEARCH_ calls (the OS/2 and original core level calls). The old code was completely wrong in many respects. also fixed the EA_SIZE level in the server extended the RAW-SEARCH test suite to test the new code properly (This used to be commit 71480271ad84b57fcdde264a54bb2408cf783255) --- source4/libcli/clilist.c | 6 +-- source4/libcli/raw/rawsearch.c | 92 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 0e2cdabc0a..91a989d361 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -29,7 +29,7 @@ struct search_private { int total_received; /* total received all together */ enum smb_search_level info_level; const char *last_name; /* used to continue trans2 search */ - DATA_BLOB status; /* used for old-style search */ + struct smb_search_id id; /* used for old-style search */ }; @@ -238,7 +238,7 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) state->total_received++; state->ff_searchcount++; - state->status = file->search.search_id; /* return resume info */ + state->id = file->search.id; /* return resume info */ return True; } @@ -294,7 +294,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu next_parms.search_next.level = RAW_SEARCH_SEARCH; next_parms.search_next.in.max_count = num_asked; next_parms.search_next.in.search_attrib = attribute; - next_parms.search_next.in.search_id = state.status; + next_parms.search_next.in.id = state.id; status = smb_raw_search_next(tree, state.mem_ctx, &next_parms, diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 67410283ed..df44dbffa4 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -42,11 +42,15 @@ static void smb_raw_search_backend(struct smbcli_request *req, p = req->in.data + 3; for (i=0; i < count; i++) { - search_data.search.search_id = smbcli_req_pull_blob(req, mem_ctx, p, 21); - search_data.search.attrib = CVAL(p, 21); - search_data.search.write_time = raw_pull_dos_date(req->transport, - p + 22); - search_data.search.size = IVAL(p, 26); + search_data.search.id.reserved = CVAL(p, 0); + memcpy(search_data.search.id.name, p+1, 11); + search_data.search.id.handle = CVAL(p, 12); + search_data.search.id.server_cookie = IVAL(p, 13); + search_data.search.id.client_cookie = IVAL(p, 17); + search_data.search.attrib = CVAL(p, 21); + search_data.search.write_time = raw_pull_dos_date(req->transport, + p + 22); + search_data.search.size = IVAL(p, 26); smbcli_req_pull_ascii(req, mem_ctx, &search_data.search.name, p+30, 13, STR_ASCII); if (!callback(private, &search_data)) { break; @@ -65,8 +69,15 @@ static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, { struct smbcli_request *req; - - req = smbcli_request_setup(tree, SMBsearch, 2, 0); + uint8_t op = SMBsearch; + + if (io->generic.level == RAW_SEARCH_FFIRST) { + op = SMBffirst; + } else if (io->generic.level == RAW_SEARCH_FUNIQUE) { + op = SMBfunique; + } + + req = smbcli_request_setup(tree, op, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } @@ -99,8 +110,14 @@ static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, { struct smbcli_request *req; + uint8_t var_block[21]; + uint8_t op = SMBsearch; + + if (io->generic.level == RAW_SEARCH_FFIRST) { + op = SMBffirst; + } - req = smbcli_request_setup(tree, SMBsearch, 2, 0); + req = smbcli_request_setup(tree, op, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } @@ -108,7 +125,14 @@ static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, SSVAL(req->out.vwv, VWV(0), io->search_next.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_next.in.search_attrib); smbcli_req_append_ascii4(req, "", STR_TERMINATE); - smbcli_req_append_var_block(req, io->search_next.in.search_id.data, 21); + + SCVAL(var_block, 0, io->search_next.in.id.reserved); + memcpy(&var_block[1], io->search_next.in.id.name, 11); + SCVAL(var_block, 12, io->search_next.in.id.handle); + SIVAL(var_block, 13, io->search_next.in.id.server_cookie); + SIVAL(var_block, 17, io->search_next.in.id.client_cookie); + + smbcli_req_append_var_block(req, var_block, 21); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { @@ -123,6 +147,43 @@ static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, return smbcli_request_destroy(req); } + +/**************************************************************************** + Old style search next. +****************************************************************************/ +static NTSTATUS smb_raw_search_close_old(struct smbcli_tree *tree, + union smb_search_close *io) +{ + struct smbcli_request *req; + uint8_t var_block[21]; + + req = smbcli_request_setup(tree, SMBfclose, 2, 0); + if (!req) { + return NT_STATUS_NO_MEMORY; + } + + SSVAL(req->out.vwv, VWV(0), io->fclose.in.max_count); + SSVAL(req->out.vwv, VWV(1), io->fclose.in.search_attrib); + smbcli_req_append_ascii4(req, "", STR_TERMINATE); + + SCVAL(var_block, 0, io->fclose.in.id.reserved); + memcpy(&var_block[1], io->fclose.in.id.name, 11); + SCVAL(var_block, 12, io->fclose.in.id.handle); + SIVAL(var_block, 13, io->fclose.in.id.server_cookie); + SIVAL(var_block, 17, io->fclose.in.id.client_cookie); + + smbcli_req_append_var_block(req, var_block, 21); + + if (!smbcli_request_send(req) || + !smbcli_request_receive(req)) { + return smbcli_request_destroy(req); + } + + return smbcli_request_destroy(req); +} + + + /**************************************************************************** Very raw search first - returns param/data blobs. ****************************************************************************/ @@ -245,6 +306,8 @@ static int parse_trans2_search(struct smbcli_tree *tree, switch (level) { case RAW_SEARCH_GENERIC: case RAW_SEARCH_SEARCH: + case RAW_SEARCH_FFIRST: + case RAW_SEARCH_FUNIQUE: /* handled elsewhere */ return -1; @@ -499,7 +562,9 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, DATA_BLOB p_blob, d_blob; NTSTATUS status; - if (io->generic.level == RAW_SEARCH_SEARCH) { + if (io->generic.level == RAW_SEARCH_SEARCH || + io->generic.level == RAW_SEARCH_FFIRST || + io->generic.level == RAW_SEARCH_FUNIQUE) { return smb_raw_search_first_old(tree, mem_ctx, io, private, callback); } if (io->generic.level >= RAW_SEARCH_GENERIC) { @@ -543,7 +608,8 @@ NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, DATA_BLOB p_blob, d_blob; NTSTATUS status; - if (io->generic.level == RAW_SEARCH_SEARCH) { + if (io->generic.level == RAW_SEARCH_SEARCH || + io->generic.level == RAW_SEARCH_FFIRST) { return smb_raw_search_next_old(tree, mem_ctx, io, private, callback); } if (io->generic.level >= RAW_SEARCH_GENERIC) { @@ -582,6 +648,10 @@ NTSTATUS smb_raw_search_close(struct smbcli_tree *tree, union smb_search_close *io) { struct smbcli_request *req; + + if (io->generic.level == RAW_FINDCLOSE_FCLOSE) { + return smb_raw_search_close_old(tree, io); + } req = smbcli_request_setup(tree, SMBfindclose, 1, 0); if (!req) { -- cgit From 1d2611df82e80d7b5af7f75ffd66ce18ea68858e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 05:13:00 +0000 Subject: r2494: fixed connecting to a share mode server (tested and really works now) (This used to be commit 25f725c9be8fe5a7fd85488214b598bc431d4c7f) --- source4/libcli/cliconnect.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index f25f29f86e..66882f605d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -83,7 +83,11 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.generic.in.domain = ""; setup.generic.in.capabilities &= ~CAP_EXTENDED_SECURITY; } else { - setup.generic.in.password = password; + if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { + setup.generic.in.password = password; + } else { + setup.generic.in.password = NULL; + } setup.generic.in.user = user; setup.generic.in.domain = domain; } @@ -121,8 +125,11 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { tcon.tconx.in.password = data_blob(NULL, 0); } else if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 16); - E_md4hash(password, tcon.tconx.in.password.data); + tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 24); + if (cli->transport->negotiate.secblob.length < 8) { + return NT_STATUS_INVALID_PARAMETER; + } + SMBencrypt(password, cli->transport->negotiate.secblob.data, tcon.tconx.in.password.data); } else { tcon.tconx.in.password = data_blob_talloc(mem_ctx, password, strlen(password)+1); } -- cgit From e6e4e3e0a3f2222efeca7bee535fe26162c974c8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 05:13:32 +0000 Subject: r2495: cope properly with STATUS_NO_MORE_FILES in old search client code (This used to be commit 878729b7d97869a3d6dacea115ed4af2fd18e93c) --- source4/libcli/clilist.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 91a989d361..67a2e980ca 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -300,7 +300,10 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu &next_parms, (void*)&state, smbcli_list_old_callback); - + + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) { + break; + } if (!NT_STATUS_IS_OK(status)) { talloc_destroy(state.mem_ctx); return -1; -- cgit From 57196843320a1b833bcd669d0b23b429dfd34fb3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 05:14:20 +0000 Subject: r2497: fixed an uninitialised 4 bytes in old style session setup (found with valgrind) (This used to be commit b2bb41721817256618124907a6922a00d50643dc) --- source4/libcli/raw/clisession.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index dcf32c8485..2bd2d0e054 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -80,6 +80,7 @@ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num); SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey); SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length); + SIVAL(req->out.vwv,VWV(8), 0); /* reserved */ smbcli_req_append_blob(req, &parms->old.in.password); smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE); smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER); -- cgit From 2e55ba2018a25aac33cec76ee16c2e9754421448 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 05:14:59 +0000 Subject: r2498: added STATUS_NO_MORE_FILES to nt status codes that we can map to a string (This used to be commit b7191999634cf3817dc69dd3743d185ae41dbdc3) --- source4/libcli/util/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index c71dc2247b..563e27ddbf 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -31,6 +31,7 @@ typedef struct static const nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, + { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, -- cgit From 211d3cff2f6d5669af71699c74e6d40c4206249a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Sep 2004 10:42:09 +0000 Subject: r2507: Allow a case-insensitive lookup when converting strings into NTSTATUS values. Andrew Bartlett (This used to be commit 59e361f7cca1bbaeba5d5952173b90665a76ab2d) --- source4/libcli/util/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 563e27ddbf..2adb561222 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -707,7 +707,7 @@ NTSTATUS nt_status_string_to_code(char *nt_status_str) int idx = 0; while (nt_errs[idx].nt_errstr != NULL) { - if (strcmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { + if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { return nt_errs[idx].nt_errcode; } idx++; -- cgit From 566c38c820a273c8ce25f16c35346a68561d50fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Sep 2004 10:42:58 +0000 Subject: r2508: - implemented ldap_decode() for UnbindRequest and ExtendedRequest - fail when we got a wrong tag in ldap_decode() metze (This used to be commit e942f414c5f9130c7ac9996612caaefd29f5eeca) --- source4/libcli/ldap/ldap.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 72e8f605dc..5d233bcdca 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -879,8 +879,10 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_UnbindRequest): { + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest)); + asn1_end_tag(data); break; } @@ -1087,8 +1089,29 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { -/* struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; */ + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return False; + } + r->oid = blob2string_talloc(msg->mem_ctx, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return False; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = data_blob(NULL, 0); + } + + asn1_end_tag(data); break; } @@ -1105,7 +1128,8 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) r->value.length = 0; break; } - + default: + return False; } asn1_end_tag(data); -- cgit From bc8ef3d1b6bfdf279d65783869b9a247c1da38aa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 22 Sep 2004 12:25:53 +0000 Subject: r2516: Remove duplicate line. (This used to be commit dff6262e4f9d48ed753e00faf081e52c03c7129c) --- source4/libcli/util/dom_sid.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index 0ca4cd731f..c2d188abec 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -66,7 +66,6 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) ret->sid_rev_num = rev; ret->id_auth[0] = 0; - ret->id_auth[0] = 0; ret->id_auth[1] = 0; ret->id_auth[2] = ia >> 24; ret->id_auth[3] = ia >> 16; -- cgit From ca60193f24bb2540e65c8c272ca2bead3850b456 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 12:38:19 +0000 Subject: r2520: - finished implementing the server side of the old style search requests (This used to be commit 4e4859c06b9de5fe60ebd17cfb09eed480b79ec1) --- source4/libcli/util/errormap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index e2aeded65d..482743b03b 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -50,6 +50,7 @@ static const struct { uint32_t dos_code; NTSTATUS ntstatus; } ntstatus_to_dos_map[] = { + {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, @@ -616,6 +617,7 @@ static const struct { uint32_t dos_code; NTSTATUS ntstatus; } dos_to_ntstatus_map[] = { + {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, @@ -628,7 +630,6 @@ static const struct { {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, - {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, -- cgit From 366be01eef961c183a3c59ddd084059378aedc27 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Sep 2004 21:45:52 +0000 Subject: r2534: Change NTLMSSP parsing to avoid a seperate str_chrnum() call - storing away the string as a data blob to be put in the buffers later. This also avoids a length-limited push_str, moving to push_ucs2_talloc(). Andrew Bartlett (This used to be commit 69163500e0b577f19d1ffeea87f08e05539f5bcc) --- source4/libcli/auth/ntlmssp_parse.c | 104 +++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 44 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index bb835b367c..8edadf50f5 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -43,12 +43,19 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *format, ...) { - int i, n; + int i; + ssize_t n; va_list ap; char *s; uint8_t *b; int head_size=0, data_size=0; int head_ofs, data_ofs; + int *intargs; + + DATA_BLOB *pointers; + + pointers = talloc_array_p(mem_ctx, DATA_BLOB, strlen(format)); + intargs = talloc_array_p(pointers, int, strlen(format)); /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -57,34 +64,60 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, case 'U': s = va_arg(ap, char *); head_size += 8; - data_size += str_charnum(s) * 2; + n = push_ucs2_talloc(pointers, (smb_ucs2_t **)&pointers[i].data, s); + if (n == -1) { + return False; + } + pointers[i].length = n; + pointers[i].length -= 2; + data_size += pointers[i].length; break; case 'A': s = va_arg(ap, char *); head_size += 8; - data_size += str_ascii_charnum(s); + n = push_ascii_talloc(pointers, (char **)&pointers[i].data, s); + if (n == -1) { + return False; + } + pointers[i].length = n; + pointers[i].length -= 1; + data_size += pointers[i].length; break; case 'a': n = va_arg(ap, int); + intargs[i] = n; s = va_arg(ap, char *); - data_size += (str_charnum(s) * 2) + 4; + n = push_ucs2_talloc(pointers, (smb_ucs2_t **)&pointers[i].data, s); + if (n == -1) { + return False; + } + pointers[i].length = n; + pointers[i].length -= 2; + data_size += pointers[i].length + 4; break; case 'B': b = va_arg(ap, uint8_t *); head_size += 8; - data_size += va_arg(ap, int); + pointers[i].data = b; + pointers[i].length = va_arg(ap, int); + data_size += pointers[i].length; break; case 'b': b = va_arg(ap, uint8_t *); - head_size += va_arg(ap, int); + pointers[i].data = b; + pointers[i].length = va_arg(ap, int); + head_size += pointers[i].length; break; case 'd': n = va_arg(ap, int); + intargs[i] = n; head_size += 4; break; case 'C': s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; + pointers[i].data = s; + pointers[i].length = strlen(s)+1; + head_size += pointers[i].length; break; } } @@ -100,64 +133,47 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, for (i=0; format[i]; i++) { switch (format[i]) { case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); + case 'B': + n = pointers[i].length; SSVAL(blob->data, head_ofs, n); head_ofs += 2; SSVAL(blob->data, head_ofs, n); head_ofs += 2; SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + if (pointers[i].data && n) /* don't follow null pointers... */ + memcpy(blob->data+data_ofs, pointers[i].data, n); data_ofs += n; break; case 'a': - n = va_arg(ap, int); + n = intargs[i]; SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - break; - case 'B': - b = va_arg(ap, uint8_t *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - if (n && b) /* don't follow null pointers... */ - memcpy(blob->data+data_ofs, b, n); + n = pointers[i].length; + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + if (n >= 0) { + memcpy(blob->data+data_ofs, pointers[i].data, n); + } data_ofs += n; break; case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; + n = intargs[i]; + SIVAL(blob->data, head_ofs, n); + head_ofs += 4; break; case 'b': - b = va_arg(ap, uint8_t *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); + n = pointers[i].length; + memcpy(blob->data + head_ofs, pointers[i].data, n); head_ofs += n; break; case 'C': - s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, - STR_ASCII|STR_TERMINATE); + n = pointers[i].length; + memcpy(blob->data + head_ofs, pointers[i].data, n); + head_ofs += n; break; } } va_end(ap); + + talloc_free(pointers); return True; } -- cgit From 5e7259a6977078b95008856a3f8986fbb99e7a1b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Sep 2004 21:50:49 +0000 Subject: r2535: Make certain, that even if we have invalid ASN.1 here, and the caller does not check the return value, that we don't return uninitialised memory here. Andrew Bartlett (This used to be commit 0e081ecb9d752067b99305b3b62477c3eed9ac24) --- source4/libcli/util/asn1.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index ca62a0b574..3dc5abc09a 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -566,7 +566,13 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) *blob = data_blob(NULL, len); asn1_read(data, blob->data, len); asn1_end_tag(data); - return !data->has_error; + + if (data->has_error) { + data_blob_free(blob); + *blob = data_blob(NULL, 0); + return False; + } + return True; } BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) -- cgit From 9a9dcc7250ccd4544cb797c15b3bc3dfbb760be0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 Sep 2004 00:51:45 +0000 Subject: r2552: Character set conversion and string handling updates. The intial motivation for this commit was to merge in some of the bugfixes present in Samba3's chrcnv and string handling code into Samba4. However, along the way I found a lot of unused functions, and decided to do a bit more... The strlen_m code now does not use a fixed buffer, but more work is needed to finish off other functions in str_util.c. These fixed length buffers hav caused very nasty, hard to chase down bugs at some sites. The strupper_m() function has a strupper_talloc() to replace it (we need to go around and fix more uses, but it's a start). Use of these new functions will avoid bugs where the upper or lowercase version of a string is a different length. I have removed the push_*_allocate functions, which are replaced by calls to push_*_talloc. Likewise, pstring and other 'fixed length' wrappers are removed, where possible. I have removed the first ('base pointer') argument, used by push_ucs2, as the Samba4 way of doing things ensures that this is always on an even boundary anyway. (It was used in only one place, in any case). (This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392) --- source4/libcli/auth/ntlmssp_parse.c | 6 +++--- source4/libcli/raw/rawrequest.c | 17 ++++++++++------ source4/libcli/util/smbencrypt.c | 39 ++++++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 8edadf50f5..9c4cc40acf 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -236,7 +236,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, return False; if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), + pull_string(p, blob->data + ptr, sizeof(p), len1, STR_UNICODE|STR_NOALIGN); (*ps) = talloc_strdup(mem_ctx, p); @@ -267,7 +267,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, return False; if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), + pull_string(p, blob->data + ptr, sizeof(p), len1, STR_ASCII|STR_NOALIGN); (*ps) = talloc_strdup(mem_ctx, p); @@ -322,7 +322,7 @@ BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) return False; - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), + head_ofs += pull_string(p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); if (strcmp(s, p) != 0) { diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 6536af3072..1ff36d0a8d 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -369,13 +369,14 @@ size_t smbcli_req_append_string(struct smbcli_request *req, const char *str, uin smbcli_req_grow_allocation(req, len + req->out.data_size); - len = push_string(NULL, req->out.data + req->out.data_size, str, len, flags); + len = push_string(req->out.data + req->out.data_size, str, len, flags); smbcli_req_grow_data(req, len + req->out.data_size); return len; } + /* this is like smbcli_req_append_string but it also return the non-terminated string byte length, which can be less than the number @@ -528,7 +529,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c return 0; } - ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (const void **)dest); + ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest); if (ret == -1) { *dest = NULL; return 0; @@ -570,7 +571,7 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, src_len2++; } - ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (const void **)dest); + ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest); if (ret == -1) { *dest = NULL; @@ -696,6 +697,7 @@ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, { int src_len, src_len2, alignment=0; ssize_t ret; + char *dest2; if (src < (const char *)blob->data || src >= (const char *)(blob->data + blob->length)) { @@ -727,11 +729,12 @@ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, src_len2 += 2; } - ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (const void **)dest); + ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; return 0; } + *dest = dest2; return src_len2 + alignment; } @@ -755,6 +758,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, { int src_len, src_len2; ssize_t ret; + char *dest2; src_len = blob->length - PTR_DIFF(src, blob->data); if (src_len < 0) { @@ -771,12 +775,13 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, src_len2++; } - ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (const void **)dest); + ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; return 0; } + *dest = dest2; return ret; } @@ -911,7 +916,7 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, return 0; } - len = push_string(NULL, blob->data + blob->length, str, max_len, flags); + len = push_string(blob->data + blob->length, str, max_len, flags); blob->length += len; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index a50b4edc88..f0dba16a5a 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -61,15 +61,17 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) void E_md4hash(const char *passwd, uint8_t p16[16]) { int len; - smb_ucs2_t wpwd[129]; + smb_ucs2_t *wpwd; - /* Password must be converted to NT unicode - null terminated. */ - push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); - /* Calculate length in bytes */ - len = strlen_w(wpwd) * sizeof(int16_t); + TALLOC_CTX *mem_ctx = talloc_init("E_md4hash"); + SMB_ASSERT(mem_ctx); + len = push_ucs2_talloc(mem_ctx, &wpwd, passwd); + SMB_ASSERT(len >= 2); + + len -= 2; mdfour(p16, (uint8_t *)wpwd, len); - ZERO_STRUCT(wpwd); + talloc_free(mem_ctx); } /** @@ -114,16 +116,22 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], size_t domain_byte_len; HMACMD5Context ctx; + TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); + if (!mem_ctx) { + return False; + } - user_byte_len = push_ucs2_allocate(&user, user_in); - if (user_byte_len == (size_t)-1) { - DEBUG(0, ("push_uss2_allocate() for user returned -1 (probably malloc() failure)\n")); + user_byte_len = push_ucs2_talloc(mem_ctx, &user, user_in); + if (user_byte_len == (ssize_t)-1) { + DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); + talloc_free(mem_ctx); return False; } - domain_byte_len = push_ucs2_allocate(&domain, domain_in); - if (domain_byte_len == (size_t)-1) { - DEBUG(0, ("push_uss2_allocate() for domain returned -1 (probably malloc() failure)\n")); + domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in); + if (domain_byte_len == (ssize_t)-1) { + DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); + talloc_free(mem_ctx); return False; } @@ -152,8 +160,7 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], dump_data(100, kr_buf, 16); #endif - SAFE_FREE(user); - SAFE_FREE(domain); + talloc_free(mem_ctx); return True; } @@ -407,7 +414,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) uint8_t new_pw[512]; size_t new_pw_len; - new_pw_len = push_string(NULL, new_pw, + new_pw_len = push_string(new_pw, password, sizeof(new_pw), string_flags); @@ -459,7 +466,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, } /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + *new_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, string_flags); #ifdef DEBUG_PASSWORD -- cgit From f5db8edc97a3dcbbab7a33a41b54fc17902872ea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 06:51:14 +0000 Subject: r2587: fixed a couple of authentication memory leaks. There are more to be fixed - I'll commit a little test suite soon. (This used to be commit 5b967c1cbb9831f7f2c6c6187f9e8e6dcc284497) --- source4/libcli/auth/spnego.c | 2 ++ source4/libcli/auth/spnego_parse.c | 4 ++++ source4/libcli/raw/clisession.c | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 696240f8d6..bbf8f86676 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -528,6 +528,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA nt_status = gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal); if (!NT_STATUS_IS_OK(nt_status)) { + spnego_free_data(&spnego); return nt_status; } } @@ -540,6 +541,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA &unwrapped_out); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { + spnego_free_data(&spnego); return nt_status; } diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 047d17ce5a..20b766a4e2 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -54,6 +54,10 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token talloc_realloc(token->mechTypes, (i + 2) * sizeof(*token->mechTypes)); asn1_read_OID(asn1, token->mechTypes + i); + if (token->mechTypes[i]) { + talloc_steal(token->mechTypes, + token->mechTypes[i]); + } } token->mechTypes[i] = NULL; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 2bd2d0e054..264c1cd616 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -446,8 +446,8 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess } status = gensec_update(session->gensec, mem_ctx, - session->transport->negotiate.secblob, - &s2.spnego.in.secblob); + session->transport->negotiate.secblob, + &s2.spnego.in.secblob); while(1) { if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { @@ -493,6 +493,7 @@ done: parms->generic.out.lanman = s2.spnego.out.lanman; parms->generic.out.domain = s2.spnego.out.domain; } else { + gensec_end(&session->gensec); DEBUG(1, ("Failed to login with %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); return status; } -- cgit From 30381686c4874e4f9602a977a31399e49350e597 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 11:15:18 +0000 Subject: r2621: - now that the client code is non-blocking, we no longer need write_data and read_data, which are inherently blocking operations - got rid of some old NBT keepalive routines that are not needed (This used to be commit e73b4ae4e500d3b7ee57e160e0f8b63c99b2542a) --- source4/libcli/raw/clisocket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 9aea8624d0..654d8ee61b 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -125,7 +125,7 @@ ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t l return -1; } - return write_data(sock->fd, data, len); + return write(sock->fd, data, len); } @@ -139,7 +139,7 @@ ssize_t smbcli_sock_read(struct smbcli_socket *sock, char *data, size_t len) return -1; } - return read_data(sock->fd, data, len); + return read(sock->fd, data, len); } /**************************************************************************** -- cgit From daa66ec96c2df1d59fa50c6e8869e4c1bcc2af88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 11:18:04 +0000 Subject: r2624: - save some system calls by only trying read/write operations that select has indicated are possible - when a socket is dead, don't try to do anything more on it (This used to be commit e95e5c591fcf9c3b7fde7fbdcc1837e22195e0a8) --- source4/libcli/raw/clitransport.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 2d29ba371f..85d5337da7 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -21,6 +21,10 @@ #include "includes.h" + +static void smbcli_transport_process_recv(struct smbcli_transport *transport); +static void smbcli_transport_process_send(struct smbcli_transport *transport); + /* an event has happened on the socket */ @@ -29,7 +33,12 @@ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_e { struct smbcli_transport *transport = fde->private; - smbcli_transport_process(transport); + if (flags & EVENT_FD_READ) { + smbcli_transport_process_recv(transport); + } + if (flags & EVENT_FD_WRITE) { + smbcli_transport_process_send(transport); + } } /* @@ -265,6 +274,7 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport) return; } smbcli_transport_dead(transport); + return; } req->out.buffer += ret; req->out.size -= ret; -- cgit From c5f4378361b9671e39fa83b043f28c972ab30b70 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 12:08:57 +0000 Subject: r2629: convert gensec to the new talloc model by making our gensec structures a talloc child of the open connection we can be sure that it will be destroyed when the connection is dropped. (This used to be commit f12ee2f241aab1549bc1d9ca4c35a35a1ca0d09d) --- source4/libcli/auth/gensec.c | 56 ++++++++++++++++++--------------------- source4/libcli/auth/gensec.h | 1 - source4/libcli/auth/gensec_krb5.c | 4 +-- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/raw/clisession.c | 2 +- 5 files changed, 30 insertions(+), 35 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index b47840dc65..3d8246cd97 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -114,26 +114,22 @@ const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) return oid_list; } -static NTSTATUS gensec_start(struct gensec_security **gensec_security) +/* + note that memory context is the parent context to hang this gensec context off. It may be NULL. +*/ +static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { - TALLOC_CTX *mem_ctx; /* awaiting a correct fix from metze */ if (!gensec_init()) { return NT_STATUS_INTERNAL_ERROR; } - mem_ctx = talloc_init("gensec_security struct"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); + (*gensec_security) = talloc_p(NULL, struct gensec_security); if (!(*gensec_security)) { - talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } + talloc_set_name(*gensec_security, "gensec_start"); - (*gensec_security)->mem_ctx = mem_ctx; (*gensec_security)->ops = NULL; ZERO_STRUCT((*gensec_security)->user); @@ -141,8 +137,8 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) ZERO_STRUCT((*gensec_security)->default_user); (*gensec_security)->default_user.name = ""; - (*gensec_security)->default_user.domain = talloc_strdup(mem_ctx, lp_workgroup()); - (*gensec_security)->default_user.realm = talloc_strdup(mem_ctx, lp_realm()); + (*gensec_security)->default_user.domain = talloc_strdup(*gensec_security, lp_workgroup()); + (*gensec_security)->default_user.realm = talloc_strdup(*gensec_security, lp_realm()); (*gensec_security)->subcontext = False; (*gensec_security)->want_features = 0; @@ -158,7 +154,7 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) NTSTATUS gensec_subcontext_start(struct gensec_security *parent, struct gensec_security **gensec_security) { - (*gensec_security) = talloc_p(parent->mem_ctx, struct gensec_security); + (*gensec_security) = talloc_p(parent, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; } @@ -172,10 +168,10 @@ NTSTATUS gensec_subcontext_start(struct gensec_security *parent, return NT_STATUS_OK; } -NTSTATUS gensec_client_start(struct gensec_security **gensec_security) +NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { NTSTATUS status; - status = gensec_start(gensec_security); + status = gensec_start(mem_ctx, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -187,10 +183,10 @@ NTSTATUS gensec_client_start(struct gensec_security **gensec_security) return status; } -NTSTATUS gensec_server_start(struct gensec_security **gensec_security) +NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { NTSTATUS status; - status = gensec_start(gensec_security); + status = gensec_start(mem_ctx, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -443,7 +439,7 @@ void gensec_end(struct gensec_security **gensec_security) if (!(*gensec_security)->subcontext) { /* don't destory this if this is a subcontext - it belongs to the parent */ - talloc_destroy((*gensec_security)->mem_ctx); + talloc_free(*gensec_security); } gensec_security = NULL; } @@ -467,7 +463,7 @@ void gensec_want_feature(struct gensec_security *gensec_security, NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, const char *user) { char *p; - char *u = talloc_strdup(gensec_security->mem_ctx, user); + char *u = talloc_strdup(gensec_security, user); if (!u) { return NT_STATUS_NO_MEMORY; } @@ -476,12 +472,12 @@ NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, c if (p) { *p = '\0'; - gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, u); + gensec_security->user.name = talloc_strdup(gensec_security, u); if (!gensec_security->user.name) { return NT_STATUS_NO_MEMORY; } - gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, p+1); + gensec_security->user.realm = talloc_strdup(gensec_security, p+1); if (!gensec_security->user.realm) { return NT_STATUS_NO_MEMORY; } @@ -495,11 +491,11 @@ NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, c if (p) { *p = '\0'; - gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, u); + gensec_security->user.domain = talloc_strdup(gensec_security, u); if (!gensec_security->user.domain) { return NT_STATUS_NO_MEMORY; } - gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, p+1); + gensec_security->user.name = talloc_strdup(gensec_security, p+1); if (!gensec_security->user.name) { return NT_STATUS_NO_MEMORY; } @@ -521,7 +517,7 @@ NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, c NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) { - gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, user); + gensec_security->user.name = talloc_strdup(gensec_security, user); if (!gensec_security->user.name) { return NT_STATUS_NO_MEMORY; } @@ -548,7 +544,7 @@ const char *gensec_get_username(struct gensec_security *gensec_security) NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain) { - gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, domain); + gensec_security->user.domain = talloc_strdup(gensec_security, domain); if (!gensec_security->user.domain) { return NT_STATUS_NO_MEMORY; } @@ -577,7 +573,7 @@ const char *gensec_get_domain(struct gensec_security *gensec_security) NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *realm) { - gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, realm); + gensec_security->user.realm = talloc_strdup(gensec_security, realm); if (!gensec_security->user.realm) { return NT_STATUS_NO_MEMORY; } @@ -625,7 +621,7 @@ char *gensec_get_client_principal(struct gensec_security *gensec_security, TALLO NTSTATUS gensec_set_password(struct gensec_security *gensec_security, const char *password) { - gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); + gensec_security->user.password = talloc_strdup(gensec_security, password); if (!gensec_security->user.password) { return NT_STATUS_NO_MEMORY; } @@ -639,7 +635,7 @@ NTSTATUS gensec_set_password(struct gensec_security *gensec_security, NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) { - gensec_security->target.principal = talloc_strdup(gensec_security->mem_ctx, principal); + gensec_security->target.principal = talloc_strdup(gensec_security, principal); if (!gensec_security->target.principal) { return NT_STATUS_NO_MEMORY; } @@ -653,7 +649,7 @@ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, co NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service) { - gensec_security->target.service = talloc_strdup(gensec_security->mem_ctx, service); + gensec_security->target.service = talloc_strdup(gensec_security, service); if (!gensec_security->target.service) { return NT_STATUS_NO_MEMORY; } @@ -667,7 +663,7 @@ NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, cons NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname) { - gensec_security->target.hostname = talloc_strdup(gensec_security->mem_ctx, hostname); + gensec_security->target.hostname = talloc_strdup(gensec_security, hostname); if (!gensec_security->target.hostname) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 00c1c0dd0a..7020435f44 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -88,7 +88,6 @@ typedef NTSTATUS (*gensec_password_callback)(struct gensec_security *gensec_secu #define GENSEC_INTERFACE_VERSION 0 struct gensec_security { - TALLOC_CTX *mem_ctx; gensec_password_callback password_callback; void *password_callback_private; const struct gensec_security_ops *ops; diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index c9e6d572db..37fa95bac4 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -367,14 +367,14 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security char *password; time_t kdc_time = 0; nt_status = gensec_get_password(gensec_security, - gensec_security->mem_ctx, + gensec_security, &password); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } ret = kerberos_kinit_password_cc(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache, - gensec_get_client_principal(gensec_security, gensec_security->mem_ctx), + gensec_get_client_principal(gensec_security, gensec_security), password, NULL, &kdc_time); /* cope with ticket being in the future due to clock skew */ diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5d233bcdca..a94a4f2f30 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1458,7 +1458,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha if (conn == NULL) return result; - status = gensec_client_start(&conn->gensec); + status = gensec_client_start(conn, &conn->gensec); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); return result; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 264c1cd616..37992968a4 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -395,7 +395,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess smbcli_temp_set_signing(session->transport); - status = gensec_client_start(&session->gensec); + status = gensec_client_start(session, &session->gensec); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); goto done; -- cgit From 6bea5bea4ccd4eb45b9cd4dd1e16538b14e2180e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 01:43:05 +0000 Subject: r2643: convert more of the auth subsyystem to the new talloc methods. This also fixes a memory leak found with --leak-check. (This used to be commit f19201ea274f0a542314c61c4af676197bf154ad) --- source4/libcli/auth/gensec_krb5.c | 18 +++++++++--------- source4/libcli/auth/gensec_ntlmssp.c | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 37fa95bac4..06630455ce 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -627,13 +627,13 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security server_info->guest = False; - principal = talloc_strdup(server_info->mem_ctx, gensec_krb5_state->peer_principal); + principal = talloc_strdup(server_info, gensec_krb5_state->peer_principal); p = strchr(principal, '@'); if (p) { *p = '\0'; } server_info->account_name = principal; - server_info->domain = talloc_strdup(server_info->mem_ctx, p++); + server_info->domain = talloc_strdup(server_info, p++); if (!server_info->domain) { free_server_info(&server_info); return NT_STATUS_NO_MEMORY; @@ -650,7 +650,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security * kind... */ if (logon_info) { - ptoken = talloc_p(session_info->mem_ctx, struct nt_user_token); + ptoken = talloc_p(session_info, struct nt_user_token); if (!ptoken) { return NT_STATUS_NO_MEMORY; } @@ -663,16 +663,16 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security } - sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); - ptoken->user_sids[0] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->user_rid); + sid = dom_sid_dup(session_info, logon_info->dom_sid); + ptoken->user_sids[0] = dom_sid_add_rid(session_info, sid, logon_info->user_rid); ptoken->num_sids++; - sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); - ptoken->user_sids[1] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->group_rid); + sid = dom_sid_dup(session_info, logon_info->dom_sid); + ptoken->user_sids[1] = dom_sid_add_rid(session_info, sid, logon_info->group_rid); ptoken->num_sids++; for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) { - sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid); - ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->groups[ptoken->num_sids - 2].rid); + sid = dom_sid_dup(session_info, logon_info->dom_sid); + ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info, sid, logon_info->groups[ptoken->num_sids - 2].rid); } debug_nt_user_token(DBGC_AUTH, 0, ptoken); diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 0c96a783f1..8b760bcd45 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -386,11 +386,11 @@ static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_secur /* the session_info owns this now */ gensec_ntlmssp_state->server_info = NULL; - (*session_info)->session_key = data_blob_talloc((*session_info)->mem_ctx, + (*session_info)->session_key = data_blob_talloc(*session_info, gensec_ntlmssp_state->ntlmssp_state->session_key.data, gensec_ntlmssp_state->ntlmssp_state->session_key.length); - (*session_info)->workstation = talloc_strdup((*session_info)->mem_ctx, + (*session_info)->workstation = talloc_strdup(*session_info, gensec_ntlmssp_state->ntlmssp_state->workstation); return NT_STATUS_OK; -- cgit From 4b1050a6cf3e6d9f7a8e75dd90ed1ccd52f29abb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 02:16:25 +0000 Subject: r2645: converted the NTLMSSP code to the new style of talloc (This used to be commit b378aae95d4001c4cf4e6e59ed80ee1bd55382ee) --- source4/libcli/auth/gensec_krb5.c | 21 +++------ source4/libcli/auth/gensec_ntlmssp.c | 23 ++++----- source4/libcli/auth/ntlmssp.c | 91 ++++++++++++++++-------------------- source4/libcli/auth/ntlmssp.h | 1 - source4/libcli/auth/ntlmssp_sign.c | 8 ++-- source4/libcli/auth/spnego.c | 23 +++------ 6 files changed, 64 insertions(+), 103 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 06630455ce..7d92873ac7 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -36,7 +36,6 @@ enum GENSEC_KRB5_STATE { }; struct gensec_krb5_state { - TALLOC_CTX *mem_ctx; DATA_BLOB session_key; struct PAC_LOGON_INFO *logon_info; enum GENSEC_KRB5_STATE state_position; @@ -230,18 +229,11 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) struct gensec_krb5_state *gensec_krb5_state; krb5_error_code ret = 0; - TALLOC_CTX *mem_ctx = talloc_init("gensec_krb5"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - gensec_krb5_state = talloc_p(mem_ctx, struct gensec_krb5_state); + gensec_krb5_state = talloc_p(gensec_security, struct gensec_krb5_state); if (!gensec_krb5_state) { return NT_STATUS_NO_MEMORY; } - gensec_krb5_state->mem_ctx = mem_ctx; - gensec_security->private_data = gensec_krb5_state; initialize_krb5_error_table(); @@ -429,7 +421,7 @@ static void gensec_krb5_end(struct gensec_security *gensec_security) krb5_free_context(gensec_krb5_state->krb5_context); } - talloc_destroy(gensec_krb5_state->mem_ctx); + talloc_free(gensec_krb5_state); gensec_security->private_data = NULL; } @@ -544,7 +536,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL if (pac.data) { /* decode and verify the pac */ - nt_status = gensec_krb5_decode_pac(gensec_krb5_state->mem_ctx, &gensec_krb5_state->logon_info, pac, + nt_status = gensec_krb5_decode_pac(gensec_krb5_state, &gensec_krb5_state->logon_info, pac, gensec_krb5_state); } else { /* NULL PAC, we might need to figure this information out the hard way */ @@ -556,7 +548,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL /* wrap that up in a nice GSS-API wrapping */ *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REP); - gensec_krb5_state->peer_principal = talloc_steal(gensec_krb5_state->mem_ctx, principal); + gensec_krb5_state->peer_principal = talloc_steal(gensec_krb5_state, principal); } return nt_status; } @@ -591,7 +583,7 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, } if (err == 0 && skey != NULL) { DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); - gensec_krb5_state->session_key = data_blob_talloc(gensec_krb5_state->mem_ctx, + gensec_krb5_state->session_key = data_blob_talloc(gensec_krb5_state, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); *session_key = gensec_krb5_state->session_key; dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); @@ -609,7 +601,6 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security { NTSTATUS nt_status; struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - TALLOC_CTX *mem_ctx; struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info = gensec_krb5_state->logon_info; @@ -657,7 +648,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security ptoken->num_sids = 0; - ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, logon_info->groups_count + 2); + ptoken->user_sids = talloc_array_p(ptoken, struct dom_sid*, logon_info->groups_count + 2); if (!ptoken->user_sids) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 8b760bcd45..7270797f52 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -24,7 +24,6 @@ #include "includes.h" struct gensec_ntlmssp_state { - TALLOC_CTX *mem_ctx; struct auth_context *auth_context; struct auth_serversupplied_info *server_info; struct ntlmssp_state *ntlmssp_state; @@ -125,13 +124,13 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, } if (gensec_ntlmssp_state->server_info->user_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length)); - *user_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + *user_session_key = data_blob_talloc(ntlmssp_state, gensec_ntlmssp_state->server_info->user_session_key.data, gensec_ntlmssp_state->server_info->user_session_key.length); } if (gensec_ntlmssp_state->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", gensec_ntlmssp_state->server_info->lm_session_key.length)); - *lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + *lm_session_key = data_blob_talloc(ntlmssp_state, gensec_ntlmssp_state->server_info->lm_session_key.data, gensec_ntlmssp_state->server_info->lm_session_key.length); } @@ -142,17 +141,11 @@ static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) { struct gensec_ntlmssp_state *gensec_ntlmssp_state; - TALLOC_CTX *mem_ctx = talloc_init("gensec_ntlmssp"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - gensec_ntlmssp_state = talloc_p(mem_ctx, struct gensec_ntlmssp_state); + gensec_ntlmssp_state = talloc_p(gensec_security, struct gensec_ntlmssp_state); if (!gensec_ntlmssp_state) { return NT_STATUS_NO_MEMORY; } - gensec_ntlmssp_state->mem_ctx = mem_ctx; gensec_ntlmssp_state->ntlmssp_state = NULL; gensec_ntlmssp_state->auth_context = NULL; gensec_ntlmssp_state->server_info = NULL; @@ -175,7 +168,8 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur gensec_ntlmssp_state = gensec_security->private_data; - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&gensec_ntlmssp_state->ntlmssp_state))) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(gensec_security, + &gensec_ntlmssp_state->ntlmssp_state))) { return nt_status; } @@ -221,7 +215,8 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur } gensec_ntlmssp_state = gensec_security->private_data; - status = ntlmssp_client_start(&gensec_ntlmssp_state->ntlmssp_state); + status = ntlmssp_client_start(gensec_security, + &gensec_ntlmssp_state->ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -265,7 +260,7 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur return status; } - status = gensec_get_password(gensec_security, gensec_ntlmssp_state->mem_ctx, &password); + status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -410,7 +405,7 @@ static void gensec_ntlmssp_end(struct gensec_security *gensec_security) if (gensec_ntlmssp_state->server_info) { free_server_info(&gensec_ntlmssp_state->server_info); } - talloc_destroy(gensec_ntlmssp_state->mem_ctx); + talloc_free(gensec_ntlmssp_state); gensec_security->private_data = NULL; } diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index f52f1ffbf9..2ea0bcb84e 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -107,7 +107,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) { - uint8_t *chal = talloc(ntlmssp_state->mem_ctx, 8); + uint8_t *chal = talloc(ntlmssp_state, 8); generate_random_buffer(chal, 8); return chal; @@ -143,7 +143,7 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) { - ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + ntlmssp_state->user = talloc_strdup(ntlmssp_state, user); if (!ntlmssp_state->user) { return NT_STATUS_NO_MEMORY; } @@ -159,7 +159,7 @@ NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *p if (!password) { ntlmssp_state->password = NULL; } else { - ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + ntlmssp_state->password = talloc_strdup(ntlmssp_state, password); if (!ntlmssp_state->password) { return NT_STATUS_NO_MEMORY; } @@ -173,7 +173,7 @@ NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *p */ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) { - ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain); if (!ntlmssp_state->domain) { return NT_STATUS_NO_MEMORY; } @@ -186,7 +186,7 @@ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *dom */ NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) { - ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation); + ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation); if (!ntlmssp_state->domain) { return NT_STATUS_NO_MEMORY; } @@ -201,7 +201,7 @@ NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state, DATA_BLOB response) { - ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, + ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state, response.data, response.length); return NT_STATUS_OK; } @@ -234,7 +234,7 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, if (!out_mem_ctx) { /* if the caller doesn't want to manage/own the memory, we can put it on our context */ - out_mem_ctx = ntlmssp_state->mem_ctx; + out_mem_ctx = ntlmssp_state; } if (!in.length && ntlmssp_state->stored_response.length) { @@ -257,7 +257,7 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, break; } } else { - if (!msrpc_parse(ntlmssp_state->mem_ctx, + if (!msrpc_parse(ntlmssp_state, &input, "Cd", "NTLMSSP", &ntlmssp_command)) { @@ -311,12 +311,10 @@ NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state, void ntlmssp_end(struct ntlmssp_state **ntlmssp_state) { - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - (*ntlmssp_state)->ref_count--; if ((*ntlmssp_state)->ref_count == 0) { - talloc_destroy(mem_ctx); + talloc_free(*ntlmssp_state); } *ntlmssp_state = NULL; @@ -464,7 +462,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (in.length) { - if (!msrpc_parse(ntlmssp_state->mem_ctx, + if (!msrpc_parse(ntlmssp_state, &in, "CddAA", "NTLMSSP", &ntlmssp_command, @@ -502,8 +500,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; - ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); - ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); + ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; @@ -599,7 +597,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state->mem_ctx, + if (!msrpc_parse(ntlmssp_state, &request, parse_string, "NTLMSSP", &ntlmssp_command, @@ -625,7 +623,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, } /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state->mem_ctx, + if (!msrpc_parse(ntlmssp_state, &request, parse_string, "NTLMSSP", &ntlmssp_command, @@ -690,7 +688,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); - ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, session_nonce_hash, 8); /* LM response is no longer useful, zero it out */ @@ -736,7 +734,7 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, /* Handle the different session key derivation for NTLM2 */ if (ntlmssp_state->doing_ntlm2) { if (user_session_key && user_session_key->data && user_session_key->length == 16) { - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + session_key = data_blob_talloc(ntlmssp_state, NULL, 16); hmac_md5(user_session_key->data, ntlmssp_state->session_nonce, sizeof(ntlmssp_state->session_nonce), session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); @@ -752,7 +750,7 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) { if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + session_key = data_blob_talloc(ntlmssp_state, NULL, 16); SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); @@ -761,7 +759,7 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, /* When there is no LM response, just use zeros */ static const uint8_t zeros[24]; - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + session_key = data_blob_talloc(ntlmssp_state, NULL, 16); SMBsesskeygen_lm_sess_key(zeros, zeros, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); @@ -820,7 +818,7 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, arcfour_crypt(ntlmssp_state->encrypted_session_key.data, session_key.data, ntlmssp_state->encrypted_session_key.length); - ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, ntlmssp_state->encrypted_session_key.data, ntlmssp_state->encrypted_session_key.length); dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data, @@ -903,22 +901,17 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, * @param ntlmssp_state NTLMSSP State, allocated by this function */ -NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state) +NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) { - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); - talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } + ZERO_STRUCTP(*ntlmssp_state); (*ntlmssp_state)->role = NTLMSSP_SERVER; - (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_challenge = get_challenge; (*ntlmssp_state)->set_challenge = set_challenge; (*ntlmssp_state)->may_set_challenge = may_set_challenge; @@ -1025,7 +1018,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; - if (!msrpc_parse(ntlmssp_state->mem_ctx, + if (!msrpc_parse(ntlmssp_state, &in, "CdBd", "NTLMSSP", &ntlmssp_command, @@ -1064,7 +1057,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (!msrpc_parse(ntlmssp_state->mem_ctx, + if (!msrpc_parse(ntlmssp_state, &in, chal_parse_string, "NTLMSSP", &ntlmssp_command, @@ -1089,8 +1082,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* do nothing - blobs are zero length */ /* session key is all zeros */ - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); - lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); + session_key = data_blob_talloc(ntlmssp_state, zeros, 16); + lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16); /* not doing NLTM2 without a password */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; @@ -1126,7 +1119,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, uint8_t user_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); - lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); generate_random_buffer(lm_response.data, 8); memset(lm_response.data+8, 0, 16); @@ -1142,12 +1135,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("challenge is: \n")); dump_data(5, (const char *)session_nonce_hash, 8); - nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt(ntlmssp_state->password, session_nonce_hash, nt_response.data); - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + session_key = data_blob_talloc(ntlmssp_state, NULL, 16); SMBsesskeygen_ntv1(nt_hash, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); @@ -1159,18 +1152,18 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, uint8_t nt_hash[16]; if (ntlmssp_state->use_nt_response) { - nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, nt_response.data); E_md4hash(ntlmssp_state->password, nt_hash); - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + session_key = data_blob_talloc(ntlmssp_state, NULL, 16); SMBsesskeygen_ntv1(nt_hash, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { - lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); + lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data, lm_response.data)) { /* If the LM password was too long (and therefore the LM hash being @@ -1181,7 +1174,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } else { E_deshash(ntlmssp_state->password, lm_hash); - lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16); memcpy(lm_session_key.data, lm_hash, 8); memset(&lm_session_key.data[8], '\0', 8); @@ -1197,7 +1190,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth() && lm_session_key.length == 16) { - DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16); if (lm_response.length == 24) { SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, new_session_key.data); @@ -1220,14 +1213,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, generate_random_buffer(client_session_key, sizeof(client_session_key)); /* Encrypt the new session key with the old one */ - encrypted_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + encrypted_session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); + session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key)); } /* this generates the actual auth packet */ @@ -1266,23 +1259,17 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state) +NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) { - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP Client context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); - talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } + ZERO_STRUCTP(*ntlmssp_state); (*ntlmssp_state)->role = NTLMSSP_CLIENT; - (*ntlmssp_state)->mem_ctx = mem_ctx; - (*ntlmssp_state)->get_global_myname = lp_netbios_name; (*ntlmssp_state)->get_domain = lp_workgroup; diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index a318025650..a6d1510450 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -75,7 +75,6 @@ enum ntlmssp_message_type struct ntlmssp_state { - TALLOC_CTX *mem_ctx; uint_t ref_count; enum ntlmssp_role role; enum samr_Role server_role; diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 2b9659ae52..5a99f14496 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -387,14 +387,14 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) weak_session_key.length); /* SEND */ - calc_ntlmv2_key(ntlmssp_state->mem_ctx, + calc_ntlmv2_key(ntlmssp_state, &ntlmssp_state->send_sign_key, ntlmssp_state->session_key, send_sign_const); dump_data_pw("NTLMSSP send sign key:\n", ntlmssp_state->send_sign_key.data, ntlmssp_state->send_sign_key.length); - calc_ntlmv2_key(ntlmssp_state->mem_ctx, + calc_ntlmv2_key(ntlmssp_state, &ntlmssp_state->send_seal_key, weak_session_key, send_seal_const); dump_data_pw("NTLMSSP send seal key:\n", @@ -409,14 +409,14 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) sizeof(ntlmssp_state->send_seal_hash)); /* RECV */ - calc_ntlmv2_key(ntlmssp_state->mem_ctx, + calc_ntlmv2_key(ntlmssp_state, &ntlmssp_state->recv_sign_key, ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP recv sign key:\n", ntlmssp_state->recv_sign_key.data, ntlmssp_state->recv_sign_key.length); - calc_ntlmv2_key(ntlmssp_state->mem_ctx, + calc_ntlmv2_key(ntlmssp_state, &ntlmssp_state->recv_seal_key, weak_session_key, recv_seal_const); dump_data_pw("NTLMSSP recv seal key:\n", diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index bbf8f86676..efe9ad675b 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -37,7 +37,6 @@ enum spnego_state_position { }; struct spnego_state { - TALLOC_CTX *mem_ctx; uint_t ref_count; enum spnego_message_type expected_packet; enum spnego_state_position state_position; @@ -47,19 +46,14 @@ struct spnego_state { static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; - TALLOC_CTX *mem_ctx = talloc_init("gensec_spnego_client_start"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - spnego_state = talloc_p(mem_ctx, struct spnego_state); - + + spnego_state = talloc_p(gensec_security, struct spnego_state); if (!spnego_state) { return NT_STATUS_NO_MEMORY; } spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_CLIENT_START; - spnego_state->mem_ctx = mem_ctx; spnego_state->sub_sec_security = NULL; gensec_security->private_data = spnego_state; @@ -69,19 +63,14 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; - TALLOC_CTX *mem_ctx = talloc_init("gensec_spnego_server_start"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - spnego_state = talloc_p(mem_ctx, struct spnego_state); - + + spnego_state = talloc_p(gensec_security, struct spnego_state); if (!spnego_state) { return NT_STATUS_NO_MEMORY; } spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_SERVER_START; - spnego_state->mem_ctx = mem_ctx; spnego_state->sub_sec_security = NULL; gensec_security->private_data = spnego_state; @@ -426,7 +415,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA *out = data_blob(NULL, 0); if (!out_mem_ctx) { - out_mem_ctx = spnego_state->mem_ctx; + out_mem_ctx = spnego_state; } /* and switch into the state machine */ @@ -701,7 +690,7 @@ static void gensec_spnego_end(struct gensec_security *gensec_security) gensec_end(&spnego_state->sub_sec_security); } - talloc_destroy(spnego_state->mem_ctx); + talloc_free(spnego_state); gensec_security->private_data = NULL; } -- cgit From 764eddb69647681f784f343a122251ca1ecf62df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 03:05:04 +0000 Subject: r2646: - use a talloc destructor to ensure that sockets from the new socket library are closed on abnormal termination - convert the service.h structures to the new talloc methods (This used to be commit 2dc334a3284858eb1c7190f9687c9b6c879ecc9d) --- source4/libcli/auth/gensec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 3d8246cd97..b6c4f91610 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -124,11 +124,10 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense return NT_STATUS_INTERNAL_ERROR; } - (*gensec_security) = talloc_p(NULL, struct gensec_security); + (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; } - talloc_set_name(*gensec_security, "gensec_start"); (*gensec_security)->ops = NULL; -- cgit From 9a62dce0ac2dd751c9cc3b9906eec8c4fe7c51b7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 03:50:24 +0000 Subject: r2648: - use a destructor on struct server_connection to simplify the connection termination cleanup, and to ensure that the event contexts are properly removed for every process model - gave auth_context the new talloc treatment, which removes another source of memory leaks. (This used to be commit 230e1cd777b0fba82dffcbd656cfa23c155d0560) --- source4/libcli/auth/gensec_ntlmssp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 7270797f52..40f3e605eb 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -65,7 +65,7 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, SMB_ASSERT(challenge->length == 8); - auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, + auth_context->challenge = data_blob_talloc(auth_context, challenge->data, challenge->length); auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)"; @@ -189,7 +189,8 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur } ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; - if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) { + nt_status = make_auth_context_subsystem(gensec_security, &gensec_ntlmssp_state->auth_context); + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } -- cgit From ec0128ef012f4280b2fb607cb9c88c7673894fe6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 04:59:03 +0000 Subject: r2649: - used some cpp tricks to make users of talloc() and talloc_realloc() to get auto-naming of pointers very cheaply. - fixed a couple of memory leaks found with the new tricks A typical exit report for smbd is now: talloc report on 'null_context' (total 811 bytes in 54 blocks) auth/auth_sam.c:334 contains 20 bytes in 1 blocks struct auth_serversupplied_info contains 498 bytes in 33 blocks UNNAMED contains 8 bytes in 1 blocks lib/data_blob.c:40 contains 16 bytes in 1 blocks iconv(CP850,UTF8) contains 61 bytes in 4 blocks iconv(UTF8,CP850) contains 61 bytes in 4 blocks iconv(UTF8,UTF-16LE) contains 67 bytes in 4 blocks iconv(UTF-16LE,UTF8) contains 67 bytes in 4 blocks UNNAMED contains 13 bytes in 1 blocks which is much better than before (This used to be commit 6e721393d03afd3c2f8ced8422533547a9e33342) --- source4/libcli/raw/rawtrans.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 49b43dd930..e6c928e3ed 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -84,7 +84,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, /* allocate it */ if (total_data != 0) { - tdata = talloc_realloc(parms->out.data.data,total_data); + tdata = talloc(mem_ctx, total_data); if (!tdata) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); req->status = NT_STATUS_NO_MEMORY; @@ -94,7 +94,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, } if (total_param != 0) { - tparam = talloc_realloc(parms->out.params.data,total_param); + tparam = talloc(mem_ctx, total_param); if (!tparam) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); req->status = NT_STATUS_NO_MEMORY; -- cgit From df6dce1065d4323ebf8ca97b69f0a44804f19e11 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 05:38:45 +0000 Subject: r2650: fixed a memory leak in make_server_info() (This used to be commit 4aba6e7101041100f7d400abd5e7144b95528fc3) --- source4/libcli/auth/gensec_krb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 7d92873ac7..7895a6f1ed 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -611,7 +611,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security *session_info_out = NULL; - nt_status = make_server_info(&server_info, gensec_krb5_state->peer_principal); + nt_status = make_server_info(gensec_security, &server_info, gensec_krb5_state->peer_principal); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } -- cgit From 3ea916b2278c202c99c80c02e80e588bd7daedb8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 06:44:08 +0000 Subject: r2654: fixed some more server memory leaks. We are now down to a single leak of 16 bytes, caused by the 16 byte data_blob in the smb_signing code. (This used to be commit 2f1b788e09686e065d22f621f5c0c585192c6740) --- source4/libcli/cliconnect.c | 2 +- source4/libcli/raw/clisession.c | 2 +- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/raw/clitree.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 66882f605d..27caaa9df9 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -211,7 +211,7 @@ struct smbcli_state *smbcli_state_init(void) { struct smbcli_state *cli; - cli = talloc_named(NULL, sizeof(*cli), "smbcli_state"); + cli = talloc_p(NULL, struct smbcli_state); if (cli) { ZERO_STRUCTP(cli); } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 37992968a4..75b9645018 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -33,7 +33,7 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) { struct smbcli_session *session; - session = talloc_named(NULL, sizeof(*session), "smbcli_session"); + session = talloc_p(transport, struct smbcli_session); if (!session) { return NULL; } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 654d8ee61b..5663672333 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -29,7 +29,7 @@ struct smbcli_socket *smbcli_sock_init(void) { struct smbcli_socket *sock; - sock = talloc_named(NULL, sizeof(*sock), "smbcli_socket"); + sock = talloc_p(NULL, struct smbcli_socket); if (!sock) { return NULL; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 85d5337da7..c0d84179d6 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -49,7 +49,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) struct smbcli_transport *transport; struct fd_event fde; - transport = talloc_named(NULL, sizeof(*transport), "smbcli_transport"); + transport = talloc_p(sock, struct smbcli_transport); if (!transport) return NULL; ZERO_STRUCTP(transport); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 03a49708b3..c383eef768 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -34,7 +34,7 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) { struct smbcli_tree *tree; - tree = talloc_named(NULL, sizeof(*tree), "smbcli_tree"); + tree = talloc_p(session, struct smbcli_tree); if (!tree) { return NULL; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 1ff36d0a8d..a94e796628 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -62,7 +62,7 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran { struct smbcli_request *req; - req = talloc_named(NULL, sizeof(struct smbcli_request), "smcli_request"); + req = talloc_p(transport, struct smbcli_request); if (!req) { return NULL; } -- cgit From 954869efdb8b0006fd4457a1c6d56a31c3825421 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 07:04:35 +0000 Subject: r2655: fixed an error in the shutdown of the sock->transport->session->tree smbcli raw context handling (This used to be commit d5fd6388751944f11c34e5124d403d57c8670e3b) --- source4/libcli/raw/clisession.c | 1 - source4/libcli/raw/clisocket.c | 1 + source4/libcli/raw/clitransport.c | 3 +-- source4/libcli/raw/clitree.c | 3 ++- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 75b9645018..516da2fa2e 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -55,7 +55,6 @@ void smbcli_session_close(struct smbcli_session *session) session->reference_count--; if (session->reference_count <= 0) { smbcli_transport_close(session->transport); - talloc_free(session); } } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 5663672333..8481bc73e2 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -104,6 +104,7 @@ void smbcli_sock_close(struct smbcli_socket *sock) sock->reference_count--; if (sock->reference_count <= 0) { smbcli_sock_dead(sock); + talloc_free(sock); } } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index c0d84179d6..d70ceceab3 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -90,11 +90,10 @@ void smbcli_transport_close(struct smbcli_transport *transport) { transport->reference_count--; if (transport->reference_count <= 0) { - smbcli_sock_close(transport->socket); event_remove_fd(transport->event.ctx, transport->event.fde); event_remove_timed(transport->event.ctx, transport->event.te); event_context_destroy(transport->event.ctx); - talloc_free(transport); + smbcli_sock_close(transport->socket); } } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index c383eef768..e3a1a6d341 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -55,7 +55,6 @@ void smbcli_tree_close(struct smbcli_tree *tree) tree->reference_count--; if (tree->reference_count <= 0) { smbcli_session_close(tree->session); - talloc_free(tree); } } @@ -193,6 +192,8 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, return NT_STATUS_NO_MEMORY; } + talloc_set_name_const(sock, "smbcli_tree_full_connection"); + /* open a TCP socket to the server */ if (!smbcli_sock_connect_byname(sock, dest_host, port)) { DEBUG(2,("Failed to establish socket connection - %s\n", strerror(errno))); -- cgit From e3880fa759cfa03222262327854fe7bbe585fe01 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 11:30:20 +0000 Subject: r2660: - converted the libcli/raw/ library to use talloc_increase_ref_count() rather than manual reference counts - properly support SMBexit in the cifs and posix backends - added a logoff method to all backends With these changes the RAW-CONTEXT test now passes against the posix backend (This used to be commit c315d6ac1cc40546fde1474702a6d66d07ee13c8) --- source4/libcli/cliconnect.c | 12 +++------- source4/libcli/raw/clisession.c | 50 ++++++++++++++++++++++++--------------- source4/libcli/raw/clisocket.c | 28 ++++++++++++---------- source4/libcli/raw/clitransport.c | 34 +++++++++++++------------- source4/libcli/raw/clitree.c | 38 +++++++++++++---------------- 5 files changed, 83 insertions(+), 79 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 27caaa9df9..f772070305 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -31,13 +31,13 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) if (!sock) return False; if (!smbcli_sock_connect_byname(sock, server, 0)) { - smbcli_sock_close(sock); + talloc_free(sock); return False; } cli->transport = smbcli_transport_init(sock); if (!cli->transport) { - smbcli_sock_close(sock); + talloc_free(sock); return False; } @@ -112,8 +112,6 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, cli->tree = smbcli_tree_init(cli->session); if (!cli->tree) return NT_STATUS_UNSUCCESSFUL; - cli->tree->reference_count++; - mem_ctx = talloc_init("tcon"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; @@ -188,7 +186,6 @@ NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, (*ret_cli)->tree = tree; (*ret_cli)->session = tree->session; (*ret_cli)->transport = tree->session->transport; - tree->reference_count++; done: talloc_free(mem_ctx); @@ -225,9 +222,6 @@ struct smbcli_state *smbcli_state_init(void) void smbcli_shutdown(struct smbcli_state *cli) { if (!cli) return; - if (cli->tree) { - cli->tree->reference_count++; - smbcli_tree_close(cli->tree); - } + talloc_free(cli->tree); talloc_free(cli); } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 516da2fa2e..0c6c80d94c 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -26,6 +26,17 @@ if (!req) return NULL; \ } while (0) + +/* + destroy a smbcli_session +*/ +static int session_destroy(void *ptr) +{ + struct smbcli_session *session = ptr; + talloc_free(session->transport); + return 0; +} + /**************************************************************************** Initialize the session context ****************************************************************************/ @@ -42,20 +53,10 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) session->transport = transport; session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; - session->transport->reference_count++; - return session; -} + talloc_set_destructor(session, session_destroy); -/**************************************************************************** -reduce reference_count and destroy is <= 0 -****************************************************************************/ -void smbcli_session_close(struct smbcli_session *session) -{ - session->reference_count--; - if (session->reference_count <= 0) { - smbcli_transport_close(session->transport); - } + return session; } /**************************************************************************** @@ -590,16 +591,27 @@ NTSTATUS smb_raw_ulogoff(struct smbcli_session *session) /**************************************************************************** - Send a SMBexit -****************************************************************************/ -NTSTATUS smb_raw_exit(struct smbcli_session *session) + Send a exit (async send) +*****************************************************************************/ +struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session) { struct smbcli_request *req; - req = smbcli_request_setup_session(session, SMBexit, 0, 0); + SETUP_REQUEST_SESSION(SMBexit, 0, 0); - if (smbcli_request_send(req)) { - smbcli_request_receive(req); + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); + return NULL; } - return smbcli_request_destroy(req); + + return req; +} + +/**************************************************************************** + Send a exit (sync interface) +*****************************************************************************/ +NTSTATUS smb_raw_exit(struct smbcli_session *session) +{ + struct smbcli_request *req = smb_raw_exit_send(session); + return smbcli_request_simple_recv(req); } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 8481bc73e2..37188f4e77 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -21,6 +21,18 @@ #include "includes.h" +/* + destroy a socket + */ +static int sock_destructor(void *ptr) +{ + struct smbcli_socket *sock = ptr; + if (sock->fd != -1) { + close(sock->fd); + sock->fd = -1; + } + return 0; +} /* create a smbcli_socket context @@ -37,11 +49,13 @@ struct smbcli_socket *smbcli_sock_init(void) ZERO_STRUCTP(sock); sock->fd = -1; sock->port = 0; + /* 20 second default timeout */ sock->timeout = 20000; - sock->hostname = NULL; + talloc_set_destructor(sock, sock_destructor); + return sock; } @@ -96,18 +110,6 @@ void smbcli_sock_dead(struct smbcli_socket *sock) } } -/**************************************************************************** - reduce socket reference count - if it becomes zero then close -****************************************************************************/ -void smbcli_sock_close(struct smbcli_socket *sock) -{ - sock->reference_count--; - if (sock->reference_count <= 0) { - smbcli_sock_dead(sock); - talloc_free(sock); - } -} - /**************************************************************************** Set socket options on a open connection. ****************************************************************************/ diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index d70ceceab3..eb1d3631ee 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -41,6 +41,21 @@ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_e } } +/* + destroy a transport + */ +static int transport_destructor(void *ptr) +{ + struct smbcli_transport *transport = ptr; + + smbcli_transport_dead(transport); + event_remove_fd(transport->event.ctx, transport->event.fde); + event_remove_timed(transport->event.ctx, transport->event.te); + event_context_destroy(transport->event.ctx); + talloc_free(transport->socket); + return 0; +} + /* create a transport structure based on an established socket */ @@ -67,8 +82,6 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) smbcli_init_signing(transport); - transport->socket->reference_count++; - ZERO_STRUCT(transport->called); fde.fd = sock->fd; @@ -79,22 +92,9 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) transport->event.fde = event_add_fd(transport->event.ctx, &fde); - return transport; -} + talloc_set_destructor(transport, transport_destructor); -/* - decrease reference count on a transport, and destroy if it becomes - zero -*/ -void smbcli_transport_close(struct smbcli_transport *transport) -{ - transport->reference_count--; - if (transport->reference_count <= 0) { - event_remove_fd(transport->event.ctx, transport->event.fde); - event_remove_timed(transport->event.ctx, transport->event.te); - event_context_destroy(transport->event.ctx); - smbcli_sock_close(transport->socket); - } + return transport; } /* diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index e3a1a6d341..e0072a31b1 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -26,6 +26,15 @@ if (!req) return NULL; \ } while (0) +/* + destroy a smbcli_tree +*/ +static int tree_destructor(void *ptr) +{ + struct smbcli_tree *tree = ptr; + talloc_free(tree->session); + return 0; +} /**************************************************************************** Initialize the tree context @@ -41,24 +50,11 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) ZERO_STRUCTP(tree); tree->session = session; - tree->session->reference_count++; + talloc_set_destructor(tree, tree_destructor); return tree; } -/**************************************************************************** -reduce reference count on a tree and destroy if <= 0 -****************************************************************************/ -void smbcli_tree_close(struct smbcli_tree *tree) -{ - if (!tree) return; - tree->reference_count--; - if (tree->reference_count <= 0) { - smbcli_session_close(tree->session); - } -} - - /**************************************************************************** Send a tconX (async send) ****************************************************************************/ @@ -202,7 +198,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, transport = smbcli_transport_init(sock); if (!transport) { - smbcli_sock_close(sock); + talloc_free(sock); return NT_STATUS_NO_MEMORY; } @@ -211,7 +207,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, choose_called_name(&called, dest_host, 0x20); if (!smbcli_transport_connect(transport, &calling, &called)) { - smbcli_transport_close(transport); + talloc_free(transport); return NT_STATUS_UNSUCCESSFUL; } @@ -219,13 +215,13 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, /* negotiate protocol options with the server */ status = smb_raw_negotiate(transport); if (!NT_STATUS_IS_OK(status)) { - smbcli_transport_close(transport); + talloc_free(transport); return status; } session = smbcli_session_init(transport); if (!session) { - smbcli_transport_close(transport); + talloc_free(transport); return NT_STATUS_NO_MEMORY; } @@ -251,7 +247,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, status = smb_raw_session_setup(session, mem_ctx, &setup); if (!NT_STATUS_IS_OK(status)) { - smbcli_session_close(session); + talloc_free(session); talloc_free(mem_ctx); return status; } @@ -260,7 +256,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, tree = smbcli_tree_init(session); if (!tree) { - smbcli_session_close(session); + talloc_free(session); talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -284,7 +280,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, SAFE_FREE(in_path); if (!NT_STATUS_IS_OK(status)) { - smbcli_tree_close(tree); + talloc_free(tree); talloc_free(mem_ctx); return status; } -- cgit From 9010d3859eca98d6a28ccf4f461b66a5778be4d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 11:45:14 +0000 Subject: r2661: fixed a client side memory leak in the clilist code. This sort of bug happens quite easily with the new talloc_realloc() interface. talloc_realloc() now looks like this: void *talloc_realloc(void *ptr, size_t size); and if ptr is not NULL then everything is fine. If ptr is NULL then talloc_realloc() presumes you want to allocate in the NULL context, which is probably not what is wanted. For now the solution is to initialise ptr like this: ptr = talloc(mem_ctx, 0); so when the realloc happens it has a context to get hold of. I might change the interface of talloc_realloc() later to prevent this problem in a more robust manner (This used to be commit bd813dfb1b08b586dc71f9cec4eb65b35ea808fe) --- source4/libcli/clilist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 67a2e980ca..529d4f81a3 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -117,11 +117,11 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu int ff_dir_handle=0; /* initialize state for search */ - state.dirlist = NULL; state.mem_ctx = talloc_init("smbcli_list_new"); state.dirlist_len = 0; state.total_received = 0; + state.dirlist = talloc(state.mem_ctx, 0); mask = talloc_strdup(state.mem_ctx, Mask); if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) { @@ -258,11 +258,11 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu int i; /* initialize state for search */ - state.dirlist = NULL; state.mem_ctx = talloc_init("smbcli_list_old"); state.dirlist_len = 0; state.total_received = 0; - + + state.dirlist = talloc(state.mem_ctx, 0); mask = talloc_strdup(state.mem_ctx, Mask); while (1) { -- cgit From 729d17c27013eae731a97ac8413135c93244bca6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 12:51:49 +0000 Subject: r2664: fixed the final server leak for normal operation. We now get a clean report from --leak-check (This used to be commit 1ff41bbcae8dc7514a85d69679e44dc7c5b0342f) --- source4/libcli/raw/smb_signing.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index bd29abe3e6..9ba385e062 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -321,7 +321,8 @@ BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, +BOOL smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, + struct smb_signing_context *sign_info, const DATA_BLOB *user_session_key, const DATA_BLOB *response) { @@ -332,9 +333,9 @@ BOOL smbcli_simple_set_signing(struct smb_signing_context *sign_info, DEBUG(5, ("SMB signing enabled!\n")); if (response && response->length) { - sign_info->mac_key = data_blob(NULL, response->length + user_session_key->length); + sign_info->mac_key = data_blob_talloc(mem_ctx, NULL, response->length + user_session_key->length); } else { - sign_info->mac_key = data_blob(NULL, user_session_key->length); + sign_info->mac_key = data_blob_talloc(mem_ctx, NULL, user_session_key->length); } memcpy(&sign_info->mac_key.data[0], user_session_key->data, user_session_key->length); @@ -365,7 +366,8 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, return False; } - return smbcli_simple_set_signing(&transport->negotiate.sign_info, + return smbcli_simple_set_signing(transport, + &transport->negotiate.sign_info, &user_session_key, &response); } -- cgit From 5a064d4a62c35167d888356d01dfdb76f59bc6b1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 23:39:18 +0000 Subject: r2669: convert make_user_info() and associated functions from malloc to talloc (This used to be commit 278cef77f083c002d17ecbbe18c20825a380eda3) --- source4/libcli/auth/gensec_ntlmssp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 40f3e605eb..0683581495 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -101,7 +101,8 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, reload_services(True); #endif - nt_status = make_user_info_map(&user_info, + nt_status = make_user_info_map(ntlmssp_state, + &user_info, gensec_ntlmssp_state->ntlmssp_state->user, gensec_ntlmssp_state->ntlmssp_state->domain, gensec_ntlmssp_state->ntlmssp_state->workstation, -- cgit From 5b44130afad1bb1764d986de3ef0e8e04b0e7357 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 01:36:19 +0000 Subject: r2671: we're getting too many errors caused by the talloc_realloc() API not taking a context (so when you pass a NULL pointer you end up with memory in a top level context). Fixed it by changing the API to take a context. The context is only used if the pointer you are reallocing is NULL. (This used to be commit 8dc23821c9f54b2f13049b5e608a0cafb81aa540) --- source4/libcli/auth/spnego_parse.c | 2 +- source4/libcli/clilist.c | 6 ++++-- source4/libcli/ldap/ldap.c | 7 ++++--- source4/libcli/ldap/ldap_ldif.c | 27 +++++++++++++++------------ source4/libcli/raw/raweas.c | 2 +- source4/libcli/raw/rawfileinfo.c | 6 ++++-- source4/libcli/raw/rawrequest.c | 4 ++-- source4/libcli/util/asn1.c | 2 +- 8 files changed, 32 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 20b766a4e2..07dba61dde 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -51,7 +51,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - talloc_realloc(token->mechTypes, (i + 2) * + talloc_realloc(NULL, token->mechTypes, (i + 2) * sizeof(*token->mechTypes)); asn1_read_OID(asn1, token->mechTypes + i); if (token->mechTypes[i]) { diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 529d4f81a3..2659e81419 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -83,7 +83,8 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) file_info *tdl; /* add file info to the dirlist pool */ - tdl = talloc_realloc(state->dirlist, + tdl = talloc_realloc(state, + state->dirlist, state->dirlist_len + sizeof(struct file_info)); if (!tdl) { @@ -225,7 +226,8 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) file_info *tdl; /* add file info to the dirlist pool */ - tdl = talloc_realloc(state->dirlist, + tdl = talloc_realloc(state, + state->dirlist, state->dirlist_len + sizeof(struct file_info)); if (!tdl) { diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index a94a4f2f30..af21962265 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -179,9 +179,10 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { struct ldap_parse_tree **e; - e = talloc_realloc(ret->u.list.elements, - sizeof(struct ldap_parse_tree) * - (ret->u.list.num_elements+1)); + e = talloc_realloc_p(ret, + ret->u.list.elements, + struct ldap_parse_tree *, + ret->u.list.num_elements+1); if (!e) { errno = ENOMEM; return NULL; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 2ec3b827ce..8fe50b6d08 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -51,7 +51,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(chunk, alloc_size); + c2 = talloc_realloc(mem_ctx, chunk, alloc_size); if (!c2) { errno = ENOMEM; return NULL; @@ -156,11 +156,12 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) } BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, - struct ldap_attribute *attrib) + struct ldap_attribute *attrib) { - attrib->values = talloc_realloc(attrib->values, - sizeof(*attrib->values) * - (attrib->num_values+1)); + attrib->values = talloc_realloc_p(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); if (attrib->values == NULL) return False; @@ -175,8 +176,10 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_attribute **attribs, int *num_attribs) { - *attribs = talloc_realloc(*attribs, - sizeof(**attribs) * (*num_attribs+1)); + *attribs = talloc_realloc_p(mem_ctx, + *attribs, + struct ldap_attribute, + *num_attribs+1); if (*attribs == NULL) return False; @@ -207,9 +210,10 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc(r->attributes, - sizeof(*r->attributes) * - (r->num_attributes+1)); + r->attributes = talloc_realloc_p(msg->mem_ctx, + r->attributes, + struct ldap_attribute, + r->num_attributes+1); if (r->attributes == NULL) return False; @@ -231,8 +235,7 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod **mods, int *num_mods) { - *mods = talloc_realloc(*mods, - sizeof(**mods) * ((*num_mods)+1)); + *mods = talloc_realloc_p(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); if (*mods == NULL) return False; diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index d78f10fe1a..e07fbcd288 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -128,7 +128,7 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, blob2.data = blob->data + ofs; blob2.length = ea_size - ofs; - *eas = talloc_realloc(*eas, sizeof(**eas) * (n+1)); + *eas = talloc_realloc(mem_ctx, *eas, sizeof(**eas) * (n+1)); if (! *eas) return NT_STATUS_NO_MEMORY; len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index aac8f2657b..cbb666b7ce 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -174,8 +174,10 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, while (blob->length - ofs >= 24) { uint_t n = parms->stream_info.out.num_streams; parms->stream_info.out.streams = - talloc_realloc(parms->stream_info.out.streams, - (n+1) * sizeof(parms->stream_info.out.streams[0])); + talloc_realloc_p(mem_ctx, + parms->stream_info.out.streams, + struct stream_struct, + n+1); if (!parms->stream_info.out.streams) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index a94e796628..a15d681a5c 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -213,7 +213,7 @@ static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_si /* we need to realloc */ req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION; - buf2 = talloc_realloc(req->out.buffer, req->out.allocated); + buf2 = talloc_realloc(req, req->out.buffer, req->out.allocated); if (buf2 == NULL) { smb_panic("out of memory in req_grow_allocation"); } @@ -911,7 +911,7 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, max_len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; - blob->data = talloc_realloc(blob->data, blob->length + max_len); + blob->data = talloc_realloc(mem_ctx, blob->data, blob->length + max_len); if (!blob->data) { return 0; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 3dc5abc09a..4ff335399a 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -32,7 +32,7 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) if (data->has_error) return False; if (data->length < data->ofs+len) { uint8_t *newp; - newp = talloc_realloc(data->data, data->ofs+len); + newp = talloc_realloc(NULL, data->data, data->ofs+len); if (!newp) { asn1_free(data); data->has_error = True; -- cgit From aa12305945df5f1578250b56ae2f3653b051736f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 08:41:39 +0000 Subject: r2680: switched the libcli/raw/ code over to use talloc_reference(), which simplifies things quite a bit (This used to be commit c82a9cf750829c4f6982ca3133295c8599023c4e) --- source4/libcli/cliconnect.c | 15 ++++++++------- source4/libcli/raw/clisession.c | 14 +------------- source4/libcli/raw/clitransport.c | 3 +-- source4/libcli/raw/clitree.c | 22 +++++----------------- 4 files changed, 15 insertions(+), 39 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index f772070305..aa6aec4a1e 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -36,8 +36,8 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) } cli->transport = smbcli_transport_init(sock); + talloc_free(sock); if (!cli->transport) { - talloc_free(sock); return False; } @@ -60,9 +60,9 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli) /* wrapper around smb_raw_session_setup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, - const char *user, - const char *password, - const char *domain) + const char *user, + const char *password, + const char *domain) { union smb_sesssetup setup; NTSTATUS status; @@ -70,6 +70,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, cli->session = smbcli_session_init(cli->transport); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; + talloc_free(cli->transport); mem_ctx = talloc_init("smbcli_session_setup"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; @@ -110,6 +111,7 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, NTSTATUS status; cli->tree = smbcli_tree_init(cli->session); + talloc_free(cli->session); if (!cli->tree) return NT_STATUS_UNSUCCESSFUL; mem_ctx = talloc_init("tcon"); @@ -183,7 +185,8 @@ NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, (*ret_cli) = smbcli_state_init(); - (*ret_cli)->tree = tree; + (*ret_cli)->tree = talloc_reference(*ret_cli, tree); + talloc_free(tree); (*ret_cli)->session = tree->session; (*ret_cli)->transport = tree->session->transport; @@ -221,7 +224,5 @@ struct smbcli_state *smbcli_state_init(void) ****************************************************************************/ void smbcli_shutdown(struct smbcli_state *cli) { - if (!cli) return; - talloc_free(cli->tree); talloc_free(cli); } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 0c6c80d94c..431d225021 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -27,16 +27,6 @@ } while (0) -/* - destroy a smbcli_session -*/ -static int session_destroy(void *ptr) -{ - struct smbcli_session *session = ptr; - talloc_free(session->transport); - return 0; -} - /**************************************************************************** Initialize the session context ****************************************************************************/ @@ -50,12 +40,10 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) } ZERO_STRUCTP(session); - session->transport = transport; + session->transport = talloc_reference(session, transport); session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; - talloc_set_destructor(session, session_destroy); - return session; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index eb1d3631ee..f06f2c57ff 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -52,7 +52,6 @@ static int transport_destructor(void *ptr) event_remove_fd(transport->event.ctx, transport->event.fde); event_remove_timed(transport->event.ctx, transport->event.te); event_context_destroy(transport->event.ctx); - talloc_free(transport->socket); return 0; } @@ -75,7 +74,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) return NULL; } - transport->socket = sock; + transport->socket = talloc_reference(transport, sock); transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(); transport->negotiate.max_xmit = ~0; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index e0072a31b1..f19cbf8e28 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -26,16 +26,6 @@ if (!req) return NULL; \ } while (0) -/* - destroy a smbcli_tree -*/ -static int tree_destructor(void *ptr) -{ - struct smbcli_tree *tree = ptr; - talloc_free(tree->session); - return 0; -} - /**************************************************************************** Initialize the tree context ****************************************************************************/ @@ -49,8 +39,7 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) } ZERO_STRUCTP(tree); - tree->session = session; - talloc_set_destructor(tree, tree_destructor); + tree->session = talloc_reference(tree, session); return tree; } @@ -188,17 +177,16 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, return NT_STATUS_NO_MEMORY; } - talloc_set_name_const(sock, "smbcli_tree_full_connection"); - /* open a TCP socket to the server */ if (!smbcli_sock_connect_byname(sock, dest_host, port)) { + talloc_free(sock); DEBUG(2,("Failed to establish socket connection - %s\n", strerror(errno))); return NT_STATUS_UNSUCCESSFUL; } transport = smbcli_transport_init(sock); + talloc_free(sock); if (!transport) { - talloc_free(sock); return NT_STATUS_NO_MEMORY; } @@ -220,8 +208,8 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, } session = smbcli_session_init(transport); + talloc_free(transport); if (!session) { - talloc_free(transport); return NT_STATUS_NO_MEMORY; } @@ -255,8 +243,8 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, session->vuid = setup.generic.out.vuid; tree = smbcli_tree_init(session); + talloc_free(session); if (!tree) { - talloc_free(session); talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } -- cgit From 456e2f82e801cbc26898fad20c273b05248ee0d6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Sep 2004 14:11:11 +0000 Subject: r2689: Use consistent naming Del -> Delete Add delete functionality to ldb simple lda server backend add some const in ldap.h (This used to be commit 5ed9a6eb184f34eb572dd81202237042518ec7cd) --- source4/libcli/ldap/ldap.c | 26 +++++++++++++------------- source4/libcli/ldap/ldap.h | 11 ++++++----- source4/libcli/ldap/ldap_ldif.c | 7 ++----- 3 files changed, 21 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index af21962265..12842b4dc4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -547,16 +547,16 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ldap_encode_response(msg->type, r, &data); break; } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; + case LDAP_TAG_DeleteRequest: { + struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); asn1_write(&data, r->dn, strlen(r->dn)); asn1_pop_tag(&data); break; } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; + case LDAP_TAG_DeleteResponse: { + struct ldap_Result *r = &msg->r.DeleteResponse; ldap_encode_response(msg->type, r, &data); break; } @@ -1009,13 +1009,13 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest): { + struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; int len; char *dn; - msg->type = LDAP_TAG_DelRequest; + msg->type = LDAP_TAG_DeleteRequest; asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); len = asn1_tag_remaining(data); dn = talloc(msg->mem_ctx, len+1); if (dn == NULL) @@ -1027,11 +1027,11 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; + case ASN1_APPLICATION(LDAP_TAG_DeleteResponse): { + struct ldap_Result *r = &msg->r.DeleteResponse; + msg->type = LDAP_TAG_DeleteResponse; ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_DelResponse, r); + LDAP_TAG_DeleteResponse, r); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 449be9e015..cda065ce6e 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -33,8 +33,8 @@ enum ldap_request_tag { LDAP_TAG_ModifyResponse = 7, LDAP_TAG_AddRequest = 8, LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, + LDAP_TAG_DeleteRequest = 10, + LDAP_TAG_DeleteResponse = 11, LDAP_TAG_ModifyDNRequest = 12, LDAP_TAG_ModifyDNResponse = 13, LDAP_TAG_CompareRequest = 14, @@ -53,6 +53,7 @@ enum ldap_auth_mechanism { enum ldap_result_code { LDAP_SUCCESS = 0, LDAP_SASL_BIND_IN_PROGRESS = 0x0e, + LDAP_NO_SUCH_OBJECT = 0x20, LDAP_INVALID_CREDENTIALS = 0x31, LDAP_OTHER = 0x50 }; @@ -154,7 +155,7 @@ struct ldap_AddRequest { struct ldap_attribute *attributes; }; -struct ldap_DelRequest { +struct ldap_DeleteRequest { const char *dn; }; @@ -198,8 +199,8 @@ union ldap_Request { struct ldap_Result ModifyResponse; struct ldap_AddRequest AddRequest; struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; + struct ldap_DeleteRequest DeleteRequest; + struct ldap_Result DeleteResponse; struct ldap_ModifyDNRequest ModifyDNRequest; struct ldap_Result ModifyDNResponse; struct ldap_CompareRequest CompareRequest; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 8fe50b6d08..df912c038a 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -3,9 +3,6 @@ LDAP protocol helper functions for SAMBA Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 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 @@ -352,8 +349,8 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), } if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; + msg->type = LDAP_TAG_DeleteRequest; + msg->r.DeleteRequest.dn = dn; return msg; } -- cgit From 159b8c2d386af821d265c9cfb5896c001ae8852a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Sep 2004 14:18:25 +0000 Subject: r2690: deleted by mistake (This used to be commit 3d587a7141908362657afc2dfd0c78d73a5fed07) --- source4/libcli/ldap/ldap_ldif.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index df912c038a..8530a60a29 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -3,6 +3,9 @@ LDAP protocol helper functions for SAMBA Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 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 -- cgit From eac532ee3af95654b62d4db57feea0df6abab345 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Sep 2004 15:40:12 +0000 Subject: r2695: revert "Del" renaming (This used to be commit ddd74dae8efe4e04b5a56ee9ecd9d4f87f99d104) --- source4/libcli/ldap/ldap.c | 26 +++++++++++++------------- source4/libcli/ldap/ldap.h | 10 +++++----- source4/libcli/ldap/ldap_ldif.c | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 12842b4dc4..af21962265 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -547,16 +547,16 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ldap_encode_response(msg->type, r, &data); break; } - case LDAP_TAG_DeleteRequest: { - struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); asn1_write(&data, r->dn, strlen(r->dn)); asn1_pop_tag(&data); break; } - case LDAP_TAG_DeleteResponse: { - struct ldap_Result *r = &msg->r.DeleteResponse; + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; ldap_encode_response(msg->type, r, &data); break; } @@ -1009,13 +1009,13 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest): { - struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; int len; char *dn; - msg->type = LDAP_TAG_DeleteRequest; + msg->type = LDAP_TAG_DelRequest; asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); dn = talloc(msg->mem_ctx, len+1); if (dn == NULL) @@ -1027,11 +1027,11 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_DeleteResponse): { - struct ldap_Result *r = &msg->r.DeleteResponse; - msg->type = LDAP_TAG_DeleteResponse; + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_DeleteResponse, r); + LDAP_TAG_DelResponse, r); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index cda065ce6e..ca546e11e1 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -33,8 +33,8 @@ enum ldap_request_tag { LDAP_TAG_ModifyResponse = 7, LDAP_TAG_AddRequest = 8, LDAP_TAG_AddResponse = 9, - LDAP_TAG_DeleteRequest = 10, - LDAP_TAG_DeleteResponse = 11, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, LDAP_TAG_ModifyDNRequest = 12, LDAP_TAG_ModifyDNResponse = 13, LDAP_TAG_CompareRequest = 14, @@ -155,7 +155,7 @@ struct ldap_AddRequest { struct ldap_attribute *attributes; }; -struct ldap_DeleteRequest { +struct ldap_DelRequest { const char *dn; }; @@ -199,8 +199,8 @@ union ldap_Request { struct ldap_Result ModifyResponse; struct ldap_AddRequest AddRequest; struct ldap_Result AddResponse; - struct ldap_DeleteRequest DeleteRequest; - struct ldap_Result DeleteResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; struct ldap_ModifyDNRequest ModifyDNRequest; struct ldap_Result ModifyDNResponse; struct ldap_CompareRequest CompareRequest; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 8530a60a29..8fe50b6d08 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -352,8 +352,8 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), } if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DeleteRequest; - msg->r.DeleteRequest.dn = dn; + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; return msg; } -- cgit From b2f1a29e4348a5bc34a87d72d526e23e421ed9d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Sep 2004 05:44:59 +0000 Subject: r2710: continue with the new style of providing a parent context whenever possible to a structure creation routine. This makes for much easier global cleanup. (This used to be commit e14ee428ec357fab76a960387a9820a673786e27) --- source4/libcli/cliconnect.c | 41 ++++++++++++++++++++++------------------- source4/libcli/clidfs.c | 2 +- source4/libcli/raw/clisocket.c | 4 ++-- source4/libcli/raw/clitree.c | 5 +++-- 4 files changed, 28 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index aa6aec4a1e..8e7e128a4e 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -27,7 +27,7 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) { struct smbcli_socket *sock; - sock = smbcli_sock_init(); + sock = smbcli_sock_init(cli); if (!sock) return False; if (!smbcli_sock_connect_byname(sock, server, 0)) { @@ -149,17 +149,18 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, /* easy way to get to a fully connected smbcli_state in one call */ -NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, - const char *myname, - const char *host, - struct in_addr *ip, - const char *sharename, - const char *devtype, - const char *username, - const char *domain, - const char *password, - uint_t flags, - BOOL *retry) +NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, + struct smbcli_state **ret_cli, + const char *myname, + const char *host, + struct in_addr *ip, + const char *sharename, + const char *devtype, + const char *username, + const char *domain, + const char *password, + uint_t flags, + BOOL *retry) { struct smbcli_tree *tree; NTSTATUS status; @@ -177,21 +178,23 @@ NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli, username = talloc_strdup(mem_ctx, p+1); } - status = smbcli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, + status = smbcli_tree_full_connection(parent_ctx, + &tree, myname, host, 0, sharename, devtype, username, domain, password); if (!NT_STATUS_IS_OK(status)) { goto done; } - (*ret_cli) = smbcli_state_init(); + (*ret_cli) = smbcli_state_init(parent_ctx); - (*ret_cli)->tree = talloc_reference(*ret_cli, tree); - talloc_free(tree); + (*ret_cli)->tree = tree; (*ret_cli)->session = tree->session; (*ret_cli)->transport = tree->session->transport; - + talloc_steal(*ret_cli, tree->session->transport->socket); + done: talloc_free(mem_ctx); + return status; } @@ -207,11 +210,11 @@ NTSTATUS smbcli_tdis(struct smbcli_state *cli) /**************************************************************************** Initialise a client state structure. ****************************************************************************/ -struct smbcli_state *smbcli_state_init(void) +struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) { struct smbcli_state *cli; - cli = talloc_p(NULL, struct smbcli_state); + cli = talloc_p(mem_ctx, struct smbcli_state); if (cli) { ZERO_STRUCTP(cli); } diff --git a/source4/libcli/clidfs.c b/source4/libcli/clidfs.c index 674666a60a..c007d061a9 100644 --- a/source4/libcli/clidfs.c +++ b/source4/libcli/clidfs.c @@ -244,7 +244,7 @@ int smbcli_dfs_open_connection(struct smbcli_client* cluster, return -1; c = cluster->cli[i]; - if (NT_STATUS_IS_ERR(smbcli_full_connection(&c, + if (NT_STATUS_IS_ERR(smbcli_full_connection(NULL, &c, NULL, host, NULL, 0, share, "?????", cluster->username, cluster->workgroup, diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 37188f4e77..14862a39f0 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -37,11 +37,11 @@ static int sock_destructor(void *ptr) /* create a smbcli_socket context */ -struct smbcli_socket *smbcli_sock_init(void) +struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) { struct smbcli_socket *sock; - sock = talloc_p(NULL, struct smbcli_socket); + sock = talloc_p(mem_ctx, struct smbcli_socket); if (!sock) { return NULL; } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index f19cbf8e28..77fe0ebe2f 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -151,7 +151,8 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) a convenient function to establish a smbcli_tree from scratch, using reasonable default parameters */ -NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, +NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, + struct smbcli_tree **ret_tree, const char *my_name, const char *dest_host, int port, const char *service, const char *service_type, @@ -172,7 +173,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree, *ret_tree = NULL; - sock = smbcli_sock_init(); + sock = smbcli_sock_init(parent_ctx); if (!sock) { return NT_STATUS_NO_MEMORY; } -- cgit From 88ead90b1d6f7e32181b5e9bf2b48cf0ef0b7c95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2004 12:18:06 +0000 Subject: r2747: use DATA_BLOB for attribute values en/decode CompareRequest/Response correct metze (This used to be commit 72dfea2b07aea83d0965a585f6e388eb88a7c6d1) --- source4/libcli/ldap/ldap.c | 20 ++++++++++++++++---- source4/libcli/ldap/ldap.h | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index af21962265..a2f8e91b6c 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -589,14 +589,15 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, r->attribute, strlen(r->attribute)); - asn1_write_OctetString(&data, r->value, - strlen(r->value)); + asn1_write_OctetString(&data, r->value.data, + r->value.length); asn1_pop_tag(&data); asn1_pop_tag(&data); break; } case LDAP_TAG_CompareResponse: { -/* struct ldap_Result *r = &msg->r.CompareResponse; */ + struct ldap_Result *r = &msg->r.ModifyDNResponse; + ldap_encode_response(msg->type, r, &data); break; } case LDAP_TAG_AbandonRequest: { @@ -1070,8 +1071,19 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { -/* struct ldap_CompareRequest *r = &msg->r.CompareRequest; */ + struct ldap_CompareRequest *r = &msg->r.CompareRequest; msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->attribute); + asn1_read_OctetString(data, &r->value); + if (r->value.data) { + talloc_steal(msg->mem_ctx, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index ca546e11e1..c0d16e67a3 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -169,7 +169,7 @@ struct ldap_ModifyDNRequest { struct ldap_CompareRequest { const char *dn; const char *attribute; - const char *value; + DATA_BLOB value; }; struct ldap_AbandonRequest { -- cgit From e54cc10f1680a965c058dcb9c32c3cd1750ae13d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2004 12:40:30 +0000 Subject: r2749: add asn1_read_implicit_Integer() metze (This used to be commit a62fbcb30f63245d9dfb48c83a5f449965bb1ca7) --- source4/libcli/util/asn1.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 4ff335399a..138ae930e3 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -591,17 +591,27 @@ BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) return !data->has_error; } -/* read an interger */ -BOOL asn1_read_Integer(ASN1_DATA *data, int *i) +/* read an interger without tag*/ +BOOL asn1_read_implicit_Integer(ASN1_DATA *data, int *i) { uint8_t b; *i = 0; - - if (!asn1_start_tag(data, ASN1_INTEGER)) return False; + while (asn1_tag_remaining(data)>0) { - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) return False; *i = (*i << 8) + b; } + return !data->has_error; + +} + +/* read an interger */ +BOOL asn1_read_Integer(ASN1_DATA *data, int *i) +{ + *i = 0; + + if (!asn1_start_tag(data, ASN1_INTEGER)) return False; + if (!asn1_read_implicit_Integer(data, i)) return False; return asn1_end_tag(data); } -- cgit From cd5326a44ee1f83ff9a1d96d50b56db9a2eb0d94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2004 13:06:26 +0000 Subject: r2750: decode AbandonRequest correct (untested:-) metze (This used to be commit 4233067921d386d4bf02218b479083cdbe2bd3c1) --- source4/libcli/ldap/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index a2f8e91b6c..c78e49bdfe 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1095,9 +1095,13 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_AbandonRequest): { -/* struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; */ + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); break; } -- cgit From d1a568363049c82f4314f7a1c5453a92bee84343 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 2 Oct 2004 12:30:02 +0000 Subject: r2787: force masktest to use RAW_SEARCH_BOTH_DIRECTORY_INFO so it can obtain the short name (This used to be commit ad5a5ea08d5be812e0ef662948477add2433bc6f) --- source4/libcli/clilist.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 2659e81419..84d96d62f4 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -103,8 +103,9 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) } int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, - void (*fn)(file_info *, const char *, void *), - void *caller_state) + enum smb_search_level level, + void (*fn)(file_info *, const char *, void *), + void *caller_state) { union smb_search_first first_parms; union smb_search_next next_parms; @@ -125,11 +126,14 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.dirlist = talloc(state.mem_ctx, 0); mask = talloc_strdup(state.mem_ctx, Mask); - if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) { - state.info_level = RAW_SEARCH_BOTH_DIRECTORY_INFO; - } else { - state.info_level = RAW_SEARCH_STANDARD; + if (level == RAW_SEARCH_GENERIC) { + if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) { + level = RAW_SEARCH_BOTH_DIRECTORY_INFO; + } else { + level = RAW_SEARCH_STANDARD; + } } + state.info_level = level; while (1) { state.ff_searchcount = 0; @@ -336,5 +340,5 @@ int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) return smbcli_list_old(tree, Mask, attribute, fn, state); - return smbcli_list_new(tree, Mask, attribute, fn, state); + return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_GENERIC, fn, state); } -- cgit From 5bf740dfb8fddd4348cb707c17ed47132d3be13b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Oct 2004 14:44:18 +0000 Subject: r2850: - check for GENSEC_WANT_SEAL in gensec_unseal_packet() - pass functions to the subcontext in spnego metze (This used to be commit d02fab41f8261095ca8f9a819e0c25bef41b5807) --- source4/libcli/auth/gensec.c | 4 ++++ source4/libcli/auth/spnego.c | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index b6c4f91610..d9849276a6 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -314,6 +314,10 @@ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->unseal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } + if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index efe9ad675b..4409f5ea9d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -108,7 +108,6 @@ static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_securi { struct spnego_state *spnego_state = gensec_security->private_data; - return NT_STATUS_NOT_IMPLEMENTED; if (spnego_state->state_position != SPNEGO_DONE && spnego_state->state_position != SPNEGO_FALLBACK) { return NT_STATUS_INVALID_PARAMETER; @@ -129,7 +128,6 @@ static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_securit { struct spnego_state *spnego_state = gensec_security->private_data; - return NT_STATUS_NOT_IMPLEMENTED; if (spnego_state->state_position != SPNEGO_DONE && spnego_state->state_position != SPNEGO_FALLBACK) { return NT_STATUS_INVALID_PARAMETER; -- cgit From dba5773d9d0b2a92938b8f3c434a4d6ef17cc236 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Oct 2004 14:46:58 +0000 Subject: r2851: don't destroy the gensec context it's used for sign and seal check the result of ldap_receive() metze (This used to be commit 778cf6d92bc3c50add43b573652c2aefef65026c) --- source4/libcli/ldap/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c78e49bdfe..bea78a8928 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1557,8 +1557,6 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha } done: - if (conn->gensec) - gensec_end(&conn->gensec); if (mem_ctx) talloc_destroy(mem_ctx); @@ -1696,6 +1694,9 @@ struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, } result = ldap_receive(conn, conn->searchid, endtime); + if (!result) { + return NULL; + } if (result->type == LDAP_TAG_SearchResultEntry) return result; -- cgit From 6aa4a9bd1648237cac01724932efdd991786441e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Oct 2004 15:13:20 +0000 Subject: r2853: add torture test to find the defaultNamingContext on the RootDSE try a sasl sealed CompareRequest abartlet: we need to check how SINGING only can work, it failed for me:-( metze (This used to be commit 1dabd04e265bbc1e8335f816708c2639746d9afd) --- source4/libcli/ldap/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index bea78a8928..b589b6dd6d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1481,6 +1481,8 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha return result; } + gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN|GENSEC_WANT_SEAL); + status = gensec_set_domain(conn->gensec, domain); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", -- cgit From 7d32679e9683c81aca538f0267684332a28a286f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Oct 2004 08:13:00 +0000 Subject: r2857: this commit gets rid of smb_ucs2_t, wpstring and fpstring, plus lots of associated functions. The motivation for this change was to avoid having to convert to/from ucs2 strings for so many operations. Doing that was slow, used many static buffers, and was also incorrect as it didn't cope properly with unicode codepoints above 65536 (which could not be represented correctly as smb_ucs2_t chars) The two core functions that allowed this change are next_codepoint() and push_codepoint(). These functions allow you to correctly walk a arbitrary multi-byte string a character at a time without converting the whole string to ucs2. While doing this cleanup I also fixed several ucs2 string handling bugs. See the commit for details. The following code (which counts the number of occuraces of 'c' in a string) shows how to use the new interface: size_t count_chars(const char *s, char c) { size_t count = 0; while (*s) { size_t size; codepoint_t c2 = next_codepoint(s, &size); if (c2 == c) count++; s += size; } return count; } (This used to be commit 814881f0e50019196b3aa9fbe4aeadbb98172040) --- source4/libcli/auth/ntlmssp_parse.c | 4 ++-- source4/libcli/raw/rawrequest.c | 13 ++--------- source4/libcli/util/smbencrypt.c | 44 +++++++++++++++++++++---------------- 3 files changed, 29 insertions(+), 32 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 9c4cc40acf..22ed783666 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -64,7 +64,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, case 'U': s = va_arg(ap, char *); head_size += 8; - n = push_ucs2_talloc(pointers, (smb_ucs2_t **)&pointers[i].data, s); + n = push_ucs2_talloc(pointers, &pointers[i].data, s); if (n == -1) { return False; } @@ -87,7 +87,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, n = va_arg(ap, int); intargs[i] = n; s = va_arg(ap, char *); - n = push_ucs2_talloc(pointers, (smb_ucs2_t **)&pointers[i].data, s); + n = push_ucs2_talloc(pointers, &pointers[i].data, s); if (n == -1) { return False; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index a15d681a5c..89155451da 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -517,11 +517,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c src_len = byte_len; } - src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2; - if (src_len2 < src_len - 2) { - /* include the termination if we didn't reach the end of the packet */ - src_len2 += 2; - } + src_len2 = utf16_len_n(src, src_len); /* ucs2 strings must be at least 2 bytes long */ if (src_len2 < 2) { @@ -722,12 +718,7 @@ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, return 0; } - src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2; - - if (src_len2 < src_len - 2) { - /* include the termination if we didn't reach the end of the packet */ - src_len2 += 2; - } + src_len2 = utf16_len_n(src, src_len); ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index f0dba16a5a..1089c3a4cf 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -61,17 +61,15 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) void E_md4hash(const char *passwd, uint8_t p16[16]) { int len; - smb_ucs2_t *wpwd; - - TALLOC_CTX *mem_ctx = talloc_init("E_md4hash"); - SMB_ASSERT(mem_ctx); + void *wpwd; - len = push_ucs2_talloc(mem_ctx, &wpwd, passwd); + len = push_ucs2_talloc(NULL, &wpwd, passwd); SMB_ASSERT(len >= 2); len -= 2; - mdfour(p16, (uint8_t *)wpwd, len); - talloc_free(mem_ctx); + mdfour(p16, wpwd, len); + + talloc_free(wpwd); } /** @@ -109,9 +107,8 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], BOOL upper_case_domain, /* Transform the domain into UPPER case */ uint8_t kr_buf[16]) { - smb_ucs2_t *user; - smb_ucs2_t *domain; - + void *user; + void *domain; size_t user_byte_len; size_t domain_byte_len; @@ -121,6 +118,20 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], return False; } + user_in = strupper_talloc(mem_ctx, user_in); + if (user_in == NULL) { + talloc_free(mem_ctx); + return False; + } + + if (upper_case_domain) { + domain_in = strupper_talloc(mem_ctx, domain_in); + if (domain_in == NULL) { + talloc_free(mem_ctx); + return False; + } + } + user_byte_len = push_ucs2_talloc(mem_ctx, &user, user_in); if (user_byte_len == (ssize_t)-1) { DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); @@ -135,11 +146,6 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], return False; } - strupper_w(user); - - if (upper_case_domain) - strupper_w(domain); - SMB_ASSERT(user_byte_len >= 2); SMB_ASSERT(domain_byte_len >= 2); @@ -148,14 +154,14 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], domain_byte_len = domain_byte_len - 2; hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const uint8_t *)user, user_byte_len, &ctx); - hmac_md5_update((const uint8_t *)domain, domain_byte_len, &ctx); + hmac_md5_update(user, user_byte_len, &ctx); + hmac_md5_update(domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, (const char *)user, user_byte_len); - dump_data(100, (const char *)domain, domain_byte_len); + dump_data(100, user, user_byte_len); + dump_data(100, domain, domain_byte_len); dump_data(100, owf, 16); dump_data(100, kr_buf, 16); #endif -- cgit From 59ef8de1293e171e740e4aa9b9d16271859191d2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Oct 2004 10:16:34 +0000 Subject: r2859: It seems useful to allow the seal/unseal functions in gensec to pass though to the sign/check_sig functions. Andrew Bartlett (This used to be commit 18367c4235cf16f3c2fee003153ec9b19b02aa9b) --- source4/libcli/auth/gensec.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index d9849276a6..5d8e3bbca4 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -315,6 +315,12 @@ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, return NT_STATUS_NOT_IMPLEMENTED; } if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) { + if (gensec_security->want_features & GENSEC_WANT_SIGN) { + return gensec_check_packet(gensec_security, mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); + } return NT_STATUS_INVALID_PARAMETER; } @@ -350,6 +356,12 @@ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, return NT_STATUS_NOT_IMPLEMENTED; } if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) { + if (gensec_security->want_features & GENSEC_WANT_SIGN) { + return gensec_sign_packet(gensec_security, mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); + } return NT_STATUS_INVALID_PARAMETER; } -- cgit From 4228ef28153fb985d9d2097832fe628327623044 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2004 11:29:43 +0000 Subject: r2860: add gensec_have_feature() to check what feature are used in the connection metze (This used to be commit 30aa8af04498d674dbcf428a9e62df9055f53ea2) --- source4/libcli/auth/gensec.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 5d8e3bbca4..353c5f562d 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -470,6 +470,21 @@ void gensec_want_feature(struct gensec_security *gensec_security, gensec_security->want_features |= feature; } +/** + * Check the requirement for a certain feature on the connection + * + */ + +BOOL gensec_have_feature(struct gensec_security *gensec_security, + uint32 feature) +{ + if (gensec_security->want_features & feature) { + return True; + } + + return False; +} + /** * Set a username on a GENSEC context - ensures it is talloc()ed * -- cgit From 78782df5542290a7a10a4e8c933f99d9962dfffd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2004 12:08:43 +0000 Subject: r2861: encode and decode BindRequest/Response correct and some minor changes - make ldap_encode/decode_response maore usable metze (This used to be commit cc77baf729a56499e19a50dcb1a404a4777b36d5) --- source4/libcli/ldap/ldap.c | 151 ++++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 69 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b589b6dd6d..fbb5a21d84 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -351,11 +351,8 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) return !data->has_error; } -static void ldap_encode_response(enum ldap_request_tag tag, - struct ldap_Result *result, - ASN1_DATA *data) +static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result) { - asn1_push_tag(data, ASN1_APPLICATION(tag)); asn1_write_enumerated(data, result->resultcode); asn1_write_OctetString(data, result->dn, (result->dn) ? strlen(result->dn) : 0); @@ -365,7 +362,6 @@ static void ldap_encode_response(enum ldap_request_tag tag, if (result->referral != NULL) asn1_write_OctetString(data, result->referral, strlen(result->referral)); - asn1_pop_tag(data); } BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) @@ -380,7 +376,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) switch (msg->type) { case LDAP_TAG_BindRequest: { struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_Integer(&data, r->version); asn1_write_OctetString(&data, r->dn, (r->dn != NULL) ? strlen(r->dn) : 0); @@ -388,14 +384,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) switch (r->mechanism) { case LDAP_AUTH_MECH_SIMPLE: /* context, primitive */ - asn1_push_tag(&data, r->mechanism | 0x80); + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->creds.password, strlen(r->creds.password)); asn1_pop_tag(&data); break; case LDAP_AUTH_MECH_SASL: /* context, constructed */ - asn1_push_tag(&data, r->mechanism | 0xa0); + asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); asn1_write_OctetString(&data, r->creds.SASL.secblob.data, @@ -412,7 +408,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_BindResponse: { struct ldap_BindResponse *r = &msg->r.BindResponse; - ldap_encode_response(msg->type, &r->response, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, &r->response); + if (r->SASL.secblob.length > 0) { + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + } + asn1_pop_tag(&data); break; } case LDAP_TAG_UnbindRequest: { @@ -421,7 +422,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); asn1_write_enumerated(&data, r->deref); @@ -458,7 +459,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchResultEntry: { struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -481,12 +482,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchResultDone: { struct ldap_Result *r = &msg->r.SearchResultDone; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_ModifyRequest: { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -515,12 +518,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ModifyResponse: { struct ldap_Result *r = &msg->r.ModifyResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_AddRequest: { struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -544,26 +549,28 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_AddResponse: { struct ldap_Result *r = &msg->r.AddResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_DelRequest: { struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); asn1_write(&data, r->dn, strlen(r->dn)); asn1_pop_tag(&data); break; } case LDAP_TAG_DelResponse: { struct ldap_Result *r = &msg->r.DelResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_ModifyDNRequest: { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(&data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); asn1_write_BOOLEAN(&data, r->deleteolddn); @@ -578,13 +585,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ModifyDNResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_CompareRequest: { struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(&data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, r->attribute, @@ -597,13 +605,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_CompareResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_AbandonRequest: { struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); asn1_write_implicit_Integer(&data, r->messageid); asn1_pop_tag(&data); break; @@ -614,7 +623,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ExtendedRequest: { struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->oid, strlen(r->oid)); asn1_pop_tag(&data); @@ -626,7 +635,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ExtendedResponse: { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - ldap_encode_response(msg->type, &r->response, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, &r->response); + asn1_pop_tag(&data); break; } default: @@ -662,10 +673,8 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, static void ldap_decode_response(TALLOC_CTX *mem_ctx, ASN1_DATA *data, - enum ldap_request_tag tag, struct ldap_Result *result) { - asn1_start_tag(data, ASN1_APPLICATION(tag)); asn1_read_enumerated(data, &result->resultcode); asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); @@ -676,7 +685,6 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } else { result->referral = NULL; } - asn1_end_tag(data); } static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, @@ -834,14 +842,14 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindRequest): { struct ldap_BindRequest *r = &msg->r.BindRequest; msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_start_tag(data, tag); asn1_read_Integer(data, &r->version); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); - if (asn1_peek_tag(data, 0x80)) { + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { int pwlen; r->creds.password = ""; - /* Mechanism 0 (SIMPLE) */ - asn1_start_tag(data, 0x80); + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen != 0) { char *pw = talloc(msg->mem_ctx, pwlen+1); @@ -850,6 +858,15 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) r->creds.password = pw; } asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->creds.SASL.mechanism); + asn1_read_OctetString(data, &r->creds.SASL.secblob); + if (r->creds.SASL.secblob.data) { + talloc_steal(msg->mem_ctx, r->creds.SASL.secblob.data); + } + asn1_end_tag(data); } asn1_end_tag(data); break; @@ -858,17 +875,8 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindResponse): { struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindResponse)); - asn1_read_enumerated(data, &r->response.resultcode); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.dn); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.referral); - asn1_end_tag(data); - } else { - r->response.referral = NULL; - } + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, &r->response); if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); asn1_read_ContextSimple(data, 7, &tmp_blob); @@ -883,7 +891,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest)); + asn1_start_tag(data, tag); asn1_end_tag(data); break; } @@ -891,7 +899,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { struct ldap_SearchRequest *r = &msg->r.SearchRequest; msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn); asn1_read_enumerated(data, (int *)&(r->scope)); asn1_read_enumerated(data, (int *)&(r->deref)); @@ -929,8 +937,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) msg->type = LDAP_TAG_SearchResultEntry; r->attributes = NULL; r->num_attributes = 0; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, &r->num_attributes); @@ -941,8 +948,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { struct ldap_Result *r = &msg->r.SearchResultDone; msg->type = LDAP_TAG_SearchResultDone; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_SearchResultDone, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -982,15 +990,16 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { struct ldap_Result *r = &msg->r.ModifyResponse; msg->type = LDAP_TAG_ModifyResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_ModifyResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } case ASN1_APPLICATION(LDAP_TAG_AddRequest): { struct ldap_AddRequest *r = &msg->r.AddRequest; msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); r->attributes = NULL; @@ -1005,8 +1014,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_AddResponse): { struct ldap_Result *r = &msg->r.AddResponse; msg->type = LDAP_TAG_AddResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_AddResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -1031,8 +1041,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_DelResponse): { struct ldap_Result *r = &msg->r.DelResponse; msg->type = LDAP_TAG_DelResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_DelResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -1065,8 +1076,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { struct ldap_Result *r = &msg->r.ModifyDNResponse; msg->type = LDAP_TAG_ModifyDNResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_ModifyDNResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -1090,16 +1102,16 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { struct ldap_Result *r = &msg->r.CompareResponse; msg->type = LDAP_TAG_CompareResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_CompareResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_start_tag(data, tag); asn1_read_implicit_Integer(data, &r->messageid); asn1_end_tag(data); break; @@ -1110,7 +1122,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) DATA_BLOB tmp_blob = data_blob(NULL, 0); msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + asn1_start_tag(data,tag); if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { return False; } @@ -1135,14 +1147,15 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; msg->type = LDAP_TAG_ExtendedResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_ExtendedResponse, &r->response); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, &r->response); /* I have to come across an operation that actually sends * something back to really see what's going on. The currently * needed pwdchange does not send anything back. */ r->name = NULL; r->value.data = NULL; r->value.length = 0; + asn1_end_tag(data); break; } default: -- cgit From 9d26f044a34bbc53a7621c7343cdcbbc752f99ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Oct 2004 23:58:11 +0000 Subject: r2883: set BOOL to the internal values not the wire ones metze (This used to be commit ad7b0385cfdb989d69a5c42c21fdaf8cd816999e) --- source4/libcli/util/asn1.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 138ae930e3..15d9243acd 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -241,8 +241,14 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) BOOL asn1_read_BOOLEAN(ASN1_DATA *data, BOOL *v) { + uint8_t tmp = 0; asn1_start_tag(data, ASN1_BOOLEAN); - asn1_read_uint8(data, (uint8 *)v); + asn1_read_uint8(data, &tmp); + if (tmp == 0xFF) { + *v = True; + } else { + *v = False; + } asn1_end_tag(data); return !data->has_error; } -- cgit From f49f6e0c83a8296bcaba3cb11b5fcaa55dd5ce5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Oct 2004 23:59:12 +0000 Subject: r2884: parse LDAP Control messages metze (This used to be commit e23dcb18870450be4252a0dba3e427f73291da25) --- source4/libcli/ldap/ldap.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index fbb5a21d84..7e12f42f06 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1162,6 +1162,47 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) return False; } + msg->num_controls = 0; + msg->controls = NULL; + + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + int i; + struct ldap_Control *ctrl = NULL; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + ctrl = talloc_realloc_p(msg->mem_ctx, ctrl, struct ldap_Control, i+1); + if (!ctrl) { + return False; + } + ctrl[i].oid = NULL; + ctrl[i].critical = False; + ctrl[i].value = data_blob(NULL, 0); + + asn1_read_OctetString_talloc(ctrl, data, &ctrl[i].oid); + + if (asn1_peek_tag(data, ASN1_BOOLEAN)) { + asn1_read_BOOLEAN(data, &ctrl[i].critical); + } + + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + asn1_read_OctetString(data, &ctrl[i].value); + if (ctrl[i].value.data) { + talloc_steal(msg->mem_ctx, ctrl[i].value.data); + } + } + + asn1_end_tag(data); + } + msg->num_controls = i; + msg->controls = ctrl; + + asn1_end_tag(data); + } + asn1_end_tag(data); return ((!data->has_error) && (data->nesting == NULL)); } -- cgit From 12ea0fd34cec2d7b6d8c8374dfd95728112585b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Oct 2004 13:47:00 +0000 Subject: r3005: added talloc wrappers around tdb_open() and ldb_connect(), so that the caller doesn't have to worry about the constraint of only opening a database a single time in a process. These wrappers will ensure that only a single open is done, and will auto-close when the last instance is gone. When you are finished with a database pointer, use talloc_free() to close it. note that this code does not take account of the threads process model, and does not yet take account of symlinks or hard links to tdb files. (This used to be commit 04e1171996612ddb15f84134cadded68f0d173b2) --- source4/libcli/unexpected.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c index 22795e6c4c..e109c9d5bf 100644 --- a/source4/libcli/unexpected.c +++ b/source4/libcli/unexpected.c @@ -21,7 +21,7 @@ #include "includes.h" -static TDB_CONTEXT *tdbd = NULL; +static struct tdb_wrap *tdbd = NULL; /* the key type used in the unexpeceted packet database */ struct unexpected_key { @@ -49,9 +49,9 @@ void unexpected_packet(struct packet_struct *p) if (!tdbd) { mem_ctx = talloc_init("receive_unexpected"); if (!mem_ctx) return; - tdbd = tdb_open_log(lock_path(mem_ctx, "unexpected.tdb"), 0, - TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); + tdbd = tdb_wrap_open(NULL, lock_path(mem_ctx, "unexpected.tdb"), 0, + TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644); talloc_destroy(mem_ctx); if (!tdbd) { return; @@ -71,7 +71,7 @@ void unexpected_packet(struct packet_struct *p) dbuf.dptr = buf; dbuf.dsize = len; - tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE); + tdb_store(tdbd->tdb, kbuf, dbuf, TDB_REPLACE); } @@ -106,7 +106,7 @@ void clear_unexpected(time_t t) lastt = t; - tdb_traverse(tdbd, traverse_fn, NULL); + tdb_traverse(tdbd->tdb, traverse_fn, NULL); } @@ -149,23 +149,25 @@ check for a particular packet in the unexpected packet queue struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, const char *mailslot_name) { - TDB_CONTEXT *tdb2; + struct tdb_wrap *tdb2; TALLOC_CTX *mem_ctx; mem_ctx = talloc_init("receive_unexpected"); if (!mem_ctx) return NULL; - tdb2 = tdb_open_log(lock_path(mem_ctx, "unexpected.tdb"), 0, 0, O_RDONLY, 0); - talloc_destroy(mem_ctx); - if (!tdb2) return NULL; + tdb2 = tdb_wrap_open(mem_ctx, lock_path(mem_ctx, "unexpected.tdb"), 0, 0, O_RDONLY, 0); + if (!tdb2) { + talloc_destroy(mem_ctx); + return NULL; + } matched_packet = NULL; match_id = id; match_type = packet_type; match_name = mailslot_name; - tdb_traverse(tdb2, traverse_match, NULL); + tdb_traverse(tdb2->tdb, traverse_match, NULL); - tdb_close(tdb2); + talloc_destroy(mem_ctx); return matched_packet; } -- cgit From 6591a226144d371a6b68fc5e7201a90a77dc9153 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 10:04:49 +0000 Subject: r3016: - converted the events code to talloc - added the new messaging system, based on unix domain sockets. It gets over 10k messages/second on my laptop without any socket cacheing, which is better than I expected. - added a LOCAL-MESSAGING torture test (This used to be commit 3af06478da7ab34a272226d8d9ac87e0a4940cfb) --- source4/libcli/raw/clitransport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index f06f2c57ff..3944afb638 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -68,7 +68,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) ZERO_STRUCTP(transport); - transport->event.ctx = event_context_init(); + transport->event.ctx = event_context_init(transport); if (transport->event.ctx == NULL) { talloc_free(transport); return NULL; -- cgit From 53891ed37e32a97380430e6911878f3b94133e01 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 11:37:22 +0000 Subject: r3017: nicer memory handling for event_context_merge() (This used to be commit 1cef44505e5de9b8ae5206522b624082ad2343b2) --- source4/libcli/raw/clitransport.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 3944afb638..c84c025c74 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -51,7 +51,6 @@ static int transport_destructor(void *ptr) smbcli_transport_dead(transport); event_remove_fd(transport->event.ctx, transport->event.fde); event_remove_timed(transport->event.ctx, transport->event.te); - event_context_destroy(transport->event.ctx); return 0; } -- cgit From d78ae0b646028916b59c2beeeefe9c62c1d97517 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 18 Oct 2004 15:26:16 +0000 Subject: r3044: resolve the error code for WERR_DS_OBJ_NOT_FOUND to the name metze (This used to be commit c79bbe54b400f8e088401e1d59a626cb2a37ee34) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index b8605864fc..c8e0e89078 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -67,6 +67,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, + { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, { NULL, W_ERROR(0) } }; -- cgit From a71b9135710995a381f0bfaea29fe1a9da93ce20 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Oct 2004 02:10:46 +0000 Subject: r3075: Initialise (and check for intialisation) of the private pointer to ensure we don't segfault on the cleanup from an incomplete schannel bind. Andrew Bartlett (This used to be commit 173f29a1d8db111d5adb258eead5379d681d3bb2) --- source4/libcli/auth/schannel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index aa89e7b84f..2e752f0172 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -278,8 +278,10 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, */ void schannel_end(struct schannel_state **state) { - talloc_destroy((*state)->mem_ctx); - (*state) = NULL; + if (*state) { + talloc_destroy((*state)->mem_ctx); + (*state) = NULL; + } } /* -- cgit From d0d86b53483f1455fa41ed457502d1452be336fb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Oct 2004 02:14:28 +0000 Subject: r3079: make code more pretty :-) Andrew Bartlett (This used to be commit 9c911b361c4dbb058eb48150c113c2e95b8053da) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7e12f42f06..6e182c3843 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1535,7 +1535,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha return result; } - gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN|GENSEC_WANT_SEAL); + gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); status = gensec_set_domain(conn->gensec, domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From 20d17b80571f0d0265c99c1ccdc21910c2eed043 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Oct 2004 08:28:31 +0000 Subject: r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e) --- source4/libcli/raw/rawfile.c | 6 ------ source4/libcli/raw/rawreadwrite.c | 12 ------------ 2 files changed, 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 1b858d489a..3eb2ab49b2 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -493,9 +493,6 @@ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_cl struct smbcli_request *req = NULL; switch (parms->generic.level) { - case RAW_CLOSE_GENERIC: - return NULL; - case RAW_CLOSE_CLOSE: SETUP_REQUEST(SMBclose, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum); @@ -539,9 +536,6 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc struct smbcli_request *req = NULL; switch (parms->generic.level) { - case RAW_LOCK_GENERIC: - return NULL; - case RAW_LOCK_LOCK: SETUP_REQUEST(SMBlock, 5, 0); SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum); diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index dbca6fb7a5..e145ff9c10 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -36,9 +36,6 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea struct smbcli_request *req = NULL; switch (parms->generic.level) { - case RAW_READ_GENERIC: - return NULL; - case RAW_READ_READBRAW: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = True; @@ -115,10 +112,6 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) } switch (parms->generic.level) { - case RAW_READ_GENERIC: - /* handled in _send() */ - break; - case RAW_READ_READBRAW: parms->readbraw.out.nread = req->in.size - NBT_HDR_SIZE; if (parms->readbraw.out.nread > @@ -188,9 +181,6 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr struct smbcli_request *req = NULL; switch (parms->generic.level) { - case RAW_WRITE_GENERIC: - return NULL; - case RAW_WRITE_WRITEUNLOCK: SETUP_REQUEST(SMBwriteunlock, 5, 3 + parms->writeunlock.in.count); SSVAL(req->out.vwv, VWV(0), parms->writeunlock.in.fnum); @@ -284,8 +274,6 @@ NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms) } switch (parms->generic.level) { - case RAW_WRITE_GENERIC: - break; case RAW_WRITE_WRITEUNLOCK: SMBCLI_CHECK_WCT(req, 1); parms->writeunlock.out.nwritten = SVAL(req->in.vwv, VWV(0)); -- cgit From 86ab5f126723b3af71506b2f7f43741018b6286a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Oct 2004 20:34:32 +0000 Subject: r3094: import all LDAP error codes from the RFC 2251 metze (This used to be commit f1d8f4bc5df5b4f284739096684c9dbc76352511) --- source4/libcli/ldap/ldap.h | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index c0d16e67a3..6492df41d9 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -51,11 +51,45 @@ enum ldap_auth_mechanism { }; enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_SASL_BIND_IN_PROGRESS = 0x0e, - LDAP_NO_SUCH_OBJECT = 0x20, - LDAP_INVALID_CREDENTIALS = 0x31, - LDAP_OTHER = 0x50 + LDAP_SUCCESS = 0, + LDAP_OPERATIONS_ERROR = 1, + LDAP_PROTOCOL_ERROR = 2, + LDAP_TIME_LIMIT_EXCEEDED = 3, + LDAP_SIZE_LIMIT_EXCEEDED = 4, + LDAP_COMPARE_FALSE = 5, + LDAP_COMPARE_TRUe = 6, + LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, + LDAP_STRONG_AUTH_REQUIRED = 8, + LDAP_REFERRAL = 10, + LDAP_ADMIN_LIMIT_EXCEEDED = 11, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, + LDAP_CONFIDENTIALITY_REQUIRED = 13, + LDAP_SASL_BIND_IN_PROGRESS = 14, + LDAP_NO_SUCH_ATTRIBUTE = 16, + LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, + LDAP_INAPPROPRIATE_MATCHING = 18, + LDAP_CONSTRAINT_VIOLATION = 19, + LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, + LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, + LDAP_NO_SUCH_OBJECT = 32, + LDAP_ALIAS_PROBLEM = 33, + LDAP_INVALID_DN_SYNTAX = 34, + LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, + LDAP_INAPPROPRIATE_AUTHENTICATION = 48, + LDAP_INVALID_CREDENTIALS = 49, + LDAP_INSUFFICIENT_ACCESS_RIGHTs = 50, + LDAP_BUSY = 51, + LDAP_UNAVAILABLE = 52, + LDAP_UNWILLING_TO_PERFORM = 53, + LDAP_LOOP_DETECT = 54, + LDAP_NAMING_VIOLATION = 64, + LDAP_OBJECT_CLASS_VIOLATION = 65, + LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, + LDAP_NOT_ALLOWED_ON_RDN = 67, + LDAP_ENTRY_ALREADY_EXISTS = 68, + LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, + LDAP_AFFECTS_MULTIPLE_DSAS = 71, + LDAP_OTHER = 80 }; struct ldap_Result { -- cgit From 367b3bfa12aada4254cfdb8e1de5929be675c952 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Oct 2004 22:44:08 +0000 Subject: r3096: typo metze (This used to be commit c730d7d638875c239f0b67c1d4b25eb1fb01c5ff) --- source4/libcli/ldap/ldap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 6492df41d9..c27aba8d7a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -57,7 +57,7 @@ enum ldap_result_code { LDAP_TIME_LIMIT_EXCEEDED = 3, LDAP_SIZE_LIMIT_EXCEEDED = 4, LDAP_COMPARE_FALSE = 5, - LDAP_COMPARE_TRUe = 6, + LDAP_COMPARE_TRUE = 6, LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, LDAP_STRONG_AUTH_REQUIRED = 8, LDAP_REFERRAL = 10, -- cgit From 6a304256d00e225872a06d1ec10152629352f41c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Oct 2004 08:52:01 +0000 Subject: r3110: Fix the krb5 client and server, so that it doesn't segfault. There were also gensec bugs that didn't turn up until we hit error paths in the krb5 code. Andrew Bartlett (This used to be commit e08366ffeb52e8c522d3808a2af1aa0bc632b55f) --- source4/libcli/auth/gensec.c | 7 ++-- source4/libcli/auth/gensec_krb5.c | 70 +++++++++++++++++++++------------------ source4/libcli/auth/spnego.c | 21 ++++++------ 3 files changed, 49 insertions(+), 49 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 353c5f562d..a00a36e171 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -452,11 +452,8 @@ void gensec_end(struct gensec_security **gensec_security) } (*gensec_security)->private_data = NULL; - if (!(*gensec_security)->subcontext) { - /* don't destory this if this is a subcontext - it belongs to the parent */ - talloc_free(*gensec_security); - } - gensec_security = NULL; + talloc_free(*gensec_security); + *gensec_security = NULL; } /** diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 7895a6f1ed..26bf0cf663 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -224,6 +224,40 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, return status; } +static void gensec_krb5_end(struct gensec_security *gensec_security) +{ + struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + + if (gensec_krb5_state->ticket.length) { + /* Hmm, heimdal dooesn't have this - what's the correct call? */ +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); +#endif + } + if (gensec_krb5_state->krb5_ccache) { + /* Removed by jra. They really need to fix their kerberos so we don't leak memory. + JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro + */ +#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ + krb5_cc_close(context, gensec_krb5_state->krb5_ccache); +#endif + } + + if (gensec_krb5_state->krb5_auth_context) { + krb5_auth_con_free(gensec_krb5_state->krb5_context, + gensec_krb5_state->krb5_auth_context); + } + + if (gensec_krb5_state->krb5_context) { + krb5_free_context(gensec_krb5_state->krb5_context); + } + + talloc_free(gensec_krb5_state); + gensec_security->private_data = NULL; +} + + static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state; @@ -324,6 +358,9 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); return NT_STATUS_ACCESS_DENIED; } + + in_data.length = 0; + ret = krb5_mk_req(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_auth_context, AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, @@ -392,39 +429,6 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } } -static void gensec_krb5_end(struct gensec_security *gensec_security) -{ - struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - - if (gensec_krb5_state->ticket.length) { - /* Hmm, heimdal dooesn't have this - what's the correct call? */ -#ifdef HAVE_KRB5_FREE_DATA_CONTENTS - krb5_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); -#endif - } - if (gensec_krb5_state->krb5_ccache) { - /* Removed by jra. They really need to fix their kerberos so we don't leak memory. - JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro - */ -#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ - krb5_cc_close(context, gensec_krb5_state->krb5_ccache); -#endif - } - - if (gensec_krb5_state->krb5_auth_context) { - krb5_auth_con_free(gensec_krb5_state->krb5_context, - gensec_krb5_state->krb5_auth_context); - } - - if (gensec_krb5_state->krb5_context) { - krb5_free_context(gensec_krb5_state->krb5_context); - } - - talloc_free(gensec_krb5_state); - gensec_security->private_data = NULL; -} - /** * Next state function for the Krb5 GENSEC mechanism diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 4409f5ea9d..dff9cb0c51 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -277,19 +277,17 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ null_data_blob, unwrapped_out); } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) - && (!NT_STATUS_IS_OK(nt_status))) { + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - gensec_end(&spnego_state->sub_sec_security); - } else { - break; + gensec_end(&spnego_state->sub_sec_security); } + return nt_status; } if (!mechType || !mechType[i]) { DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); } - return nt_status; + return NT_STATUS_INVALID_PARAMETER; } /** create a client negTokenInit @@ -369,22 +367,23 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; spnego_out.negTokenTarg.responseToken = unwrapped_out; spnego_out.negTokenTarg.mechListMIC = null_data_blob; if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->state_position = SPNEGO_SERVER_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; spnego_state->state_position = SPNEGO_DONE; } else { + spnego_out.negTokenTarg.supportedMech = NULL; spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; - DEBUG(1, ("SPNEGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); + DEBUG(1, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); spnego_state->state_position = SPNEGO_DONE; } -- cgit From f30a08813cbb9b7c50625ad3c2d8476a82e65d42 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Oct 2004 15:24:50 +0000 Subject: r3115: Bugfixes and extra debug in our kerberos verify code. Andrew Bartlett (This used to be commit 9f19aae0c0812b156054385ef77785971488e21c) --- source4/libcli/auth/gensec_krb5.c | 15 +++++++------- source4/libcli/auth/kerberos_verify.c | 38 +++++++++++++++++------------------ 2 files changed, 26 insertions(+), 27 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 26bf0cf663..14e2f586c3 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -229,21 +229,19 @@ static void gensec_krb5_end(struct gensec_security *gensec_security) struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; if (gensec_krb5_state->ticket.length) { - /* Hmm, heimdal dooesn't have this - what's the correct call? */ + /* Hmm, early heimdal dooesn't have this - correct call would be krb5_data_free */ #ifdef HAVE_KRB5_FREE_DATA_CONTENTS krb5_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); #endif } if (gensec_krb5_state->krb5_ccache) { - /* Removed by jra. They really need to fix their kerberos so we don't leak memory. - JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro - */ -#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ - krb5_cc_close(context, gensec_krb5_state->krb5_ccache); -#endif + /* current heimdal - 0.6.3, which we need anyway, fixes segfaults here */ + krb5_cc_close(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache); } + krb5_free_keyblock_contents(gensec_krb5_state->krb5_context, + &gensec_krb5_state->krb5_keyblock); + if (gensec_krb5_state->krb5_auth_context) { krb5_auth_con_free(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context); @@ -275,6 +273,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) gensec_krb5_state->krb5_auth_context = NULL; gensec_krb5_state->krb5_ccache = NULL; ZERO_STRUCT(gensec_krb5_state->ticket); + ZERO_STRUCT(gensec_krb5_state->krb5_keyblock); gensec_krb5_state->session_key = data_blob(NULL, 0); ret = krb5_init_context(&gensec_krb5_state->krb5_context); diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 9afc4caacc..f0efd286a6 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -62,12 +62,11 @@ static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) ads_keytab_add_entry function for details. ***********************************************************************************/ -static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, +static krb5_error_code ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, krb5_keyblock *keyblock) { krb5_error_code ret = 0; - BOOL auth_ok = False; krb5_keytab keytab = NULL; krb5_kt_cursor cursor; @@ -91,12 +90,13 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { + while (!(ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor))) { ret = krb5_unparse_name(context, kt_entry.principal, &princ_name); if (ret) { DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); goto out; } + DEBUG(10, ("Checking principal: %s\n", princ_name)); /* Look for a CIFS ticket */ if (!strncasecmp(princ_name, "cifs/", 5) || (!strncasecmp(princ_name, "host/", 5))) { #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK @@ -123,7 +123,6 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", keytype)); - auth_ok = True; break; } } @@ -133,9 +132,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut if (ret && ret != KRB5_KT_END) { /* This failed because something went wrong, not because the keytab file was empty. */ DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_next_entry failed (%s)\n", error_message(ret))); - goto out; + } else if (ret == KRB5_KT_END) { + DEBUG(10, ("ads_keytab_verify_ticket: no keytab entry found: %s\n", error_message(ret))); + } else { + DEBUG(10, ("ads_keytab_verify_ticket: keytab entry found: %s\n", princ_name)); } - out: if (princ_name) { @@ -152,7 +153,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut krb5_kt_close(context, keytab); } - return auth_ok; + return ret; } /********************************************************************************** @@ -165,7 +166,6 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_keyblock *keyblock) { krb5_error_code ret = 0; - BOOL auth_ok = False; char *password_s = NULL; krb5_data password; krb5_enctype *enctypes = NULL; @@ -175,13 +175,13 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); - return False; + return KRB5_KT_END; } password_s = secrets_fetch_machine_password(lp_workgroup()); if (!password_s) { DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n")); - return False; + return KRB5_KT_END; } password.data = password_s; @@ -200,7 +200,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { - if (create_kerberos_key_from_string(context, host_princ, &password, keyblock, enctypes[i])) { + ret = create_kerberos_key_from_string(context, host_princ, &password, keyblock, enctypes[i]); + if (ret) { continue; } @@ -212,11 +213,10 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au if (!ret) { DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); - auth_ok = True; break; } - krb5_free_keyblock(context, keyblock); + krb5_free_keyblock_contents(context, keyblock); DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", @@ -228,7 +228,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au free_kerberos_etypes(context, enctypes); SAFE_FREE(password_s); - return auth_ok; + return ret; } /********************************************************************************** @@ -255,7 +255,6 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au BOOL got_replay_mutex = False; char *myname; - BOOL auth_ok = False; char *malloc_principal; @@ -304,16 +303,17 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au goto out; } - auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, keyblock); - if (!auth_ok) { - auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ret = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, keyblock); + if (ret) { + DEBUG(10, ("ads_secrets_verify_ticket: using host principal: [%s]\n", host_princ_s)); + ret = ads_secrets_verify_ticket(context, auth_context, host_princ, ticket, &packet, &tkt, keyblock); } release_server_mutex(); got_replay_mutex = False; - if (!auth_ok) { + if (ret) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); goto out; -- cgit From 450359e28202d27bde8e050bee3ffdae86beb938 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 22 Oct 2004 03:02:51 +0000 Subject: r3128: Return the correct error code for a secrets/kerberos login, but skipping 'bad encryption type'. Andrew Bartlett (This used to be commit 4efb87eb03acfa888d455e4ca0aff18bda7f7ba5) --- source4/libcli/auth/kerberos_verify.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index f0efd286a6..8d050182f9 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -160,7 +160,7 @@ static krb5_error_code ads_keytab_verify_ticket(krb5_context context, krb5_auth_ Try to verify a ticket using the secrets.tdb. ***********************************************************************************/ -static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, +static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, krb5_principal host_princ, const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, krb5_keyblock *keyblock) @@ -198,29 +198,37 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au p_packet->length = ticket->length; p_packet->data = (krb5_pointer)ticket->data; + ret = KRB5_BAD_ENCTYPE; /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { - ret = create_kerberos_key_from_string(context, host_princ, &password, keyblock, enctypes[i]); - if (ret) { + krb5_error_code our_ret; + our_ret = create_kerberos_key_from_string(context, host_princ, &password, keyblock, enctypes[i]); + if (our_ret) { + ret = our_ret; continue; } krb5_auth_con_setuseruserkey(context, auth_context, keyblock); - ret = krb5_rd_req(context, &auth_context, p_packet, + our_ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt); - if (!ret) { + if (!our_ret) { DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); + ret = our_ret; break; } krb5_free_keyblock_contents(context, keyblock); - DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, + DEBUG((our_ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", - (unsigned int)enctypes[i], error_message(ret))); + (unsigned int)enctypes[i], error_message(our_ret))); + + if (our_ret != KRB5_BAD_ENCTYPE) { + ret = our_ret; + } } out: -- cgit From 651f3903f0a380a951bfe5bf80322f1ab2330705 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 06:49:27 +0000 Subject: r3131: - make map_nt_error_from_unix() return NT_STATUS_UNSUCCESSFUL if errno is 0 - more consistent checking for system call return values in simple backend (This used to be commit 375a9a1347abf0b917cf94ea0cabcdea37d60e98) --- source4/libcli/util/errormap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 482743b03b..650dc55e50 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1534,13 +1534,13 @@ const struct unix_error_map unix_dos_nt_errmap[] = { /********************************************************************* Map an NT error code from a Unix error code. *********************************************************************/ - NTSTATUS map_nt_error_from_unix(int unix_error) { int i = 0; - if (unix_error == 0) - return NT_STATUS_OK; + if (unix_error == 0) { + return NT_STATUS_UNSUCCESSFUL; + } /* Look through list */ while(unix_dos_nt_errmap[i].unix_error != 0) { -- cgit From db9b96d8e59b38b5900f4bcf1193c2110232137e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Oct 2004 04:21:41 +0000 Subject: r3187: This 'optional' part of the ASN.1 in SPNEGO is required by Samba3 (but not Microsoft). Unfortunetly it's harder to fix Samba3 than to make Samba4 cope... Andrew Bartlett (This used to be commit bbd52ab2641d5d6fc184235ac838ce4a022174a9) --- source4/libcli/auth/spnego_parse.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 07dba61dde..4b94235962 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -233,11 +233,10 @@ static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *toke asn1_push_tag(asn1, ASN1_CONTEXT(1)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - if (token->negResult != SPNEGO_NONE_RESULT) { - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_write_enumerated(asn1, token->negResult); - asn1_pop_tag(asn1); - } + /* Optional, except that Samba3 requires it... */ + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_write_enumerated(asn1, token->negResult); + asn1_pop_tag(asn1); if (token->supportedMech) { asn1_push_tag(asn1, ASN1_CONTEXT(1)); -- cgit From 596d2de763dc2289051dd12b08ebfaae07ca3db2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Oct 2004 04:25:29 +0000 Subject: r3190: When we don't have a PAC, do a lookup in the local ldb instead. This required reworking the auth_sam code, so that it would export the 'name -> server_info' functionality. It's a bit ugly from a modular point of view, but it's what we have to do... Fix up some of the code to better use the new talloc() Andrew Bartlett (This used to be commit 18e08b4497ebabc2f31210254e145458b7c6a198) --- source4/libcli/auth/gensec_krb5.c | 80 +++++++++++++++++++++++++----------- source4/libcli/auth/gensec_ntlmssp.c | 7 +--- 2 files changed, 57 insertions(+), 30 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 14e2f586c3..1ce05b519e 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -611,39 +611,48 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security struct dom_sid *sid; char *p; char *principal; + const char *username; + const char *realm; *session_info_out = NULL; - nt_status = make_server_info(gensec_security, &server_info, gensec_krb5_state->peer_principal); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - server_info->guest = False; + /* IF we have the PAC - otherwise (TODO) we need to get this + * data from elsewere - local ldb, or lookup of some + * kind... */ - principal = talloc_strdup(server_info, gensec_krb5_state->peer_principal); + principal = talloc_strdup(gensec_krb5_state, gensec_krb5_state->peer_principal); p = strchr(principal, '@'); if (p) { *p = '\0'; } - server_info->account_name = principal; - server_info->domain = talloc_strdup(server_info, p++); - if (!server_info->domain) { - free_server_info(&server_info); - return NT_STATUS_NO_MEMORY; - } - - nt_status = make_session_info(server_info, &session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - free_server_info(&server_info); - return nt_status; - } + p++; + username = principal; + realm = p; + + if (logon_info) { + nt_status = make_server_info(gensec_krb5_state, &server_info, gensec_krb5_state->peer_principal); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + server_info->guest = False; + + server_info->account_name = talloc_strdup(server_info, principal); + server_info->domain = talloc_strdup(server_info, realm); + if (!server_info->domain) { + free_server_info(&server_info); + return NT_STATUS_NO_MEMORY; + } + + /* references the server_info into the session_info */ + nt_status = make_session_info(gensec_krb5_state, server_info, &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + free_server_info(&server_info); + return nt_status; + } - /* IF we have the PAC - otherwise (TODO) we need to get this - * data from elsewere - local ldb, or lookup of some - * kind... */ + talloc_free(server_info); - if (logon_info) { ptoken = talloc_p(session_info, struct nt_user_token); if (!ptoken) { return NT_STATUS_NO_MEMORY; @@ -666,16 +675,37 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) { sid = dom_sid_dup(session_info, logon_info->dom_sid); - ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info, sid, logon_info->groups[ptoken->num_sids - 2].rid); + ptoken->user_sids[ptoken->num_sids] + = dom_sid_add_rid(session_info, sid, + logon_info->groups[ptoken->num_sids - 2].rid); } debug_nt_user_token(DBGC_AUTH, 0, ptoken); session_info->nt_user_token = ptoken; } else { - session_info->nt_user_token = NULL; + TALLOC_CTX *mem_ctx = talloc_named(gensec_krb5_state, 0, "PAC-less session info discovery for %s@%s", username, realm); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + nt_status = sam_get_server_info(username, realm, gensec_krb5_state, &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + /* references the server_info into the session_info */ + nt_status = make_session_info(gensec_krb5_state, server_info, &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + talloc_free(mem_ctx); } + talloc_free(principal); + nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key); session_info->workstation = NULL; diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 0683581495..48438aaae1 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -370,19 +370,16 @@ static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, T */ static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security, - struct auth_session_info **session_info) + struct auth_session_info **session_info) { NTSTATUS nt_status; struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - nt_status = make_session_info(gensec_ntlmssp_state->server_info, session_info); + nt_status = make_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } - /* the session_info owns this now */ - gensec_ntlmssp_state->server_info = NULL; - (*session_info)->session_key = data_blob_talloc(*session_info, gensec_ntlmssp_state->ntlmssp_state->session_key.data, gensec_ntlmssp_state->ntlmssp_state->session_key.length); -- cgit From 6b2fc6e2d431261ea0877afa27a70ec15d504f37 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 06:22:29 +0000 Subject: r3197: fixed error code mapping for ENOTDIR (This used to be commit 2c852539ed089b584b721a31cd411667bb5669c7) --- source4/libcli/util/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 650dc55e50..ce7832eaac 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1498,7 +1498,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY }, { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, -- cgit From e1c43f243a7dea8c8a7ae235252091d1e18c2fb4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 07:56:48 +0000 Subject: r3206: - added the reverse map for ERRbaduid to NT_STATUS_INVALID_HANDLE - force disable spnego in the RAW-CONTEXT test (it breaks the test) (This used to be commit 3f247ec21c59af92b420a3e550552b5a1f1f08e2) --- source4/libcli/util/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index ce7832eaac..91ebddc181 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -747,6 +747,7 @@ static const struct { {ERRSRV, ERRnoroom, NT_STATUS_DISK_FULL}, {ERRSRV, ERRnoresource, NT_STATUS_REQUEST_NOT_ACCEPTED}, {ERRSRV, ERRtoomanyuids, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRSRV, ERRbaduid, NT_STATUS_INVALID_HANDLE}, {ERRSRV, 123, NT_STATUS_OBJECT_NAME_INVALID}, {ERRSRV, 206, NT_STATUS_OBJECT_NAME_INVALID}, {ERRHRD, 1, NT_STATUS_NOT_IMPLEMENTED}, -- cgit From 101a407dd72491c05c72bc2825d09133676f242c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Oct 2004 17:23:21 +0000 Subject: r3219: Hi, Andrew B.! Not sure which Samba3 you mean, but *my* one bails out with INVALID_PARAMETER... Volker (This used to be commit d91659b0370a6bd5eebd5730d304b5a2cf496594) --- source4/libcli/auth/spnego_parse.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 4b94235962..337ba7a339 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -233,10 +233,12 @@ static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *toke asn1_push_tag(asn1, ASN1_CONTEXT(1)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); +#if 0 /* Optional, except that Samba3 requires it... */ asn1_push_tag(asn1, ASN1_CONTEXT(0)); asn1_write_enumerated(asn1, token->negResult); asn1_pop_tag(asn1); +#endif if (token->supportedMech) { asn1_push_tag(asn1, ASN1_CONTEXT(1)); -- cgit From fef66179dd5a7c3498f23a79a43de9632f02648b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 05:34:35 +0000 Subject: r3237: - allow for readx calls larger than 64k - combine setattre and standard levels in setfileinfo, as they use the same structure (This used to be commit e9aa1f789955533aca4fe43d5d74ffa1e8d1300b) --- source4/libcli/raw/rawreadwrite.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index e145ff9c10..bc9730f33d 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -77,9 +77,9 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->readx.in.fnum); SIVAL(req->out.vwv, VWV(3), parms->readx.in.offset); - SSVAL(req->out.vwv, VWV(5), parms->readx.in.maxcnt); + SSVAL(req->out.vwv, VWV(5), parms->readx.in.maxcnt & 0xFFFF); SSVAL(req->out.vwv, VWV(6), parms->readx.in.mincnt); - SIVAL(req->out.vwv, VWV(7), 0); /* reserved */ + SIVAL(req->out.vwv, VWV(7), parms->readx.in.maxcnt >> 16); SSVAL(req->out.vwv, VWV(9), parms->readx.in.remaining); if (bigoffset) { SIVAL(req->out.vwv, VWV(10),parms->readx.in.offset>>32); -- cgit From 9d055846f225bea4953822f40fab1d2f1a2e2d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Oct 2004 03:15:42 +0000 Subject: r3278: - rewrote the client side rpc connection code to use lib/socket/ rather than doing everything itself. This greatly simplifies the code, although I really don't like the socket_recv() interface (it always allocates memory for you, which means an extra memcpy in this code) - fixed several bugs in the socket_ipv4.c code, in particular client side code used a non-blocking connect but didn't handle EINPROGRESS, so it had no chance of working. Also fixed the error codes, using map_nt_error_from_unix() - cleaned up and expanded map_nt_error_from_unix() - changed interpret_addr2() to not take a mem_ctx. It makes absolutely no sense to allocate a fixed size 4 byte structure like this. Dozens of places in the code were also using interpret_addr2() incorrectly (precisely because the allocation made no sense) (This used to be commit 7f2c771b0e0e98c5c9e5cf662592d64d34ff1205) --- source4/libcli/namequery.c | 6 ++-- source4/libcli/util/errormap.c | 73 ++++++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 38 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index de0f406209..0f21e33b85 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -522,7 +522,7 @@ BOOL getlmhostsent( TALLOC_CTX *mem_ctx, continue; } - *ipaddr = *interpret_addr2(mem_ctx, ip); + *ipaddr = interpret_addr2(ip); /* Extra feature. If the name ends in '#XX', where XX is a hex number, then only add that name type. */ @@ -643,7 +643,7 @@ BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, } /* the address we will be sending from */ - src_ip = *interpret_addr2(mem_ctx, lp_socket_address()); + src_ip = interpret_addr2(lp_socket_address()); /* in the worst case we will try every wins server with every tag! */ @@ -900,7 +900,7 @@ BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ int count = 0; if (is_ipaddress(name)) { - *return_ip = *interpret_addr2(mem_ctx, name); + *return_ip = interpret_addr2(name); return True; } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 91ebddc181..46e4831f89 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1490,66 +1490,69 @@ WERROR ntstatus_to_werror(NTSTATUS error) struct unix_error_map { int unix_error; - int dos_class; - int dos_code; NTSTATUS nt_error; }; -const struct unix_error_map unix_dos_nt_errmap[] = { - { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY }, - { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, - { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, - { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, - { EISDIR, ERRDOS, ERRbadpath, NT_STATUS_FILE_IS_A_DIRECTORY }, +const struct unix_error_map unix_nt_errmap[] = { + { EAGAIN, STATUS_MORE_ENTRIES }, + { EINTR, STATUS_MORE_ENTRIES }, + { EINPROGRESS, STATUS_MORE_ENTRIES }, + { EPERM, NT_STATUS_ACCESS_DENIED }, + { EACCES, NT_STATUS_ACCESS_DENIED }, + { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { ENOTDIR, NT_STATUS_NOT_A_DIRECTORY }, + { EIO, NT_STATUS_IO_DEVICE_ERROR }, + { EBADF, NT_STATUS_INVALID_HANDLE }, + { EINVAL, NT_STATUS_INVALID_PARAMETER }, + { EEXIST, NT_STATUS_OBJECT_NAME_COLLISION}, + { ENFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, + { EMFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, + { ENOSPC, NT_STATUS_DISK_FULL }, + { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY }, + { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, + { EFAULT, NT_STATUS_INVALID_PARAMETER }, + { EMSGSIZE, NT_STATUS_INVALID_BUFFER_SIZE }, + { ENOBUFS, NT_STATUS_NO_MEMORY }, + { ENOMEM, NT_STATUS_NO_MEMORY }, + { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, + { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, + { EBUSY, NT_STATUS_SHARING_VIOLATION }, #ifdef EDQUOT - { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { EDQUOT, NT_STATUS_QUOTA_EXCEEDED }, #endif #ifdef ENOTEMPTY - { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, + { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY }, #endif #ifdef EXDEV - { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, + { EXDEV, NT_STATUS_NOT_SAME_DEVICE }, #endif #ifdef EROFS - { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, + { EROFS, NT_STATUS_MEDIA_WRITE_PROTECTED }, #endif #ifdef ENAMETOOLONG - { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, + { ENAMETOOLONG, NT_STATUS_NAME_TOO_LONG }, #endif #ifdef EFBIG - { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { EFBIG, NT_STATUS_DISK_FULL }, #endif -#ifdef EFBIG - { EBUSY, ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION }, -#endif - { 0, 0, 0, NT_STATUS_OK } + { 0, NT_STATUS_UNSUCCESSFUL } }; + /********************************************************************* Map an NT error code from a Unix error code. *********************************************************************/ NTSTATUS map_nt_error_from_unix(int unix_error) { - int i = 0; - - if (unix_error == 0) { - return NT_STATUS_UNSUCCESSFUL; - } + int i; /* Look through list */ - while(unix_dos_nt_errmap[i].unix_error != 0) { - if (unix_dos_nt_errmap[i].unix_error == unix_error) - return unix_dos_nt_errmap[i].nt_error; - i++; + for (i=0;i Date: Wed, 27 Oct 2004 12:59:41 +0000 Subject: r3289: Mr. L. and Mr. B.! can we decide to not break WinXP clients:-) metze (This used to be commit 5eb0ff78d5e68f488a439545fdaec90c28ef877a) --- source4/libcli/auth/spnego.c | 3 +-- source4/libcli/auth/spnego_parse.c | 11 +++++------ 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index dff9cb0c51..85d77992fa 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -376,8 +376,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->state_position = SPNEGO_SERVER_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; + spnego_out.negTokenTarg.supportedMech = NULL; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; spnego_state->state_position = SPNEGO_DONE; } else { diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 337ba7a339..07dba61dde 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -233,12 +233,11 @@ static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *toke asn1_push_tag(asn1, ASN1_CONTEXT(1)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); -#if 0 - /* Optional, except that Samba3 requires it... */ - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_write_enumerated(asn1, token->negResult); - asn1_pop_tag(asn1); -#endif + if (token->negResult != SPNEGO_NONE_RESULT) { + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_write_enumerated(asn1, token->negResult); + asn1_pop_tag(asn1); + } if (token->supportedMech) { asn1_push_tag(asn1, ASN1_CONTEXT(1)); -- cgit From 971754c0ed8613b1897041bc5e5b67d1e3b68abe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Oct 2004 17:40:41 +0000 Subject: r3295: Fix for SMB signing with 56-bit DES session keys. From Nalin Dahyabhai . Jeremy. (This used to be commit afed78f359a15809b2d9b7566e16ade294944fa9) --- source4/libcli/raw/smb_signing.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 9ba385e062..e1d7b071f2 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -102,6 +102,8 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_ { uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; + unsigned char key_buf[16]; + /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. @@ -114,8 +116,15 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_ /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); - MD5Update(&md5_ctx, mac_key->data, - mac_key->length); + + /* NB. When making and verifying SMB signatures, Windows apparently + zero-pads the key to 128 bits if it isn't long enough. + From Nalin Dahyabhai */ + MD5Update(&md5_ctx, mac_key->data, mac_key->length); + if (mac_key->length < sizeof(key_buf)) { + memset(key_buf, 0, sizeof(key_buf)); + MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - mac_key->length); + } MD5Update(&md5_ctx, out->buffer + NBT_HDR_SIZE, out->size - NBT_HDR_SIZE); -- cgit From c272e60955bff28ff6431fd50e94807aca1ea016 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 08:15:12 +0000 Subject: r3315: converted the libcli/raw/ code to use the generic socket library. This allows me to test with the socket:testnonblock option. It passes. (This used to be commit 7cb4bf8662825d507d8246647ffb10aa08bad794) --- source4/libcli/raw/clisocket.c | 83 ++++++++++++++++++++++----------------- source4/libcli/raw/clitransport.c | 6 +-- 2 files changed, 49 insertions(+), 40 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 14862a39f0..907206a5e8 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -21,19 +21,6 @@ #include "includes.h" -/* - destroy a socket - */ -static int sock_destructor(void *ptr) -{ - struct smbcli_socket *sock = ptr; - if (sock->fd != -1) { - close(sock->fd); - sock->fd = -1; - } - return 0; -} - /* create a smbcli_socket context */ @@ -47,15 +34,13 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) } ZERO_STRUCTP(sock); - sock->fd = -1; + sock->sock = NULL; sock->port = 0; /* 20 second default timeout */ sock->timeout = 20000; sock->hostname = NULL; - talloc_set_destructor(sock, sock_destructor); - return sock; } @@ -65,10 +50,7 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) */ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int port) { - if (getenv("LIBSMB_PROG")) { - sock->fd = sock_exec(getenv("LIBSMB_PROG")); - return sock->fd != -1; - } + NTSTATUS status; if (port == 0) { int i; @@ -82,18 +64,23 @@ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int por return False; } - sock->dest_ip = *ip; - sock->port = port; - sock->fd = open_socket_out(SOCK_STREAM, - &sock->dest_ip, - sock->port, - LONG_CONNECT_TIMEOUT); - if (sock->fd == -1) { + status = socket_create("ip", SOCKET_TYPE_STREAM, &sock->sock, 0); + if (!NT_STATUS_IS_OK(status)) { return False; } + talloc_steal(sock, sock->sock); - set_blocking(sock->fd, False); - set_socket_options(sock->fd, lp_socket_options()); + status = socket_connect(sock->sock, NULL, 0, inet_ntoa(*ip), port, 0); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(sock->sock); + sock->sock = NULL; + return False; + } + + sock->dest_ip = *ip; + sock->port = port; + + socket_set_option(sock->sock, lp_socket_options(), NULL); return True; } @@ -104,9 +91,9 @@ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int por ****************************************************************************/ void smbcli_sock_dead(struct smbcli_socket *sock) { - if (sock->fd != -1) { - close(sock->fd); - sock->fd = -1; + if (sock->sock != NULL) { + talloc_free(sock->sock); + sock->sock = NULL; } } @@ -115,7 +102,7 @@ void smbcli_sock_dead(struct smbcli_socket *sock) ****************************************************************************/ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) { - set_socket_options(sock->fd, options); + socket_set_option(sock->sock, options, NULL); } /**************************************************************************** @@ -123,12 +110,24 @@ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) ****************************************************************************/ ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t len) { - if (sock->fd == -1) { + NTSTATUS status; + DATA_BLOB blob; + size_t nsent; + + if (sock->sock == NULL) { errno = EIO; return -1; } - return write(sock->fd, data, len); + blob.data = discard_const(data); + blob.length = len; + + status = socket_send(sock->sock, &blob, &nsent, 0); + if (NT_STATUS_IS_ERR(status)) { + return -1; + } + + return nsent; } @@ -137,12 +136,20 @@ ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t l ****************************************************************************/ ssize_t smbcli_sock_read(struct smbcli_socket *sock, char *data, size_t len) { - if (sock->fd == -1) { + NTSTATUS status; + size_t nread; + + if (sock->sock == NULL) { errno = EIO; return -1; } - return read(sock->fd, data, len); + status = socket_recv(sock->sock, data, len, &nread, 0); + if (NT_STATUS_IS_ERR(status)) { + return -1; + } + + return nread; } /**************************************************************************** @@ -155,10 +162,12 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in char *name, *p; BOOL ret; +#if 0 if (getenv("LIBSMB_PROG")) { sock->fd = sock_exec(getenv("LIBSMB_PROG")); return sock->fd != -1; } +#endif name = talloc_strdup(sock, host); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index c84c025c74..d82d97a0d9 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -82,7 +82,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) ZERO_STRUCT(transport->called); - fde.fd = sock->fd; + fde.fd = socket_get_fd(sock->sock); fde.flags = EVENT_FD_READ; fde.handler = smbcli_transport_event_handler; fde.private = transport; @@ -501,7 +501,7 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) { smbcli_transport_process_send(transport); smbcli_transport_process_recv(transport); - if (transport->socket->fd == -1) { + if (transport->socket->sock == NULL) { return False; } return True; @@ -515,7 +515,7 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) void smbcli_transport_send(struct smbcli_request *req) { /* check if the transport is dead */ - if (req->transport->socket->fd == -1) { + if (req->transport->socket->sock == NULL) { req->state = SMBCLI_REQUEST_ERROR; req->status = NT_STATUS_NET_WRITE_FAULT; return; -- cgit From 28c3dcf6a3be18fd9fcb56bff039925a1244508d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 11:58:09 +0000 Subject: r3319: fixed a bug in the client library found by the new non-block testing code (This used to be commit 1e62aa262aac1c8e3676caac7b65086d21b7a01e) --- source4/libcli/raw/clitransport.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index d82d97a0d9..3335f557e5 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -443,14 +443,7 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) transport->recv_buffer.header + transport->recv_buffer.received, NBT_HDR_SIZE - transport->recv_buffer.received); - if (ret == 0) { - smbcli_transport_dead(transport); - return; - } if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) { - return; - } smbcli_transport_dead(transport); return; } @@ -478,9 +471,6 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) transport->recv_buffer.req_size - transport->recv_buffer.received); if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) { - return; - } smbcli_transport_dead(transport); return; } -- cgit From e481385391a25c19d82ce93fbec11a973cf82e9f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 12:46:59 +0000 Subject: r3322: fixed a bunch of warnings in the build, including one case where it was a real bug (This used to be commit 02d5d0f685e44bd66aff4a007f0bf34c8f915574) --- source4/libcli/auth/clikrb5.c | 2 +- source4/libcli/auth/ntlmssp_parse.c | 4 ++-- source4/libcli/auth/spnego.c | 2 +- source4/libcli/auth/spnego.h | 2 +- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/raw/rawsearch.c | 5 ++++- source4/libcli/util/asn1.c | 4 ++-- 7 files changed, 12 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 78492d2352..c3ea33aaec 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -386,7 +386,7 @@ cleanup_princ: { static krb5_data kdata; - kdata.data = krb5_principal_get_comp_string(context, principal, i); + kdata.data = discard_const(krb5_principal_get_comp_string(context, principal, i)); kdata.length = strlen(kdata.data); return &kdata; } diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 22ed783666..c36bb6a4fc 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -64,7 +64,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, case 'U': s = va_arg(ap, char *); head_size += 8; - n = push_ucs2_talloc(pointers, &pointers[i].data, s); + n = push_ucs2_talloc(pointers, (void **)&pointers[i].data, s); if (n == -1) { return False; } @@ -87,7 +87,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, n = va_arg(ap, int); intargs[i] = n; s = va_arg(ap, char *); - n = push_ucs2_talloc(pointers, &pointers[i].data, s); + n = push_ucs2_talloc(pointers, (void **)&pointers[i].data, s); if (n == -1) { return False; } diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 85d77992fa..2779f47474 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -483,7 +483,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA { /* The server offers a list of mechanisms */ - char *my_mechs[] = {NULL, NULL}; + const char *my_mechs[] = {NULL, NULL}; NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; if (!in.length) { diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index 926cb7f88d..3b9d148c67 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -41,7 +41,7 @@ enum spnego_negResult { }; struct spnego_negTokenInit { - char **mechTypes; + const char **mechTypes; int reqFlags; DATA_BLOB mechToken; DATA_BLOB mechListMIC; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 89155451da..dd21eb89ea 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -548,7 +548,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c of bytes consumed in the packet is returned */ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, uint_t flags) + char **dest, const char *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index df44dbffa4..dd8904dfd1 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -42,6 +42,8 @@ static void smb_raw_search_backend(struct smbcli_request *req, p = req->in.data + 3; for (i=0; i < count; i++) { + char *name; + search_data.search.id.reserved = CVAL(p, 0); memcpy(search_data.search.id.name, p+1, 11); search_data.search.id.handle = CVAL(p, 12); @@ -51,7 +53,8 @@ static void smb_raw_search_backend(struct smbcli_request *req, search_data.search.write_time = raw_pull_dos_date(req->transport, p + 22); search_data.search.size = IVAL(p, 26); - smbcli_req_pull_ascii(req, mem_ctx, &search_data.search.name, p+30, 13, STR_ASCII); + smbcli_req_pull_ascii(req, mem_ctx, &name, p+30, 13, STR_ASCII); + search_data.search.name = name; if (!callback(private, &search_data)) { break; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 15d9243acd..e03b1d5f39 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -494,7 +494,7 @@ int asn1_tag_remaining(ASN1_DATA *data) } /* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID(ASN1_DATA *data, char **OID) +BOOL asn1_read_OID(ASN1_DATA *data, const char **OID) { uint8_t b; char *tmp_oid = NULL; @@ -525,7 +525,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) /* check that the next object ID is correct */ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) { - char *id; + const char *id; if (!asn1_read_OID(data, &id)) return False; -- cgit From a6ae640313a47ac2950c0948e4385fa934a5ef09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 13:19:39 +0000 Subject: r3323: more warning reductions (This used to be commit 5921587ec26e4892efc678421277e4969417d7f5) --- source4/libcli/auth/spnego_parse.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 07dba61dde..12d3d05734 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -349,10 +349,6 @@ BOOL spnego_free_data(struct spnego_data *spnego) switch(spnego->type) { case SPNEGO_NEG_TOKEN_INIT: if (spnego->negTokenInit.mechTypes) { - int i; - for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - talloc_free(spnego->negTokenInit.mechTypes[i]); - } talloc_free(spnego->negTokenInit.mechTypes); } data_blob_free(&spnego->negTokenInit.mechToken); -- cgit From 1331667abf1b45abe40353ce70978294314d1a63 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Oct 2004 21:00:38 +0000 Subject: r3331: Add string descriptions for a couple more WERROR's (This used to be commit 1d374cdeb09b856449287cf12a77b23296c82a1d) --- source4/libcli/util/doserr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index c8e0e89078..8f997cf092 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -68,9 +68,19 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, + { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, + { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE }, + { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE }, + { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { NULL, W_ERROR(0) } }; + + + +/* DFS errors */ + /***************************************************************************** returns a windows error message. not amazingly helpful, but better than a number. *****************************************************************************/ -- cgit From b2df91639065168643ea8b921f24b879daf2e71f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 05:31:35 +0000 Subject: r3352: make smbcli_read() and smbcli_write() work with very small negotiated SMB buffer sizes (This used to be commit 320ca0214d97dc6cebb00ddc98a1eb71e2b4c917) --- source4/libcli/clireadwrite.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 45c99f4f89..f8220526e3 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -42,8 +42,7 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, char *buf, off_t offset, * Set readsize to the maximum size we can handle in one readX, * rounded down to a multiple of 1024. */ - readsize = (tree->session->transport->negotiate.max_xmit - - (MIN_SMB_SIZE+32)) & ~1023; + readsize = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)); if (readsize > 0xFFFF) readsize = 0xFFFF; while (total < size) { @@ -87,7 +86,7 @@ ssize_t smbcli_write(struct smbcli_tree *tree, const uint8_t *buf, off_t offset, size_t size) { union smb_write parms; - int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)) & ~1023; + int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)); ssize_t total = 0; if (size == 0) { -- cgit From 072dfad0afc9940c4c51cbecad9b3acf0cc38844 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 06:01:00 +0000 Subject: r3354: honor "max xmit" and "max mux" from smb.conf in our client code. This is important as it allows the test suite to exercise the multiple reply logic in smbd for trans2 search replies. (This used to be commit 865159016ab1e806465a55697444228fb3fa286e) --- source4/libcli/raw/clisession.c | 12 ++++++------ source4/libcli/raw/clitransport.c | 5 ++++- source4/libcli/raw/rawnegotiate.c | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 431d225021..5d769f9e32 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -263,8 +263,8 @@ static NTSTATUS smb_raw_session_setup_generic_old(struct smbcli_session *session /* use the old interface */ s2.generic.level = RAW_SESSSETUP_OLD; - s2.old.in.bufsize = ~0; - s2.old.in.mpx_max = 50; + s2.old.in.bufsize = session->transport->options.max_xmit; + s2.old.in.mpx_max = session->transport->options.max_mux; s2.old.in.vc_num = 1; s2.old.in.sesskey = parms->generic.in.sesskey; s2.old.in.domain = parms->generic.in.domain; @@ -311,8 +311,8 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct smbcli_session *session union smb_sesssetup s2; s2.generic.level = RAW_SESSSETUP_NT1; - s2.nt1.in.bufsize = ~0; - s2.nt1.in.mpx_max = 50; + s2.nt1.in.bufsize = session->transport->options.max_xmit; + s2.nt1.in.mpx_max = session->transport->options.max_mux; s2.nt1.in.vc_num = 1; s2.nt1.in.sesskey = parms->generic.in.sesskey; s2.nt1.in.capabilities = parms->generic.in.capabilities; @@ -371,8 +371,8 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess const char *chosen_oid; s2.generic.level = RAW_SESSSETUP_SPNEGO; - s2.spnego.in.bufsize = ~0; - s2.spnego.in.mpx_max = 50; + s2.spnego.in.bufsize = session->transport->options.max_xmit; + s2.spnego.in.mpx_max = session->transport->options.max_mux; s2.spnego.in.vc_num = 1; s2.spnego.in.sesskey = parms->generic.in.sesskey; s2.spnego.in.capabilities = parms->generic.in.capabilities; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 3335f557e5..c0ec5d70fe 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -76,7 +76,10 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) transport->socket = talloc_reference(transport, sock); transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(); - transport->negotiate.max_xmit = ~0; + transport->options.max_xmit = lp_max_xmit(); + transport->options.max_mux = lp_maxmux(); + + transport->negotiate.max_xmit = transport->options.max_xmit; smbcli_init_signing(transport); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index fdc1d0eb60..f99b9741f4 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -169,7 +169,7 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) /* the old core protocol */ transport->negotiate.sec_mode = 0; transport->negotiate.server_time = time(NULL); - transport->negotiate.max_xmit = ~0; + transport->negotiate.max_xmit = transport->options.max_xmit; transport->negotiate.server_zone = get_time_zone(transport->negotiate.server_time); } -- cgit From dbf03959244c392073281c10badd2095397ad2f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 07:29:26 +0000 Subject: r3357: removed the need to use TDB_CLEAR_IF_FIRST in Samba4. We found a few months ago that TDB_CLEAR_IF_FIRST is extremely inefficient for large numbers of connections, due to a fundamental limitation in the way posix byte range locking is implemented. Rather than the nasty workaround we had for Samba3, we now have a single "cleanup tmp files" function that runs when smbd starts. That deletes the tmp tdbs, so TDB_CLEAR_IF_FIRST is not needed at all. (This used to be commit ffa285bc783c775a2d53a58fb691ca339e6c76ae) --- source4/libcli/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c index e109c9d5bf..19a02bdeb8 100644 --- a/source4/libcli/unexpected.c +++ b/source4/libcli/unexpected.c @@ -50,7 +50,7 @@ void unexpected_packet(struct packet_struct *p) mem_ctx = talloc_init("receive_unexpected"); if (!mem_ctx) return; tdbd = tdb_wrap_open(NULL, lock_path(mem_ctx, "unexpected.tdb"), 0, - TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + TDB_DEFAULT, O_RDWR | O_CREAT, 0644); talloc_destroy(mem_ctx); if (!tdbd) { -- cgit From 659332794871c64470fd23b5a15e1f45fcb78a84 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Oct 2004 08:31:27 +0000 Subject: r3358: Try to put all the basic struct dom_sid manipulation functions in one place. (I always have trouble finding one half or the other). Andrew Bartlett (This used to be commit 224b59edba7c00ad515b4c5e3e9a886700247ad4) --- source4/libcli/util/dom_sid.c | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c index c2d188abec..1faf3debab 100644 --- a/source4/libcli/util/dom_sid.c +++ b/source4/libcli/util/dom_sid.c @@ -22,6 +22,39 @@ #include "includes.h" +/* + convert a dom_sid to a string +*/ +char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +{ + int i, ofs, maxlen; + uint32_t ia; + char *ret; + + if (!sid) { + return talloc_strdup(mem_ctx, "(NULL SID)"); + } + + maxlen = sid->num_auths * 11 + 25; + ret = talloc(mem_ctx, maxlen); + if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); + + ia = (sid->id_auth[5]) + + (sid->id_auth[4] << 8 ) + + (sid->id_auth[3] << 16) + + (sid->id_auth[2] << 24); + + ofs = snprintf(ret, maxlen, "S-%u-%lu", + (uint_t)sid->sid_rev_num, (unsigned long)ia); + + for (i = 0; i < sid->num_auths; i++) { + ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); + } + + return ret; +} + + /* convert a string to a dom_sid, returning a talloc'd dom_sid */ @@ -121,3 +154,27 @@ struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, struct dom_sid *dom_sid) return ret; } +/* + add a rid to a domain dom_sid to make a full dom_sid +*/ +struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, + const struct dom_sid *domain_sid, + uint32_t rid) +{ + struct dom_sid *sid; + + sid = talloc_p(mem_ctx, struct dom_sid); + if (!sid) return NULL; + + *sid = *domain_sid; + /*TODO: use realloc! */ + sid->sub_auths = talloc_array_p(mem_ctx, uint32_t, sid->num_auths+1); + if (!sid->sub_auths) { + return NULL; + } + memcpy(sid->sub_auths, domain_sid->sub_auths, sid->num_auths*sizeof(uint32_t)); + sid->sub_auths[sid->num_auths] = rid; + sid->num_auths++; + return sid; +} + -- cgit From 09d0b152b7bd85aa01898af81bd166a7673ab886 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 08:38:59 +0000 Subject: r3360: improved the deletion of tmp files. smbd now puts all tmp files in var/locks/smbd.tmp/ and deletes that dir on startup. (This used to be commit 7e942e7f1bd2c293a0e6648df43a96f8b8a2a295) --- source4/libcli/unexpected.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c index 19a02bdeb8..264b9d7b33 100644 --- a/source4/libcli/unexpected.c +++ b/source4/libcli/unexpected.c @@ -44,15 +44,13 @@ void unexpected_packet(struct packet_struct *p) struct unexpected_key key; char buf[1024]; int len=0; - TALLOC_CTX *mem_ctx; if (!tdbd) { - mem_ctx = talloc_init("receive_unexpected"); - if (!mem_ctx) return; - tdbd = tdb_wrap_open(NULL, lock_path(mem_ctx, "unexpected.tdb"), 0, + char *path = smbd_tmp_path(NULL, "unexpected.tdb"); + tdbd = tdb_wrap_open(NULL, path, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644); - talloc_destroy(mem_ctx); + talloc_free(path); if (!tdbd) { return; } @@ -150,13 +148,12 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, const char *mailslot_name) { struct tdb_wrap *tdb2; - TALLOC_CTX *mem_ctx; + char *path; - mem_ctx = talloc_init("receive_unexpected"); - if (!mem_ctx) return NULL; - tdb2 = tdb_wrap_open(mem_ctx, lock_path(mem_ctx, "unexpected.tdb"), 0, 0, O_RDONLY, 0); + path = smbd_tmp_path(NULL, "unexpected.tdb"); + tdb2 = tdb_wrap_open(NULL, path, 0, 0, O_RDONLY, 0); + talloc_free(path); if (!tdb2) { - talloc_destroy(mem_ctx); return NULL; } @@ -167,7 +164,7 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, tdb_traverse(tdb2->tdb, traverse_match, NULL); - talloc_destroy(mem_ctx); + talloc_free(tdb2); return matched_packet; } -- cgit From 85796280f4e9a4f8ac6a1c327c13c7dbef9ce424 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Oct 2004 09:15:41 +0000 Subject: r3361: Allow Samba4 (I'm interested in ntlm_auth in particular) to use Samba3's winbind. This is also the start of domain membership code in Samba4, as we now (partially) parse the info3, and use it like Samba3 does. Andrew Bartlett (This used to be commit c1b7303c1c7d9fb815006c3bd2af20a0010d15a8) --- source4/libcli/auth/gensec_ntlmssp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 48438aaae1..f75e7b4d73 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -115,8 +115,11 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, return nt_status; } - nt_status = gensec_ntlmssp_state->auth_context->check_ntlm_password(gensec_ntlmssp_state->auth_context, - user_info, &gensec_ntlmssp_state->server_info); + nt_status = gensec_ntlmssp_state-> + auth_context->check_ntlm_password(gensec_ntlmssp_state->auth_context, + user_info, + gensec_ntlmssp_state, + &gensec_ntlmssp_state->server_info); free_user_info(&user_info); -- cgit From 9a09b41b013e957fb7ce9cd644ac1f6d1fd26528 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Oct 2004 09:58:23 +0000 Subject: r3365: Fill in the user and primary group SIDs into the 'server info' before the session info. Andrew Bartlett (This used to be commit 5db5c30ebedca1fee8924a9416bcb94ed13af372) --- source4/libcli/auth/gensec_krb5.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 1ce05b519e..ea70b471e5 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -616,8 +616,8 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security *session_info_out = NULL; - /* IF we have the PAC - otherwise (TODO) we need to get this - * data from elsewere - local ldb, or lookup of some + /* IF we have the PAC - otherwise we need to get this + * data from elsewere - local ldb, or (TODO) lookup of some * kind... */ principal = talloc_strdup(gensec_krb5_state, gensec_krb5_state->peer_principal); @@ -666,14 +666,17 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security } - sid = dom_sid_dup(session_info, logon_info->dom_sid); - ptoken->user_sids[0] = dom_sid_add_rid(session_info, sid, logon_info->user_rid); + sid = dom_sid_dup(server_info, logon_info->dom_sid); + server_info->user_sid = dom_sid_add_rid(server_info, sid, logon_info->user_rid); + sid = dom_sid_dup(server_info, logon_info->dom_sid); + server_info->primary_group_sid = dom_sid_add_rid(server_info, sid, logon_info->group_rid); + + ptoken->user_sids[0] = talloc_reference(session_info, server_info->user_sid); ptoken->num_sids++; - sid = dom_sid_dup(session_info, logon_info->dom_sid); - ptoken->user_sids[1] = dom_sid_add_rid(session_info, sid, logon_info->group_rid); + ptoken->user_sids[1] = talloc_reference(session_info, server_info->primary_group_sid); ptoken->num_sids++; - - for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) { + + for (;ptoken->num_sids < (logon_info->groups_count + 2); ptoken->num_sids++) { sid = dom_sid_dup(session_info, logon_info->dom_sid); ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info, sid, -- cgit From ad8c4ae941047aa7409ff0d8d10de721f5ff0659 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Oct 2004 01:22:52 +0000 Subject: r3380: - changed the default behaviour of server signing. We now have a default setting of "server signing = auto", which means to offer signing only if we have domain logons enabled (ie. we are a DC). This is a better match for what windows clients want, as unfortunately windows clients always use signing if it is offered, and when they use signing they not only go slower because of the signing itself, they also disable large readx/writex support, so they end up sending very small IOs for. - changed the default max xmit again, this time matching longhorn, which uses 12288. That seems to be a fairly good compromise value. (This used to be commit e63edc81716fefd58a3be25deb3b25e45471f196) --- source4/libcli/raw/smb_signing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index e1d7b071f2..2a0c64f598 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -394,6 +394,7 @@ BOOL smbcli_init_signing(struct smbcli_transport *transport) transport->negotiate.sign_info.allow_smb_signing = False; break; case SMB_SIGNING_SUPPORTED: + case SMB_SIGNING_AUTO: transport->negotiate.sign_info.allow_smb_signing = True; break; case SMB_SIGNING_REQUIRED: -- cgit From 39883a90cf3ecabfc39e68e8b1d3265a4026d25c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Oct 2004 02:17:03 +0000 Subject: r3383: avoid multi-part SMBtrans and SMBtrans2 replies until our client library can handle them properly (they are difficult to do in an async fashion). By choosing trans.in.max_data to fix in the negotiated buffer size a server won't send us multi-part replies. I notice that windows seems to avoid them too :) (This used to be commit e23edf762cace35f937959c9ffbef718431a79b9) --- source4/libcli/raw/rawacl.c | 2 +- source4/libcli/raw/rawfileinfo.c | 4 ++-- source4/libcli/raw/rawfsinfo.c | 2 +- source4/libcli/raw/rawsearch.c | 8 ++++---- source4/libcli/raw/rawtrans.c | 12 ++++++++++++ 5 files changed, 20 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 20e6d6df31..9b4f2db3b2 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -31,7 +31,7 @@ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, nt.in.max_setup = 0; nt.in.max_param = 4; - nt.in.max_data = 0x10000; + nt.in.max_data = smb_raw_max_trans_data(tree, 4); nt.in.setup_count = 0; nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; nt.in.setup = NULL; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index cbb666b7ce..a0ee7891bf 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -291,7 +291,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); tp.in.max_param = 2; - tp.in.max_data = 0xFFFF; + tp.in.max_data = smb_raw_max_trans_data(tree, 2); tp.in.setup = &setup; tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); @@ -344,7 +344,7 @@ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tre tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); tp.in.max_param = 2; - tp.in.max_data = 0xFFFF; + tp.in.max_data = smb_raw_max_trans_data(tree, 2); tp.in.setup = &setup; tp.in.params = data_blob_talloc(mem_ctx, NULL, 6); diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index aefe8e3085..49378887fa 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -77,7 +77,7 @@ static struct smbcli_request *smb_raw_qfsinfo_send(struct smbcli_tree *tree, tp.in.timeout = 0; tp.in.setup_count = 1; tp.in.max_param = 0; - tp.in.max_data = 0x1000; /* plenty for all possible QFS levels */ + tp.in.max_data = smb_raw_max_trans_data(tree, 0); tp.in.setup = &setup; tp.in.data = data_blob(NULL, 0); tp.in.timeout = 0; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index dd8904dfd1..120a42f0d6 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -206,8 +206,8 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, tp.in.timeout = 0; tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); - tp.in.max_param = 1024; - tp.in.max_data = 8192; + tp.in.max_param = 10; + tp.in.max_data = smb_raw_max_trans_data(tree, 10); tp.in.setup = &setup; tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); @@ -258,8 +258,8 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, tp.in.timeout = 0; tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); - tp.in.max_param = 1024; - tp.in.max_data = 8192; + tp.in.max_param = 10; + tp.in.max_data = smb_raw_max_trans_data(tree, 10); tp.in.setup = &setup; tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index e6c928e3ed..21e20d00e0 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -531,3 +531,15 @@ NTSTATUS smb_raw_nttrans(struct smbcli_tree *tree, return smb_raw_nttrans_recv(req, mem_ctx, parms); } + +/* + work out the maximum data size for a trans request while avoiding + multi-part replies + + TODO: we only need to avoid multi-part replies because the + multi-part trans receive code is broken. +*/ +size_t smb_raw_max_trans_data(struct smbcli_tree *tree, size_t param_size) +{ + return tree->session->transport->options.max_xmit - (70 + param_size); +} -- cgit From 1dc8e52f91797bb6953301cc1ebd9bb5a60626ea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Oct 2004 04:56:27 +0000 Subject: r3385: when discarding a unmatched reply print the command type to help debugging (This used to be commit 91139ed8d41a1d4b99379142b3e09c6d0a8ff159) --- source4/libcli/raw/clitransport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index c0ec5d70fe..9d2dd49985 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -350,7 +350,8 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) } if (!req) { - DEBUG(1,("Discarding unmatched reply with mid %d\n", mid)); + DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", + mid, CVAL(hdr, HDR_COM))); goto error; } -- cgit From feff2e9cbdd2e3e8e9db5d9b01b5d5cec42943c0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Oct 2004 11:07:28 +0000 Subject: r3390: fixed schannel server side support. RPC-SCHANNEL now works against Samba4. (This used to be commit 01f5c1c72d9fc8f21029adc586154b0c54f76c9e) --- source4/libcli/auth/gensec.h | 3 ++- source4/libcli/auth/schannel.c | 27 ++++++++++++--------------- source4/libcli/auth/schannel.h | 35 ----------------------------------- 3 files changed, 14 insertions(+), 51 deletions(-) delete mode 100644 source4/libcli/auth/schannel.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 7020435f44..624c7ebe1d 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -108,4 +108,5 @@ struct gensec_critical_sizes { }; - +/* pre-declare schannel structure for schannel backend */ +struct schannel_state; diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 2e752f0172..a99822534b 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -22,6 +22,16 @@ #include "includes.h" +struct schannel_state { + TALLOC_CTX *mem_ctx; + uint8_t session_key[16]; + uint32_t seq_num; + BOOL initiator; +}; + +#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } + /******************************************************************* Encode or Decode the sequence number (which is symmetric) ********************************************************************/ @@ -209,13 +219,7 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); - if (!state->signature.data) { - state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); - if (!state->signature.data) { - return NT_STATUS_NO_MEMORY; - } - } - (*sig) = state->signature; + (*sig) = data_blob_talloc(state->mem_ctx, NULL, 32); memcpy(sig->data, netsec_sig, 8); memcpy(sig->data+8, seq_num, 8); @@ -252,13 +256,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); - if (!state->signature.data) { - state->signature = data_blob_talloc(state->mem_ctx, NULL, 32); - if (!state->signature.data) { - return NT_STATUS_NO_MEMORY; - } - } - (*sig) = state->signature; + (*sig) = data_blob_talloc(state->mem_ctx, NULL, 32); memcpy(sig->data, netsec_sig, 8); memcpy(sig->data+8, seq_num, 8); @@ -307,7 +305,6 @@ NTSTATUS schannel_start(struct schannel_state **state, (*state)->mem_ctx = mem_ctx; memcpy((*state)->session_key, session_key, 16); (*state)->initiator = initiator; - (*state)->signature = data_blob(NULL, 0); (*state)->seq_num = 0; return NT_STATUS_OK; diff --git a/source4/libcli/auth/schannel.h b/source4/libcli/auth/schannel.h deleted file mode 100644 index b074b104fb..0000000000 --- a/source4/libcli/auth/schannel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - schannel library code - - Copyright (C) Andrew Tridgell 2004 - - 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" - -struct schannel_state { - TALLOC_CTX *mem_ctx; - uint8_t session_key[16]; - uint32_t seq_num; - BOOL initiator; - DATA_BLOB signature; -}; - -#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } -#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } - -- cgit From 173dda6bf4db2faf29a1845ce2b1028105511dab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Oct 2004 11:37:17 +0000 Subject: r3391: fixed some memory leaks in the schannel code (This used to be commit eb3366d3667ddddf7ab5eae5d1fbc5de86c41072) --- source4/libcli/auth/schannel.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index a99822534b..2f20a3e906 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -23,7 +23,6 @@ #include "includes.h" struct schannel_state { - TALLOC_CTX *mem_ctx; uint8_t session_key[16]; uint32_t seq_num; BOOL initiator; @@ -219,7 +218,7 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); - (*sig) = data_blob_talloc(state->mem_ctx, NULL, 32); + (*sig) = data_blob_talloc(mem_ctx, NULL, 32); memcpy(sig->data, netsec_sig, 8); memcpy(sig->data+8, seq_num, 8); @@ -256,7 +255,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, netsec_deal_with_seq_num(state, digest_final, seq_num); - (*sig) = data_blob_talloc(state->mem_ctx, NULL, 32); + (*sig) = data_blob_talloc(mem_ctx, NULL, 32); memcpy(sig->data, netsec_sig, 8); memcpy(sig->data+8, seq_num, 8); @@ -277,7 +276,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, void schannel_end(struct schannel_state **state) { if (*state) { - talloc_destroy((*state)->mem_ctx); + talloc_free(*state); (*state) = NULL; } } @@ -289,20 +288,11 @@ NTSTATUS schannel_start(struct schannel_state **state, const uint8_t session_key[16], BOOL initiator) { - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("schannel_state"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - (*state) = talloc_p(mem_ctx, struct schannel_state); + (*state) = talloc_p(NULL, struct schannel_state); if (!(*state)) { - talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } - (*state)->mem_ctx = mem_ctx; memcpy((*state)->session_key, session_key, 16); (*state)->initiator = initiator; (*state)->seq_num = 0; -- cgit From b24fcfc1aadf56130f9f2f2371282c0c399611c2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 31 Oct 2004 03:26:30 +0000 Subject: r3400: - allow callers to control the flags2 field in raw packets - added testing of the FLAGS2_READ_PERMIT_EXECUTE bit in the ntdeny tests (This used to be commit adf4a682705871186f3b77ea6d417942445fc5d3) --- source4/libcli/raw/clisession.c | 22 ++++++++++++++++++++++ source4/libcli/raw/rawrequest.c | 22 ++-------------------- 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 5d769f9e32..9c73c07831 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -33,6 +33,8 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) { struct smbcli_session *session; + uint16_t flags2; + uint32_t capabilities; session = talloc_p(transport, struct smbcli_session); if (!session) { @@ -44,6 +46,26 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; + + capabilities = transport->negotiate.capabilities; + + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + + if (capabilities & CAP_UNICODE) { + flags2 |= FLAGS2_UNICODE_STRINGS; + } + if (capabilities & CAP_STATUS32) { + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + } + if (capabilities & CAP_EXTENDED_SECURITY) { + flags2 |= FLAGS2_EXTENDED_SECURITY; + } + if (session->transport->negotiate.sign_info.doing_signing) { + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + } + + session->flags2 = flags2; + return session; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index dd21eb89ea..26604cbcd4 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -139,35 +139,17 @@ struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *t way. This interface is used before a session is setup. */ struct smbcli_request *smbcli_request_setup_session(struct smbcli_session *session, - uint8_t command, uint_t wct, uint_t buflen) + uint8_t command, uint_t wct, uint_t buflen) { struct smbcli_request *req; - uint16_t flags2; - uint32_t capabilities; req = smbcli_request_setup_transport(session->transport, command, wct, buflen); if (!req) return NULL; req->session = session; - - flags2 = FLAGS2_LONG_PATH_COMPONENTS; - capabilities = session->transport->negotiate.capabilities; - - if (capabilities & CAP_UNICODE) { - flags2 |= FLAGS2_UNICODE_STRINGS; - } - if (capabilities & CAP_STATUS32) { - flags2 |= FLAGS2_32_BIT_ERROR_CODES; - } - if (capabilities & CAP_EXTENDED_SECURITY) { - flags2 |= FLAGS2_EXTENDED_SECURITY; - } - if (session->transport->negotiate.sign_info.doing_signing) { - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - } - SSVAL(req->out.hdr, HDR_FLG2, flags2); + SSVAL(req->out.hdr, HDR_FLG2, session->flags2); SSVAL(req->out.hdr, HDR_PID, session->pid & 0xFFFF); SSVAL(req->out.hdr, HDR_PIDHIGH, session->pid >> 16); SSVAL(req->out.hdr, HDR_UID, session->vuid); -- cgit From 9f1210a243654fd6d94acdef83f468a33c1b3b3f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 01:03:22 +0000 Subject: r3419: moved the libcli/raw structures into libcli/raw/libcliraw.h and made them private (This used to be commit 386ac565c452ede1d74e06acb401ca9db99d3ff3) --- source4/libcli/cliconnect.c | 1 + source4/libcli/clifile.c | 1 + source4/libcli/clilist.c | 1 + source4/libcli/climessage.c | 1 + source4/libcli/clireadwrite.c | 1 + source4/libcli/raw/clioplock.c | 1 + source4/libcli/raw/clisession.c | 1 + source4/libcli/raw/clisocket.c | 1 + source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/clitree.c | 1 + source4/libcli/raw/libcliraw.h | 286 ++++++++++++++++++++++++++++++++++++ source4/libcli/raw/rawacl.c | 1 + source4/libcli/raw/rawdate.c | 1 + source4/libcli/raw/raweas.c | 1 + source4/libcli/raw/rawfile.c | 1 + source4/libcli/raw/rawfileinfo.c | 1 + source4/libcli/raw/rawfsinfo.c | 1 + source4/libcli/raw/rawioctl.c | 1 + source4/libcli/raw/rawnegotiate.c | 1 + source4/libcli/raw/rawnotify.c | 1 + source4/libcli/raw/rawreadwrite.c | 1 + source4/libcli/raw/rawrequest.c | 1 + source4/libcli/raw/rawsearch.c | 1 + source4/libcli/raw/rawsetfileinfo.c | 1 + source4/libcli/raw/rawtrans.c | 1 + source4/libcli/raw/smb_signing.c | 1 + source4/libcli/util/clierror.c | 1 + source4/libcli/util/cliutil.c | 2 + 28 files changed, 314 insertions(+) create mode 100644 source4/libcli/raw/libcliraw.h (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 8e7e128a4e..c3bc43aa8c 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* wrapper around smbcli_sock_connect() diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index e8b49f71df..b233064085 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** Hard/Symlink a file (UNIX extensions). diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 84d96d62f4..dde2a7befa 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" struct search_private { file_info *dirlist; diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index dde512159e..7e3a50b842 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index f8220526e3..6b6cb2f2a2 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** Read size bytes at offset offset using SMBreadX. diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index 6ae21a08f4..f26aa0c5f2 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** send an ack for an oplock break request diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 9c73c07831..14018f676c 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ req = smbcli_request_setup_session(session, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 907206a5e8..c641f8bf12 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* create a smbcli_socket context diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 9d2dd49985..a6e8071a05 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" static void smbcli_transport_process_recv(struct smbcli_transport *transport); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 77fe0ebe2f..daa8549099 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h new file mode 100644 index 0000000000..48abc82a68 --- /dev/null +++ b/source4/libcli/raw/libcliraw.h @@ -0,0 +1,286 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + Copyright (C) Jeremy Allison 1998 + Copyright (C) James Myers 2003 + + 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. +*/ + +struct smbcli_tree; /* forward declare */ +struct smbcli_request; /* forward declare */ +struct smbcli_session; /* forward declare */ +struct smbcli_transport; /* forward declare */ + +/* context that will be and has been negotiated between the client and server */ +struct smbcli_negotiate { + /* + * negotiated maximum transmit size - this is given to us by the server + */ + uint32_t max_xmit; + + /* maximum number of requests that can be multiplexed */ + uint16_t max_mux; + + /* the negotiatiated protocol */ + enum protocol_types protocol; + + uint8_t sec_mode; /* security mode returned by negprot */ + uint8_t key_len; + DATA_BLOB server_guid; /* server_guid */ + DATA_BLOB secblob; /* cryptkey or negTokenInit blob */ + uint32_t sesskey; + + struct smb_signing_context sign_info; + + /* capabilities that the server reported */ + uint32_t capabilities; + + int server_zone; + time_t server_time; + uint_t readbraw_supported:1; + uint_t writebraw_supported:1; + + char *server_domain; +}; + +/* this is the context for a SMB socket associated with the socket itself */ +struct smbcli_socket { + struct in_addr dest_ip; + /* dest hostname (which may or may not be a DNS name) */ + char *hostname; + + /* the port used */ + int port; + + struct socket_context *sock; + + /* a count of the number of packets we have received. We + * actually only care about zero/non-zero at this stage */ + uint_t pkt_count; + + /* the network address of the client */ + char *client_addr; + + /* timeout for socket operations in milliseconds. */ + int timeout; +}; + +/* + this structure allows applications to control the behaviour of the + client library +*/ +struct smbcli_options { + uint_t use_oplocks:1; + uint_t use_level2_oplocks:1; + uint_t use_spnego:1; + uint32_t max_xmit; + uint16_t max_mux; +}; + +/* this is the context for the client transport layer */ +struct smbcli_transport { + /* socket level info */ + struct smbcli_socket *socket; + + /* the next mid to be allocated - needed for signing and + request matching */ + uint16_t next_mid; + + /* negotiated protocol information */ + struct smbcli_negotiate negotiate; + + /* options to control the behaviour of the client code */ + struct smbcli_options options; + + /* is a readbraw pending? we need to handle that case + specially on receiving packets */ + uint_t readbraw_pending:1; + + /* an idle function - if this is defined then it will be + called once every period seconds while we are waiting + for a packet */ + struct { + void (*func)(struct smbcli_transport *, void *); + void *private; + uint_t period; + } idle; + + /* the error fields from the last message */ + struct { + enum {ETYPE_NONE, ETYPE_DOS, ETYPE_NT, ETYPE_SOCKET, ETYPE_NBT} etype; + union { + struct { + uint8_t eclass; + uint16_t ecode; + } dos; + NTSTATUS nt_status; + enum {SOCKET_READ_TIMEOUT, + SOCKET_READ_EOF, + SOCKET_READ_ERROR, + SOCKET_WRITE_ERROR, + SOCKET_READ_BAD_SIG} socket_error; + uint_t nbt_error; + } e; + } error; + + struct { + /* a oplock break request handler */ + BOOL (*handler)(struct smbcli_transport *transport, + uint16_t tid, uint16_t fnum, uint8_t level, void *private); + /* private data passed to the oplock handler */ + void *private; + } oplock; + + /* a list of async requests that are pending for send on this connection */ + struct smbcli_request *pending_send; + + /* a list of async requests that are pending for receive on this connection */ + struct smbcli_request *pending_recv; + + /* remember the called name - some sub-protocols require us to + know the server name */ + struct nmb_name called; + + /* a buffer for partially received SMB packets. */ + struct { + uint8_t header[NBT_HDR_SIZE]; + size_t req_size; + size_t received; + uint8_t *buffer; + } recv_buffer; + + /* the event handle for waiting for socket IO */ + struct { + struct event_context *ctx; + struct fd_event *fde; + struct timed_event *te; + } event; +}; + +/* this is the context for the user */ + +/* this is the context for the session layer */ +struct smbcli_session { + /* transport layer info */ + struct smbcli_transport *transport; + + /* after a session setup the server provides us with + a vuid identifying the security context */ + uint16_t vuid; + + /* default pid for this session */ + uint32_t pid; + + /* the flags2 for each packet - this allows + the user to control these for torture testing */ + uint16_t flags2; + + DATA_BLOB user_session_key; + + /* the spnego context if we use extented security */ + struct gensec_security *gensec; +}; + +/* + smbcli_tree context: internal state for a tree connection. + */ +struct smbcli_tree { + /* session layer info */ + struct smbcli_session *session; + + uint16_t tid; /* tree id, aka cnum */ + char *device; + char *fs_type; +}; + + +/* + a client request moves between the following 4 states. +*/ +enum smbcli_request_state {SMBCLI_REQUEST_INIT, /* we are creating the request */ + SMBCLI_REQUEST_SEND, /* the request is in the outgoing socket Q */ + SMBCLI_REQUEST_RECV, /* we are waiting for a matching reply */ + SMBCLI_REQUEST_DONE, /* the request is finished */ + SMBCLI_REQUEST_ERROR}; /* a packet or transport level error has occurred */ + +/* the context for a single SMB request. This is passed to any request-context + * functions (similar to context.h, the server version). + * This will allow requests to be multi-threaded. */ +struct smbcli_request { + /* allow a request to be part of a list of requests */ + struct smbcli_request *next, *prev; + + /* each request is in one of 4 possible states */ + enum smbcli_request_state state; + + /* a request always has a transport context, nearly always has + a session context and usually has a tree context */ + struct smbcli_transport *transport; + struct smbcli_session *session; + struct smbcli_tree *tree; + + /* the flags2 from the SMB request, in raw form (host byte + order). Used to parse strings */ + uint16_t flags2; + + /* the NT status for this request. Set by packet receive code + or code detecting error. */ + NTSTATUS status; + + /* the sequence number of this packet - used for signing */ + uint_t seq_num; + + /* set if this is a one-way request, meaning we are not + expecting a reply from the server. */ + uint_t one_way_request:1; + + /* set this when the request should only increment the signing + counter by one */ + uint_t sign_single_increment:1; + + /* the mid of this packet - used to match replies */ + uint16_t mid; + + struct request_buffer in; + struct request_buffer out; + + /* information on what to do with a reply when it is received + asyncronously. If this is not setup when a reply is received then + the reply is discarded + + The private pointer is private to the caller of the client + library (the application), not private to the library + */ + struct { + void (*fn)(struct smbcli_request *); + void *private; + } async; +}; + +/* useful way of catching wct errors with file and line number */ +#define SMBCLI_CHECK_MIN_WCT(req, wcount) if ((req)->in.wct < (wcount)) { \ + DEBUG(1,("Unexpected WCT %d at %s(%d) - expected min %d\n", (req)->in.wct, __FILE__, __LINE__, wcount)); \ + req->status = NT_STATUS_INVALID_PARAMETER; \ + goto failed; \ +} + +#define SMBCLI_CHECK_WCT(req, wcount) if ((req)->in.wct != (wcount)) { \ + DEBUG(1,("Unexpected WCT %d at %s(%d) - expected %d\n", (req)->in.wct, __FILE__, __LINE__, wcount)); \ + req->status = NT_STATUS_INVALID_PARAMETER; \ + goto failed; \ +} diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 9b4f2db3b2..35c7ce2049 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** fetch file ACL (async send) diff --git a/source4/libcli/raw/rawdate.c b/source4/libcli/raw/rawdate.c index bfb7465bd5..db18a7a194 100644 --- a/source4/libcli/raw/rawdate.c +++ b/source4/libcli/raw/rawdate.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /******************************************************************* put a dos date into a buffer (time/date format) diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index e07fbcd288..da079c402b 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* work out how many bytes on the wire a ea list will consume. diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 3eb2ab49b2..92b995dd4a 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index a0ee7891bf..c844f923b8 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* local macros to make the code more readable */ #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \ diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 49378887fa..7cec93b6bc 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** Query FS Info - SMBdskattr call (async send) diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 798300451b..874d055013 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index f99b9741f4..da7bcabda9 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" static const struct { enum protocol_types prot; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 47553e735e..ea5fada1ee 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** change notify (async send) diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index bc9730f33d..4978514d26 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 26604cbcd4..5cf1621d2d 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 256 diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 120a42f0d6..4907eec70a 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** Old style search backend - process output. diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 2b525f2661..0c263ac082 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** Handle setfileinfo/setpathinfo trans2 backend. diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 21e20d00e0..32c12382f6 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 2a0c64f598..d348c202f5 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /*********************************************************** SMB signing - Common code before we set a new signing implementation diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index e7e413bbcb..1c82958ce2 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /*************************************************************************** diff --git a/source4/libcli/util/cliutil.c b/source4/libcli/util/cliutil.c index 3efa1dbbc9..ead09c4b41 100644 --- a/source4/libcli/util/cliutil.c +++ b/source4/libcli/util/cliutil.c @@ -20,6 +20,8 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" + /******************************************************************* Functions nicked from lib/util.c needed by client. *******************************************************************/ -- cgit From 475c958450c863a8fc530ccf5bb712bd7a6e8aa4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 05:46:52 +0000 Subject: r3425: got rid of a bunch of cruft from rewrite.h (This used to be commit 3f902f8d851d32fa81d89ed61bfda6edaea00984) --- source4/libcli/namequery.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 0f21e33b85..a9464718c5 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -21,6 +21,14 @@ #include "includes.h" +/* A netbios node status array element. */ +struct node_status { + char name[16]; + uint8_t type; + uint8_t flags; +}; + + /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; -- cgit From 90067934cd3195df80f8b1e614629d51fffcb38b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 10:30:34 +0000 Subject: r3428: switched to using minimal includes for the auto-generated RPC code. The thing that finally convinced me that minimal includes was worth pursuing for rpc was a compiler (tcc) that failed to build Samba due to reaching internal limits of the size of include files. Also the fact that includes.h.gch was 16MB, which really seems excessive. This patch brings it back to 12M, which is still too large, but better. Note that this patch speeds up compile times for both the pch and non-pch case. This change also includes the addition iof a "depends()" option in our IDL files, allowing you to specify that one IDL file depends on another. This capability was needed for the auto-includes generation. (This used to be commit b8f5fa8ac8e8725f3d321004f0aedf4246fc6b49) --- source4/libcli/auth/gensec_krb5.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index ea70b471e5..95cc6bacbe 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/ndr_krb5pac.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -- cgit From 652b8b34f8b326f79771b03e039cfa3c6ba3427e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 20:21:54 +0000 Subject: r3441: some include file cleanups and general housekeeping (This used to be commit 73ea8ee6c268371d05cf74160f2ad451dd2ae699) --- source4/libcli/clifile.c | 6 +-- source4/libcli/clitrans2.c | 4 +- source4/libcli/config.m4 | 1 - source4/libcli/util/cliutil.c | 109 ------------------------------------------ 4 files changed, 5 insertions(+), 115 deletions(-) delete mode 100644 source4/libcli/util/cliutil.c (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index b233064085..cdb29beb2d 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -429,7 +429,7 @@ NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint Lock a file with 64 bit offsets. ****************************************************************************/ NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, - SMB_OFF_T offset, SMB_OFF_T len, int timeout, + off_t offset, off_t len, int timeout, enum brl_type lock_type) { union smb_lock parms; @@ -464,8 +464,8 @@ NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, /**************************************************************************** Unlock a file with 64 bit offsets. ****************************************************************************/ -NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, SMB_OFF_T offset, - SMB_OFF_T len) +NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset, + off_t len) { union smb_lock parms; struct smb_lock_entry lock[1]; diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 7a37df6e1f..eb2c671a95 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -67,7 +67,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, size_t *size, uint16_t *mode, - SMB_INO_T *ino) + ino_t *ino) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; @@ -143,7 +143,7 @@ send a qfileinfo call NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum, uint16_t *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino) + time_t *w_time, ino_t *ino) { union smb_fileinfo parms; TALLOC_CTX *mem_ctx; diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 41f7ad6812..32a62dbb20 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -34,7 +34,6 @@ SMB_SUBSYSTEM(LIBCLI_UTILS,[], libcli/util/doserr.o libcli/util/errormap.o libcli/util/clierror.o - libcli/util/cliutil.o libcli/util/nterr.o libcli/util/smbdes.o libcli/util/smbencrypt.o diff --git a/source4/libcli/util/cliutil.c b/source4/libcli/util/cliutil.c deleted file mode 100644 index ead09c4b41..0000000000 --- a/source4/libcli/util/cliutil.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - Unix SMB/CIFS implementation. - client utility routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) James Myers 2003 - - 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 "libcli/raw/libcliraw.h" - -/******************************************************************* - Functions nicked from lib/util.c needed by client. -*******************************************************************/ - -/******************************************************************* - A wrapper that handles case sensitivity and the special handling - of the ".." name. -*******************************************************************/ - -BOOL mask_match(struct smbcli_state *cli, const char *string, char *pattern, BOOL is_case_sensitive) -{ - fstring p2, s2; - - if (strcmp(string,"..") == 0) - string = "."; - if (strcmp(pattern,".") == 0) - return False; - - if (is_case_sensitive) - return ms_fnmatch(pattern, string, - cli->transport->negotiate.protocol) == 0; - - fstrcpy(p2, pattern); - fstrcpy(s2, string); - strlower(p2); - strlower(s2); - return ms_fnmatch(p2, s2, cli->transport->negotiate.protocol) == 0; -} - -/**************************************************************************** - Put up a yes/no prompt. -****************************************************************************/ - -BOOL yesno(char *p) -{ - pstring ans; - printf("%s",p); - - if (!fgets(ans,sizeof(ans)-1,stdin)) - return(False); - - if (*ans == 'y' || *ans == 'Y') - return(True); - - return(False); -} - -/******************************************************************* - A readdir wrapper which just returns the file name. - ********************************************************************/ - -const char *readdirname(DIR *p) -{ - struct smb_dirent *ptr; - char *dname; - - if (!p) - return(NULL); - - ptr = (struct smb_dirent *)sys_readdir(p); - if (!ptr) - return(NULL); - - dname = ptr->d_name; - -#ifdef NEXT2 - if (telldir(p) < 0) - return(NULL); -#endif - -#ifdef HAVE_BROKEN_READDIR - /* using /usr/ucb/cc is BAD */ - dname = dname - 2; -#endif - - { - static pstring buf; - int len = NAMLEN(ptr); - memcpy(buf, dname, len); - buf[len] = 0; - dname = buf; - } - - return(dname); -} -- cgit From 284349482f5293a9a23d0f72d7c2aab46b55843b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 22:48:25 +0000 Subject: r3443: the next stage in the include files re-organisation. I have created the include/system/ directory, which will contain the wrappers for the system includes for logical subsystems. So far I have created include/system/kerberos.h and include/system/network.h, which contain all the system includes for kerberos code and networking code. These are the included in subsystems that need kerberos or networking respectively. Note that this method avoids the mess of #ifdef HAVE_XXX_H in every C file, instead each C module includes the include/system/XXX.h file for the logical system support it needs, and the details are kept isolated in include/system/ This patch also creates a "struct ipv4_addr" which replaces "struct in_addr" in our code. That avoids every C file needing to import all the system networking headers. (This used to be commit 2e25c71853f8996f73755277e448e7d670810349) --- source4/libcli/auth/clikrb5.c | 2 + source4/libcli/auth/gensec_krb5.c | 2 + source4/libcli/auth/kerberos.c | 1 + source4/libcli/auth/kerberos_verify.c | 2 + source4/libcli/cliconnect.c | 2 +- source4/libcli/ldap/ldap.c | 3 +- source4/libcli/namecache.c | 6 +-- source4/libcli/namequery.c | 93 ++++++++++++++++++----------------- source4/libcli/namequery_dc.c | 6 +-- source4/libcli/nmblib.c | 15 +++--- source4/libcli/raw/clisocket.c | 6 +-- source4/libcli/raw/libcliraw.h | 2 +- 12 files changed, 75 insertions(+), 65 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index c3ea33aaec..6f17bddfa0 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -20,6 +20,8 @@ */ #include "includes.h" +#include "system/network.h" +#include "system/kerberos.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 95cc6bacbe..f393ce09c1 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -24,6 +24,8 @@ */ #include "includes.h" +#include "system/kerberos.h" +#include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #undef DBGC_CLASS diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index b08c7f505c..06e89d4d33 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "system/kerberos.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 8d050182f9..8e598e2a66 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -23,6 +23,8 @@ */ #include "includes.h" +#include "system/kerberos.h" +#include "libcli/auth/kerberos.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index c3bc43aa8c..2949633b86 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -154,7 +154,7 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_state **ret_cli, const char *myname, const char *host, - struct in_addr *ip, + struct ipv4_addr *ip, const char *sharename, const char *devtype, const char *username, diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6e182c3843..1eb7888d41 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "system/network.h" /**************************************************************************** * @@ -1272,7 +1273,7 @@ struct ldap_connection *new_ldap_connection(void) BOOL ldap_connect(struct ldap_connection *conn, const char *url) { struct hostent *hp; - struct in_addr ip; + struct ipv4_addr ip; if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, &conn->port, &conn->ldaps)) diff --git a/source4/libcli/namecache.c b/source4/libcli/namecache.c index 9f4796af1a..8a4dab7522 100644 --- a/source4/libcli/namecache.c +++ b/source4/libcli/namecache.c @@ -113,7 +113,7 @@ static char* namecache_key(TALLOC_CTX *mem_ctx, const char *name, int name_type) **/ BOOL namecache_store(TALLOC_CTX *mem_ctx, const char *name, int name_type, - int num_names, struct in_addr *ip_list) + int num_names, struct ipv4_addr *ip_list) { time_t expiry; char *key, *value_string; @@ -129,7 +129,7 @@ BOOL namecache_store(TALLOC_CTX *mem_ctx, const char *name, int name_type, num_names, num_names == 1 ? "": "es", name, name_type)); for (i = 0; i < num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), + DEBUGADD(5, ("%s%s", sys_inet_ntoa(ip_list[i]), i == (num_names - 1) ? "" : ", ")); DEBUGADD(5, ("\n")); @@ -172,7 +172,7 @@ BOOL namecache_store(TALLOC_CTX *mem_ctx, const char *name, int name_type, * false if name isn't found in the cache or has expired **/ -BOOL namecache_fetch(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct in_addr **ip_list, +BOOL namecache_fetch(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct ipv4_addr **ip_list, int *num_names) { char *key, *value; diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index a9464718c5..7a2d697797 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "system/network.h" /* A netbios node status array element. */ struct node_status { @@ -83,7 +84,7 @@ do a NBT node status query on an open socket and return an array of structures holding the returned names or NULL if the query failed **************************************************************************/ struct node_status *node_status_query(int fd,struct nmb_name *name, - struct in_addr to_ip, int *num_names) + struct ipv4_addr to_ip, int *num_names) { BOOL found=False; int retries = 2; @@ -170,7 +171,7 @@ a servers name given its IP return the matched name in *name **************************************************************************/ -BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) +BOOL name_status_find(const char *q_name, int q_type, int type, struct ipv4_addr to_ip, char *name) { struct node_status *status = NULL; struct nmb_name nname; @@ -184,7 +185,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t } DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, - q_type, inet_ntoa(to_ip))); + q_type, sys_inet_ntoa(to_ip))); sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); if (sock == -1) @@ -213,7 +214,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not ")); if (result) - DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip))); + DEBUGADD(10, (", ip address is %s", sys_inet_ntoa(to_ip))); DEBUG(10, ("\n")); @@ -224,14 +225,14 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t /* comparison function used by sort_ip_list */ -int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +int ip_compare(struct ipv4_addr *ip1, struct ipv4_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); int i; for (i=0;is_addr, (uint8_t *)&ip.s_addr); @@ -256,13 +257,13 @@ int ip_compare(struct in_addr *ip1, struct in_addr *ip2) are at the top. This prevents the problem where a WINS server returns an IP that is not reachable from our subnet as the first match */ -static void sort_ip_list(struct in_addr *iplist, int count) +static void sort_ip_list(struct ipv4_addr *iplist, int count) { if (count <= 1) { return; } - qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); + qsort(iplist, count, sizeof(struct ipv4_addr), QSORT_CAST ip_compare); } @@ -272,9 +273,9 @@ static void sort_ip_list(struct in_addr *iplist, int count) *count will be set to the number of addresses returned. *timed_out is set if we failed by timing out ****************************************************************************/ -struct in_addr *name_query(int fd,const char *name,int name_type, +struct ipv4_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count, int *flags, + struct ipv4_addr to_ip, int *count, int *flags, BOOL *timed_out) { BOOL found=False; @@ -284,7 +285,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - struct in_addr *ip_list = NULL; + struct ipv4_addr *ip_list = NULL; if (lp_disable_netbios()) { DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type)); @@ -333,7 +334,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, while (1) { struct timeval tval2; - struct in_addr *tmp_ip_list; + struct ipv4_addr *tmp_ip_list; GetTimeOfDay(&tval2); if (TvalDiff(&tval,&tval2) > retry_time) { @@ -398,7 +399,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, continue; } - tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) + tmp_ip_list = (struct ipv4_addr *)Realloc( ip_list, sizeof( ip_list[0] ) * ( (*count) + nmb2->answers->rdlength/6 ) ); if (!tmp_ip_list) { @@ -409,10 +410,10 @@ struct in_addr *name_query(int fd,const char *name,int name_type, ip_list = tmp_ip_list; if (ip_list) { - DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); + DEBUG(2,("Got a positive name query response from %s ( ", sys_inet_ntoa(p2->ip))); for (i=0;ianswers->rdlength/6;i++) { putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); + DEBUGADD(2,("%s ",sys_inet_ntoa(ip_list[(*count)]))); (*count)++; } DEBUGADD(2,(")\n")); @@ -474,7 +475,7 @@ XFILE *startlmhosts(char *fname) *********************************************************/ BOOL getlmhostsent( TALLOC_CTX *mem_ctx, - XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) + XFILE *fp, pstring name, int *name_type, struct ipv4_addr *ipaddr) { pstring line; @@ -571,7 +572,7 @@ void endlmhosts(XFILE *fp) *********************************************************/ BOOL name_resolve_bcast(const char *name, int name_type, - struct in_addr **return_ip_list, int *return_count) + struct ipv4_addr **return_ip_list, int *return_count) { int sock, i; int num_interfaces = iface_count(); @@ -601,7 +602,7 @@ BOOL name_resolve_bcast(const char *name, int name_type, * the first successful match. */ for( i = num_interfaces-1; i >= 0; i--) { - struct in_addr sendto_ip; + struct ipv4_addr sendto_ip; int flags; /* Done this way to fix compiler error on IRIX 5.x */ sendto_ip = *iface_n_bcast(i); @@ -621,11 +622,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, Resolve via "wins" method. *********************************************************/ BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) + struct ipv4_addr **return_iplist, int *return_count) { int sock, t, i; char **wins_tags; - struct in_addr src_ip; + struct ipv4_addr src_ip; if (lp_disable_netbios()) { DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); @@ -658,7 +659,7 @@ BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, for (t=0; wins_tags && wins_tags[t]; t++) { int srv_count = wins_srv_count_tag(wins_tags[t]); for (i=0; i\n", name)); if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - struct in_addr return_ip; + struct ipv4_addr return_ip; putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + *return_iplist = (struct ipv4_addr *)malloc(sizeof(struct ipv4_addr)); if(*return_iplist == NULL) { DEBUG(3,("resolve_hosts: malloc fail !\n")); return False; @@ -749,7 +750,7 @@ static BOOL resolve_hosts(const char *name, *********************************************************/ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) + struct ipv4_addr **return_iplist, int *return_count) { char *name_resolve_list; fstring tok; @@ -758,7 +759,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); BOOL is_address = is_ipaddress(name); BOOL result = False; - struct in_addr *nodupes_iplist; + struct ipv4_addr *nodupes_iplist; int i; *return_iplist = NULL; @@ -767,7 +768,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); if (allzeros || allones || is_address) { - *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + *return_iplist = (struct ipv4_addr *)malloc(sizeof(struct ipv4_addr)); if(*return_iplist == NULL) { DEBUG(3,("internal_resolve_name: malloc fail !\n")); return False; @@ -841,8 +842,8 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam controllers including the PDC in iplist[1..n]. Iterating over the iplist when the PDC is down will cause two sets of timeouts. */ - if (*return_count && (nodupes_iplist = (struct in_addr *) - malloc(sizeof(struct in_addr) * (*return_count)))) { + if (*return_count && (nodupes_iplist = (struct ipv4_addr *) + malloc(sizeof(struct ipv4_addr) * (*return_count)))) { int nodupes_count = 0; /* Iterate over return_iplist looking for duplicates */ @@ -879,7 +880,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam /* Save in name cache */ for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, - name_type, inet_ntoa((*return_iplist)[i]))); + name_type, sys_inet_ntoa((*return_iplist)[i]))); namecache_store(mem_ctx, name, name_type, *return_count, *return_iplist); @@ -889,7 +890,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam *return_count)); for (i = 0; i < *return_count; i++) - DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i]))); + DEBUGADD(10, ("%s ", sys_inet_ntoa((*return_iplist)[i]))); DEBUG(10, ("\n")); @@ -902,9 +903,9 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. *********************************************************/ -BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ip, int name_type) +BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct ipv4_addr *return_ip, int name_type) { - struct in_addr *ip_list = NULL; + struct ipv4_addr *ip_list = NULL; int count = 0; if (is_ipaddress(name)) { @@ -916,7 +917,7 @@ BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ int i; /* only return valid addresses for TCP connections */ for (i=0; isource_name),nmb_namestr(&dgram2->dest_name), - inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); + sys_inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); if(SVAL(buf2,0) != QUERYFORPDC_R) { DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", @@ -1175,9 +1176,9 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... for a domain. *********************************************************/ -BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr *ip) +BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr *ip) { - struct in_addr *ip_list; + struct ipv4_addr *ip_list; int count; int i = 0; @@ -1217,7 +1218,7 @@ BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr *ip) a domain. *********************************************************/ -BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_list, int *count, int *ordered) +BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr **ip_list, int *count, int *ordered) { *ordered = False; @@ -1230,8 +1231,8 @@ BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_li fstring name; int num_addresses = 0; int local_count, i, j; - struct in_addr *return_iplist = NULL; - struct in_addr *auto_ip_list = NULL; + struct ipv4_addr *return_iplist = NULL; + struct ipv4_addr *auto_ip_list = NULL; BOOL done_auto_lookup = False; int auto_count = 0; @@ -1266,7 +1267,7 @@ BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_li if ( (num_addresses == 0) && !done_auto_lookup ) return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count); - return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr)); + return_iplist = (struct ipv4_addr *)malloc(num_addresses * sizeof(struct ipv4_addr)); if (return_iplist == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); @@ -1279,7 +1280,7 @@ BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct in_addr **ip_li /* fill in the return list now with real IP's */ while ( (local_count 1) ) { - qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare); + qsort(ip_list, count, sizeof(struct ipv4_addr), QSORT_CAST ip_compare); } for (i = 0; i < count; i++) { diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index 5eeec48003..ef5210cf63 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "system/network.h" static const struct opcode_names { const char *nmb_opcode_name; @@ -102,7 +103,7 @@ void debug_nmb_packet(struct packet_struct *p) if (DEBUGLVL(4)) { DEBUG(4, ("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, + sys_inet_ntoa(p->ip), p->port, nmb->header.name_trn_id, lookup_opcode_name(nmb->header.opcode), nmb->header.opcode, @@ -696,7 +697,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) struct packet_struct *packet; char buf[MAX_DGRAM_SIZE]; int length; - struct in_addr addr; + struct ipv4_addr addr; int port; length = read_udp_socket(fd, buf, sizeof(buf), &addr, &port); @@ -710,7 +711,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) packet->port = port; DEBUG(5,("Received a packet of len %d from (%s) port %d\n", - length, inet_ntoa(packet->ip), packet->port)); + length, sys_inet_ntoa(packet->ip), packet->port)); return packet; } @@ -719,7 +720,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) /******************************************************************* send a udp packet on a already open socket ******************************************************************/ -static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) +static BOOL send_udp(int fd,char *buf,int len,struct ipv4_addr ip,int port) { BOOL ret = False; int i; @@ -732,7 +733,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) sock_out.sin_family = AF_INET; DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", - len, inet_ntoa(ip), port ) ); + len, sys_inet_ntoa(ip), port ) ); /* * Patch to fix asynch error notifications from Linux kernel. @@ -746,7 +747,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) if (!ret) DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", - inet_ntoa(ip),port,strerror(errno))); + sys_inet_ntoa(ip),port,strerror(errno))); return(ret); } @@ -1069,7 +1070,7 @@ static int name_query_comp(uint8_t *p1, uint8_t *p2) sort a set of 6 byte name query response records so that the IPs that have the most leading bits in common with the specified address come first ***************************************************************************/ -void sort_query_replies(char *data, int n, struct in_addr ip) +void sort_query_replies(char *data, int n, struct ipv4_addr ip) { if (n <= 1) return; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index c641f8bf12..349b4b9a9c 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -49,7 +49,7 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) connect a smbcli_socket context to an IP/port pair if port is 0 then choose 445 then 139 */ -BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int port) +BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct ipv4_addr *ip, int port) { NTSTATUS status; @@ -71,7 +71,7 @@ BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct in_addr *ip, int por } talloc_steal(sock, sock->sock); - status = socket_connect(sock->sock, NULL, 0, inet_ntoa(*ip), port, 0); + status = socket_connect(sock->sock, NULL, 0, sys_inet_ntoa(*ip), port, 0); if (!NT_STATUS_IS_OK(status)) { talloc_free(sock->sock); sock->sock = NULL; @@ -159,7 +159,7 @@ resolve a hostname and connect BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, int port) { int name_type = 0x20; - struct in_addr ip; + struct ipv4_addr ip; char *name, *p; BOOL ret; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 48abc82a68..9bbdd8a222 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -60,7 +60,7 @@ struct smbcli_negotiate { /* this is the context for a SMB socket associated with the socket itself */ struct smbcli_socket { - struct in_addr dest_ip; + struct ipv4_addr dest_ip; /* dest hostname (which may or may not be a DNS name) */ char *hostname; -- cgit From ead3508ac81ff3ed2a48753f3b5e23537ba6ec73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 00:24:21 +0000 Subject: r3447: more include/system/XXX.h include files (This used to be commit 264ce9181089922547e8f6f67116f2d7277a5105) --- source4/libcli/auth/credentials.c | 1 + source4/libcli/namecache.c | 1 + source4/libcli/namequery.c | 1 + source4/libcli/nmblib.c | 1 + source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/rawnegotiate.c | 1 + source4/libcli/util/smbencrypt.c | 1 + 7 files changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 60feee7884..f3f8324005 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "system/time.h" /* initialise the credentials state for old-style 64 bit session keys diff --git a/source4/libcli/namecache.c b/source4/libcli/namecache.c index 8a4dab7522..34df4a3c5f 100644 --- a/source4/libcli/namecache.c +++ b/source4/libcli/namecache.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "system/time.h" #define NBTKEY_FMT "NBT/%s#%02X" diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 7a2d697797..8dae5e1206 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -21,6 +21,7 @@ #include "includes.h" #include "system/network.h" +#include "system/time.h" /* A netbios node status array element. */ struct node_status { diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index ef5210cf63..120b937be5 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -21,6 +21,7 @@ #include "includes.h" #include "system/network.h" +#include "system/time.h" static const struct opcode_names { const char *nmb_opcode_name; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index a6e8071a05..e70ee915c6 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "system/time.h" static void smbcli_transport_process_recv(struct smbcli_transport *transport); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index da7bcabda9..4f7d7b4058 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "system/time.h" static const struct { enum protocol_types prot; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 1089c3a4cf..1cf0890ba8 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "system/time.h" #include "byteorder.h" /* -- cgit From 26c6b4c70bd85d8030a96651f2a255a4d48fcda1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 01:42:45 +0000 Subject: r3449: more include file reduction the ldb part isn't ideal, I will have to think of a better solution (This used to be commit 6b1f86aea8427a8e957b1aeb0ec2f507297f07cb) --- source4/libcli/ldap/ldap.c | 1 + source4/libcli/ldap/ldap_ldif.c | 1 + source4/libcli/nmblib.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1eb7888d41..987a822219 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/network.h" +#include "system/iconv.h" /**************************************************************************** * diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 8fe50b6d08..19f4e56e73 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "system/iconv.h" /**************************************************************************** * diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index 120b937be5..06030f9aca 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/network.h" #include "system/time.h" +#include "system/iconv.h" static const struct opcode_names { const char *nmb_opcode_name; -- cgit From edbfc0f6e70150e321822365bf0eead2821551bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:57:18 +0000 Subject: r3453: - split out the auth and popt includes - tidied up some of the system includes - moved a few more structures back from misc.idl to netlogon.idl and samr.idl now that pidl knows about inter-IDL dependencies (This used to be commit 7b7477ac42d96faac1b0ff361525d2c63cedfc64) --- source4/libcli/auth/credentials.c | 1 + source4/libcli/auth/gensec.c | 1 + source4/libcli/auth/gensec.h | 3 --- source4/libcli/auth/gensec_krb5.c | 1 + source4/libcli/auth/gensec_ntlmssp.c | 1 + source4/libcli/auth/ntlmssp.c | 1 + source4/libcli/auth/ntlmssp_sign.c | 1 + source4/libcli/auth/spnego.c | 1 + source4/libcli/auth/spnego_parse.c | 1 + source4/libcli/cliconnect.c | 1 + source4/libcli/ldap/ldap.c | 1 + source4/libcli/raw/clisession.c | 1 + source4/libcli/util/smbencrypt.c | 2 +- 13 files changed, 12 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index f3f8324005..4a17b13910 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,6 +23,7 @@ #include "includes.h" #include "system/time.h" +#include "auth/auth.h" /* initialise the credentials state for old-style 64 bit session keys diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index a00a36e171..aab1928687 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "auth/auth.h" /* the list of currently registered GENSEC backends */ const static struct gensec_security_ops **generic_security_ops; diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 624c7ebe1d..b2c685332b 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -82,9 +82,6 @@ struct gensec_security_ops { void (*end)(struct gensec_security *gensec_security); }; -typedef NTSTATUS (*gensec_password_callback)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, - char **password); - #define GENSEC_INTERFACE_VERSION 0 struct gensec_security { diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index f393ce09c1..0e374e8219 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -27,6 +27,7 @@ #include "system/kerberos.h" #include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" +#include "auth/auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index f75e7b4d73..4b1d5f3b02 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "auth/auth.h" struct gensec_ntlmssp_state { struct auth_context *auth_context; diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 2ea0bcb84e..96c733e3b0 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "auth/auth.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 5a99f14496..689a2d353e 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "auth/auth.h" #define CLI_SIGN "session key to client-to-server signing key magic constant" #define CLI_SEAL "session key to client-to-server sealing key magic constant" diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 2779f47474..ef9763cad7 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "auth/auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 12d3d05734..d6eacc4a6a 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "auth/auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 2949633b86..2c66a1b5b3 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "libcli/raw/libcliraw.h" /* diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 987a822219..9b481313e3 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -26,6 +26,7 @@ #include "includes.h" #include "system/network.h" #include "system/iconv.h" +#include "auth/auth.h" /**************************************************************************** * diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 14018f676c..23e1d8507e 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "auth/auth.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ req = smbcli_request_setup_session(session, cmd, wct, buflen); \ diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 1cf0890ba8..1e911f094b 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -24,7 +24,7 @@ #include "includes.h" #include "system/time.h" -#include "byteorder.h" +#include "auth/auth.h" /* This implements the X/Open SMB password encryption -- cgit From 6148deca663f7b6504b044120b166d6c9ae28750 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 03:13:06 +0000 Subject: r3454: moved a few more things out if includes.h into the include/system/ include files. this brings us down to about 11k lines of headers included with includes.h, while still retaining the speed of building with pch (This used to be commit 10188869ef072309ca580b8b933e172571fcdda7) --- source4/libcli/clifile.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index cdb29beb2d..992d2c225d 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "libcli/raw/libcliraw.h" /**************************************************************************** -- cgit From 5011f901aa0140ed60a0b58e80ab0f14810ba432 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 03:58:27 +0000 Subject: r3457: s_addr is a macro on solaris, so we can't use it in structure names. arrgh. (This used to be commit 7842b23d01c53009259a2461600bd01159cecebf) --- source4/libcli/namequery.c | 14 +++++++------- source4/libcli/namequery_dc.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 8dae5e1206..2a67df5ffd 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -236,8 +236,8 @@ int ip_compare(struct ipv4_addr *ip1, struct ipv4_addr *ip2) struct ipv4_addr ip; int bits1, bits2; ip = *iface_n_bcast(i); - bits1 = matching_quad_bits((uint8_t *)&ip1->s_addr, (uint8_t *)&ip.s_addr); - bits2 = matching_quad_bits((uint8_t *)&ip2->s_addr, (uint8_t *)&ip.s_addr); + bits1 = matching_quad_bits((uint8_t *)&ip1->addr, (uint8_t *)&ip.addr); + bits2 = matching_quad_bits((uint8_t *)&ip2->addr, (uint8_t *)&ip.addr); max_bits1 = MAX(bits1, max_bits1); max_bits2 = MAX(bits2, max_bits2); } @@ -678,7 +678,7 @@ BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", sys_inet_ntoa(wins_ip), wins_tags[t])); - sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True); + sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.addr, True); if (sock == -1) { continue; } @@ -776,12 +776,12 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam } if(is_address) { /* if it's in the form of an IP address then get the lib to interpret it */ - if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){ + if (((*return_iplist)->addr = inet_addr(name)) == 0xFFFFFFFF ){ DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); return False; } } else { - (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0; + (*return_iplist)->addr = allones ? 0xFFFFFFFF : 0; *return_count = 1; } return True; @@ -854,7 +854,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam int j; for (j = i + 1; j < *return_count; j++) { - if (ip_equal((*return_iplist)[i], + if (ipv4_equal((*return_iplist)[i], (*return_iplist)[j])) { is_dupe = True; break; @@ -1312,7 +1312,7 @@ BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr **ip_ continue; for ( j=i+1; j Date: Tue, 2 Nov 2004 04:17:30 +0000 Subject: r3458: more solaris portability fixes, the main one being that we can't use a structure element called "open" as its a macro on solaris. (This used to be commit 4e92e15c4e396b1d8cd211192888fea68c2cf0f9) --- source4/libcli/raw/rawfile.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 92b995dd4a..4da7ff3a9e 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -300,15 +300,15 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope int len; struct smbcli_request *req = NULL; - switch (parms->open.level) { + switch (parms->generic.level) { case RAW_OPEN_T2OPEN: return smb_raw_t2open_send(tree, parms); case RAW_OPEN_OPEN: SETUP_REQUEST(SMBopen, 2, 0); - SSVAL(req->out.vwv, VWV(0), parms->open.in.flags); - SSVAL(req->out.vwv, VWV(1), parms->open.in.search_attrs); - smbcli_req_append_ascii4(req, parms->open.in.fname, STR_TERMINATE); + SSVAL(req->out.vwv, VWV(0), parms->openold.in.flags); + SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs); + smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE); break; case RAW_OPEN_OPENX: @@ -397,18 +397,18 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio goto failed; } - switch (parms->open.level) { + switch (parms->openold.level) { case RAW_OPEN_T2OPEN: return smb_raw_t2open_recv(req, mem_ctx, parms); case RAW_OPEN_OPEN: SMBCLI_CHECK_WCT(req, 7); - parms->open.out.fnum = SVAL(req->in.vwv, VWV(0)); - parms->open.out.attrib = SVAL(req->in.vwv, VWV(1)); - parms->open.out.write_time = raw_pull_dos_date3(req->transport, + parms->openold.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1)); + parms->openold.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(2)); - parms->open.out.size = IVAL(req->in.vwv, VWV(4)); - parms->open.out.rmode = SVAL(req->in.vwv, VWV(6)); + parms->openold.out.size = IVAL(req->in.vwv, VWV(4)); + parms->openold.out.rmode = SVAL(req->in.vwv, VWV(6)); break; case RAW_OPEN_OPENX: -- cgit From a1d0b97ed40fe6985bb45b1715309638e7faaffc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:14:15 +0000 Subject: r3462: separate out the crypto includes (This used to be commit 3f75117db921e493bb77a5dc14b8ce91a6288f30) --- source4/libcli/auth/credentials.c | 1 + source4/libcli/auth/ntlmssp.c | 1 + source4/libcli/auth/ntlmssp_sign.c | 1 + source4/libcli/auth/schannel.c | 1 + source4/libcli/raw/smb_signing.c | 1 + source4/libcli/util/smbencrypt.c | 1 + 6 files changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 4a17b13910..a09d767e89 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -24,6 +24,7 @@ #include "includes.h" #include "system/time.h" #include "auth/auth.h" +#include "lib/crypto/crypto.h" /* initialise the credentials state for old-style 64 bit session keys diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 96c733e3b0..55a80d0d5e 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -23,6 +23,7 @@ #include "includes.h" #include "auth/auth.h" +#include "lib/crypto/crypto.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 689a2d353e..7d193c850c 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -22,6 +22,7 @@ #include "includes.h" #include "auth/auth.h" +#include "lib/crypto/crypto.h" #define CLI_SIGN "session key to client-to-server signing key magic constant" #define CLI_SEAL "session key to client-to-server sealing key magic constant" diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 2f20a3e906..51b8690c97 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "lib/crypto/crypto.h" struct schannel_state { uint8_t session_key[16]; diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index d348c202f5..c0c1337312 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "lib/crypto/crypto.h" /*********************************************************** SMB signing - Common code before we set a new signing implementation diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 1e911f094b..6034c0e327 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/time.h" #include "auth/auth.h" +#include "lib/crypto/crypto.h" /* This implements the X/Open SMB password encryption -- cgit From 3643fb11092e28a9538ef32cedce8ff21ad86a28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:42:15 +0000 Subject: r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h) (This used to be commit b97e395c814762024336c1cf4d7c25be8da5813a) --- source4/libcli/auth/gensec_krb5.c | 1 + source4/libcli/auth/gensec_ntlmssp.c | 1 + source4/libcli/auth/gssapi_parse.c | 5 ++- source4/libcli/auth/kerberos_verify.c | 3 +- source4/libcli/auth/spnego.c | 1 + source4/libcli/auth/spnego_parse.c | 13 +++--- source4/libcli/ldap/ldap.c | 20 +++++---- source4/libcli/raw/clisession.c | 1 + source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/rawrequest.c | 1 + source4/libcli/util/asn1.c | 77 ++++++++++++++++++----------------- 11 files changed, 68 insertions(+), 56 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 0e374e8219..c3dd84135a 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -28,6 +28,7 @@ #include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" +#include "asn_1.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 4b1d5f3b02..8ab90ebcfb 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -23,6 +23,7 @@ #include "includes.h" #include "auth/auth.h" +#include "asn_1.h" struct gensec_ntlmssp_state { struct auth_context *auth_context; diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c index 4a80e1d799..529799955d 100644 --- a/source4/libcli/auth/gssapi_parse.c +++ b/source4/libcli/auth/gssapi_parse.c @@ -23,13 +23,14 @@ */ #include "includes.h" +#include "asn_1.h" /* generate a krb5 GSS-API wrapper packet given a ticket */ DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8 tok_id[2]) { - ASN1_DATA data; + struct asn1_data data; DATA_BLOB ret; ZERO_STRUCT(data); @@ -58,7 +59,7 @@ DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *tick BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8 tok_id[2]) { BOOL ret; - ASN1_DATA data; + struct asn1_data data; int data_remaining; asn1_load(&data, *blob); diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 8e598e2a66..6d87cf8d8b 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/kerberos.h" #include "libcli/auth/kerberos.h" +#include "asn_1.h" #ifdef HAVE_KRB5 @@ -32,7 +33,7 @@ static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) { DATA_BLOB out; DATA_BLOB pac_contents = data_blob(NULL, 0); - ASN1_DATA data; + struct asn1_data data; int data_type; if (!auth_data->length) { return data_blob(NULL, 0); diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index ef9763cad7..ab3aff32bb 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -24,6 +24,7 @@ #include "includes.h" #include "auth/auth.h" +#include "asn_1.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index d6eacc4a6a..f9385ed96e 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -23,11 +23,12 @@ #include "includes.h" #include "auth/auth.h" +#include "asn_1.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token) { ZERO_STRUCTP(token); @@ -117,7 +118,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token return !asn1->has_error; } -static BOOL write_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token) +static BOOL write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token) { asn1_push_tag(asn1, ASN1_CONTEXT(0)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); @@ -180,7 +181,7 @@ static BOOL write_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *toke return !asn1->has_error; } -static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +static BOOL read_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token) { ZERO_STRUCTP(token); @@ -229,7 +230,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token return !asn1->has_error; } -static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token) +static BOOL write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token) { asn1_push_tag(asn1, ASN1_CONTEXT(1)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); @@ -268,7 +269,7 @@ static BOOL write_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *toke ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) { - ASN1_DATA asn1; + struct asn1_data asn1; ssize_t ret = -1; uint8_t context; @@ -312,7 +313,7 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego) { - ASN1_DATA asn1; + struct asn1_data asn1; ssize_t ret = -1; ZERO_STRUCT(asn1); diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 9b481313e3..5224373afc 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -27,6 +27,8 @@ #include "system/network.h" #include "system/iconv.h" #include "auth/auth.h" +#include "asn_1.h" +#include "dlinklist.h" /**************************************************************************** * @@ -303,7 +305,7 @@ static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char * return ldap_parse_simple(mem_ctx, s); } -static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) +static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tree) { switch (tree->operation) { case LDAP_OP_SIMPLE: { @@ -354,7 +356,7 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) return !data->has_error; } -static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result) +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) { asn1_write_enumerated(data, result->resultcode); asn1_write_OctetString(data, result->dn, @@ -369,7 +371,7 @@ static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result) BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) { - ASN1_DATA data; + struct asn1_data data; int i, j; ZERO_STRUCT(data); @@ -663,7 +665,7 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, } static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - ASN1_DATA *data, + struct asn1_data *data, const char **result) { DATA_BLOB string; @@ -675,7 +677,7 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, } static void ldap_decode_response(TALLOC_CTX *mem_ctx, - ASN1_DATA *data, + struct asn1_data *data, struct ldap_Result *result) { asn1_read_enumerated(data, &result->resultcode); @@ -690,7 +692,7 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, +static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, char **filter) { uint8 filter_tag, tag_desc; @@ -795,7 +797,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, return True; } -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { asn1_start_tag(data, ASN1_SEQUENCE(0)); @@ -815,7 +817,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, } -static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, ASN1_DATA *data, +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute **attributes, int *num_attributes) { @@ -830,7 +832,7 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, ASN1_DATA *data, asn1_end_tag(data); } -BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) +BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) { uint8 tag; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 23e1d8507e..b7802d8065 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "auth/auth.h" +#include "asn_1.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ req = smbcli_request_setup_session(session, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index e70ee915c6..c5e3d39545 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "system/time.h" +#include "dlinklist.h" static void smbcli_transport_process_recv(struct smbcli_transport *transport); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 5cf1621d2d..0526fec74b 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -25,6 +25,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "dlinklist.h" /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 256 diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index e03b1d5f39..15858f4f75 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -19,15 +19,16 @@ */ #include "includes.h" +#include "asn_1.h" /* free an asn1 structure */ -void asn1_free(ASN1_DATA *data) +void asn1_free(struct asn1_data *data) { talloc_free(data->data); } /* write to the ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_write(ASN1_DATA *data, const void *p, int len) +BOOL asn1_write(struct asn1_data *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { @@ -47,13 +48,13 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) } /* useful fn for writing a uint8_t */ -BOOL asn1_write_uint8(ASN1_DATA *data, uint8_t v) +BOOL asn1_write_uint8(struct asn1_data *data, uint8_t v) { return asn1_write(data, &v, 1); } /* push a tag onto the asn1 data buffer. Used for nested structures */ -BOOL asn1_push_tag(ASN1_DATA *data, uint8_t tag) +BOOL asn1_push_tag(struct asn1_data *data, uint8_t tag) { struct nesting *nesting; @@ -71,7 +72,7 @@ BOOL asn1_push_tag(ASN1_DATA *data, uint8_t tag) } /* pop a tag */ -BOOL asn1_pop_tag(ASN1_DATA *data) +BOOL asn1_pop_tag(struct asn1_data *data) { struct nesting *nesting; size_t len; @@ -110,7 +111,7 @@ BOOL asn1_pop_tag(ASN1_DATA *data) /* "i" is the one's complement representation, as is the normal result of an * implicit signed->unsigned conversion */ -static BOOL push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) +static BOOL push_int_bigendian(struct asn1_data *data, unsigned int i, BOOL negative) { uint8_t lowest = i & 0xFF; @@ -153,7 +154,7 @@ static BOOL push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) /* write an Integer without the tag framing. Needed for example for the LDAP * Abandon Operation */ -BOOL asn1_write_implicit_Integer(ASN1_DATA *data, int i) +BOOL asn1_write_implicit_Integer(struct asn1_data *data, int i) { if (i == -1) { /* -1 is special as it consists of all-0xff bytes. In @@ -168,7 +169,7 @@ BOOL asn1_write_implicit_Integer(ASN1_DATA *data, int i) /* write an integer */ -BOOL asn1_write_Integer(ASN1_DATA *data, int i) +BOOL asn1_write_Integer(struct asn1_data *data, int i) { if (!asn1_push_tag(data, ASN1_INTEGER)) return False; if (!asn1_write_implicit_Integer(data, i)) return False; @@ -176,7 +177,7 @@ BOOL asn1_write_Integer(ASN1_DATA *data, int i) } /* write an object ID to a ASN1 buffer */ -BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) +BOOL asn1_write_OID(struct asn1_data *data, const char *OID) { uint_t v, v2; const char *p = (const char *)OID; @@ -205,7 +206,7 @@ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) } /* write an octet string */ -BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) +BOOL asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) { asn1_push_tag(data, ASN1_OCTET_STRING); asn1_write(data, p, length); @@ -214,7 +215,7 @@ BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) } /* write a general string */ -BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) +BOOL asn1_write_GeneralString(struct asn1_data *data, const char *s) { asn1_push_tag(data, ASN1_GENERAL_STRING); asn1_write(data, s, strlen(s)); @@ -222,7 +223,7 @@ BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) return !data->has_error; } -BOOL asn1_write_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) +BOOL asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); asn1_write(data, blob->data, blob->length); @@ -231,7 +232,7 @@ BOOL asn1_write_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) } /* write a BOOLEAN */ -BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) +BOOL asn1_write_BOOLEAN(struct asn1_data *data, BOOL v) { asn1_push_tag(data, ASN1_BOOLEAN); asn1_write_uint8(data, v ? 0xFF : 0); @@ -239,7 +240,7 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return !data->has_error; } -BOOL asn1_read_BOOLEAN(ASN1_DATA *data, BOOL *v) +BOOL asn1_read_BOOLEAN(struct asn1_data *data, BOOL *v) { uint8_t tmp = 0; asn1_start_tag(data, ASN1_BOOLEAN); @@ -254,7 +255,7 @@ BOOL asn1_read_BOOLEAN(ASN1_DATA *data, BOOL *v) } /* check a BOOLEAN */ -BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) +BOOL asn1_check_BOOLEAN(struct asn1_data *data, BOOL v) { uint8_t b = 0; @@ -272,8 +273,8 @@ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) } -/* load a ASN1_DATA structure with a lump of data, ready to be parsed */ -BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) +/* load a struct asn1_data structure with a lump of data, ready to be parsed */ +BOOL asn1_load(struct asn1_data *data, DATA_BLOB blob) { ZERO_STRUCTP(data); data->data = talloc_memdup(NULL, blob.data, blob.length); @@ -286,7 +287,7 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) } /* Peek into an ASN1 buffer, not advancing the pointer */ -BOOL asn1_peek(ASN1_DATA *data, void *p, int len) +BOOL asn1_peek(struct asn1_data *data, void *p, int len) { if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) return False; @@ -299,7 +300,7 @@ BOOL asn1_peek(ASN1_DATA *data, void *p, int len) } /* read from a ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_read(ASN1_DATA *data, void *p, int len) +BOOL asn1_read(struct asn1_data *data, void *p, int len) { if (!asn1_peek(data, p, len)) { data->has_error = True; @@ -311,17 +312,17 @@ BOOL asn1_read(ASN1_DATA *data, void *p, int len) } /* read a uint8_t from a ASN1 buffer */ -BOOL asn1_read_uint8(ASN1_DATA *data, uint8_t *v) +BOOL asn1_read_uint8(struct asn1_data *data, uint8_t *v) { return asn1_read(data, v, 1); } -BOOL asn1_peek_uint8(ASN1_DATA *data, uint8_t *v) +BOOL asn1_peek_uint8(struct asn1_data *data, uint8_t *v) { return asn1_peek(data, v, 1); } -BOOL asn1_peek_tag(ASN1_DATA *data, uint8_t tag) +BOOL asn1_peek_tag(struct asn1_data *data, uint8_t tag) { uint8_t b; @@ -336,7 +337,7 @@ BOOL asn1_peek_tag(ASN1_DATA *data, uint8_t tag) } /* start reading a nested asn1 structure */ -BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) +BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) { uint8_t b; struct nesting *nesting; @@ -378,7 +379,7 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) return !data->has_error; } -static BOOL read_one_uint8(int sock, uint8_t *result, ASN1_DATA *data, +static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data, const struct timeval *endtime) { if (read_data_until(sock, result, 1, endtime) != 1) @@ -388,7 +389,7 @@ static BOOL read_one_uint8(int sock, uint8_t *result, ASN1_DATA *data, } /* Read a complete ASN sequence (ie LDAP result) from a socket */ -BOOL asn1_read_sequence_until(int sock, ASN1_DATA *data, +BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, const struct timeval *endtime) { uint8_t b; @@ -444,7 +445,7 @@ BOOL asn1_read_sequence_until(int sock, ASN1_DATA *data, BOOL asn1_object_length(uint8_t *buf, size_t buf_length, uint8_t tag, size_t *result) { - ASN1_DATA data; + struct asn1_data data; /* Fake the asn1_load to avoid the memdup, this is just to be able to * re-use the length-reading in asn1_start_tag */ @@ -461,7 +462,7 @@ BOOL asn1_object_length(uint8_t *buf, size_t buf_length, } /* stop reading a tag */ -BOOL asn1_end_tag(ASN1_DATA *data) +BOOL asn1_end_tag(struct asn1_data *data) { struct nesting *nesting; @@ -484,7 +485,7 @@ BOOL asn1_end_tag(ASN1_DATA *data) } /* work out how many bytes are left in this nested tag */ -int asn1_tag_remaining(ASN1_DATA *data) +int asn1_tag_remaining(struct asn1_data *data) { if (!data->nesting) { data->has_error = True; @@ -494,7 +495,7 @@ int asn1_tag_remaining(ASN1_DATA *data) } /* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID(ASN1_DATA *data, const char **OID) +BOOL asn1_read_OID(struct asn1_data *data, const char **OID) { uint8_t b; char *tmp_oid = NULL; @@ -523,7 +524,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, const char **OID) } /* check that the next object ID is correct */ -BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) +BOOL asn1_check_OID(struct asn1_data *data, const char *OID) { const char *id; @@ -538,7 +539,7 @@ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) } /* read a GeneralString from a ASN1 buffer */ -BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) +BOOL asn1_read_GeneralString(struct asn1_data *data, char **s) { int len; if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; @@ -559,7 +560,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) } /* read a octet string blob */ -BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) +BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); @@ -581,7 +582,7 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) return True; } -BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) +BOOL asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); @@ -598,7 +599,7 @@ BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) } /* read an interger without tag*/ -BOOL asn1_read_implicit_Integer(ASN1_DATA *data, int *i) +BOOL asn1_read_implicit_Integer(struct asn1_data *data, int *i) { uint8_t b; *i = 0; @@ -612,7 +613,7 @@ BOOL asn1_read_implicit_Integer(ASN1_DATA *data, int *i) } /* read an interger */ -BOOL asn1_read_Integer(ASN1_DATA *data, int *i) +BOOL asn1_read_Integer(struct asn1_data *data, int *i) { *i = 0; @@ -623,7 +624,7 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) } /* read an interger */ -BOOL asn1_read_enumerated(ASN1_DATA *data, int *v) +BOOL asn1_read_enumerated(struct asn1_data *data, int *v) { *v = 0; @@ -637,7 +638,7 @@ BOOL asn1_read_enumerated(ASN1_DATA *data, int *v) } /* check a enumarted value is correct */ -BOOL asn1_check_enumerated(ASN1_DATA *data, int v) +BOOL asn1_check_enumerated(struct asn1_data *data, int v) { uint8_t b; if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; @@ -651,7 +652,7 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) } /* write an enumarted value to the stream */ -BOOL asn1_write_enumerated(ASN1_DATA *data, uint8_t v) +BOOL asn1_write_enumerated(struct asn1_data *data, uint8_t v) { if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; asn1_write_uint8(data, v); -- cgit From aa34fcebf8aa0660574a7c6976b33b3f37985e27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 07:18:24 +0000 Subject: r3466: split out request.h, signing.h, and smb_server.h (This used to be commit 7c4e6ebf05790dd6e29896dd316db0fff613aa4e) --- source4/libcli/raw/libcliraw.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 9bbdd8a222..9b03ab713b 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -21,6 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "request.h" + struct smbcli_tree; /* forward declare */ struct smbcli_request; /* forward declare */ struct smbcli_session; /* forward declare */ -- cgit From c5e4c834648fd7639d9024f15f4e4f8163340581 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 11:16:34 +0000 Subject: r3475: don't pass a ptr to an enum as a ptr to an int (bug found by tcc) (This used to be commit a7e5bde6befa8da8fc7447b295d9177126f74964) --- source4/libcli/ldap/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5224373afc..6d2cef8bdb 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -977,9 +977,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) while (asn1_tag_remaining(data) > 0) { struct ldap_mod mod; + int v; ZERO_STRUCT(mod); asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &mod.type); + asn1_read_enumerated(data, &v); + mod.type = v; ldap_decode_attrib(msg->mem_ctx, data, &mod.attrib); asn1_end_tag(data); if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, -- cgit From acc9f59c7f3bdaa5be20f7c46e9e1a9eaa21192a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 11:17:06 +0000 Subject: r3476: fixed some const warnings (This used to be commit 7dc58dc01e19b342df76dcc14ee28ff37a8f9ace) --- source4/libcli/auth/spnego_parse.c | 2 +- source4/libcli/util/asn1.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index f9385ed96e..825b0a78d2 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -359,7 +359,7 @@ BOOL spnego_free_data(struct spnego_data *spnego) break; case SPNEGO_NEG_TOKEN_TARG: if (spnego->negTokenTarg.supportedMech) { - talloc_free(spnego->negTokenTarg.supportedMech); + talloc_free(discard_const(spnego->negTokenTarg.supportedMech)); } data_blob_free(&spnego->negTokenTarg.responseToken); data_blob_free(&spnego->negTokenTarg.mechListMIC); diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 15858f4f75..2bf29f9161 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -534,7 +534,7 @@ BOOL asn1_check_OID(struct asn1_data *data, const char *OID) data->has_error = True; return False; } - talloc_free(id); + talloc_free(discard_const(id)); return True; } -- cgit From a99b6219a810a1cd10bd62a6716780602808f0cd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 12:15:17 +0000 Subject: r3481: split out client.h and events.h (This used to be commit c6f486574470a311e0d336c026103f131451e21e) --- source4/libcli/clideltree.c | 3 ++- source4/libcli/clilist.c | 21 +++++++++++---------- source4/libcli/raw/clitransport.c | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index aa73f5b90b..7dd3803735 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "client.h" struct delete_state { struct smbcli_tree *tree; @@ -29,7 +30,7 @@ struct delete_state { /* callback function for torture_deltree() */ -static void delete_fn(file_info *finfo, const char *name, void *state) +static void delete_fn(struct file_info *finfo, const char *name, void *state) { struct delete_state *dstate = state; char *s, *n; diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index dde2a7befa..e8b97f324d 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -20,10 +20,11 @@ */ #include "includes.h" +#include "client.h" #include "libcli/raw/libcliraw.h" struct search_private { - file_info *dirlist; + struct file_info *dirlist; TALLOC_CTX *mem_ctx; int dirlist_len; int ff_searchcount; /* total received in 1 server trip */ @@ -39,9 +40,9 @@ struct search_private { ****************************************************************************/ static BOOL interpret_long_filename(enum smb_search_level level, union smb_search_data *info, - file_info *finfo) + struct file_info *finfo) { - file_info finfo2; + struct file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); @@ -81,7 +82,7 @@ static BOOL interpret_long_filename(enum smb_search_level level, static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; - file_info *tdl; + struct file_info *tdl; /* add file info to the dirlist pool */ tdl = talloc_realloc(state, @@ -105,7 +106,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, enum smb_search_level level, - void (*fn)(file_info *, const char *, void *), + void (*fn)(struct file_info *, const char *, void *), void *caller_state) { union smb_search_first first_parms; @@ -208,9 +209,9 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu ****************************************************************************/ static BOOL interpret_short_filename(int level, union smb_search_data *info, - file_info *finfo) + struct file_info *finfo) { - file_info finfo2; + struct file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); @@ -228,7 +229,7 @@ static BOOL interpret_short_filename(int level, static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; - file_info *tdl; + struct file_info *tdl; /* add file info to the dirlist pool */ tdl = talloc_realloc(state, @@ -251,7 +252,7 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) } int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, - void (*fn)(file_info *, const char *, void *), + void (*fn)(struct file_info *, const char *, void *), void *caller_state) { union smb_search_first first_parms; @@ -337,7 +338,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu ****************************************************************************/ int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, - void (*fn)(file_info *, const char *, void *), void *state) + void (*fn)(struct file_info *, const char *, void *), void *state) { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) return smbcli_list_old(tree, Mask, attribute, fn, state); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index c5e3d39545..00e52f3a14 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -23,6 +23,7 @@ #include "libcli/raw/libcliraw.h" #include "system/time.h" #include "dlinklist.h" +#include "events.h" static void smbcli_transport_process_recv(struct smbcli_transport *transport); -- cgit From 6f214cc510a59b7a65ee9d4486baf14a3e579f73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 00:17:12 +0000 Subject: r3494: got rid of include/rewrite.h, and split out the dynconfig.h header (This used to be commit 558de54ec6432a4ae90aa14a585f32c6cd03ced2) --- source4/libcli/namequery.c | 112 --------------------------------------------- 1 file changed, 112 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 2a67df5ffd..85270c1001 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -456,118 +456,6 @@ struct ipv4_addr *name_query(int fd,const char *name,int name_type, return ip_list; } -/******************************************************** - Start parsing the lmhosts file. -*********************************************************/ - -XFILE *startlmhosts(char *fname) -{ - XFILE *fp = x_fopen(fname,O_RDONLY, 0); - if (!fp) { - DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", - fname, strerror(errno))); - return NULL; - } - return fp; -} - -/******************************************************** - Parse the next line in the lmhosts file. -*********************************************************/ - -BOOL getlmhostsent( TALLOC_CTX *mem_ctx, - XFILE *fp, pstring name, int *name_type, struct ipv4_addr *ipaddr) -{ - pstring line; - - while(!x_feof(fp) && !x_ferror(fp)) { - pstring ip,flags,extra; - const char *ptr; - char *ptr1; - int count = 0; - - *name_type = -1; - - if (!fgets_slash(line,sizeof(pstring),fp)) - continue; - - if (*line == '#') - continue; - - pstrcpy(ip,""); - pstrcpy(name,""); - pstrcpy(flags,""); - - ptr = line; - - if (next_token(&ptr,ip ,NULL,sizeof(ip))) - ++count; - if (next_token(&ptr,name ,NULL, sizeof(pstring))) - ++count; - if (next_token(&ptr,flags,NULL, sizeof(flags))) - ++count; - if (next_token(&ptr,extra,NULL, sizeof(extra))) - ++count; - - if (count <= 0) - continue; - - if (count > 0 && count < 2) - { - DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); - continue; - } - - if (count >= 4) - { - DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); - continue; - } - - DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); - - if (strchr_m(flags,'G') || strchr_m(flags,'S')) - { - DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); - continue; - } - - *ipaddr = interpret_addr2(ip); - - /* Extra feature. If the name ends in '#XX', where XX is a hex number, - then only add that name type. */ - if((ptr1 = strchr_m(name, '#')) != NULL) - { - char *endptr; - - ptr1++; - *name_type = (int)strtol(ptr1, &endptr, 16); - - if(!*ptr1 || (endptr == ptr1)) - { - DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); - continue; - } - - *(--ptr1) = '\0'; /* Truncate at the '#' */ - } - - return True; - } - - return False; -} - -/******************************************************** - Finish parsing the lmhosts file. -*********************************************************/ - -void endlmhosts(XFILE *fp) -{ - x_fclose(fp); -} - - /******************************************************** Resolve via "bcast" method. *********************************************************/ -- cgit From dde07058075d357cfdc63624c8dcaa67ebd40add Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 10:09:48 +0000 Subject: r3507: - added deferred replies on sharing violation in pvfs open. The deferred reply is short-circuited immediately when the file is closed by another user, allowing it to be opened by the waiting user. - added a sane set of timeval manipulation routines - converted all the events code and code that uses it to use struct timeval instead of time_t, which allows for microsecond resolution instead of 1 second resolution. This was needed for doing the pvfs deferred open code, and is why the patch is so big. (This used to be commit 0d51511d408d91eb5f68a35e980e0875299b1831) --- source4/libcli/raw/clitransport.c | 16 ++++++++-------- source4/libcli/raw/libcliraw.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 00e52f3a14..52cb4d8beb 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -33,7 +33,7 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport); an event has happened on the socket */ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_event *fde, - time_t t, uint16_t flags) + struct timeval t, uint16_t flags) { struct smbcli_transport *transport = fde->private; @@ -233,21 +233,21 @@ again: } static void idle_handler(struct event_context *ev, - struct timed_event *te, time_t t) + struct timed_event *te, struct timeval t) { struct smbcli_transport *transport = te->private; - te->next_event = t + transport->idle.period; + te->next_event = timeval_add(&te->next_event, 0, transport->idle.period); transport->idle.func(transport, transport->idle.private); } /* setup the idle handler for a transport - the period is in seconds + the period is in microseconds */ void smbcli_transport_idle_handler(struct smbcli_transport *transport, - void (*idle_func)(struct smbcli_transport *, void *), - uint_t period, - void *private) + void (*idle_func)(struct smbcli_transport *, void *), + uint64_t period, + void *private) { struct timed_event te; transport->idle.func = idle_func; @@ -258,7 +258,7 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, event_remove_timed(transport->event.ctx, transport->event.te); } - te.next_event = time(NULL) + period; + te.next_event = timeval_current_ofs(0, period); te.handler = idle_handler; te.private = transport; transport->event.te = event_add_timed(transport->event.ctx, &te); diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 9b03ab713b..b00af846b7 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -114,7 +114,7 @@ struct smbcli_transport { uint_t readbraw_pending:1; /* an idle function - if this is defined then it will be - called once every period seconds while we are waiting + called once every period microseconds while we are waiting for a packet */ struct { void (*func)(struct smbcli_transport *, void *); -- cgit From 37baa01e75f7ff92e9fb280e9ef3e0359c2d8553 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 4 Nov 2004 02:49:25 +0000 Subject: r3519: Include time headers to fix the build. Andrew Bartlett (This used to be commit d13e2aa89e72c63e552f1b24547abe6fc319ee61) --- source4/libcli/auth/clikrb5.c | 1 + source4/libcli/auth/gensec_krb5.c | 1 + source4/libcli/auth/kerberos.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 6f17bddfa0..82311e625b 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/network.h" #include "system/kerberos.h" +#include "system/time.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index c3dd84135a..0af29d6087 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/kerberos.h" +#include "system/time.h" #include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 06e89d4d33..d70444d5bc 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/kerberos.h" +#include "system/time.h" #ifdef HAVE_KRB5 -- cgit From 9fe5fa11d637252f1fbe79c7baf778e2d3cdade2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 07:29:02 +0000 Subject: r3545: initial support for using extended attributes to hold extended dos attributes of files. I decided to use IDL/NDR to encode the attribute, as it gives us a simple way to describe and extend the saved attributes. The xattr code needs to hook into quite a few more places in the pvfs code, but this at least gets the basics done. I will start encoding alternate data streams streams, DOS EAs etc soon using the same basic mechanism. I'll probably stick to "version 1" for the xattr.idl for quite a while even though it will be changing, as I don't expect anyone to be deploying this in production just yet. Once we have production users we will need to keep compatibility by supporting all the old version numbers in xattr.idl. (This used to be commit c54253ed1b7dce1d14f43e747da61089aea87094) --- source4/libcli/util/errormap.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 46e4831f89..417f4571a7 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1517,6 +1517,13 @@ const struct unix_error_map unix_nt_errmap[] = { { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, { EBUSY, NT_STATUS_SHARING_VIOLATION }, + { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, +#ifdef ENOATTR + { ENOATTR, NT_STATUS_NOT_FOUND }, +#endif +#ifdef ENODATA + { ENODATA, NT_STATUS_NOT_FOUND }, +#endif #ifdef EDQUOT { EDQUOT, NT_STATUS_QUOTA_EXCEEDED }, #endif -- cgit From ed277bb89ecbd1d9f99f9cfce705903bd3762dfd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 5 Nov 2004 23:26:02 +0000 Subject: r3565: Move PAC parsing into the session_info generation, and out of the basic krb5 request path. The idea is that we should not do the extra work, if we are not going to use the results. Andrew Bartlett (This used to be commit 13a2a9e326c027d76d27ecd08fb9863fe881bf30) --- source4/libcli/auth/gensec_krb5.c | 57 ++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 0af29d6087..37e96cf9dc 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -43,7 +43,7 @@ enum GENSEC_KRB5_STATE { struct gensec_krb5_state { DATA_BLOB session_key; - struct PAC_LOGON_INFO *logon_info; + DATA_BLOB pac; enum GENSEC_KRB5_STATE state_position; krb5_context krb5_context; krb5_auth_context krb5_auth_context; @@ -281,6 +281,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) ZERO_STRUCT(gensec_krb5_state->ticket); ZERO_STRUCT(gensec_krb5_state->krb5_keyblock); gensec_krb5_state->session_key = data_blob(NULL, 0); + gensec_krb5_state->pac = data_blob(NULL, 0); ret = krb5_init_context(&gensec_krb5_state->krb5_context); if (ret) { @@ -544,12 +545,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL } if (pac.data) { - /* decode and verify the pac */ - nt_status = gensec_krb5_decode_pac(gensec_krb5_state, &gensec_krb5_state->logon_info, pac, - gensec_krb5_state); - } else { - /* NULL PAC, we might need to figure this information out the hard way */ - gensec_krb5_state->logon_info = NULL; + gensec_krb5_state->pac = data_blob_talloc_reference(gensec_krb5_state, &pac); } if (NT_STATUS_IS_OK(nt_status)) { @@ -612,7 +608,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; - struct PAC_LOGON_INFO *logon_info = gensec_krb5_state->logon_info; + struct PAC_LOGON_INFO *logon_info; struct nt_user_token *ptoken; struct dom_sid *sid; char *p; @@ -622,10 +618,6 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security *session_info_out = NULL; - /* IF we have the PAC - otherwise we need to get this - * data from elsewere - local ldb, or (TODO) lookup of some - * kind... */ - principal = talloc_strdup(gensec_krb5_state, gensec_krb5_state->peer_principal); p = strchr(principal, '@'); if (p) { @@ -635,17 +627,50 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security username = principal; realm = p; - if (logon_info) { + /* decode and verify the pac */ + nt_status = gensec_krb5_decode_pac(gensec_krb5_state, &logon_info, gensec_krb5_state->pac, + gensec_krb5_state); + + /* IF we have the PAC - otherwise we need to get this + * data from elsewere - local ldb, or (TODO) lookup of some + * kind... */ + + if (NT_STATUS_IS_OK(nt_status)) { nt_status = make_server_info(gensec_krb5_state, &server_info, gensec_krb5_state->peer_principal); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } server_info->guest = False; + + if (logon_info->account_name.string) { + server_info->account_name + = talloc_reference(server_info, + logon_info->account_name.string); + } else { + server_info->account_name = talloc_strdup(server_info, username); + } + + server_info->domain = talloc_reference(server_info, + logon_info->dom_name.string); + server_info->realm = talloc_strdup(server_info, realm); + server_info->full_name = talloc_reference(server_info, + logon_info->full_name.string); + server_info->logon_script = talloc_reference(server_info, + logon_info->logon_script.string); + server_info->profile_path = talloc_reference(server_info, + logon_info->profile_path.string); + server_info->home_directory = talloc_reference(server_info, + logon_info->home_directory.string); + server_info->home_drive = talloc_reference(server_info, + logon_info->home_drive.string); - server_info->account_name = talloc_strdup(server_info, principal); - server_info->domain = talloc_strdup(server_info, realm); - if (!server_info->domain) { + server_info->logon_count = logon_info->logon_count; + /* TODO: bad password count */ + + server_info->acct_flags = logon_info->acct_flags; + + if (!server_info->domain || !server_info->account_name || !server_info->realm) { free_server_info(&server_info); return NT_STATUS_NO_MEMORY; } -- cgit From e1f38d81383c4adcb28b8e6e4bc0b3c7600277d4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 6 Nov 2004 03:44:16 +0000 Subject: r3571: rough guesses at what abartlet really wanted to do in his last commit (which I suspect was missing some pieces) this at least fixes the build so i can keep going on pvfs. Please review/fix Andrew. (This used to be commit bffd18d09df04c1e492ef12f744ff4b6c561d53c) --- source4/libcli/auth/gensec_krb5.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 37e96cf9dc..a95780236e 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -668,7 +668,9 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security server_info->logon_count = logon_info->logon_count; /* TODO: bad password count */ +#if ABARTLET_HAS_FIXED_BUILD server_info->acct_flags = logon_info->acct_flags; +#endif if (!server_info->domain || !server_info->account_name || !server_info->realm) { free_server_info(&server_info); -- cgit From 4c06ac06a13eaff5b314ad97cce824d615c06f9a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 6 Nov 2004 05:40:34 +0000 Subject: r3572: Thanks to tridge for his patience with my build breakage. This concludes the proper fixes. Andrew Bartlett (This used to be commit c1d025793f2994c8f1cab304c3394ab186654071) --- source4/libcli/auth/gensec_krb5.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index a95780236e..37e96cf9dc 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -668,9 +668,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security server_info->logon_count = logon_info->logon_count; /* TODO: bad password count */ -#if ABARTLET_HAS_FIXED_BUILD server_info->acct_flags = logon_info->acct_flags; -#endif if (!server_info->domain || !server_info->account_name || !server_info->realm) { free_server_info(&server_info); -- cgit From 8408b3428d8c263f8453a0da8ef71e7fc1e4ec81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Nov 2004 20:15:39 +0000 Subject: r3583: - seperate the ldap client code and the ldap parsing code (vl: we should only sync the parsing code with trunk) - use hierachical talloc in the ldap client code metze (This used to be commit 1e9c0b68ca9ddb28877d45fc1b47653b13a7446d) --- source4/libcli/ldap/config.mk | 1 + source4/libcli/ldap/ldap.c | 655 +----------------------------------- source4/libcli/ldap/ldap_client.c | 690 ++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_ldif.c | 10 +- 4 files changed, 699 insertions(+), 657 deletions(-) create mode 100644 source4/libcli/ldap/ldap_client.c (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index ac047214ca..284edfd95e 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -2,6 +2,7 @@ # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] ADD_OBJ_FILES = libcli/ldap/ldap.o \ + libcli/ldap/ldap_client.o \ libcli/ldap/ldap_ldif.o # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6d2cef8bdb..315241e5b1 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -24,11 +24,8 @@ */ #include "includes.h" -#include "system/network.h" #include "system/iconv.h" -#include "auth/auth.h" #include "asn_1.h" -#include "dlinklist.h" /**************************************************************************** * @@ -1218,8 +1215,8 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16 *port, BOOL *ldaps) { int tmp_port = 0; - fstring protocol; - fstring tmp_host; + char protocol[11]; + char tmp_host[255]; const char *p = url; /* skip leading "URL:" (if any) */ @@ -1245,654 +1242,8 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, if (tmp_port != 0) *port = tmp_port; - + *host = talloc_strdup(mem_ctx, tmp_host); return (*host != NULL); } - -struct ldap_connection *new_ldap_connection(void) -{ - TALLOC_CTX *mem_ctx = talloc_init("ldap_connection"); - struct ldap_connection *result; - - if (mem_ctx == NULL) - return NULL; - - result = talloc(mem_ctx, sizeof(*result)); - - if (result == NULL) - return NULL; - - result->mem_ctx = mem_ctx; - result->next_msgid = 1; - result->outstanding = NULL; - result->searchid = 0; - result->search_entries = NULL; - result->auth_dn = NULL; - result->simple_pw = NULL; - result->gensec = NULL; - - return result; -} - -BOOL ldap_connect(struct ldap_connection *conn, const char *url) -{ - struct hostent *hp; - struct ipv4_addr ip; - - if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, - &conn->port, &conn->ldaps)) - return False; - - hp = sys_gethostbyname(conn->host); - - if ((hp == NULL) || (hp->h_addr == NULL)) - return False; - - putip((char *)&ip, (char *)hp->h_addr); - - conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); - - return (conn->sock >= 0); -} - -BOOL ldap_set_simple_creds(struct ldap_connection *conn, - const char *dn, const char *password) -{ - conn->auth_dn = talloc_strdup(conn->mem_ctx, dn); - conn->simple_pw = talloc_strdup(conn->mem_ctx, password); - - return ((conn->auth_dn != NULL) && (conn->simple_pw != NULL)); -} - -struct ldap_message *new_ldap_message(void) -{ - TALLOC_CTX *mem_ctx = talloc_init("ldap_message"); - struct ldap_message *result; - - if (mem_ctx == NULL) - return NULL; - - result = talloc(mem_ctx, sizeof(*result)); - - if (result == NULL) - return NULL; - - result->mem_ctx = mem_ctx; - return result; -} - -void destroy_ldap_message(struct ldap_message *msg) -{ - if (msg != NULL) - talloc_destroy(msg->mem_ctx); -} - -BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - DATA_BLOB request; - BOOL result; - struct ldap_queue_entry *entry; - - msg->messageid = conn->next_msgid++; - - if (!ldap_encode(msg, &request)) - return False; - - result = (write_data_until(conn->sock, request.data, request.length, - endtime) == request.length); - - data_blob_free(&request); - - if (!result) - return result; - - /* abandon and unbind don't expect results */ - - if ((msg->type == LDAP_TAG_AbandonRequest) || - (msg->type == LDAP_TAG_UnbindRequest)) - return True; - - entry = malloc(sizeof(*entry)); - - if (entry == NULL) - return False; - - entry->msgid = msg->messageid; - entry->msg = NULL; - DLIST_ADD(conn->outstanding, entry); - - return True; -} - -BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - struct asn1_data data; - BOOL result; - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return False; - - result = ldap_decode(&data, msg); - - asn1_free(&data); - return result; -} - -static struct ldap_message *recv_from_queue(struct ldap_connection *conn, - int msgid) -{ - struct ldap_queue_entry *e; - - for (e = conn->outstanding; e != NULL; e = e->next) { - - if (e->msgid == msgid) { - struct ldap_message *result = e->msg; - DLIST_REMOVE(conn->outstanding, e); - SAFE_FREE(e); - return result; - } - } - - return NULL; -} - -static void add_search_entry(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e = malloc(sizeof *e); - - if (e == NULL) - return; - - e->msg = msg; - DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); - return; -} - -static void fill_outstanding_request(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e; - - for (e = conn->outstanding; e != NULL; e = e->next) { - if (e->msgid == msg->messageid) { - e->msg = msg; - return; - } - } - - /* This reply has not been expected, destroy the incoming msg */ - destroy_ldap_message(msg); - return; -} - -struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) -{ - struct ldap_message *result = recv_from_queue(conn, msgid); - - if (result != NULL) - return result; - - while (True) { - struct asn1_data data; - BOOL res; - - result = new_ldap_message(); - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return NULL; - - res = ldap_decode(&data, result); - asn1_free(&data); - - if (!res) - return NULL; - - if (result->messageid == msgid) - return result; - - if (result->type == LDAP_TAG_SearchResultEntry) { - add_search_entry(conn, result); - } else { - fill_outstanding_request(conn, result); - } - } - - return NULL; -} - -struct ldap_message *ldap_transaction(struct ldap_connection *conn, - struct ldap_message *request) -{ - if (!ldap_send_msg(conn, request, NULL)) - return False; - - return ldap_receive(conn, request->messageid, NULL); -} - -int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) -{ - struct ldap_message *response; - struct ldap_message *msg; - const char *dn, *pw; - int result = LDAP_OTHER; - - if (conn == NULL) - return result; - - if (userdn) { - dn = userdn; - } else { - if (conn->auth_dn) { - dn = conn->auth_dn; - } else { - dn = ""; - } - } - - if (password) { - pw = password; - } else { - if (conn->simple_pw) { - pw = conn->simple_pw; - } else { - pw = ""; - } - } - - msg = new_ldap_simple_bind_msg(dn, pw); - if (!msg) - return result; - - response = ldap_transaction(conn, msg); - if (!response) { - destroy_ldap_message(msg); - return result; - } - - result = response->r.BindResponse.response.resultcode; - - destroy_ldap_message(msg); - destroy_ldap_message(response); - - return result; -} - -int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) -{ - NTSTATUS status; - TALLOC_CTX *mem_ctx = NULL; - struct ldap_message *response; - struct ldap_message *msg; - DATA_BLOB input = data_blob(NULL, 0); - DATA_BLOB output = data_blob(NULL, 0); - int result = LDAP_OTHER; - - if (conn == NULL) - return result; - - status = gensec_client_start(conn, &conn->gensec); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); - return result; - } - - gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); - - status = gensec_set_domain(conn->gensec, domain); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", - domain, nt_errstr(status))); - goto done; - } - - status = gensec_set_username(conn->gensec, username); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", - username, nt_errstr(status))); - goto done; - } - - status = gensec_set_password(conn->gensec, password); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client password: %s\n", - nt_errstr(status))); - goto done; - } - - status = gensec_set_target_hostname(conn->gensec, conn->host); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto done; - } - - status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", - nt_errstr(status))); - goto done; - } - - mem_ctx = talloc_init("ldap_bind_sasl"); - if (!mem_ctx) - goto done; - - status = gensec_update(conn->gensec, mem_ctx, - input, - &output); - - while(1) { - if (NT_STATUS_IS_OK(status) && output.length == 0) { - break; - } - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - break; - } - - msg = new_ldap_sasl_bind_msg("GSS-SPNEGO", &output); - if (!msg) - goto done; - - response = ldap_transaction(conn, msg); - destroy_ldap_message(msg); - - if (!response) { - goto done; - } - - result = response->r.BindResponse.response.resultcode; - - if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { - break; - } - - status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.secblob, - &output); - - destroy_ldap_message(response); - } - -done: - if (mem_ctx) - talloc_destroy(mem_ctx); - - return result; -} - -BOOL ldap_setup_connection(struct ldap_connection *conn, - const char *url, const char *userdn, const char *password) -{ - int result; - - if (!ldap_connect(conn, url)) { - return False; - } - - result = ldap_bind_simple(conn, userdn, password); - if (result == LDAP_SUCCESS) { - return True; - } - - return False; -} - -BOOL ldap_setup_connection_with_sasl(struct ldap_connection *conn, const char *url, const char *username, const char *domain, const char *password) -{ - int result; - - if (!ldap_connect(conn, url)) { - return False; - } - - result = ldap_bind_sasl(conn, username, domain, password); - if (result == LDAP_SUCCESS) { - return True; - } - - return False; -} - -static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) -{ - struct ldap_message *msg = new_ldap_message(); - BOOL result; - - if (msg == NULL) - return False; - - msg->type = LDAP_TAG_AbandonRequest; - msg->r.AbandonRequest.messageid = msgid; - - result = ldap_send_msg(conn, msg, endtime); - destroy_ldap_message(msg); - return result; -} - -struct ldap_message *new_ldap_search_message(const char *base, - enum ldap_scope scope, - char *filter, - int num_attributes, - const char **attributes) -{ - struct ldap_message *res = new_ldap_message(); - - if (res == NULL) - return NULL; - - res->type = LDAP_TAG_SearchRequest; - res->r.SearchRequest.basedn = base; - res->r.SearchRequest.scope = scope; - res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - res->r.SearchRequest.timelimit = 0; - res->r.SearchRequest.sizelimit = 0; - res->r.SearchRequest.attributesonly = False; - res->r.SearchRequest.filter = filter; - res->r.SearchRequest.num_attributes = num_attributes; - res->r.SearchRequest.attributes = attributes; - return res; -} - -struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw) -{ - struct ldap_message *res = new_ldap_message(); - - if (res == NULL) - return NULL; - - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); - res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); - return res; -} - -struct ldap_message *new_ldap_sasl_bind_msg(const char *sasl_mechanism, DATA_BLOB *secblob) -{ - struct ldap_message *res = new_ldap_message(); - - if (res == NULL) - return NULL; - - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = ""; - res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; - res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); - res->r.BindRequest.creds.SASL.secblob = *secblob; - return res; -} - -BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - if ((conn->searchid != 0) && - (!ldap_abandon_message(conn, conn->searchid, endtime))) - return False; - - conn->searchid = conn->next_msgid; - return ldap_send_msg(conn, msg, endtime); -} - -struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_message *result; - - if (conn->search_entries != NULL) { - struct ldap_queue_entry *e = conn->search_entries; - - result = e->msg; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - return result; - } - - result = ldap_receive(conn, conn->searchid, endtime); - if (!result) { - return NULL; - } - - if (result->type == LDAP_TAG_SearchResultEntry) - return result; - - if (result->type == LDAP_TAG_SearchResultDone) { - /* TODO: Handle Paged Results */ - destroy_ldap_message(result); - return NULL; - } - - /* TODO: Handle Search References here */ - return NULL; -} - -void ldap_endsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_queue_entry *e; - - e = conn->search_entries; - - while (e != NULL) { - struct ldap_queue_entry *next = e->next; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - e = next; - } -} - -struct ldap_message *ldap_searchone(struct ldap_connection *conn, - struct ldap_message *msg, - const struct timeval *endtime) -{ - struct ldap_message *res1, *res2 = NULL; - if (!ldap_setsearchent(conn, msg, endtime)) - return NULL; - - res1 = ldap_getsearchent(conn, endtime); - - if (res1 != NULL) - res2 = ldap_getsearchent(conn, endtime); - - ldap_endsearchent(conn, endtime); - - if (res1 == NULL) - return NULL; - - if (res2 != NULL) { - /* More than one entry */ - destroy_ldap_message(res1); - destroy_ldap_message(res2); - return NULL; - } - - return res1; -} - -BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, - DATA_BLOB *value) -{ - int i; - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - - if (msg->type != LDAP_TAG_SearchResultEntry) - return False; - - for (i=0; inum_attributes; i++) { - if (strequal(attr, r->attributes[i].name)) { - if (r->attributes[i].num_values != 1) - return False; - - *value = r->attributes[i].values[0]; - return True; - } - } - return False; -} - -BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, - TALLOC_CTX *mem_ctx, char **value) -{ - DATA_BLOB blob; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - *value = talloc(mem_ctx, blob.length+1); - - if (*value == NULL) - return False; - - memcpy(*value, blob.data, blob.length); - (*value)[blob.length] = '\0'; - return True; -} - -BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, - int *value) -{ - DATA_BLOB blob; - char *val; - int errno_save; - BOOL res; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - val = malloc(blob.length+1); - if (val == NULL) - return False; - - memcpy(val, blob.data, blob.length); - val[blob.length] = '\0'; - - errno_save = errno; - errno = 0; - - *value = strtol(val, NULL, 10); - - res = (errno == 0); - - free(val); - errno = errno_save; - - return res; -} - -int ldap_error(struct ldap_connection *conn) -{ - return 0; -} - -NTSTATUS ldap2nterror(int ldaperror) -{ - return NT_STATUS_OK; -} diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c new file mode 100644 index 0000000000..7a72734c57 --- /dev/null +++ b/source4/libcli/ldap/ldap_client.c @@ -0,0 +1,690 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + 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 "system/network.h" +#include "auth/auth.h" +#include "asn_1.h" +#include "dlinklist.h" + +#if 0 +static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn, + const char *base, + enum ldap_scope scope, + char *filter, + int num_attributes, + const char **attributes) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_SearchRequest; + res->r.SearchRequest.basedn = base; + res->r.SearchRequest.scope = scope; + res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + res->r.SearchRequest.timelimit = 0; + res->r.SearchRequest.sizelimit = 0; + res->r.SearchRequest.attributesonly = False; + res->r.SearchRequest.filter = filter; + res->r.SearchRequest.num_attributes = num_attributes; + res->r.SearchRequest.attributes = attributes; + + return res; +} +#endif + +static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, const char *dn, const char *pw) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); + + return res; +} + +static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, const char *sasl_mechanism, DATA_BLOB *secblob) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = ""; + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); + res->r.BindRequest.creds.SASL.secblob = *secblob; + + return res; +} + +static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) +{ + struct ldap_connection *result; + + result = talloc_p(mem_ctx, struct ldap_connection); + + if (!result) { + return NULL; + } + + result->mem_ctx = result; + result->next_msgid = 1; + result->outstanding = NULL; + result->searchid = 0; + result->search_entries = NULL; + result->auth_dn = NULL; + result->simple_pw = NULL; + result->gensec = NULL; + + return result; +} + +struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) +{ + struct hostent *hp; + struct ipv4_addr ip; + struct ldap_connection *conn; + BOOL ret; + + conn = new_ldap_connection(mem_ctx); + if (!conn) { + return NULL; + } + + ret = ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, + &conn->port, &conn->ldaps); + if (!ret) { + talloc_free(conn); + return NULL; + } + + hp = sys_gethostbyname(conn->host); + if (!hp || !hp->h_addr) { + talloc_free(conn); + return NULL; + } + + putip((char *)&ip, (char *)hp->h_addr); + + conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); + if (conn->sock < 0) { + talloc_free(conn); + return NULL; + } + + return conn; +} + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + struct ldap_message *result; + + result = talloc_p(mem_ctx, struct ldap_message); + + if (!result) { + return NULL; + } + + result->mem_ctx = result; + + return result; +} + +BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + DATA_BLOB request; + BOOL result; + struct ldap_queue_entry *entry; + + msg->messageid = conn->next_msgid++; + + if (!ldap_encode(msg, &request)) + return False; + + result = (write_data_until(conn->sock, request.data, request.length, + endtime) == request.length); + + data_blob_free(&request); + + if (!result) + return result; + + /* abandon and unbind don't expect results */ + + if ((msg->type == LDAP_TAG_AbandonRequest) || + (msg->type == LDAP_TAG_UnbindRequest)) + return True; + + entry = malloc(sizeof(*entry)); + + if (entry == NULL) + return False; + + entry->msgid = msg->messageid; + entry->msg = NULL; + DLIST_ADD(conn->outstanding, entry); + + return True; +} + +BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + struct asn1_data data; + BOOL result; + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return False; + + result = ldap_decode(&data, msg); + + asn1_free(&data); + return result; +} + +static struct ldap_message *recv_from_queue(struct ldap_connection *conn, + int msgid) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + + if (e->msgid == msgid) { + struct ldap_message *result = e->msg; + DLIST_REMOVE(conn->outstanding, e); + SAFE_FREE(e); + return result; + } + } + + return NULL; +} + +static void add_search_entry(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e = malloc(sizeof *e); + + if (e == NULL) + return; + + e->msg = msg; + DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); + return; +} + +static void fill_outstanding_request(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + if (e->msgid == msg->messageid) { + e->msg = msg; + return; + } + } + + /* This reply has not been expected, destroy the incoming msg */ + talloc_free(msg); + return; +} + +struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *result = recv_from_queue(conn, msgid); + + if (result != NULL) + return result; + + while (True) { + struct asn1_data data; + BOOL res; + + result = new_ldap_message(conn); + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return NULL; + + res = ldap_decode(&data, result); + asn1_free(&data); + + if (!res) + return NULL; + + if (result->messageid == msgid) + return result; + + if (result->type == LDAP_TAG_SearchResultEntry) { + add_search_entry(conn, result); + } else { + fill_outstanding_request(conn, result); + } + } + + return NULL; +} + +struct ldap_message *ldap_transaction(struct ldap_connection *conn, + struct ldap_message *request) +{ + if (!ldap_send_msg(conn, request, NULL)) + return False; + + return ldap_receive(conn, request->messageid, NULL); +} + +int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) +{ + struct ldap_message *response; + struct ldap_message *msg; + const char *dn, *pw; + int result = LDAP_OTHER; + + if (conn == NULL) + return result; + + if (userdn) { + dn = userdn; + } else { + if (conn->auth_dn) { + dn = conn->auth_dn; + } else { + dn = ""; + } + } + + if (password) { + pw = password; + } else { + if (conn->simple_pw) { + pw = conn->simple_pw; + } else { + pw = ""; + } + } + + msg = new_ldap_simple_bind_msg(conn, dn, pw); + if (!msg) + return result; + + response = ldap_transaction(conn, msg); + if (!response) { + talloc_free(msg); + return result; + } + + result = response->r.BindResponse.response.resultcode; + + talloc_free(msg); + talloc_free(response); + + return result; +} + +int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + struct ldap_message *response; + struct ldap_message *msg; + DATA_BLOB input = data_blob(NULL, 0); + DATA_BLOB output = data_blob(NULL, 0); + int result = LDAP_OTHER; + + if (conn == NULL) + return result; + + status = gensec_client_start(conn, &conn->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); + return result; + } + + gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); + + status = gensec_set_domain(conn->gensec, domain); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", + domain, nt_errstr(status))); + goto done; + } + + status = gensec_set_username(conn->gensec, username); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", + username, nt_errstr(status))); + goto done; + } + + status = gensec_set_password(conn->gensec, password); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto done; + } + + mem_ctx = talloc_init("ldap_bind_sasl"); + if (!mem_ctx) + goto done; + + status = gensec_update(conn->gensec, mem_ctx, + input, + &output); + + while(1) { + if (NT_STATUS_IS_OK(status) && output.length == 0) { + break; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { + break; + } + + msg = new_ldap_sasl_bind_msg(conn, "GSS-SPNEGO", &output); + if (!msg) + goto done; + + response = ldap_transaction(conn, msg); + talloc_free(msg); + + if (!response) { + goto done; + } + + result = response->r.BindResponse.response.resultcode; + + if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + break; + } + + status = gensec_update(conn->gensec, mem_ctx, + response->r.BindResponse.SASL.secblob, + &output); + + talloc_free(response); + } + +done: + if (mem_ctx) + talloc_destroy(mem_ctx); + + return result; +} + +struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, + const char *userdn, const char *password) +{ + struct ldap_connection *conn; + int result; + + conn =ldap_connect(mem_ctx, url); + if (!conn) { + return NULL; + } + + result = ldap_bind_simple(conn, userdn, password); + if (result != LDAP_SUCCESS) { + talloc_free(conn); + return NULL; + } + + return conn; +} + +struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, + const char *username, const char *domain, const char *password) +{ + struct ldap_connection *conn; + int result; + + conn =ldap_connect(mem_ctx, url); + if (!conn) { + return NULL; + } + + result = ldap_bind_sasl(conn, username, domain, password); + if (result != LDAP_SUCCESS) { + talloc_free(conn); + return NULL; + } + + return conn; +} + +BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *msg = new_ldap_message(conn); + BOOL result; + + if (msg == NULL) + return False; + + msg->type = LDAP_TAG_AbandonRequest; + msg->r.AbandonRequest.messageid = msgid; + + result = ldap_send_msg(conn, msg, endtime); + talloc_free(msg); + return result; +} + +BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + if ((conn->searchid != 0) && + (!ldap_abandon_message(conn, conn->searchid, endtime))) + return False; + + conn->searchid = conn->next_msgid; + return ldap_send_msg(conn, msg, endtime); +} + +struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_message *result; + + if (conn->search_entries != NULL) { + struct ldap_queue_entry *e = conn->search_entries; + + result = e->msg; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + return result; + } + + result = ldap_receive(conn, conn->searchid, endtime); + if (!result) { + return NULL; + } + + if (result->type == LDAP_TAG_SearchResultEntry) + return result; + + if (result->type == LDAP_TAG_SearchResultDone) { + /* TODO: Handle Paged Results */ + talloc_free(result); + return NULL; + } + + /* TODO: Handle Search References here */ + return NULL; +} + +void ldap_endsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_queue_entry *e; + + e = conn->search_entries; + + while (e != NULL) { + struct ldap_queue_entry *next = e->next; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + e = next; + } +} + +struct ldap_message *ldap_searchone(struct ldap_connection *conn, + struct ldap_message *msg, + const struct timeval *endtime) +{ + struct ldap_message *res1, *res2 = NULL; + if (!ldap_setsearchent(conn, msg, endtime)) + return NULL; + + res1 = ldap_getsearchent(conn, endtime); + + if (res1 != NULL) + res2 = ldap_getsearchent(conn, endtime); + + ldap_endsearchent(conn, endtime); + + if (res1 == NULL) + return NULL; + + if (res2 != NULL) { + /* More than one entry */ + talloc_free(res1); + talloc_free(res2); + return NULL; + } + + return res1; +} + +BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, + DATA_BLOB *value) +{ + int i; + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + + if (msg->type != LDAP_TAG_SearchResultEntry) + return False; + + for (i=0; inum_attributes; i++) { + if (strequal(attr, r->attributes[i].name)) { + if (r->attributes[i].num_values != 1) + return False; + + *value = r->attributes[i].values[0]; + return True; + } + } + return False; +} + +BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, + TALLOC_CTX *mem_ctx, char **value) +{ + DATA_BLOB blob; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + *value = talloc(mem_ctx, blob.length+1); + + if (*value == NULL) + return False; + + memcpy(*value, blob.data, blob.length); + (*value)[blob.length] = '\0'; + return True; +} + +BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, + int *value) +{ + DATA_BLOB blob; + char *val; + int errno_save; + BOOL res; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + val = malloc(blob.length+1); + if (val == NULL) + return False; + + memcpy(val, blob.data, blob.length); + val[blob.length] = '\0'; + + errno_save = errno; + errno = 0; + + *value = strtol(val, NULL, 10); + + res = (errno == 0); + + free(val); + errno = errno_save; + + return res; +} + +int ldap_error(struct ldap_connection *conn) +{ + return 0; +} + +NTSTATUS ldap2nterror(int ldaperror) +{ + return NT_STATUS_OK; +} diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 19f4e56e73..c276b7e917 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -307,7 +307,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) /* read from a LDIF source, creating a ldap_message */ -static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), +static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *), void *private_data) { struct ldap_message *msg; @@ -318,7 +318,7 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), value.data = NULL; - msg = new_ldap_message(); + msg = new_ldap_message(mem_ctx); if (msg == NULL) return NULL; @@ -383,7 +383,7 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); failed: - destroy_ldap_message(msg); + talloc_free(msg); return NULL; } @@ -403,10 +403,10 @@ static int fgetc_string(void *private_data) return EOF; } -struct ldap_message *ldap_ldif2msg(const char *s) +struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s) { struct ldif_read_string_state state; state.s = s; - return ldif_read(fgetc_string, &state); + return ldif_read(mem_ctx, fgetc_string, &state); } -- cgit From e5c8e21129a2144633b518979f9a66eb8953dae6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Nov 2004 20:43:36 +0000 Subject: r3584: fix referral handling metze (This used to be commit 4868f1ea857e94f60dbde83bfb54def8a5ee728f) --- source4/libcli/ldap/ldap.c | 15 ++++++++++++--- source4/libcli/ldap/ldap.h | 3 +-- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 315241e5b1..2eea7b035a 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -361,9 +361,12 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res asn1_write_OctetString(data, result->errormessage, (result->errormessage) ? strlen(result->errormessage) : 0); - if (result->referral != NULL) + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, result->referral, strlen(result->referral)); + asn1_pop_tag(data); + } } BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) @@ -620,7 +623,10 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) break; } case LDAP_TAG_SearchResultReference: { -/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(&data, r->referral, strlen(r->referral)); + asn1_pop_tag(&data); break; } case LDAP_TAG_ExtendedRequest: { @@ -957,8 +963,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { -/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->referral); + asn1_end_tag(data); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index c27aba8d7a..65962bf5b5 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -161,8 +161,7 @@ struct ldap_SearchResEntry { }; struct ldap_SearchResRef { - int num_referrals; - const char **referrals; + const char *referral; }; enum ldap_modify_type { -- cgit From b012ab557b8f8a2f58dfbbe8b7818f3e6d8cf38f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Nov 2004 21:51:22 +0000 Subject: r3585: check sscanf return code metze (This used to be commit 9701abfa3a5f6351c8c7bced6adb751be9f5ff31) --- source4/libcli/ldap/ldap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2eea7b035a..dd689027f9 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1227,6 +1227,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char protocol[11]; char tmp_host[255]; const char *p = url; + int ret; /* skip leading "URL:" (if any) */ if (strncasecmp( p, "URL:", 4) == 0) { @@ -1236,7 +1237,10 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, /* Paranoia check */ SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); - sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + if (ret < 2) { + return False; + } if (strequal(protocol, "ldap")) { *port = 389; -- cgit From 71db46ea665606384f2be1be708c74c97c9adfb2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Nov 2004 23:23:15 +0000 Subject: r3586: Fix some of the issues with the module init functions. Both subsystems and modules can now have init functions, which can be specified in .mk files (INIT_FUNCTION = ...) The build system will define : - SUBSYSTEM_init_static_modules that calls the init functions of all statically compiled modules. Failing to load will generate an error which is not fatal - BINARY_init_subsystems that calls the init functions (if defined) for the subsystems the binary depends on This removes the hack with the "static bool Initialised = " and the "lazy_init" functions (This used to be commit 7a8244761bfdfdfb48f8264d76951ebdfbf7bd8a) --- source4/libcli/auth/gensec.c | 25 ++++++------------------- source4/libcli/auth/gensec.mk | 4 ++++ 2 files changed, 10 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index aab1928687..6bc33ab66d 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -120,11 +120,6 @@ const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) */ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { - /* awaiting a correct fix from metze */ - if (!gensec_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; @@ -806,25 +801,17 @@ const struct gensec_critical_sizes *gensec_interface_version(void) /* initialise the GENSEC subsystem */ -BOOL gensec_init(void) +NTSTATUS gensec_init(void) { - static BOOL initialised; - NTSTATUS status; - - /* this is *completely* the wrong way to do this */ - if (initialised) { - return True; - } - - status = register_subsystem("gensec", gensec_register); + NTSTATUS status = register_subsystem("gensec", gensec_register); if (!NT_STATUS_IS_OK(status)) { - return False; + return status; } - static_init_gensec; + gensec_init_static_modules; + gensec_dcerpc_schannel_init(); - initialised = True; DEBUG(3,("GENSEC subsystem version %d initialised\n", GENSEC_INTERFACE_VERSION)); - return True; + return NT_STATUS_OK; } diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index bab79ea2fd..1372a91ea2 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM GENSEC [SUBSYSTEM::GENSEC] +INIT_FUNCTION = gensec_init INIT_OBJ_FILES = libcli/auth/gensec.o REQUIRED_SUBSYSTEMS = \ SCHANNELDB @@ -10,6 +11,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start MODULE gensec_krb5 [MODULE::gensec_krb5] +INIT_FUNCTION = gensec_krb5_init INIT_OBJ_FILES = libcli/auth/gensec_krb5.o ADD_OBJ_FILES = \ libcli/auth/clikrb5.o \ @@ -24,6 +26,7 @@ REQUIRED_LIBRARIES = KRB5 ################################################ # Start MODULE gensec_spnego [MODULE::gensec_spnego] +INIT_FUNCTION = gensec_spnego_init INIT_OBJ_FILES = libcli/auth/spnego.o ADD_OBJ_FILES = \ libcli/auth/spnego_parse.o @@ -34,6 +37,7 @@ REQUIRED_SUBSYSTEMS = GENSEC ################################################ # Start MODULE gensec_ntlmssp [MODULE::gensec_ntlmssp] +INIT_FUNCTION = gensec_ntlmssp_init INIT_OBJ_FILES = libcli/auth/gensec_ntlmssp.o ADD_OBJ_FILES = \ libcli/auth/ntlmssp.o \ -- cgit From 70bb74eefd364908ec1234dd5a3ecf7090f7fad5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 7 Nov 2004 10:00:32 +0000 Subject: r3591: to get a bit more useful info from valgrind I'm disabling the deliberate over-allocation of request structures in smbd and libcli/raw code for now. (This used to be commit 07596d87213e8ccbf6a0e7bc216d692065f43403) --- source4/libcli/raw/rawrequest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 0526fec74b..8d0767b3f5 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -28,7 +28,7 @@ #include "dlinklist.h" /* we over allocate the data buffer to prevent too many realloc calls */ -#define REQ_OVER_ALLOCATION 256 +#define REQ_OVER_ALLOCATION 0 /* assume that a character will not consume more than 3 bytes per char */ #define MAX_BYTES_PER_CHAR 3 -- cgit From 438ca20a3c415d05bb796a3c59bddf5a649bcc5e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Nov 2004 01:46:00 +0000 Subject: r3609: Lets spew out a few less error messages for tridge, and hope to get krb5 going on recent heimdal installs. Andrew Bartlett (This used to be commit a758725407df0c87922a15aa32cc841bc4c059a2) --- source4/libcli/auth/clikrb5.c | 2 +- source4/libcli/auth/gensec_krb5.c | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 82311e625b..b5158a038a 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -326,7 +326,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, } if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { - DEBUG(1,("krb5_cc_get_principal failed (%s)\n", + DEBUG(10,("krb5_cc_get_principal failed (%s)\n", error_message(retval))); goto cleanup_creds; } diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 37e96cf9dc..feb78a016b 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -353,10 +353,6 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_security->target.principal, gensec_krb5_state->krb5_ccache, &gensec_krb5_state->ticket); - if (ret) { - DEBUG(1,("ads_krb5_mk_req failed (%s)\n", - error_message(ret))); - } } else { krb5_data in_data; const char *hostname = gensec_get_target_hostname(gensec_security); @@ -374,10 +370,6 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security hostname, &in_data, gensec_krb5_state->krb5_ccache, &gensec_krb5_state->ticket); - if (ret) { - DEBUG(1,("krb5_mk_req failed (%s)\n", - error_message(ret))); - } } switch (ret) { @@ -391,13 +383,14 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security case KRB5KRB_AP_ERR_TKT_EXPIRED: case KRB5_CC_END: { - DEBUG(3, ("kerberos: %s\n", + DEBUG(3, ("kerberos (mk_req) failed: %s\n", error_message(ret))); /* fall down to remaining code */ } /* just don't print a message for these really ordinary messages */ case KRB5_FCC_NOFILE: case KRB5_CC_NOTFOUND: + case ENOENT: { char *password; time_t kdc_time = 0; -- cgit From 009892846fb25e6698c8e38c46cae3512abb7ec6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Nov 2004 02:01:05 +0000 Subject: r3610: prevent segv with heimdal and password krb5 init (This used to be commit a4598e7fa17c7ec0fed9cb81f5a0fb30b133861b) --- source4/libcli/auth/kerberos.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index d70444d5bc..224e4abbdc 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -61,14 +61,17 @@ kerb_prompter(krb5_context ctx, void *data, krb5_error_code code = 0; krb5_principal me; krb5_creds my_creds; + krb5_get_init_creds_opt options; if ((code = krb5_parse_name(ctx, principal, &me))) { return code; } - + + ZERO_STRUCT(options); + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, - NULL, 0, NULL, NULL))) { + NULL, 0, NULL, &options))) { krb5_free_principal(ctx, me); return code; } -- cgit From 3dbc38fd6b19538e2325a1901659ead4e0a9db40 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Nov 2004 02:28:12 +0000 Subject: r3612: This appears to be the 'offical' way to initialise this struct. Andrew Bartlett (This used to be commit 47d67c6e5b265e4192fcae0d9cd72b3ac097785e) --- source4/libcli/auth/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 224e4abbdc..50f2e0f24e 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -67,7 +67,7 @@ kerb_prompter(krb5_context ctx, void *data, return code; } - ZERO_STRUCT(options); + krb5_get_init_creds_opt_init(&options); if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, -- cgit From ce51a06f029e78212b3f02e1433f050bec394152 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Nov 2004 02:43:49 +0000 Subject: r3613: fixed a typo (This used to be commit 891e3097ee00d75f8f28efcccd8c15cd08b80e88) --- source4/libcli/auth/gensec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 6bc33ab66d..88b1081b11 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -201,7 +201,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) if (gensec_security->ops->client_start) { status = gensec_security->ops->client_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Faild to start GENSEC client mech %s: %s\n", + DEBUG(1, ("Failed to start GENSEC client mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; @@ -210,7 +210,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) if (gensec_security->ops->server_start) { status = gensec_security->ops->server_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Faild to start GENSEC server mech %s: %s\n", + DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; -- cgit From 0639758dd9b19926baac1fd5636d00e3a3d23404 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 9 Nov 2004 01:04:29 +0000 Subject: r3630: More work on DCOM server side (This used to be commit e995a1c0e5d2ee2dc50c31c01ce281a303dd5231) --- source4/libcli/auth/gensec_ntlmssp.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 8ab90ebcfb..c033705f10 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -442,8 +442,5 @@ NTSTATUS gensec_ntlmssp_init(void) return ret; } - /* ugly cludge, but we need the auth subsystem for this to work */ - auth_init(); - return ret; } -- cgit From 017bf499d44d23c50406fb9647f9a2161be395f0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Nov 2004 04:52:22 +0000 Subject: r3652: Fix malloc-history dependent failures in smbtorture. Because -r 3591 removed the over-allocation, realloc() had a chance of returning a different pointer. This broke the length calculations in the trans2 send code. I think the length calculations coudld be better expressed (less cute PTR_DIFF tricks) but I'm not going to touch this any more than I need to. Andrew Bartlett (This used to be commit 4bfc916a2c3b9745f47ce4eaa892cdcc431e19db) --- source4/libcli/raw/rawtrans.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 32c12382f6..111a7ded2a 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -222,7 +222,13 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, if (!req) { return NULL; } - + + /* Watch out, this changes the req->out.* pointers */ + if (command == SMBtrans && parms->in.trans_name) { + namelen = smbcli_req_append_string(req, parms->in.trans_name, + STR_TERMINATE); + } + /* fill in SMB parameters */ outparam = req->out.data + padding; outdata = outparam + parms->in.params.length; @@ -230,11 +236,6 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, /* make sure we don't leak data via the padding */ memset(req->out.data, 0, padding); - if (command == SMBtrans && parms->in.trans_name) { - namelen = smbcli_req_append_string(req, parms->in.trans_name, - STR_TERMINATE); - } - /* primary request */ SSVAL(req->out.vwv,VWV(0),parms->in.params.length); SSVAL(req->out.vwv,VWV(1),parms->in.data.length); -- cgit From cb700e90c22d9e301a05142699df7b64402a08d8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Nov 2004 10:56:43 +0000 Subject: r3654: Add static and fix indentation. Andrew Bartlett (This used to be commit cef31134ec4cd09eafd4f9f8f64e5fe3d68f19de) --- source4/libcli/raw/rawreadwrite.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 4978514d26..8381c7b2b0 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -256,7 +256,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr } if (!smbcli_request_send(req)) { -smbcli_request_destroy(req); + smbcli_request_destroy(req); return NULL; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 8d0767b3f5..b56bfa9a3c 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -225,7 +225,7 @@ static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_si To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ -void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) +static void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) { int delta; -- cgit From 5805c780dc6d78c2cc4a86d07155db807a80bac7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Nov 2004 10:58:15 +0000 Subject: r3655: As required by the new torture test, add the LM session key output parameter to SMBNTLMv2encrypt(). Andrew Bartlett (This used to be commit 75ff351faf0a3231e17f000b006beb9cb545d905) --- source4/libcli/auth/ntlmssp.c | 3 ++- source4/libcli/util/smbencrypt.c | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 55a80d0d5e..f0003279e5 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -1104,7 +1104,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->domain, ntlmssp_state->password, &challenge_blob, &struct_blob, - &lm_response, &nt_response, &session_key)) { + &lm_response, &nt_response, + NULL, &session_key)) { data_blob_free(&challenge_blob); data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 6034c0e327..d327b53f9d 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -378,7 +378,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *user_session_key) + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) { uint8_t nt_hash[16]; uint8_t ntlm_v2_hash[16]; @@ -408,6 +408,13 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password if (lm_response) { *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); + if (lm_session_key) { + *lm_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of lm_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); + } } return True; -- cgit From a8db4dcf03bccb2e1b954d097e758d6c7780db9e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Nov 2004 04:32:01 +0000 Subject: r3677: Seperate the SamLogon tests from the main RPC-NETLOGON test into a RPC-SAMLOGON of their own. I have expanded the tests to validate the use of various flags, which change some of the crypto behaviour. Andrew Bartlett (This used to be commit 3a140a3691ce49ebf4d1efcb99cfffd26c68a28f) --- source4/libcli/auth/credentials.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index a09d767e89..ec41ebf4bd 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -25,6 +25,7 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" +#include "librpc/gen_ndr/ndr_netlogon.h" /* initialise the credentials state for old-style 64 bit session keys @@ -128,6 +129,26 @@ static void creds_step(struct creds_CredentialState *creds) } +/* + DES encrypt a 8 byte LMSessionKey buffer using the Netlogon session key +*/ +void creds_des_encrypt_LMKey(struct creds_CredentialState *creds, struct netr_LMSessionKey *key) +{ + struct netr_LMSessionKey tmp; + des_crypt56(tmp.key, key->key, creds->session_key, 1); + *key = tmp; +} + +/* + DES decrypt a 8 byte LMSessionKey buffer using the Netlogon session key +*/ +void creds_des_decrypt_LMKey(struct creds_CredentialState *creds, struct netr_LMSessionKey *key) +{ + struct netr_LMSessionKey tmp; + des_crypt56(tmp.key, key->key, creds->session_key, 0); + *key = tmp; +} + /* DES encrypt a 16 byte password buffer using the session key */ -- cgit From 189783e5b9dabdb12fdff0381f8145aea57b5be6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Nov 2004 05:04:22 +0000 Subject: r3679: We now know a few more of the Netlogon negotiate flags. Interestingly, all the interesting flags are a '4' (as hex digits in the flag). Andrew Bartlett (This used to be commit 295e09fa3ea2cae48da1e934c1ec180e5678f0c9) --- source4/libcli/auth/credentials.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index de0e086278..a6e119e1ad 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -30,16 +30,19 @@ struct creds_CredentialState { }; -#define NETLOGON_NEG_128BIT 0x4000 - /* for the timebeing, use the same neg flags as Samba3. */ /* The 7 here seems to be required to get Win2k not to downgrade us to NT4. Actually, anything other than 1ff would seem to do... */ -#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff +#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff + + +#define NETLOGON_NEG_ARCFOUR 0x00000004 +#define NETLOGON_NEG_128BIT 0x00004000 + +#define NETLOGON_NEG_SCHANNEL 0x40000000 /* these are the flags that ADS clients use */ -#define NETLOGON_NEG_AUTH2_ADS_FLAGS 0x600fffff +#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL) -#define NETLOGON_NEG_SCHANNEL 0x40000000 -- cgit From fd5135a63b4c81688c4e2d729380ca954f22286d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Nov 2004 23:24:30 +0000 Subject: r3686: The results of some work on the NETLOGON pipe: Break out the samsync tests from RPC-NETLOGON into a new RPC-SAMSYNC, that will cross-verify all the values. Add support for the way netlogon credentials are shared between the pipe that sets up schannel and the pipe that is encrypted with it. Test this support, by calling both NETLOGON and SAMR operations in the RPC-SCHANNEL test. Move some of the Netlogon NEG flags into the .idl, now we have an idea what a few of them really are. Rename the sam_pwd_hash into a name that has meaning (all other crypto functions were renamed in Samba4 ages ago). Break out NTLMv2 functionality for operation on the NT hash - I intend to do NTLMv2 logins in the samsync test in future, and naturally I only have the hash. Andrew Bartlett (This used to be commit 6e6cc6fb9842113a1b0c7f6904dac709b320a6e5) --- source4/libcli/auth/credentials.h | 6 ------ source4/libcli/auth/gensec.h | 1 - source4/libcli/util/smbdes.c | 2 +- source4/libcli/util/smbencrypt.c | 25 ++++++++++++++++++------- 4 files changed, 19 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index a6e119e1ad..30114fe7fa 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -36,12 +36,6 @@ struct creds_CredentialState { to NT4. Actually, anything other than 1ff would seem to do... */ #define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff - -#define NETLOGON_NEG_ARCFOUR 0x00000004 -#define NETLOGON_NEG_128BIT 0x00004000 - -#define NETLOGON_NEG_SCHANNEL 0x40000000 - /* these are the flags that ADS clients use */ #define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL) diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index b2c685332b..23d9861cb7 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -28,7 +28,6 @@ struct gensec_user { const char *realm; const char *name; const char *password; - char schan_session_key[16]; }; struct gensec_target { const char *principal; diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index a7c8f760ea..4e4222b9e6 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -439,7 +439,7 @@ void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len) /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ -void sam_pwd_hash(uint_t rid, const uint8_t *in, uint8_t *out, int forw) +void sam_rid_crypt(uint_t rid, const uint8_t *in, uint8_t *out, int forw) { uint8_t s[14]; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index d327b53f9d..dac8674f03 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -374,15 +374,13 @@ static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], return final_response; } -BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) +BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const char nt_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) { - uint8_t nt_hash[16]; uint8_t ntlm_v2_hash[16]; - E_md4hash(password, nt_hash); /* We don't use the NT# directly. Instead we use it mashed up with the username and domain. @@ -420,6 +418,19 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password return True; } +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) +{ + uint8_t nt_hash[16]; + E_md4hash(password, nt_hash); + + return SMBNTLMv2encrypt_hash(user, domain, nt_hash, server_chal, names_blob, + lm_response, nt_response, lm_session_key, user_session_key); +} + /*********************************************************** encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. -- cgit From 2f8804631d9b26dbc58a385788764b1cbb74ce91 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 13 Nov 2004 07:44:50 +0000 Subject: r3721: We cracked the NTLM2 puzzle long ago, and set the flags elsewhere. Remove the conditional set. Andrew Bartlett (This used to be commit f5d8a4dde58a88408892501fd3ce53f19e67f1f1) --- source4/libcli/auth/gensec_ntlmssp.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index c033705f10..e774efe94e 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -186,14 +186,6 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - /* IF we are not doing Signing or Sealing, we can actually do - * NTLM2. When we crack the crypto puzzle, then we can enable - * this always, in the constant flags */ - - if (!(gensec_security->want_features & GENSEC_WANT_SIGN) && !(gensec_security->want_features & GENSEC_WANT_SEAL)) { - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; nt_status = make_auth_context_subsystem(gensec_security, &gensec_ntlmssp_state->auth_context); if (!NT_STATUS_IS_OK(nt_status)) { @@ -247,14 +239,6 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - /* IF we are not doing Signing or Sealing, we can actually do - * NTLM2. When we crack the crypto puzzle, then we can enable - * this always, in the constant flags */ - - if (!(gensec_security->want_features & GENSEC_WANT_SIGN) && !(gensec_security->want_features & GENSEC_WANT_SEAL)) { - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, gensec_security->user.domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From 7367d23713a34a6c29a492adb365292399adffe8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 13:52:16 +0000 Subject: r3730: More build system fixes and simplifications the hierarchy in the init functions is correct now will also make it easier to implement some other features (This used to be commit cbe819a75568403ac8850ea4d344c607a46d61c2) --- source4/libcli/auth/gensec.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index 1372a91ea2..ac778ad5c8 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -18,8 +18,7 @@ ADD_OBJ_FILES = \ libcli/auth/kerberos.o \ libcli/auth/kerberos_verify.o \ libcli/auth/gssapi_parse.o -REQUIRED_SUBSYSTEMS = GENSEC -REQUIRED_LIBRARIES = KRB5 +REQUIRED_SUBSYSTEMS = GENSEC EXT_LIB_KRB5 # End MODULE gensec_krb5 ################################################ -- cgit From 8e16d8a76f8a3b8ccc89eb317c8e5daa6cf43b71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 16:22:01 +0000 Subject: r3733: More build system fixes/features: - Use .mk files directly (no need for a SMB_*_MK() macro when adding a new SUBSYSTEM, MODULE or BINARY). This allows addition of new modules and subsystems without running configure - Add support for generating .dot files with the Samba4 dependency tree (as used by the graphviz and springgraph utilities) (This used to be commit 64826da834e26ee0488674e27a0eae36491ee179) --- source4/libcli/auth/config.m4 | 1 - source4/libcli/auth/gensec.m4 | 5 ----- source4/libcli/auth/gensec.mk | 3 +++ source4/libcli/ldap/config.m4 | 1 - 4 files changed, 3 insertions(+), 7 deletions(-) delete mode 100644 source4/libcli/auth/config.m4 delete mode 100644 source4/libcli/ldap/config.m4 (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.m4 b/source4/libcli/auth/config.m4 deleted file mode 100644 index ae189d651e..0000000000 --- a/source4/libcli/auth/config.m4 +++ /dev/null @@ -1 +0,0 @@ -SMB_SUBSYSTEM_MK(LIBCLI_AUTH,libcli/auth/config.mk) diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 1894e1c136..768a2fae57 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -2,8 +2,3 @@ if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then /* enable this when krb5 is fully working */ SMB_MODULE_DEFAULT(gensec_krb5, NOT) fi - -SMB_SUBSYSTEM_MK(GENSEC,libcli/auth/gensec.mk) -SMB_MODULE_MK(gensec_krb5, GENSEC, NOT, libcli/auth/gensec.mk) -SMB_MODULE_MK(gensec_ntlmssp, GENSEC, STATIC, libcli/auth/gensec.mk) -SMB_MODULE_MK(gensec_spnego, GENSEC, STATIC, libcli/auth/gensec.mk) diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index ac778ad5c8..b6332bd68b 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -11,6 +11,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start MODULE gensec_krb5 [MODULE::gensec_krb5] +SUBSYSTEM = GENSEC INIT_FUNCTION = gensec_krb5_init INIT_OBJ_FILES = libcli/auth/gensec_krb5.o ADD_OBJ_FILES = \ @@ -25,6 +26,7 @@ REQUIRED_SUBSYSTEMS = GENSEC EXT_LIB_KRB5 ################################################ # Start MODULE gensec_spnego [MODULE::gensec_spnego] +SUBSYSTEM = GENSEC INIT_FUNCTION = gensec_spnego_init INIT_OBJ_FILES = libcli/auth/spnego.o ADD_OBJ_FILES = \ @@ -36,6 +38,7 @@ REQUIRED_SUBSYSTEMS = GENSEC ################################################ # Start MODULE gensec_ntlmssp [MODULE::gensec_ntlmssp] +SUBSYSTEM = GENSEC INIT_FUNCTION = gensec_ntlmssp_init INIT_OBJ_FILES = libcli/auth/gensec_ntlmssp.o ADD_OBJ_FILES = \ diff --git a/source4/libcli/ldap/config.m4 b/source4/libcli/ldap/config.m4 deleted file mode 100644 index 01f78279bf..0000000000 --- a/source4/libcli/ldap/config.m4 +++ /dev/null @@ -1 +0,0 @@ -SMB_SUBSYSTEM_MK(LIBCLI_LDAP,libcli/ldap/config.mk) -- cgit From 1817b3d4a533ca548141fec473843414c4a4196d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 16:51:32 +0000 Subject: r3735: Allow building subsystems as static libraries (.a files). To enable this support, run SUBSYSTEM_OUTPUT_TYPE=STATIC_LIBRARY ./config.status I haven't enabled this by default because there are some circular dependencies in the makefile that have to be resolved first (LIBRPC depends on LIBSMB and LIBSMB depends on LIBRPC..) (This used to be commit fc0432069bf3569a47a7c32f4bf789cec2ca44db) --- source4/libcli/auth/gensec.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index b6332bd68b..30da8aaa0e 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -19,7 +19,7 @@ ADD_OBJ_FILES = \ libcli/auth/kerberos.o \ libcli/auth/kerberos_verify.o \ libcli/auth/gssapi_parse.o -REQUIRED_SUBSYSTEMS = GENSEC EXT_LIB_KRB5 +REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 # End MODULE gensec_krb5 ################################################ @@ -31,7 +31,6 @@ INIT_FUNCTION = gensec_spnego_init INIT_OBJ_FILES = libcli/auth/spnego.o ADD_OBJ_FILES = \ libcli/auth/spnego_parse.o -REQUIRED_SUBSYSTEMS = GENSEC # End MODULE gensec_spnego ################################################ @@ -45,6 +44,6 @@ ADD_OBJ_FILES = \ libcli/auth/ntlmssp.o \ libcli/auth/ntlmssp_parse.o \ libcli/auth/ntlmssp_sign.o -REQUIRED_SUBSYSTEMS = GENSEC AUTH +REQUIRED_SUBSYSTEMS = AUTH # End MODULE gensec_ntlmssp ################################################ -- cgit From 31ded4901b4529ad2e49871502cab5ecba71483a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 22:23:23 +0000 Subject: r3737: - Get rid of the register_subsystem() and register_backend() functions. - Re-disable tdbtool (it was building fine on my Debian box but other machines were having problems) (This used to be commit 0d7bb2c40b7a9ed59df3f8944133ea562697e814) --- source4/libcli/auth/gensec.c | 11 +---------- source4/libcli/auth/gensec_ntlmssp.c | 2 +- source4/libcli/auth/spnego.c | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 88b1081b11..360a69c0e0 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -751,7 +751,7 @@ NTSTATUS gensec_get_password(struct gensec_security *gensec_security, The 'name' can be later used by other backends to find the operations structure for this backend. */ -static NTSTATUS gensec_register(const void *_ops) +NTSTATUS gensec_register(const void *_ops) { const struct gensec_security_ops *ops = _ops; @@ -803,15 +803,6 @@ const struct gensec_critical_sizes *gensec_interface_version(void) */ NTSTATUS gensec_init(void) { - NTSTATUS status = register_subsystem("gensec", gensec_register); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - gensec_init_static_modules; - gensec_dcerpc_schannel_init(); - - DEBUG(3,("GENSEC subsystem version %d initialised\n", GENSEC_INTERFACE_VERSION)); return NT_STATUS_OK; } diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index e774efe94e..ee8d1aa79c 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -419,7 +419,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { NTSTATUS gensec_ntlmssp_init(void) { NTSTATUS ret; - ret = register_backend("gensec", &gensec_ntlmssp_security_ops); + ret = gensec_register(&gensec_ntlmssp_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", gensec_ntlmssp_security_ops.name)); diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index ab3aff32bb..bafbf64294 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -714,7 +714,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { NTSTATUS gensec_spnego_init(void) { NTSTATUS ret; - ret = register_backend("gensec", &gensec_spnego_security_ops); + ret = gensec_register(&gensec_spnego_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", gensec_spnego_security_ops.name)); -- cgit From 3757bf5c5bd1e218ea8153964d69c00a164a17e5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 22:47:39 +0000 Subject: r3739: Remove a bunch of unused m4 macros (This used to be commit 2a38b77a1d8674b46028214896e37747c4082f13) --- source4/libcli/auth/gensec_krb5.c | 4 ++-- source4/libcli/libsmb.m4 | 12 ------------ source4/libcli/libsmb.mk | 11 +++++++++++ 3 files changed, 13 insertions(+), 14 deletions(-) delete mode 100644 source4/libcli/libsmb.m4 create mode 100644 source4/libcli/libsmb.mk (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index feb78a016b..97025fa6c4 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -772,14 +772,14 @@ NTSTATUS gensec_krb5_init(void) { NTSTATUS ret; - ret = register_backend("gensec", &gensec_krb5_security_ops); + ret = gensec_register(&gensec_krb5_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", gensec_krb5_security_ops.name)); return ret; } - ret = register_backend("gensec", &gensec_ms_krb5_security_ops); + ret = gensec_register(&gensec_ms_krb5_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", gensec_krb5_security_ops.name)); diff --git a/source4/libcli/libsmb.m4 b/source4/libcli/libsmb.m4 deleted file mode 100644 index 9293ea2038..0000000000 --- a/source4/libcli/libsmb.m4 +++ /dev/null @@ -1,12 +0,0 @@ -dnl # LIBSMB subsystem - -SMB_SUBSYSTEM(LIBSMB,[], - [libcli/clireadwrite.o - libcli/cliconnect.o - libcli/clifile.o - libcli/clilist.o - libcli/clitrans2.o - libcli/climessage.o - libcli/clideltree.o], - [], - [LIBCLI LIBRPC SOCKET]) diff --git a/source4/libcli/libsmb.mk b/source4/libcli/libsmb.mk new file mode 100644 index 0000000000..8d70888d5e --- /dev/null +++ b/source4/libcli/libsmb.mk @@ -0,0 +1,11 @@ +dnl # LIBSMB subsystem + +[SUBSYSTEM::LIBSMB] +REQUIRED_SUBSYSTEMS = LIBCLI LIBRPC SOCKET +ADD_OBJ_LIST = libcli/clireadwrite.o \ + libcli/cliconnect.o \ + libcli/clifile.o \ + libcli/clilist.o \ + libcli/clitrans2.o \ + libcli/climessage.o \ + libcli/clideltree.o -- cgit From 1824d52ff2c5492b091502c9fcf70aa073b51b37 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 23:10:04 +0000 Subject: r3740: Convert more files to .mk, fix the build (This used to be commit a7c3c8cb6256acf672996fc6bf6128865a9ba0a9) --- source4/libcli/config.m4 | 20 -------------------- source4/libcli/config.mk | 19 +++++++++++++++++++ source4/libcli/libsmb.mk | 4 +--- 3 files changed, 20 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 32a62dbb20..d0d8f3015b 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -27,23 +27,3 @@ SMB_SUBSYSTEM(LIBCLI_RAW,[], libcli/raw/rawacl.o libcli/raw/rawdate.o], [${LIBCLI_RAW_LIBS}]) - -SMB_SUBSYSTEM(LIBCLI_UTILS,[], - [libcli/util/asn1.o - libcli/util/smberr.o - libcli/util/doserr.o - libcli/util/errormap.o - libcli/util/clierror.o - libcli/util/nterr.o - libcli/util/smbdes.o - libcli/util/smbencrypt.o - libcli/util/dom_sid.o]) - -SMB_SUBSYSTEM(LIBCLI_NMB,[], - [libcli/unexpected.o - libcli/namecache.o - libcli/nmblib.o - libcli/namequery.o]) - -SMB_SUBSYSTEM(LIBCLI,[],[],[], - [LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB]) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e69de29bb2..c931d061fb 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -0,0 +1,19 @@ +[SUBSYSTEM::LIBCLI_UTILS] +ADD_OBJ_FILES = libcli/util/asn1.o \ + libcli/util/smberr.o \ + libcli/util/doserr.o \ + libcli/util/errormap.o \ + libcli/util/clierror.o \ + libcli/util/nterr.o \ + libcli/util/smbdes.o \ + libcli/util/smbencrypt.o \ + libcli/util/dom_sid.o + +[SUBSYSTEM::LIBCLI_NMB] +ADD_OBJ_FILES = libcli/unexpected.o \ + libcli/namecache.o \ + libcli/nmblib.o \ + libcli/namequery.o + +[SUBSYSTEM::LIBCLI] +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB diff --git a/source4/libcli/libsmb.mk b/source4/libcli/libsmb.mk index 8d70888d5e..ddc4eac35a 100644 --- a/source4/libcli/libsmb.mk +++ b/source4/libcli/libsmb.mk @@ -1,8 +1,6 @@ -dnl # LIBSMB subsystem - [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI LIBRPC SOCKET -ADD_OBJ_LIST = libcli/clireadwrite.o \ +ADD_OBJ_FILES = libcli/clireadwrite.o \ libcli/cliconnect.o \ libcli/clifile.o \ libcli/clilist.o \ -- cgit From 34ddb33b4bf14587f4cd5d7972095df6ffa33e02 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 15 Nov 2004 00:32:37 +0000 Subject: r3744: Support building subsystems as a shared library. Modules don't work yet, so while this does compile, it does not work yet. (This used to be commit 3d885562c9f83d60c5d4957b067e35387dfa50dd) --- source4/libcli/libsmb.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/libsmb.mk b/source4/libcli/libsmb.mk index ddc4eac35a..5f314dfca1 100644 --- a/source4/libcli/libsmb.mk +++ b/source4/libcli/libsmb.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::LIBSMB] -REQUIRED_SUBSYSTEMS = LIBCLI LIBRPC SOCKET +REQUIRED_SUBSYSTEMS = LIBCLI SOCKET ADD_OBJ_FILES = libcli/clireadwrite.o \ libcli/cliconnect.o \ libcli/clifile.o \ -- cgit From fd4c057f9f69fae8f75c003412f163cc965508c6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 15 Nov 2004 10:43:10 +0000 Subject: r3751: Some fixes to using enable and disable for subsystems, ext libs and modules (This used to be commit c7757dd9adc18549fa3f908c2714624ec3f91394) --- source4/libcli/auth/gensec.m4 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 768a2fae57..dd72d967dd 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -1,3 +1,5 @@ +SMB_MODULE_DEFAULT(gensec_krb5, NOT) + if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then /* enable this when krb5 is fully working */ SMB_MODULE_DEFAULT(gensec_krb5, NOT) -- cgit From e2ebe810873f1e5f5592e7378f130e87904d8de2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Nov 2004 20:31:12 +0000 Subject: r3770: - fix endless recursion loop in spnego fallback code - fix compiler warnings metze (This used to be commit 37a8bd2e30cab98bc8b1bf10d0a516827cbb3373) --- source4/libcli/auth/spnego.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index bafbf64294..316deaee0d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -218,6 +218,10 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec if (!all_ops[i]->oid) { continue; } + if (strcasecmp(OID_SPNEGO,all_ops[i]->oid) == 0) { + continue; + } + nt_status = gensec_subcontext_start(gensec_security, &spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -437,7 +441,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (spnego.type != spnego_state->expected_packet) { DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } @@ -497,7 +501,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (len == -1) { DEBUG(1, ("Invalid SPNEGO request:\n")); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -505,7 +509,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (spnego.type != spnego_state->expected_packet) { DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } @@ -563,7 +567,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (len == -1) { DEBUG(1, ("Invalid SPNEGO request:\n")); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -571,7 +575,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (spnego.type != spnego_state->expected_packet) { DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } @@ -603,7 +607,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (len == -1) { DEBUG(1, ("Invalid SPNEGO request:\n")); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -611,7 +615,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (spnego.type != spnego_state->expected_packet) { DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, spnego_state->expected_packet)); - dump_data(1, (const char *)in.data, in.length); + dump_data(1, in.data, in.length); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 4af8f37d64dc24e6747589b90eae253d930b311a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 Nov 2004 13:05:51 +0000 Subject: r3786: send a mechListMIC to make the current samba3 client happy metze (This used to be commit 2403186562698b8e13c20741a0cbed812e1b8e89) --- source4/libcli/auth/spnego.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 316deaee0d..b6436fe8c6 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -465,11 +465,19 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return nt_status; } else { const char **mechlist = gensec_security_oids(out_mem_ctx, OID_SPNEGO); + const char *mechListMIC; + + mechListMIC = talloc_asprintf(out_mem_ctx,"%s$@%s", + lp_netbios_name(), + lp_realm()); + if (!mechListMIC) { + return NT_STATUS_NO_MEMORY; + } spnego_out.type = SPNEGO_NEG_TOKEN_INIT; spnego_out.negTokenInit.mechTypes = mechlist; spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = null_data_blob; + spnego_out.negTokenInit.mechListMIC = data_blob(mechListMIC, strlen(mechListMIC)); spnego_out.negTokenInit.mechToken = unwrapped_out; if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { -- cgit From 285db3339931c47a569f49e8e18760d6185aac54 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 00:31:56 +0000 Subject: r3792: improved the posix -> nt error mapping, so we get things like NT_STATUS_HOST_UNREACHABLE instead of NT_STATUS_UNSUCCESSFUL (This used to be commit f2a488e5668ab5d262269f1bab1b33a63265cbe9) --- source4/libcli/util/errormap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 417f4571a7..6849d7d0cd 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1518,6 +1518,18 @@ const struct unix_error_map unix_nt_errmap[] = { { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, { EBUSY, NT_STATUS_SHARING_VIOLATION }, { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, +#ifdef EHOSTUNREACH + { EHOSTUNREACH, NT_STATUS_HOST_UNREACHABLE }, +#endif +#ifdef ENETUNREACH + { ENETUNREACH, NT_STATUS_NETWORK_UNREACHABLE }, +#endif +#ifdef ETIMEDOUT + { ETIMEDOUT, NT_STATUS_IO_TIMEOUT }, +#endif +#ifdef EADDRINUSE + { EADDRINUSE, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, +#endif #ifdef ENOATTR { ENOATTR, NT_STATUS_NOT_FOUND }, #endif -- cgit From 91e94014beb145541c051b4df28dde7ad0899da5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 17 Nov 2004 12:27:16 +0000 Subject: r3805: Fix the LSA portions of the RPC-SAMSYNC test - I was not using the LSA secrets interface correctly. (New interface added). Andrew Bartlett (This used to be commit 994ac7f031e2b2d528595a4a0a446d92074d6ecf) --- source4/libcli/auth/session.c | 77 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 598f2d4f28..fdb6462b00 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -131,3 +131,80 @@ char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) return ret; } + +/* + a convenient wrapper around sess_crypt_blob() for DATA_BLOBs, using the LSA convention + + note that we round the length to a multiple of 8. This seems to be needed for + compatibility with windows + + caller should free using data_blob_free() +*/ +DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_BLOB *session_key) +{ + DATA_BLOB ret, src; + int dlen = (blob_in->length+7) & ~7; + + src = data_blob_talloc(mem_ctx, NULL, 8+dlen); + if (!src.data) { + return data_blob(NULL, 0); + } + + ret = data_blob(NULL, 8+dlen); + if (!ret.data) { + data_blob_free(&src); + return data_blob(NULL, 0); + } + + SIVAL(src.data, 0, blob_in->length); + SIVAL(src.data, 4, 1); + memset(src.data+8, 0, dlen); + memcpy(src.data+8, blob_in->data, blob_in->length); + + sess_crypt_blob(&ret, &src, session_key, True); + + data_blob_free(&src); + + return ret; +} + +/* + a convenient wrapper around sess_crypt_blob() for strings, using the LSA convention + + caller should free the returned string +*/ +DATA_BLOB sess_decrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const DATA_BLOB *session_key) +{ + DATA_BLOB out; + int slen; + DATA_BLOB ret; + + if (blob->length < 8) { + return data_blob(NULL, 0); + } + + out = data_blob_talloc(mem_ctx, NULL, blob->length); + if (!out.data) { + return data_blob(NULL, 0); + } + + sess_crypt_blob(&out, blob, session_key, False); + + slen = IVAL(out.data, 0); + if (slen > blob->length - 8) { + DEBUG(0,("Invalid crypt length %d\n", slen)); + return data_blob(NULL, 0); + } + + if (IVAL(out.data, 4) != 1) { + DEBUG(0,("Unexpected revision number %d in session crypted string\n", + IVAL(out.data, 4))); + return data_blob(NULL, 0); + } + + ret = data_blob_talloc(mem_ctx, out.data+8, slen); + + data_blob_free(&out); + + return ret; +} -- cgit From 696fdc8cf91cc1660725fd93c2b91ec6b65d06b5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 12:36:14 +0000 Subject: r3806: added support to smb_server and pvfs for the NTTRANS Create call. This call has an optional sec_desc and ea_list. (This used to be commit 8379ad14e3d51a848a99865d9ce8d56a301e8a3c) --- source4/libcli/raw/raweas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index da079c402b..52c7832a6c 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -122,7 +122,7 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, *num_eas = 0; *eas = NULL; - while (ofs < ea_size) { + while (ofs+6 < ea_size) { uint_t len; DATA_BLOB blob2; -- cgit From 856ee665374071c89f5ecf540dcc3d68ccf2ff16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Nov 2004 14:35:29 +0000 Subject: r3810: create a LIB_SECURITY subsystem - move dom_sid, security_descriptor, security_* funtions to one place and rename some of them metze (This used to be commit b620bdd672cfdf0e009492e648b0709e6b6d8596) --- source4/libcli/config.mk | 3 +- source4/libcli/raw/rawacl.c | 1 + source4/libcli/security/config.mk | 18 ++ source4/libcli/security/dom_sid.c | 242 ++++++++++++++++++++++++++ source4/libcli/security/security_descriptor.c | 102 +++++++++++ source4/libcli/security/security_token.c | 56 ++++++ source4/libcli/util/dom_sid.c | 180 ------------------- 7 files changed, 420 insertions(+), 182 deletions(-) create mode 100644 source4/libcli/security/config.mk create mode 100644 source4/libcli/security/dom_sid.c create mode 100644 source4/libcli/security/security_descriptor.c create mode 100644 source4/libcli/security/security_token.c delete mode 100644 source4/libcli/util/dom_sid.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c931d061fb..e48e5b5066 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -6,8 +6,7 @@ ADD_OBJ_FILES = libcli/util/asn1.o \ libcli/util/clierror.o \ libcli/util/nterr.o \ libcli/util/smbdes.o \ - libcli/util/smbencrypt.o \ - libcli/util/dom_sid.o + libcli/util/smbencrypt.o [SUBSYSTEM::LIBCLI_NMB] ADD_OBJ_FILES = libcli/unexpected.o \ diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 35c7ce2049..642d0ba72b 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/ndr_security.h" #include "libcli/raw/libcliraw.h" /**************************************************************************** diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk new file mode 100644 index 0000000000..908a993ce6 --- /dev/null +++ b/source4/libcli/security/config.mk @@ -0,0 +1,18 @@ +################################# +# Start SUBSYSTEM LIB_SECURITY_NDR +[SUBSYSTEM::LIB_SECURITY_NDR] +ADD_OBJ_FILES = librpc/gen_ndr/ndr_security.o +NOPROTO = YES +# End SUBSYSTEM LIB_SECURITY_NDR +################################# + +################################# +# Start SUBSYSTEM LIB_SECURITY +[SUBSYSTEM::LIB_SECURITY] +ADD_OBJ_FILES = libcli/security/security_token.o \ + libcli/security/security_descriptor.o \ + libcli/security/dom_sid.o \ + librpc/ndr/ndr_sec.o +REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR +# End SUBSYSTEM LIB_SECURITY +################################# diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c new file mode 100644 index 0000000000..701fa88017 --- /dev/null +++ b/source4/libcli/security/dom_sid.c @@ -0,0 +1,242 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Luke Kenneth Caseson Leighton 1998-1999 + Copyright (C) Jeremy Allison 1999 + Copyright (C) Stefan (metze) Metzmacher 2002-2004 + Copyright (C) Simo Sorce 2002 + + 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 "librpc/gen_ndr/ndr_security.h" + +/***************************************************************** + Compare the auth portion of two sids. +*****************************************************************/ + +static int dom_sid_compare_auth(const struct dom_sid *sid1, const struct dom_sid *sid2) +{ + int i; + + if (sid1 == sid2) + return 0; + if (!sid1) + return -1; + if (!sid2) + return 1; + + if (sid1->sid_rev_num != sid2->sid_rev_num) + return sid1->sid_rev_num - sid2->sid_rev_num; + + for (i = 0; i < 6; i++) + if (sid1->id_auth[i] != sid2->id_auth[i]) + return sid1->id_auth[i] - sid2->id_auth[i]; + + return 0; +} + +/***************************************************************** + Compare two sids. +*****************************************************************/ + +static int dom_sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid2) +{ + int i; + + if (sid1 == sid2) + return 0; + if (!sid1) + return -1; + if (!sid2) + return 1; + + /* Compare most likely different rids, first: i.e start at end */ + if (sid1->num_auths != sid2->num_auths) + return sid1->num_auths - sid2->num_auths; + + for (i = sid1->num_auths-1; i >= 0; --i) + if (sid1->sub_auths[i] != sid2->sub_auths[i]) + return sid1->sub_auths[i] - sid2->sub_auths[i]; + + return dom_sid_compare_auth(sid1, sid2); +} + +/***************************************************************** + Compare two sids. +*****************************************************************/ + +BOOL dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) +{ + return dom_sid_compare(sid1, sid2) == 0; +} + +/* + convert a dom_sid to a string +*/ +char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +{ + int i, ofs, maxlen; + uint32_t ia; + char *ret; + + if (!sid) { + return talloc_strdup(mem_ctx, "(NULL SID)"); + } + + maxlen = sid->num_auths * 11 + 25; + ret = talloc(mem_ctx, maxlen); + if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); + + ia = (sid->id_auth[5]) + + (sid->id_auth[4] << 8 ) + + (sid->id_auth[3] << 16) + + (sid->id_auth[2] << 24); + + ofs = snprintf(ret, maxlen, "S-%u-%lu", + (uint_t)sid->sid_rev_num, (unsigned long)ia); + + for (i = 0; i < sid->num_auths; i++) { + ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); + } + + return ret; +} + + +/* + convert a string to a dom_sid, returning a talloc'd dom_sid +*/ +struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) +{ + struct dom_sid *ret; + uint_t rev, ia, num_sub_auths, i; + char *p; + + if (strncasecmp(sidstr, "S-", 2)) { + return NULL; + } + + sidstr += 2; + + rev = strtol(sidstr, &p, 10); + if (*p != '-') { + return NULL; + } + sidstr = p+1; + + ia = strtol(sidstr, &p, 10); + if (p == sidstr) { + return NULL; + } + sidstr = p; + + num_sub_auths = 0; + for (i=0;sidstr[i];i++) { + if (sidstr[i] == '-') num_sub_auths++; + } + + ret = talloc_p(mem_ctx, struct dom_sid); + if (!ret) { + return NULL; + } + + ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, num_sub_auths); + if (!ret->sub_auths) { + return NULL; + } + + ret->sid_rev_num = rev; + ret->id_auth[0] = 0; + ret->id_auth[1] = 0; + ret->id_auth[2] = ia >> 24; + ret->id_auth[3] = ia >> 16; + ret->id_auth[4] = ia >> 8; + ret->id_auth[5] = ia; + ret->num_auths = num_sub_auths; + + for (i=0;isub_auths[i] = strtoul(sidstr, &p, 10); + if (p == sidstr) { + return NULL; + } + sidstr = p; + } + + return ret; +} + +/* + convert a string to a dom_sid, returning a talloc'd dom_sid +*/ +struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid) +{ + struct dom_sid *ret; + int i; + ret = talloc_p(mem_ctx, struct dom_sid); + if (!ret) { + return NULL; + } + + ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, dom_sid->num_auths); + if (!ret->sub_auths) { + return NULL; + } + + ret->sid_rev_num = dom_sid->sid_rev_num; + ret->id_auth[0] = dom_sid->id_auth[0]; + ret->id_auth[1] = dom_sid->id_auth[1]; + ret->id_auth[2] = dom_sid->id_auth[2]; + ret->id_auth[3] = dom_sid->id_auth[3]; + ret->id_auth[4] = dom_sid->id_auth[4]; + ret->id_auth[5] = dom_sid->id_auth[5]; + ret->num_auths = dom_sid->num_auths; + + for (i=0;inum_auths;i++) { + ret->sub_auths[i] = dom_sid->sub_auths[i]; + } + + return ret; +} + +/* + add a rid to a domain dom_sid to make a full dom_sid +*/ +struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, + const struct dom_sid *domain_sid, + uint32_t rid) +{ + struct dom_sid *sid; + + sid = talloc_p(mem_ctx, struct dom_sid); + if (!sid) return NULL; + + *sid = *domain_sid; + /*TODO: use realloc! */ + sid->sub_auths = talloc_array_p(mem_ctx, uint32_t, sid->num_auths+1); + if (!sid->sub_auths) { + return NULL; + } + memcpy(sid->sub_auths, domain_sid->sub_auths, sid->num_auths*sizeof(uint32_t)); + sid->sub_auths[sid->num_auths] = rid; + sid->num_auths++; + return sid; +} diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c new file mode 100644 index 0000000000..255836066a --- /dev/null +++ b/source4/libcli/security/security_descriptor.c @@ -0,0 +1,102 @@ +/* + Unix SMB/CIFS implementation. + + security descriptror utility functions + + Copyright (C) Andrew Tridgell 2004 + + 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 "librpc/gen_ndr/ndr_security.h" + +/* + return a blank security descriptor (no owners, dacl or sacl) +*/ +struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx) +{ + struct security_descriptor *sd; + + sd = talloc_p(mem_ctx, struct security_descriptor); + if (!sd) { + return NULL; + } + + sd->revision = SD_REVISION; + /* we mark as self relative, even though it isn't while it remains + a pointer in memory because this simplifies the ndr code later. + All SDs that we store/emit are in fact SELF_RELATIVE + */ + sd->type = SEC_DESC_SELF_RELATIVE; + + sd->owner_sid = NULL; + sd->group_sid = NULL; + sd->sacl = NULL; + sd->dacl = NULL; + + return sd; +} + +/* + talloc and copy a security descriptor + */ +struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, + const struct security_descriptor *osd) +{ + struct security_descriptor *nsd; + + /* FIXME */ + DEBUG(1, ("security_descriptor_copy(): sorry unimplemented yet\n")); + nsd = NULL; + + return nsd; +} + +NTSTATUS security_check_dacl(struct security_token *st, struct security_descriptor *sd, uint32 access_mask) +{ + size_t i,y; + NTSTATUS status = NT_STATUS_ACCESS_DENIED; + + DEBUG(1, ("security_check_dacl(): sorry untested yet\n")); + return status; + + if (!sd->dacl) { + return NT_STATUS_INVALID_ACL; + } + + for (i=0; i < st->num_sids; i++) { + for (y=0; y < sd->dacl->num_aces; y++) { + if (dom_sid_equal(&st->sids[i], &sd->dacl->aces[y].trustee)) { + switch (sd->dacl->aces[y].type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED: + if (access_mask & sd->dacl->aces[y].access_mask) { + status = NT_STATUS_OK; + } + break; + case SEC_ACE_TYPE_ACCESS_DENIED: + if (access_mask & sd->dacl->aces[y].access_mask) { + return NT_STATUS_ACCESS_DENIED; + } + break; + default: + return NT_STATUS_INVALID_ACL; + } + } + } + } + + return status; +} diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c new file mode 100644 index 0000000000..9e26f5a385 --- /dev/null +++ b/source4/libcli/security/security_token.c @@ -0,0 +1,56 @@ +/* + Unix SMB/CIFS implementation. + + security descriptror utility functions + + Copyright (C) Andrew Tridgell 2004 + + 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 "librpc/gen_ndr/ndr_security.h" + +/* + return a blank security descriptor (no owners, dacl or sacl) +*/ +struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx) +{ + struct security_token *st; + + st = talloc_p(mem_ctx, struct security_token); + if (!st) { + return NULL; + } + + st->flags = 0; + + st->user_sid = NULL; + st->group_sid = NULL; + st->logon_sid = NULL; + + st->num_sids = 0; + st->sids = NULL; + + st->num_restricted_sids = 0; + st->restricted_sids = NULL; + + st->num_privileges = 0; + st->privileges = NULL; + + st->dacl = NULL; + + return st; +} diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c deleted file mode 100644 index 1faf3debab..0000000000 --- a/source4/libcli/util/dom_sid.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines to manipulate a "struct dom_sid" - - Copyright (C) Andrew Tridgell 2004 - - 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" - -/* - convert a dom_sid to a string -*/ -char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) -{ - int i, ofs, maxlen; - uint32_t ia; - char *ret; - - if (!sid) { - return talloc_strdup(mem_ctx, "(NULL SID)"); - } - - maxlen = sid->num_auths * 11 + 25; - ret = talloc(mem_ctx, maxlen); - if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); - - ia = (sid->id_auth[5]) + - (sid->id_auth[4] << 8 ) + - (sid->id_auth[3] << 16) + - (sid->id_auth[2] << 24); - - ofs = snprintf(ret, maxlen, "S-%u-%lu", - (uint_t)sid->sid_rev_num, (unsigned long)ia); - - for (i = 0; i < sid->num_auths; i++) { - ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); - } - - return ret; -} - - -/* - convert a string to a dom_sid, returning a talloc'd dom_sid -*/ -struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) -{ - struct dom_sid *ret; - uint_t rev, ia, num_sub_auths, i; - char *p; - - if (strncasecmp(sidstr, "S-", 2)) { - return NULL; - } - - sidstr += 2; - - rev = strtol(sidstr, &p, 10); - if (*p != '-') { - return NULL; - } - sidstr = p+1; - - ia = strtol(sidstr, &p, 10); - if (p == sidstr) { - return NULL; - } - sidstr = p; - - num_sub_auths = 0; - for (i=0;sidstr[i];i++) { - if (sidstr[i] == '-') num_sub_auths++; - } - - ret = talloc_p(mem_ctx, struct dom_sid); - if (!ret) { - return NULL; - } - - ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, num_sub_auths); - if (!ret->sub_auths) { - return NULL; - } - - ret->sid_rev_num = rev; - ret->id_auth[0] = 0; - ret->id_auth[1] = 0; - ret->id_auth[2] = ia >> 24; - ret->id_auth[3] = ia >> 16; - ret->id_auth[4] = ia >> 8; - ret->id_auth[5] = ia; - ret->num_auths = num_sub_auths; - - for (i=0;isub_auths[i] = strtoul(sidstr, &p, 10); - if (p == sidstr) { - return NULL; - } - sidstr = p; - } - - return ret; -} - -/* - convert a string to a dom_sid, returning a talloc'd dom_sid -*/ -struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, struct dom_sid *dom_sid) -{ - struct dom_sid *ret; - int i; - ret = talloc_p(mem_ctx, struct dom_sid); - if (!ret) { - return NULL; - } - - ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, dom_sid->num_auths); - if (!ret->sub_auths) { - return NULL; - } - - ret->sid_rev_num = dom_sid->sid_rev_num; - ret->id_auth[0] = dom_sid->id_auth[0]; - ret->id_auth[1] = dom_sid->id_auth[1]; - ret->id_auth[2] = dom_sid->id_auth[2]; - ret->id_auth[3] = dom_sid->id_auth[3]; - ret->id_auth[4] = dom_sid->id_auth[4]; - ret->id_auth[5] = dom_sid->id_auth[5]; - ret->num_auths = dom_sid->num_auths; - - for (i=0;inum_auths;i++) { - ret->sub_auths[i] = dom_sid->sub_auths[i]; - } - - return ret; -} - -/* - add a rid to a domain dom_sid to make a full dom_sid -*/ -struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, - const struct dom_sid *domain_sid, - uint32_t rid) -{ - struct dom_sid *sid; - - sid = talloc_p(mem_ctx, struct dom_sid); - if (!sid) return NULL; - - *sid = *domain_sid; - /*TODO: use realloc! */ - sid->sub_auths = talloc_array_p(mem_ctx, uint32_t, sid->num_auths+1); - if (!sid->sub_auths) { - return NULL; - } - memcpy(sid->sub_auths, domain_sid->sub_auths, sid->num_auths*sizeof(uint32_t)); - sid->sub_auths[sid->num_auths] = rid; - sid->num_auths++; - return sid; -} - -- cgit From 5efd740d4d4597208f835c6ed787c180056d7264 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 20:56:26 +0000 Subject: r3821: added client side code and test code for NTTRANS_CREATE (This used to be commit 8422789c06c203ea1c4761fecb16f79f99ac479b) --- source4/libcli/raw/rawfile.c | 133 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 4da7ff3a9e..5fc40bc45a 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_security.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ @@ -213,6 +214,132 @@ NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree, } +/* + Open a file using TRANSACT2_OPEN - async recv +*/ +static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req, + TALLOC_CTX *mem_ctx, + union smb_open *parms) +{ + NTSTATUS status; + struct smb_nttrans nt; + uint8_t *params; + + status = smb_raw_nttrans_recv(req, mem_ctx, &nt); + if (!NT_STATUS_IS_OK(status)) return status; + + if (nt.out.params.length < 69) { + return NT_STATUS_INVALID_PARAMETER; + } + + params = nt.out.params.data; + + parms->ntcreatex.out.oplock_level = CVAL(params, 0); + parms->ntcreatex.out.fnum = SVAL(params, 2); + parms->ntcreatex.out.create_action = IVAL(params, 4); + parms->ntcreatex.out.create_time = smbcli_pull_nttime(params, 12); + parms->ntcreatex.out.access_time = smbcli_pull_nttime(params, 20); + parms->ntcreatex.out.write_time = smbcli_pull_nttime(params, 28); + parms->ntcreatex.out.change_time = smbcli_pull_nttime(params, 36); + parms->ntcreatex.out.attrib = IVAL(params, 44); + parms->ntcreatex.out.alloc_size = BVAL(params, 48); + parms->ntcreatex.out.size = BVAL(params, 56); + parms->ntcreatex.out.file_type = SVAL(params, 64); + parms->ntcreatex.out.ipc_state = SVAL(params, 66); + parms->ntcreatex.out.is_directory = CVAL(params, 68); + + return NT_STATUS_OK; +} + + +/* + Open a file using NTTRANS CREATE - async send +*/ +static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tree, + union smb_open *parms) +{ + struct smb_nttrans nt; + uint8_t *params; + TALLOC_CTX *mem_ctx = talloc(tree, 0); + uint16_t fname_len; + DATA_BLOB sd_blob, ea_blob; + struct smbcli_request *req; + NTSTATUS status; + + nt.in.max_setup = 0; + nt.in.max_param = 101; + nt.in.max_data = 0; + nt.in.setup_count = 0; + nt.in.function = NT_TRANSACT_CREATE; + nt.in.setup = NULL; + + sd_blob = data_blob(NULL, 0); + ea_blob = data_blob(NULL, 0); + + if (parms->ntcreatex.in.sec_desc) { + status = ndr_push_struct_blob(&sd_blob, mem_ctx, + parms->ntcreatex.in.sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return NULL; + } + } + + if (parms->ntcreatex.in.ea_list) { + uint32_t ea_size = ea_list_size(parms->ntcreatex.in.ea_list->num_eas, + parms->ntcreatex.in.ea_list->eas); + ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size); + if (ea_blob.data == NULL) { + return NULL; + } + ea_put_list(ea_blob.data, + parms->ntcreatex.in.ea_list->num_eas, + parms->ntcreatex.in.ea_list->eas); + } + + nt.in.params = data_blob_talloc(mem_ctx, NULL, 54); + if (nt.in.params.data == NULL) { + talloc_free(mem_ctx); + return NULL; + } + + /* build the parameter section */ + params = nt.in.params.data; + + SIVAL(params, 0, parms->ntcreatex.in.flags); + SIVAL(params, 4, parms->ntcreatex.in.root_fid); + SIVAL(params, 8, parms->ntcreatex.in.access_mask); + SBVAL(params, 12, parms->ntcreatex.in.alloc_size); + SIVAL(params, 20, parms->ntcreatex.in.file_attr); + SIVAL(params, 24, parms->ntcreatex.in.share_access); + SIVAL(params, 28, parms->ntcreatex.in.open_disposition); + SIVAL(params, 32, parms->ntcreatex.in.create_options); + SIVAL(params, 36, sd_blob.length); + SIVAL(params, 40, ea_blob.length); + SIVAL(params, 48, parms->ntcreatex.in.impersonation); + SCVAL(params, 52, parms->ntcreatex.in.security_flags); + SCVAL(params, 53, 0); + + fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params, + parms->ntcreatex.in.fname, STR_TERMINATE); + + SIVAL(nt.in.params.data, 44, fname_len); + + /* build the data section */ + nt.in.data = data_blob_talloc(mem_ctx, NULL, sd_blob.length + ea_blob.length); + memcpy(nt.in.data.data, sd_blob.data, sd_blob.length); + memcpy(nt.in.data.data+sd_blob.length, ea_blob.data, ea_blob.length); + + /* send the request on its way */ + req = smb_raw_nttrans_send(tree, &nt); + + talloc_free(mem_ctx); + + return req; +} + + /**************************************************************************** Open a file using TRANSACT2_OPEN - async send ****************************************************************************/ @@ -377,6 +504,9 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len); SSVAL(req->out.vwv, 5, len); break; + + case RAW_OPEN_NTTRANS_CREATE: + return smb_raw_nttrans_create_send(tree, parms); } if (!smbcli_request_send(req)) { @@ -469,6 +599,9 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio parms->ntcreatex.out.ipc_state = SVAL(req->in.vwv, 65); parms->ntcreatex.out.is_directory = CVAL(req->in.vwv, 67); break; + + case RAW_OPEN_NTTRANS_CREATE: + return smb_raw_nttrans_create_recv(req, mem_ctx, parms); } failed: -- cgit From 5f868bc1acc9bdaed32ae70fb9906334663ccfff Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 22:00:15 +0000 Subject: r3826: - added testing of ea lists in NTTRANS CREATE - fixed push/pull of chained ea lists - fixed a bug in the nttrans wire encoding (This used to be commit fcd09224076508f9c10095bf2e2c394232a4d297) --- source4/libcli/raw/raweas.c | 107 ++++++++++++++++++++++++++++++++++++++++-- source4/libcli/raw/rawfile.c | 10 ++-- source4/libcli/raw/rawtrans.c | 2 +- source4/libcli/util/nterr.c | 1 + 4 files changed, 109 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 52c7832a6c..5bd90766aa 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -36,6 +36,23 @@ uint_t ea_list_size(uint_t num_eas, struct ea_struct *eas) return total; } +/* + work out how many bytes on the wire a chained ea list will consume. + This assumes the names are strict ascii, which should be a + reasonable assumption +*/ +uint_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas) +{ + uint_t total = 0; + int i; + for (i=0;i blob->length) { return NT_STATUS_INVALID_PARAMETER; } - - ofs = 4; + + ofs = 4; n = 0; *num_eas = 0; *eas = NULL; - while (ofs+6 < ea_size) { + while (ofs < ea_size) { uint_t len; DATA_BLOB blob2; @@ -146,3 +191,55 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, return NT_STATUS_OK; } + +/* + pull a chained ea_list from a buffer +*/ +NTSTATUS ea_pull_list_chained(const DATA_BLOB *blob, + TALLOC_CTX *mem_ctx, + uint_t *num_eas, struct ea_struct **eas) +{ + int n; + uint32_t ofs; + + if (blob->length < 4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + ofs = 0; + n = 0; + *num_eas = 0; + *eas = NULL; + + while (ofs < blob->length) { + uint_t len; + DATA_BLOB blob2; + uint32_t next_ofs = IVAL(blob->data, ofs); + + blob2.data = blob->data + ofs + 4; + blob2.length = blob->length - (ofs + 4); + + *eas = talloc_realloc(mem_ctx, *eas, sizeof(**eas) * (n+1)); + if (! *eas) return NT_STATUS_NO_MEMORY; + + len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); + if (len == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + ofs += next_ofs; + + if (ofs+4 > blob->length) { + return NT_STATUS_INVALID_PARAMETER; + } + n++; + if (next_ofs == 0) break; + } + + *num_eas = n; + + return NT_STATUS_OK; +} + + + diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 5fc40bc45a..69b8c6a07c 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -287,15 +287,15 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr } if (parms->ntcreatex.in.ea_list) { - uint32_t ea_size = ea_list_size(parms->ntcreatex.in.ea_list->num_eas, - parms->ntcreatex.in.ea_list->eas); + uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas, + parms->ntcreatex.in.ea_list->eas); ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size); if (ea_blob.data == NULL) { return NULL; } - ea_put_list(ea_blob.data, - parms->ntcreatex.in.ea_list->num_eas, - parms->ntcreatex.in.ea_list->eas); + ea_put_list_chained(ea_blob.data, + parms->ntcreatex.in.ea_list->num_eas, + parms->ntcreatex.in.ea_list->eas); } nt.in.params = data_blob_talloc(mem_ctx, NULL, 54); diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 111a7ded2a..2554a736f5 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -505,7 +505,7 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, memcpy(outparam, parms->in.params.data, parms->in.params.length); } if (parms->in.data.length) { - memcpy(outparam, parms->in.data.data, parms->in.data.length); + memcpy(outdata, parms->in.data.data, parms->in.data.length); } if (!smbcli_request_send(req)) { diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 2adb561222..eac7989800 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -32,6 +32,7 @@ static const nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, + { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, -- cgit From 6695019d027f19f7ebe97435fdb9826a7868768f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 22:12:46 +0000 Subject: r3827: fixed copyright notices to remove simo and lkcl who have no code left in this file (This used to be commit c75eb859391f747abc3fe513166c9f8d73ca349c) --- source4/libcli/security/dom_sid.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 701fa88017..254b8dbfab 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -1,11 +1,10 @@ /* Unix SMB/CIFS implementation. Samba utility functions + + Copyright (C) Stefan (metze) Metzmacher 2002-2004 Copyright (C) Andrew Tridgell 1992-2004 - Copyright (C) Luke Kenneth Caseson Leighton 1998-1999 Copyright (C) Jeremy Allison 1999 - Copyright (C) Stefan (metze) Metzmacher 2002-2004 - Copyright (C) Simo Sorce 2002 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 -- cgit From bbf009b46f75f292a625b853b9331b5d5e0da7c2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 01:02:27 +0000 Subject: r3829: added a RAW-ACLS test suite that tests query/set of ACLs on a file (This used to be commit 2ff9816ae0ae41e0e63e4276a70d292888346dc7) --- source4/libcli/raw/rawacl.c | 15 ++- source4/libcli/security/dom_sid.c | 4 +- source4/libcli/security/security_descriptor.c | 128 +++++++++++++++++++++++++- 3 files changed, 141 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 642d0ba72b..2e05002491 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. ACL get/set operations - Copyright (C) Andrew Tridgell 2003 + + Copyright (C) Andrew Tridgell 2003-2004 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 @@ -107,7 +108,7 @@ NTSTATUS smb_raw_query_secdesc(struct smbcli_tree *tree, set file ACL (async send) ****************************************************************************/ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, - struct smb_set_secdesc *set) + struct smb_set_secdesc *set) { struct smb_nttrans nt; uint8_t params[8]; @@ -145,3 +146,13 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, ndr_push_free(ndr); return req; } + +/**************************************************************************** +set file ACL (sync interface) +****************************************************************************/ +NTSTATUS smb_raw_set_secdesc(struct smbcli_tree *tree, + struct smb_set_secdesc *set) +{ + struct smbcli_request *req = smb_raw_set_secdesc_send(tree, set); + return smbcli_request_simple_recv(req); +} diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 254b8dbfab..001618bb07 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -184,7 +184,7 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) } /* - convert a string to a dom_sid, returning a talloc'd dom_sid + copy a dom_sid structure */ struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid) { @@ -195,7 +195,7 @@ struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid) return NULL; } - ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, dom_sid->num_auths); + ret->sub_auths = talloc_array_p(ret, uint32_t, dom_sid->num_auths); if (!ret->sub_auths) { return NULL; } diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 255836066a..671174a824 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -54,7 +54,7 @@ struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx) talloc and copy a security descriptor */ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, - const struct security_descriptor *osd) + const struct security_descriptor *osd) { struct security_descriptor *nsd; @@ -65,7 +65,9 @@ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, return nsd; } -NTSTATUS security_check_dacl(struct security_token *st, struct security_descriptor *sd, uint32 access_mask) +NTSTATUS security_check_dacl(struct security_token *st, + struct security_descriptor *sd, + uint32 access_mask) { size_t i,y; NTSTATUS status = NT_STATUS_ACCESS_DENIED; @@ -100,3 +102,125 @@ NTSTATUS security_check_dacl(struct security_token *st, struct security_descript return status; } + + +/* + add an ACE to the DACL of a security_descriptor +*/ +NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, + struct security_ace *ace) +{ + if (sd->dacl == NULL) { + sd->dacl = talloc_p(sd, struct security_acl); + if (sd->dacl == NULL) { + return NT_STATUS_NO_MEMORY; + } + sd->dacl->revision = SD_REVISION; + sd->dacl->size = 0; + sd->dacl->num_aces = 0; + sd->dacl->aces = NULL; + } + + sd->dacl->aces = talloc_realloc_p(sd->dacl, sd->dacl->aces, + struct security_ace, sd->dacl->num_aces+1); + if (sd->dacl->aces == NULL) { + return NT_STATUS_NO_MEMORY; + } + + sd->dacl->aces[sd->dacl->num_aces] = *ace; + sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths = + talloc_memdup(sd->dacl->aces, + sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths, + sizeof(uint32_t) * + sd->dacl->aces[sd->dacl->num_aces].trustee.num_auths); + if (sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths == NULL) { + return NT_STATUS_NO_MEMORY; + } + + sd->dacl->num_aces++; + + return NT_STATUS_OK; +} + + +/* + delete the ACE corresponding to the given trustee in the DACL of a security_descriptor +*/ +NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, + struct dom_sid *trustee) +{ + int i; + + if (sd->dacl == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + for (i=0;idacl->num_aces;i++) { + if (dom_sid_equal(trustee, &sd->dacl->aces[i].trustee)) { + memmove(&sd->dacl->aces[i], &sd->dacl->aces[i+1], + sizeof(sd->dacl->aces[i]) * (sd->dacl->num_aces - (i+1))); + sd->dacl->num_aces--; + if (sd->dacl->num_aces == 0) { + sd->dacl->aces = NULL; + } + return NT_STATUS_OK; + } + } + return NT_STATUS_OBJECT_NAME_NOT_FOUND; +} + + +/* + compare two security ace structures +*/ +BOOL security_ace_equal(const struct security_ace *ace1, + const struct security_ace *ace2) +{ + if (ace1 == ace2) return True; + if (!ace1 || !ace2) return False; + if (ace1->type != ace2->type) return False; + if (ace1->flags != ace2->flags) return False; + if (ace1->access_mask != ace2->access_mask) return False; + if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) return False; + + return True; +} + + +/* + compare two security acl structures +*/ +BOOL security_acl_equal(const struct security_acl *acl1, + const struct security_acl *acl2) +{ + int i; + + if (acl1 == acl2) return True; + if (!acl1 || !acl2) return False; + if (acl1->revision != acl2->revision) return False; + if (acl1->num_aces != acl2->num_aces) return False; + + for (i=0;inum_aces;i++) { + if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return False; + } + return True; +} + +/* + compare two security descriptors. +*/ +BOOL security_descriptor_equal(const struct security_descriptor *sd1, + const struct security_descriptor *sd2) +{ + if (sd1 == sd2) return True; + if (!sd1 || !sd2) return False; + if (sd1->revision != sd2->revision) return False; + if (sd1->type != sd2->type) return False; + + if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False; + if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False; + if (!security_acl_equal(sd1->sacl, sd2->sacl)) return False; + if (!security_acl_equal(sd1->dacl, sd2->dacl)) return False; + + return True; +} -- cgit From 012be92f0a771d8437f783dc8ed14f38c669893c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 01:41:43 +0000 Subject: r3830: unified the query/set security descriptor code with the rest of the queryfileinfo/setfileinfo logic, so querying/setting a security descriptor is treated as just another file query/set operation. This will allow NTVFS backends to see the query/set security descriptor operations as RAW_FILEINFO_SEC_DESC and RAW_SFILEINFO_SEC_DESC operations. (This used to be commit f68a6b6b915c37e48c42390c1e74c2d1c2636fa9) --- source4/libcli/raw/rawacl.c | 33 +++++++++++++++++---------------- source4/libcli/raw/rawfileinfo.c | 9 ++++++++- source4/libcli/raw/rawsetfileinfo.c | 4 ++++ 3 files changed, 29 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 2e05002491..253a3cbbe7 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -27,7 +27,7 @@ fetch file ACL (async send) ****************************************************************************/ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, - struct smb_query_secdesc *query) + union smb_fileinfo *io) { struct smb_nttrans nt; uint8_t params[8]; @@ -39,9 +39,9 @@ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; nt.in.setup = NULL; - SSVAL(params, 0, query->in.fnum); + SSVAL(params, 0, io->query_secdesc.in.fnum); SSVAL(params, 2, 0); /* padding */ - SIVAL(params, 4, query->in.secinfo_flags); + SIVAL(params, 4, io->query_secdesc.in.secinfo_flags); nt.in.params.data = params; nt.in.params.length = 8; @@ -57,7 +57,7 @@ fetch file ACL (async recv) ****************************************************************************/ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, - struct smb_query_secdesc *query) + union smb_fileinfo *io) { NTSTATUS status; struct smb_nttrans nt; @@ -81,11 +81,12 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, return NT_STATUS_INVALID_PARAMETER; } - query->out.sd = talloc_p(mem_ctx, struct security_descriptor); - if (!query->out.sd) { + io->query_secdesc.out.sd = talloc_p(mem_ctx, struct security_descriptor); + if (!io->query_secdesc.out.sd) { return NT_STATUS_NO_MEMORY; } - status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, query->out.sd); + status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, + io->query_secdesc.out.sd); return status; } @@ -96,10 +97,10 @@ fetch file ACL (sync interface) ****************************************************************************/ NTSTATUS smb_raw_query_secdesc(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, - struct smb_query_secdesc *query) + union smb_fileinfo *io) { - struct smbcli_request *req = smb_raw_query_secdesc_send(tree, query); - return smb_raw_query_secdesc_recv(req, mem_ctx, query); + struct smbcli_request *req = smb_raw_query_secdesc_send(tree, io); + return smb_raw_query_secdesc_recv(req, mem_ctx, io); } @@ -108,7 +109,7 @@ NTSTATUS smb_raw_query_secdesc(struct smbcli_tree *tree, set file ACL (async send) ****************************************************************************/ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, - struct smb_set_secdesc *set) + union smb_setfileinfo *io) { struct smb_nttrans nt; uint8_t params[8]; @@ -123,9 +124,9 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, nt.in.function = NT_TRANSACT_SET_SECURITY_DESC; nt.in.setup = NULL; - SSVAL(params, 0, set->in.fnum); + SSVAL(params, 0, io->set_secdesc.file.fnum); SSVAL(params, 2, 0); /* padding */ - SIVAL(params, 4, set->in.secinfo_flags); + SIVAL(params, 4, io->set_secdesc.in.secinfo_flags); nt.in.params.data = params; nt.in.params.length = 8; @@ -133,7 +134,7 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, ndr = ndr_push_init(); if (!ndr) return NULL; - status = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, set->in.sd); + status = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->set_secdesc.in.sd); if (!NT_STATUS_IS_OK(status)) { ndr_push_free(ndr); return NULL; @@ -151,8 +152,8 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, set file ACL (sync interface) ****************************************************************************/ NTSTATUS smb_raw_set_secdesc(struct smbcli_tree *tree, - struct smb_set_secdesc *set) + union smb_setfileinfo *io) { - struct smbcli_request *req = smb_raw_set_secdesc_send(tree, set); + struct smbcli_request *req = smb_raw_set_secdesc_send(tree, io); return smbcli_request_simple_recv(req); } diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index c844f923b8..6f875f51a7 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -48,6 +48,7 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, case RAW_FILEINFO_GENERIC: case RAW_FILEINFO_GETATTR: case RAW_FILEINFO_GETATTRE: + case RAW_FILEINFO_SEC_DESC: /* not handled here */ return NT_STATUS_INVALID_LEVEL; @@ -460,12 +461,15 @@ failed: Query file info (async send) ****************************************************************************/ struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree, - union smb_fileinfo *parms) + union smb_fileinfo *parms) { /* pass off the non-trans2 level to specialised functions */ if (parms->generic.level == RAW_FILEINFO_GETATTRE) { return smb_raw_getattrE_send(tree, parms); } + if (parms->generic.level == RAW_FILEINFO_SEC_DESC) { + return smb_raw_query_secdesc_send(tree, parms); + } if (parms->generic.level >= RAW_FILEINFO_GENERIC) { return NULL; } @@ -489,6 +493,9 @@ NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req, if (parms->generic.level == RAW_FILEINFO_GETATTRE) { return smb_raw_getattrE_recv(req, parms); } + if (parms->generic.level == RAW_FILEINFO_SEC_DESC) { + return smb_raw_query_secdesc_recv(req, mem_ctx, parms); + } if (parms->generic.level == RAW_FILEINFO_GETATTR) { return smb_raw_getattr_recv(req, parms); } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 0c263ac082..76756971ae 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -41,6 +41,7 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, case RAW_SFILEINFO_GENERIC: case RAW_SFILEINFO_SETATTR: case RAW_SFILEINFO_SETATTRE: + case RAW_SFILEINFO_SEC_DESC: /* not handled here */ return False; @@ -262,6 +263,9 @@ struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree, if (parms->generic.level == RAW_SFILEINFO_SETATTRE) { return smb_raw_setattrE_send(tree, parms); } + if (parms->generic.level == RAW_SFILEINFO_SEC_DESC) { + return smb_raw_set_secdesc_send(tree, parms); + } if (parms->generic.level >= RAW_SFILEINFO_GENERIC) { return NULL; } -- cgit From bc7b4abc3a85e78a73d401345265b2c022f0f04d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 03:31:35 +0000 Subject: r3832: added NT ACL query/set to the posix NTVFS backend. The default ACL is based on the current nttoken, which is completely wrong, but works as a start. The ACL is stored in the xattr system.DosAcl, using a NDR encoded IDL union with a version number to allow for future expansion. pvfs does not yet check the ACL for file access. At the moment the ACL is just query/set. We also need to do some RPC work to allow the windows ACL editor to be used. At the moment is queries the ACL fine, but displays an error when it fails to map the SIDs via rpc. (This used to be commit 3a1f20d874ab2d8b2a2f2485b7a705847abf1263) --- source4/libcli/security/security_descriptor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 671174a824..00857de1c6 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -108,7 +108,7 @@ NTSTATUS security_check_dacl(struct security_token *st, add an ACE to the DACL of a security_descriptor */ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, - struct security_ace *ace) + const struct security_ace *ace) { if (sd->dacl == NULL) { sd->dacl = talloc_p(sd, struct security_acl); -- cgit From 0b691afe81c2778de30f20c03ab2a5f29473f799 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 04:19:26 +0000 Subject: r3836: - fixed the handling of NT_STATUS_BUFFER_TOO_SMALL in nttrans server - fixed revision number on default DACL - fixed DACL_PRESENT bit in acl query with these fixes cacls.exe and the GUI ACL editor in w2k both work against pvfs. The GUI editor is slow as it times out looking up the SID -> name mappings. (This used to be commit 4468018cb63fd884920c2b0f5235bded50c6b5db) --- source4/libcli/security/security_descriptor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 00857de1c6..5ed5ef5c76 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -115,7 +115,7 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, if (sd->dacl == NULL) { return NT_STATUS_NO_MEMORY; } - sd->dacl->revision = SD_REVISION; + sd->dacl->revision = NT4_ACL_REVISION; sd->dacl->size = 0; sd->dacl->num_aces = 0; sd->dacl->aces = NULL; -- cgit From 5d35fe6f711985ac337da812bdbde006172bf256 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Nov 2004 00:29:04 +0000 Subject: r3885: Add security descriptor comparison to our RPC-SAMSYNC test. We now verify that the security descriptor found in the SamSync is the same as what is available over SAMR. Unfortunately, the administrator seems unable to retrieve the SACL on the security descriptor, so I've added a new function to compare with a mask. Andrew Bartlett (This used to be commit 39ae5e1dac31a22086be50fb23261e02be877f3f) --- source4/libcli/security/security_descriptor.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 5ed5ef5c76..a4056e5e71 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -224,3 +224,24 @@ BOOL security_descriptor_equal(const struct security_descriptor *sd1, return True; } + +/* + compare two security descriptors, but allow certain (missing) parts + to be masked out of the comparison +*/ +BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, + const struct security_descriptor *sd2, + uint32 mask) +{ + if (sd1 == sd2) return True; + if (!sd1 || !sd2) return False; + if (sd1->revision != sd2->revision) return False; + if ((sd1->type & mask) != (sd2->type & mask)) return False; + + if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False; + if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False; + if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return False; + if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return False; + + return True; +} -- cgit From cc368fa69e6a205516c64712aee701fe0cf6d20b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 Nov 2004 17:47:09 +0000 Subject: r3898: Work towards local/server DCOM support, start working on Simple example server side implementation (This used to be commit 98afb504d95ccca4d6ec48273e10b52ccfa26ad0) --- source4/libcli/util/smbencrypt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index dac8674f03..1218de1fe7 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -46,9 +46,9 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) #ifdef DEBUG_PASSWORD DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); - dump_data(100, (char *)p21, 16); - dump_data(100, (const char *)c8, 8); - dump_data(100, (char *)p24, 24); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); #endif return ret; @@ -196,9 +196,9 @@ void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) #ifdef DEBUG_PASSWORD DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, (char *)p21, 16); - dump_data(100, (char *)c8, 8); - dump_data(100, (char *)p24, 24); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); #endif } -- cgit From 2877f415ae1da30e5971840c124f6ca60813b93d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 07:54:16 +0000 Subject: r3899: fix compiler warnings metze (This used to be commit b1b47bda0177c42687b9c291e4e28ae123fb4eac) --- source4/libcli/util/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 1218de1fe7..ba89000c6c 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -435,7 +435,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) +BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) { uint8_t new_pw[512]; size_t new_pw_len; @@ -446,7 +446,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - generate_random_buffer((uint8_t *)buffer, 512 - new_pw_len); + generate_random_buffer(buffer, 512 - new_pw_len); /* * The length of the new password is in the last 4 bytes of -- cgit From ac40a16d6ac3a639f9fdd2437340eb07bb8a98ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 07:56:13 +0000 Subject: r3900: fix compiler warning metze (This used to be commit f2ff50dfc40f7bf329ab83eefcc2cff9e575a84e) --- source4/libcli/util/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index ba89000c6c..f0ff3ee08d 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -374,7 +374,7 @@ static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], return final_response; } -BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const char nt_hash[16], +BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, -- cgit From 243b314a231f0044ceee81728a0a1deb71c58283 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 07:59:14 +0000 Subject: r3901: fix compiler warnings metze (This used to be commit efe840c8b0dd599d205068a4946ef587d542f2a5) --- source4/libcli/util/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index f0ff3ee08d..9e8a4cd02d 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -463,7 +463,7 @@ BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ -BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, +BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32_t *new_pw_len, int string_flags) { @@ -497,7 +497,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (char *)new_pwrd, *new_pw_len); + dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len); DEBUG(100,("multibyte len:%d\n", *new_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif -- cgit From 7aeebaa96246660ab30c985859ea6b4323ea371f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 08:15:27 +0000 Subject: r3902: fix compiler warnings metze (This used to be commit ce7686ac3e15b0d52ef01bd8bd773641c8ce2e35) --- source4/libcli/raw/raweas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 5bd90766aa..e5f81f5eea 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -57,7 +57,7 @@ uint_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas) put a ea_list into a pre-allocated buffer - buffer must be at least of size ea_list_size() */ -void ea_put_list(char *data, uint_t num_eas, struct ea_struct *eas) +void ea_put_list(void *data, uint_t num_eas, struct ea_struct *eas) { int i; uint32_t ea_size; @@ -83,7 +83,7 @@ void ea_put_list(char *data, uint_t num_eas, struct ea_struct *eas) put a chained ea_list into a pre-allocated buffer - buffer must be at least of size ea_list_size() */ -void ea_put_list_chained(char *data, uint_t num_eas, struct ea_struct *eas) +void ea_put_list_chained(void *data, uint_t num_eas, struct ea_struct *eas) { int i; -- cgit From aae697b9246a6688155895e6c666fda2f10d67f5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 08:31:36 +0000 Subject: r3903: better fix for -r 3902 (not introduce new warnings:-) metze (This used to be commit 36b11992dc3b08914db24ec23f10cc8b3eb55320) --- source4/libcli/raw/raweas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index e5f81f5eea..17e5ce8f75 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -57,7 +57,7 @@ uint_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas) put a ea_list into a pre-allocated buffer - buffer must be at least of size ea_list_size() */ -void ea_put_list(void *data, uint_t num_eas, struct ea_struct *eas) +void ea_put_list(uint8_t *data, uint_t num_eas, struct ea_struct *eas) { int i; uint32_t ea_size; @@ -83,7 +83,7 @@ void ea_put_list(void *data, uint_t num_eas, struct ea_struct *eas) put a chained ea_list into a pre-allocated buffer - buffer must be at least of size ea_list_size() */ -void ea_put_list_chained(void *data, uint_t num_eas, struct ea_struct *eas) +void ea_put_list_chained(uint8_t *data, uint_t num_eas, struct ea_struct *eas) { int i; -- cgit From ca751e2638ca0fbb03b54e1aaa4ed1316e903947 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 10:59:46 +0000 Subject: r3906: fix compiler warnings metze (This used to be commit df924e18220aedbfbfae569e1fb37da652914c0b) --- source4/libcli/auth/credentials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index ec41ebf4bd..a61660d776 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -172,7 +172,7 @@ void creds_des_decrypt(struct creds_CredentialState *creds, struct samr_Password /* ARCFOUR encrypt/decrypt a password buffer using the session key */ -void creds_arcfour_crypt(struct creds_CredentialState *creds, char *data, size_t len) +void creds_arcfour_crypt(struct creds_CredentialState *creds, uint8_t *data, size_t len) { DATA_BLOB session_key = data_blob(creds->session_key, 16); -- cgit From 3129264308c7c68bfe94228dcb7af99876d93dff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 14:28:09 +0000 Subject: r3910: add some error codes metze (This used to be commit 64570b7a4734ec1cc56a07e6bd9b20a155a876c0) --- source4/libcli/util/doserr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 8f997cf092..0e2270d8f6 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -67,6 +67,12 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, + { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, + { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, + { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, + { "WERR_DS_SERVICE_BUSY", WERR_DS_SERVICE_BUSY }, + { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, + { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, -- cgit From 13abb5275827673c765863d7f5bd7dafea5ad8b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 18:01:40 +0000 Subject: r3959: fix compiler warnings metze (This used to be commit e28351f710525ca9863210974544a8b1a537e63a) --- source4/libcli/auth/gensec_ntlmssp.c | 2 +- source4/libcli/auth/ntlmssp.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index ee8d1aa79c..5e55082c6f 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -74,7 +74,7 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by)); DEBUG(5, ("challenge is: \n")); - dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length); + dump_data(5, auth_context->challenge.data, auth_context->challenge.length); return NT_STATUS_OK; } diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index f0003279e5..5d61361d69 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -264,7 +264,7 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, "NTLMSSP", &ntlmssp_command)) { DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); - dump_data(2, (const char *)input.data, input.length); + dump_data(2, input.data, input.length); return NT_STATUS_INVALID_PARAMETER; } } @@ -472,7 +472,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, &cliname, &domname)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); - dump_data(2, (const char *)in.data, in.length); + dump_data(2, in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -611,7 +611,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, &ntlmssp_state->encrypted_session_key, &auth_flags)) { DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); - dump_data(10, (const char *)request.data, request.length); + dump_data(10, request.data, request.length); /* zero this out */ data_blob_free(&ntlmssp_state->encrypted_session_key); @@ -635,7 +635,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, &user, &workstation)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); - dump_data(2, (const char *)request.data, request.length); + dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } @@ -1027,7 +1027,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, (const char *)in.data, in.length); + dump_data(2, in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -1069,7 +1069,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, &unkn1, &unkn2, &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - dump_data(2, (const char *)in.data, in.length); + dump_data(2, in.data, in.length); return NT_STATUS_INVALID_PARAMETER; } @@ -1136,7 +1136,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); - dump_data(5, (const char *)session_nonce_hash, 8); + dump_data(5, session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt(ntlmssp_state->password, -- cgit From 5c55901266a4f176e77d41ceb6674b0d89eaef3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 18:02:35 +0000 Subject: r3960: fix compiler warnings metze (This used to be commit 54d5b418a75d421a9c6c09bc084454f11e9b7b44) --- source4/libcli/auth/ntlmssp_sign.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 7d193c850c..e2f5237a88 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -116,7 +116,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat } else { uint32_t crc; - crc = crc32_calc_buffer((const char *)data, length); + crc = crc32_calc_buffer(data, length); if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlm_seq_num)) { return NT_STATUS_NO_MEMORY; } @@ -202,10 +202,10 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) { DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n")); - dump_data(5, (const char *)local_sig.data, local_sig.length); + dump_data(5, local_sig.data, local_sig.length); DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, (const char *)(sig->data), sig->length); + dump_data(5, sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n")); return NT_STATUS_ACCESS_DENIED; @@ -255,7 +255,7 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, } } else { uint32_t crc; - crc = crc32_calc_buffer((const char *)data, length); + crc = crc32_calc_buffer(data, length); if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlm_seq_num)) { return NT_STATUS_NO_MEMORY; } -- cgit From 089f3843c5eadc792f9f8399bf3df45601621b2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 19:21:55 +0000 Subject: r3967: fix compiler warnings metze (This used to be commit 3f2c3ce2f0d11ea9f3c058690e0bb14d590c714c) --- source4/libcli/auth/session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index fdb6462b00..91eee9ce81 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -124,8 +124,8 @@ char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) IVAL(out.data, 4))); return NULL; } - - ret = strndup(out.data+8, slen); + + ret = strndup((const char *)(out.data+8), slen); data_blob_free(&out); -- cgit From 3308087bae76a99c02687bd11f4237d803f9f605 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 20:01:47 +0000 Subject: r3971: fix compiler warnings metze (This used to be commit 234166606dc86b9e98226cff94b3869ec173671e) --- source4/libcli/auth/ntlmssp_parse.c | 2 +- source4/libcli/raw/raweas.c | 2 +- source4/libcli/raw/rawtrans.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index c36bb6a4fc..39fe5a8712 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -115,7 +115,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - pointers[i].data = s; + pointers[i].data = (void *)s; pointers[i].length = strlen(s)+1; head_size += pointers[i].length; break; diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 17e5ce8f75..621181841f 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -129,7 +129,7 @@ uint_t ea_pull_struct(const DATA_BLOB *blob, return 0; } - ea->name.s = talloc_strndup(mem_ctx, blob->data+4, nlen); + ea->name.s = talloc_strndup(mem_ctx, (const char *)(blob->data+4), nlen); ea->name.private_length = nlen; ea->value = data_blob_talloc(mem_ctx, NULL, vlen+1); if (!ea->value.data) return 0; diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 2554a736f5..371f50410d 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -56,8 +56,8 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, { int total_data=0; int total_param=0; - char *tdata; - char *tparam; + uint8_t *tdata; + uint8_t *tparam; parms->out.data.length = 0; parms->out.data.data = NULL; -- cgit From 20c0900edbba66106d602f43262cb97a48c6cbe9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 26 Nov 2004 12:30:39 +0000 Subject: r3979: added server side code for lsa_LookupSids2() and fixed authority_name return code to include our own domain. editing of ACLs via the w2k3 GUI works nicely (and faster) with these changes (This used to be commit a3f7f34b3965ddbd89b06334e03d2e1bb6aa364b) --- source4/libcli/security/dom_sid.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 001618bb07..dbd03108e4 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -239,3 +239,29 @@ struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, sid->num_auths++; return sid; } + + +/* + return True if the 2nd sid is in the domain given by the first sid +*/ +BOOL dom_sid_in_domain(const struct dom_sid *domain_sid, + const struct dom_sid *sid) +{ + int i; + + if (!domain_sid || !sid) { + return False; + } + + if (domain_sid->num_auths > sid->num_auths) { + return False; + } + + for (i = domain_sid->num_auths-1; i >= 0; --i) { + if (domain_sid->sub_auths[i] != sid->sub_auths[i]) { + return False; + } + } + + return dom_sid_compare_auth(domain_sid, sid) == 0; +} -- cgit From 3342a53c0f20af2f255152bc9077294e18376b09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Nov 2004 03:19:28 +0000 Subject: r3988: made dom_sid_add_rid() allocate the new sid with proper parent/child talloc relationship (This used to be commit 5db0eb1fe3abb5150bef27bfed4b7da723e4a287) --- source4/libcli/security/dom_sid.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index dbd03108e4..108e2f5500 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -217,7 +217,8 @@ struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid) } /* - add a rid to a domain dom_sid to make a full dom_sid + add a rid to a domain dom_sid to make a full dom_sid. This function + returns a new sid in the suppplied memory context */ struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid, @@ -229,14 +230,15 @@ struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, if (!sid) return NULL; *sid = *domain_sid; - /*TODO: use realloc! */ - sid->sub_auths = talloc_array_p(mem_ctx, uint32_t, sid->num_auths+1); + + sid->sub_auths = talloc_array_p(sid, uint32_t, sid->num_auths+1); if (!sid->sub_auths) { return NULL; } memcpy(sid->sub_auths, domain_sid->sub_auths, sid->num_auths*sizeof(uint32_t)); sid->sub_auths[sid->num_auths] = rid; sid->num_auths++; + return sid; } -- cgit From 15543f18acc9040fd3213e826147fe5604bb1ae1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Nov 2004 12:01:46 +0000 Subject: r4000: DATA_BLOB.data is uint8_t * not void * :-) (thanks abartlet for telling me) metze (This used to be commit 2783bf393f6310f9d827538329d619dad5b02dd0) --- source4/libcli/auth/ntlmssp_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 39fe5a8712..a713b9896d 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -115,7 +115,7 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - pointers[i].data = (void *)s; + pointers[i].data = (uint8_t *)s; pointers[i].length = strlen(s)+1; head_size += pointers[i].length; break; -- cgit From 692e1a214c8478ea9199542920b7083138f90691 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Nov 2004 14:46:17 +0000 Subject: r4001: fix segfault fix auth failed metze (This used to be commit 6a7eee1d9917e0884072354dddae568645798da5) --- source4/libcli/auth/gensec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 360a69c0e0..3cf96de4b3 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -443,6 +443,9 @@ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_ void gensec_end(struct gensec_security **gensec_security) { + if (!*gensec_security) { + return; + } if ((*gensec_security)->ops) { (*gensec_security)->ops->end(*gensec_security); } -- cgit From 607e3022381ab089bfcc0b153461b6b3ac76f175 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Nov 2004 05:37:57 +0000 Subject: r4013: got rid of a bunch of unused or unmaintained code - removed the clitar code. It is unmaintained, and a horribly badly done hack - removed client.h as it contained mostly unused definitions - removed the unused clidfs.c code (This used to be commit 31a7bddbb3815b4d625e993dbce4805dae1c18f8) --- source4/libcli/clideltree.c | 8 +- source4/libcli/clidfs.c | 558 -------------------------------------------- source4/libcli/clilist.c | 49 ++-- 3 files changed, 25 insertions(+), 590 deletions(-) delete mode 100644 source4/libcli/clidfs.c (limited to 'source4/libcli') diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 7dd3803735..30369b977f 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -19,7 +19,7 @@ */ #include "includes.h" -#include "client.h" +#include "clilist.h" struct delete_state { struct smbcli_tree *tree; @@ -30,7 +30,7 @@ struct delete_state { /* callback function for torture_deltree() */ -static void delete_fn(struct file_info *finfo, const char *name, void *state) +static void delete_fn(struct clilist_file_info *finfo, const char *name, void *state) { struct delete_state *dstate = state; char *s, *n; @@ -41,14 +41,14 @@ static void delete_fn(struct file_info *finfo, const char *name, void *state) n[strlen(n)-1] = 0; asprintf(&s, "%s%s", n, finfo->name); - if (finfo->mode & FILE_ATTRIBUTE_READONLY) { + if (finfo->attrib & FILE_ATTRIBUTE_READONLY) { if (NT_STATUS_IS_ERR(smbcli_setatr(dstate->tree, s, 0, 0))) { DEBUG(2,("Failed to remove READONLY on %s - %s\n", s, smbcli_errstr(dstate->tree))); } } - if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { + if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) { char *s2; asprintf(&s2, "%s\\*", s); smbcli_unlink(dstate->tree, s2); diff --git a/source4/libcli/clidfs.c b/source4/libcli/clidfs.c deleted file mode 100644 index c007d061a9..0000000000 --- a/source4/libcli/clidfs.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Dfs routines - Copyright (C) James Myers 2003 - - 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" - -BOOL smbcli_client_initialize(struct smbcli_client* context, - const char* sockops, - char* username, char* password, char* workgroup, - int flags) -{ - int i; - for (i=0; i < DFS_MAX_CLUSTER_SIZE ; i++) { - context->cli[i] = smbcli_raw_initialise(); - } - context->sockops = sockops; - context->username = username; - context->password = password; - context->workgroup = workgroup; - context->connection_flags = flags; - if (flags & SMBCLI_FULL_CONNECTION_USE_DFS) - context->use_dfs = True; - context->number_members = DFS_MAX_CLUSTER_SIZE; - return True; -} - -/**************************************************************************** - Interpret a Dfs referral structure. - The length of the structure is returned - The structure of a Dfs referral depends on the info level. -****************************************************************************/ - -static int interpret_referral(struct smbcli_state *cli, - int level,char *p,referral_info *rinfo) -{ - char* q; - int version, size; - - version = SVAL(p,0); - size = SVAL(p,2); - rinfo->server_type = SVAL(p,4); - rinfo->referral_flags = SVAL(p,6); - rinfo->proximity = SVAL(p,8); - rinfo->ttl = SVAL(p,10); - rinfo->pathOffset = SVAL(p,12); - rinfo->altPathOffset = SVAL(p,14); - rinfo->nodeOffset = SVAL(p,16); - DEBUG(3,("referral version=%d, size=%d, server_type=%d, flags=0x%x, proximity=%d, ttl=%d, pathOffset=%d, altPathOffset=%d, nodeOffset=%d\n", - version, size, rinfo->server_type, rinfo->referral_flags, - rinfo->proximity, rinfo->ttl, rinfo->pathOffset, - rinfo->altPathOffset, rinfo->nodeOffset)); - - q = (char*)(p + (rinfo->pathOffset)); - //printf("p=%p, q=%p, offset=%d\n", p, q, rinfo->pathOffset); - //printf("hex=0x%x, string=%s\n", q, q); - clistr_pull(cli, rinfo->path, q, - sizeof(rinfo->path), - -1, STR_TERMINATE); - DEBUG(4,("referral path=%s\n", rinfo->path)); - q = (char*)(p + (rinfo->altPathOffset)/sizeof(char)); - if (rinfo->altPathOffset > 0) - clistr_pull(cli, rinfo->altPath, q, - sizeof(rinfo->altPath), - -1, STR_TERMINATE); - DEBUG(4,("referral alt path=%s\n", rinfo->altPath)); - q = (char*)(p + (rinfo->nodeOffset)/sizeof(char)); - if (rinfo->nodeOffset > 0) - clistr_pull(cli, rinfo->node, q, - sizeof(rinfo->node), - -1, STR_TERMINATE); - DEBUG(4,("referral node=%s\n", rinfo->node)); - fstrcpy(rinfo->host, &rinfo->node[1]); - p = strchr_m(&rinfo->host[1],'\\'); - if (!p) { - printf("invalid referral node %s\n", rinfo->node); - return -1; - } - *p = 0; - rinfo->share = talloc_strdup(cli->mem_ctx, p+1); - DEBUG(3,("referral host=%s share=%s\n", - rinfo->host, rinfo->share)); - return size; -} - -#if 0 -int smbcli_select_dfs_referral(struct smbcli_state *cli, dfs_info* dinfo) -{ - return (int)sys_random()%dinfo->number_referrals; -} - -int smbcli_get_dfs_referral(struct smbcli_state *cli,const char *Fname, dfs_info* dinfo) -{ - struct smb_trans2 parms; - int info_level; - char *p; - pstring fname; - int i; - char *rparam=NULL, *rdata=NULL; - int param_len, data_len; - uint16_t setup; - pstring param; - DATA_BLOB trans_param, trans_data; - - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - - pstrcpy(fname,Fname); - - setup = TRANSACT2_GET_DFS_REFERRAL ; - SSVAL(param,0,SMBCLI_DFS_MAX_REFERRAL_LEVEL); /* attribute */ - p = param+2; - p += clistr_push(cli, param+2, fname, -1, - STR_TERMINATE); - - param_len = PTR_DIFF(p, param); - DEBUG(3,("smbcli_get_dfs_referral: sending request\n")); - - trans_param.length = param_len; - trans_param.data = param; - trans_data.length = 0; - trans_data.data = NULL; - - if (!smbcli_send_trans(cli, SMBtrans2, - NULL, /* Name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - &trans_param, 10, /* param, length, max */ - &trans_data, - cli->max_xmit /* data, length, max */ - )) { - return 0; - } - - if (!smbcli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len) && - smbcli_is_dos_error(cli)) { - return 0; - } - //printf("smbcli_get_dfs_referral: received response, rdata=%p, rparam=%p\n", - // rdata, rparam); - - if (smbcli_is_error(cli) || !rdata) - return 0; - - /* parse out some important return info */ - //printf("smbcli_get_dfs_referral: valid response\n"); - p = rdata; - dinfo->path_consumed = SVAL(p,0); - dinfo->number_referrals = SVAL(p,2); - dinfo->referral_flags = SVAL(p,4); - DEBUG(3,("smbcli_get_dfs_referral: path_consumed=%d, # referrals=%d, flags=0x%x\n", - dinfo->path_consumed, dinfo->number_referrals, - dinfo->referral_flags)); - - /* point to the referral bytes */ - p+=8; - for (i=0; i < dinfo->number_referrals; i++) { - p += interpret_referral(cli,info_level,p,&dinfo->referrals[i]); - } - - SAFE_FREE(rdata); - SAFE_FREE(rparam); - - DEBUG(3,("received %d Dfs referrals\n", - dinfo->number_referrals)); - - dinfo->selected_referral = smbcli_select_dfs_referral(cli, dinfo); - DEBUG(3, ("selected Dfs referral %d %s\n", - dinfo->selected_referral, dinfo->referrals[dinfo->selected_referral].node)); - - return(dinfo->number_referrals); -} -#endif - -/* check if the server produced Dfs redirect */ -BOOL smbcli_check_dfs_redirect(struct smbcli_state* c, char* fname, - dfs_info* dinfo) -{ - //printf("check_dfs_redirect: error %s\n", - // smbcli_errstr(c)); - if (smbcli_is_dos_error(c)) { - printf("got dos error\n"); - return False; - - } else { - NTSTATUS status; - - /* Check NT error */ - - status = smbcli_nt_error(c); - //printf("got nt error 0x%x\n", status); - - if (NT_STATUS_V(NT_STATUS_PATH_NOT_COVERED) != NT_STATUS_V(status)) { - return False; - } - } - /* execute trans2 getdfsreferral */ - //printf("check_dfs_redirect: process referral\n"); - //smbcli_get_dfs_referral(c, fname, dinfo); - return True; -} - -int smbcli_dfs_open_connection(struct smbcli_client* cluster, - char* host, char* share, int flags) -{ - int i; - BOOL retry; - struct smbcli_state* c; - - // check if already connected - for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { - if (cluster->cli[i]->in_use && strequal(host, smbcli_state_get_host(cluster->cli[i])) - && strequal(share, smbcli_state_get_share(cluster->cli[i]))) { - DEBUG(3,("smbcli_dfs_open_connection: already connected to \\\\%s\\%s\n", host, share)); - return i; - } - } - // open connection - DEBUG(3,("smbcli_dfs_open_connection: opening \\\\%s\\%s %s@%s\n", - host, share, cluster->username, cluster->workgroup)); - for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { - if (!cluster->cli[i]->in_use) { - break; - } - } - if (i >= DFS_MAX_CLUSTER_SIZE) - return -1; - - c = cluster->cli[i]; - if (NT_STATUS_IS_ERR(smbcli_full_connection(NULL, &c, - NULL, host, NULL, 0, - share, "?????", - cluster->username, cluster->workgroup, - cluster->password, flags, - &retry))) - return -1; - smbcli_state_set_sockopt(cluster->cli[i], cluster->sockops); - smbcli_state_set_host(cluster->cli[i], host); - smbcli_state_set_share(cluster->cli[i], share); - cluster->cli[i]->in_use = True; - DEBUG(3,("smbcli_dfs_open_connection: connected \\\\%s\\%s (%d) %s@%s\n", - smbcli_state_get_host(cluster->cli[i]), smbcli_state_get_share(cluster->cli[i]), i, - cluster->username, cluster->workgroup)); - - return i; -} - -/********************************************************************** - Parse the pathname of the form \hostname\service\reqpath - into the dfs_path structure - **********************************************************************/ - -BOOL smbcli_parse_dfs_path(char* pathname, struct dfs_path* pdp) -{ - pstring pathname_local; - char* p,*temp; - - pstrcpy(pathname_local,pathname); - p = temp = pathname_local; - - ZERO_STRUCTP(pdp); - - trim_string(temp,"\\","\\"); - DEBUG(10,("temp in smbcli_parse_dfs_path: .%s. after trimming \\'s\n",temp)); - - /* now tokenize */ - /* parse out hostname */ - p = strchr(temp,'\\'); - if(p == NULL) - return False; - *p = '\0'; - pstrcpy(pdp->hostname,temp); - DEBUG(10,("hostname: %s\n",pdp->hostname)); - - /* parse out servicename */ - temp = p+1; - p = strchr(temp,'\\'); - if(p == NULL) { - pstrcpy(pdp->servicename,temp); - pdp->reqpath[0] = '\0'; - return True; - } - *p = '\0'; - pstrcpy(pdp->servicename,temp); - DEBUG(10,("servicename: %s\n",pdp->servicename)); - - /* rest is reqpath */ - pstrcpy(pdp->reqpath, p+1); - - DEBUG(10,("rest of the path: %s\n",pdp->reqpath)); - return True; -} - -char* rebuild_filename(char *referral_fname, struct smbcli_state* c, - char* fname, int path_consumed) -{ - const char *template = "\\\\%s\\%s\\%s"; - struct dfs_path dp; - - // TODO: handle consumed length - DEBUG(3,("rebuild_filename: %s, %d consumed of %d\n", - fname, path_consumed, strlen(fname))); - if (smbcli_parse_dfs_path(fname, &dp)) { - DEBUG(3,("rebuild_filename: reqpath=%s\n", - dp.reqpath)); - asprintf(&referral_fname, - template, smbcli_state_get_host(c), - smbcli_state_get_share(c), dp.reqpath); - } - else - return NULL; - DEBUG(3,("rebuild_filename: %s -> %s\n", fname, referral_fname)); - return referral_fname; -} - -/**************************************************************************** - Open a file (allowing for Dfs referral). -****************************************************************************/ - -int smbcli_dfs_open(struct smbcli_client* cluster, int *server, - char *fname_src, int flags, int share_mode) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - int fnum; - - DEBUG(3,("smbcli_dfs_open: open %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if ((fnum = smbcli_open(cluster->cli[*server], fname_src, flags, share_mode)) < 0) { - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_open: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_open: Dfs open %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - fnum = smbcli_open(cluster->cli[*server], fname_src, flags, share_mode); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_open: open of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - return -1; - } - } - DEBUG(3,("smbcli_dfs_open: open %s fnum=%d\n", - fname_src, fnum)); - return fnum; -} - -/**************************************************************************** - Delete a file (allowing for Dfs referral). -****************************************************************************/ - -NTSTATUS smbcli_nt_unlink(struct smbcli_client* cluster, int *server, - char *fname_src, uint16_t FileAttributes) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - struct smb_unlink parms; - - DEBUG(3,("smbcli_nt_unlink: delete %s on server %s(%d), attributes=0x%x\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server, - FileAttributes)); - cluster->cli[*server]->dfs_referral = *server; - parms.in.pattern = fname_src; - parms.in.dirtype = FileAttributes; - if (NT_STATUS_IS_ERR(smbcli_raw_unlink(cluster->cli[*server], &parms))) { - printf("smbcli_nt_unlink: delete of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_nt_unlink: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return NT_STATUS_INTERNAL_ERROR; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return NT_STATUS_INTERNAL_ERROR; - fname_src = referral_fname; - DEBUG(3,("smbcli_nt_unlink: Dfs delete %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_raw_unlink(cluster->cli[*server], &parms); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_nt_unlink: delete of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - } - } - return smbcli_nt_error(cluster->cli[*server]); -} - -/**************************************************************************** - Rename a file (allowing for Dfs referral). -****************************************************************************/ - -BOOL smbcli_dfs_rename(struct smbcli_client* cluster, int *server, - char *fname_src, char *fname_dst) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - - DEBUG(3,("smbcli_dfs_rename: rename %s to %s on server %s(%d)\n", - fname_src, fname_dst, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if (!smbcli_rename(cluster->cli[*server], fname_src, fname_dst)) { - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_rename: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_rename: Dfs rename %s to %s on server %s(%d)\n", - fname_src, fname_dst, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_rename(cluster->cli[*server], fname_src, fname_dst); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_rename: rename of %s to %s failed (%s)\n", - fname_src, fname_dst, smbcli_errstr(cluster->cli[*server])); - return False; - } - } - return True; -} - -/**************************************************************************** - Make directory (allowing for Dfs referral). -****************************************************************************/ - -BOOL smbcli_dfs_mkdir(struct smbcli_client* cluster, int *server, - char *fname_src) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - - DEBUG(3,("smbcli_dfs_mkdir: mkdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if (!smbcli_mkdir(cluster->cli[*server], fname_src)) { - printf("smbcli_dfs_mkdir: mkdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_mkdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_mkdir: Dfs mkdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_mkdir(cluster->cli[*server], fname_src); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_mkdir: mkdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - return False; - } - } - return True; -} - -/**************************************************************************** - Remove directory (allowing for Dfs referral). -****************************************************************************/ - -BOOL smbcli_dfs_rmdir(struct smbcli_client* cluster, int *server, - char *fname_src) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - - DEBUG(3,("smbcli_dfs_rmdir: rmdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if (!smbcli_rmdir(cluster->cli[*server], fname_src)) { - printf("smbcli_dfs_rmdir: rmdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_rmdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_rmdir: Dfs rmdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_rmdir(cluster->cli[*server], fname_src); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_rmdir: rmdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - return False; - } - } - return True; -} diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index e8b97f324d..8b05b98e0e 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -20,11 +20,11 @@ */ #include "includes.h" -#include "client.h" +#include "clilist.h" #include "libcli/raw/libcliraw.h" struct search_private { - struct file_info *dirlist; + struct clilist_file_info *dirlist; TALLOC_CTX *mem_ctx; int dirlist_len; int ff_searchcount; /* total received in 1 server trip */ @@ -40,9 +40,9 @@ struct search_private { ****************************************************************************/ static BOOL interpret_long_filename(enum smb_search_level level, union smb_search_data *info, - struct file_info *finfo) + struct clilist_file_info *finfo) { - struct file_info finfo2; + struct clilist_file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); @@ -50,23 +50,17 @@ static BOOL interpret_long_filename(enum smb_search_level level, switch (level) { case RAW_SEARCH_STANDARD: finfo->size = info->standard.size; - finfo->ctime = info->standard.create_time; - finfo->atime = info->standard.access_time; finfo->mtime = info->standard.write_time; - finfo->mode = info->standard.attrib; + finfo->attrib = info->standard.attrib; finfo->name = info->standard.name.s; + finfo->short_name = info->standard.name.s; break; case RAW_SEARCH_BOTH_DIRECTORY_INFO: finfo->size = info->both_directory_info.size; - finfo->ctime = nt_time_to_unix(info->both_directory_info.create_time); - finfo->atime = nt_time_to_unix(info->both_directory_info.access_time); finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time); - finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */ - if (info->both_directory_info.short_name.s) { - strncpy(finfo->short_name, info->both_directory_info.short_name.s, - sizeof(finfo->short_name)-1); - } + finfo->attrib = info->both_directory_info.attrib; + finfo->short_name = info->both_directory_info.short_name.s; finfo->name = info->both_directory_info.name.s; break; @@ -82,18 +76,18 @@ static BOOL interpret_long_filename(enum smb_search_level level, static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; - struct file_info *tdl; + struct clilist_file_info *tdl; /* add file info to the dirlist pool */ tdl = talloc_realloc(state, state->dirlist, - state->dirlist_len + sizeof(struct file_info)); + state->dirlist_len + sizeof(struct clilist_file_info)); if (!tdl) { return False; } state->dirlist = tdl; - state->dirlist_len += sizeof(struct file_info); + state->dirlist_len += sizeof(struct clilist_file_info); interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]); @@ -106,7 +100,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, enum smb_search_level level, - void (*fn)(struct file_info *, const char *, void *), + void (*fn)(struct clilist_file_info *, const char *, void *), void *caller_state) { union smb_search_first first_parms; @@ -209,19 +203,18 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu ****************************************************************************/ static BOOL interpret_short_filename(int level, union smb_search_data *info, - struct file_info *finfo) + struct clilist_file_info *finfo) { - struct file_info finfo2; + struct clilist_file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); - finfo->ctime = info->search.write_time; - finfo->atime = info->search.write_time; finfo->mtime = info->search.write_time; finfo->size = info->search.size; - finfo->mode = info->search.attrib; + finfo->attrib = info->search.attrib; finfo->name = info->search.name; + finfo->short_name = info->search.name; return True; } @@ -229,18 +222,18 @@ static BOOL interpret_short_filename(int level, static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; - struct file_info *tdl; + struct clilist_file_info *tdl; /* add file info to the dirlist pool */ tdl = talloc_realloc(state, state->dirlist, - state->dirlist_len + sizeof(struct file_info)); + state->dirlist_len + sizeof(struct clilist_file_info)); if (!tdl) { return False; } state->dirlist = tdl; - state->dirlist_len += sizeof(struct file_info); + state->dirlist_len += sizeof(struct clilist_file_info); interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]); @@ -252,7 +245,7 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) } int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, - void (*fn)(struct file_info *, const char *, void *), + void (*fn)(struct clilist_file_info *, const char *, void *), void *caller_state) { union smb_search_first first_parms; @@ -338,7 +331,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu ****************************************************************************/ int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, - void (*fn)(struct file_info *, const char *, void *), void *state) + void (*fn)(struct clilist_file_info *, const char *, void *), void *state) { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) return smbcli_list_old(tree, Mask, attribute, fn, state); -- cgit From 75f58e2d0fc3d2b07659caf34a07a0fb20cc1756 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Nov 2004 05:45:37 +0000 Subject: r4015: correct copyright attributions (This used to be commit 078d9ab05bffc79e4f329ea18fe3dafd144d989c) --- source4/libcli/raw/libcliraw.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index b00af846b7..51b50fdcb9 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -1,9 +1,8 @@ /* Unix SMB/CIFS implementation. SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Luke Kenneth Casson Leighton 1996-1998 - Copyright (C) Jeremy Allison 1998 + + Copyright (C) Andrew Tridgell 2002-2004 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify -- cgit From 1a7283a8fa5a7d97abc5b10f3d73ce99a4a7b905 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 1 Dec 2004 05:22:24 +0000 Subject: r4025: added a sec_access_check() function for checking security descriptors against a users security token and access_mask (This used to be commit c4d21cd4b1ccffd5aaa70a551c57f6eab1ca9c6d) --- source4/libcli/security/access_check.c | 162 ++++++++++++++++++++++++++ source4/libcli/security/config.mk | 1 + source4/libcli/security/security_descriptor.c | 39 ------- 3 files changed, 163 insertions(+), 39 deletions(-) create mode 100644 source4/libcli/security/access_check.c (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c new file mode 100644 index 0000000000..d8809aebc6 --- /dev/null +++ b/source4/libcli/security/access_check.c @@ -0,0 +1,162 @@ +/* + Unix SMB/CIFS implementation. + + security access checking routines + + Copyright (C) Andrew Tridgell 2004 + + 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 "librpc/gen_ndr/ndr_security.h" + + +/* + check if a sid is in the supplied token +*/ +static BOOL sid_active_in_token(struct dom_sid *sid, struct nt_user_token *token) +{ + int i; + for (i=0;inum_sids;i++) { + if (dom_sid_equal(sid, token->user_sids[i])) { + return True; + } + } + return False; +} + + +/* + perform a SEC_FLAG_MAXIMUM_ALLOWED access check +*/ +static NTSTATUS access_check_max_allowed(struct security_descriptor *sd, + struct nt_user_token *token, + uint32_t *access_granted) +{ + uint32_t denied = 0, granted = 0; + int i; + + for (i = 0;idacl->num_aces; i++) { + struct security_ace *ace = &sd->dacl->aces[i]; + + if (!sid_active_in_token(&ace->trustee, token)) { + continue; + } + + switch (ace->type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED: + granted |= ace->access_mask; + break; + case SEC_ACE_TYPE_ACCESS_DENIED: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + denied |= ace->access_mask; + break; + } + } + + granted &= ~denied; + + if (granted == 0) { + return NT_STATUS_ACCESS_DENIED; + } + + *access_granted = granted; + + return NT_STATUS_OK; +} + +/* + the main entry point for access checking. +*/ +NTSTATUS sec_access_check(struct security_descriptor *sd, + struct nt_user_token *token, + uint32_t access_desired, + uint32_t *access_granted) +{ + int i; + uint32_t bits_remaining; + + bits_remaining = access_desired; + + /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */ + if (bits_remaining & (SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL)) { + if (sid_active_in_token(sd->owner_sid, token)) { + bits_remaining &= + ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); + } + } + +#if 0 + /* this is where we should check for the "system security" privilege, once we + move to the full security_token and not just the nt_user_token */ + if (access_desired & SEC_FLAG_SYSTEM_SECURITY) { + if (privilege_in_token(SE_PRIVILEGE_SYSTEM_SECURITY, token)) { + bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; + } else { + return NT_STATUS_ACCESS_DENIED; + } + } +#endif + + /* dacl not present allows access */ + if (!(sd->type & SEC_DESC_DACL_PRESENT)) { + *access_granted = access_desired; + return NT_STATUS_OK; + } + + /* empty dacl denies access */ + if (sd->dacl == NULL || sd->dacl->num_aces == 0) { + return NT_STATUS_ACCESS_DENIED; + } + + /* handle the maximum allowed case separately */ + if (access_desired == SEC_FLAG_MAXIMUM_ALLOWED) { + return access_check_max_allowed(sd, token, access_granted); + } + + /* check each ace in turn. */ + for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { + struct security_ace *ace = &sd->dacl->aces[i]; + + if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + continue; + } + + if (!sid_active_in_token(&ace->trustee, token)) { + continue; + } + + switch (ace->type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED: + bits_remaining &= ~ace->access_mask; + break; + case SEC_ACE_TYPE_ACCESS_DENIED: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + if (bits_remaining & ace->access_mask) { + return NT_STATUS_ACCESS_DENIED; + } + break; + } + } + + if (bits_remaining != 0) { + return NT_STATUS_ACCESS_DENIED; + } + + *access_granted = access_desired; + + return NT_STATUS_OK; +} diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 908a993ce6..900dbe780a 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -12,6 +12,7 @@ NOPROTO = YES ADD_OBJ_FILES = libcli/security/security_token.o \ libcli/security/security_descriptor.o \ libcli/security/dom_sid.o \ + libcli/security/access_check.o \ librpc/ndr/ndr_sec.o REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR # End SUBSYSTEM LIB_SECURITY diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index a4056e5e71..1783c62f37 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -65,45 +65,6 @@ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, return nsd; } -NTSTATUS security_check_dacl(struct security_token *st, - struct security_descriptor *sd, - uint32 access_mask) -{ - size_t i,y; - NTSTATUS status = NT_STATUS_ACCESS_DENIED; - - DEBUG(1, ("security_check_dacl(): sorry untested yet\n")); - return status; - - if (!sd->dacl) { - return NT_STATUS_INVALID_ACL; - } - - for (i=0; i < st->num_sids; i++) { - for (y=0; y < sd->dacl->num_aces; y++) { - if (dom_sid_equal(&st->sids[i], &sd->dacl->aces[y].trustee)) { - switch (sd->dacl->aces[y].type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED: - if (access_mask & sd->dacl->aces[y].access_mask) { - status = NT_STATUS_OK; - } - break; - case SEC_ACE_TYPE_ACCESS_DENIED: - if (access_mask & sd->dacl->aces[y].access_mask) { - return NT_STATUS_ACCESS_DENIED; - } - break; - default: - return NT_STATUS_INVALID_ACL; - } - } - } - } - - return status; -} - - /* add an ACE to the DACL of a security_descriptor */ -- cgit From 81476cd9fad32f5629de44d45c3a9c58d67e5864 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Dec 2004 04:34:11 +0000 Subject: r4034: add a function security_descriptor_create() which can be used to easily create complex security descriptors for testing. This greatly simplifies the smbtorture code I am writing for testing our new access_check code. (This used to be commit 891a8bc16af3c6ce5800e793ce4ec8b0078e444f) --- source4/libcli/security/security_descriptor.c | 79 +++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 1783c62f37..1c63478ab2 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -100,6 +100,8 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, sd->dacl->num_aces++; + sd->type |= SEC_DESC_DACL_PRESENT; + return NT_STATUS_OK; } @@ -206,3 +208,80 @@ BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, return True; } + + +/* + create a security descriptor using string SIDs. This is used by the + torture code to allow the easy creation of complex ACLs + This is a varargs function. The list of ACEs ends with a NULL sid. + + a typical call would be: + + sd = security_descriptor_create(mem_ctx, + mysid, + mygroup, + SID_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_FILE_ALL, + NULL); + that would create a sd with one ACE +*/ +struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, + const char *owner_sid, + const char *group_sid, + ...) +{ + va_list ap; + struct security_descriptor *sd; + const char *sidstr; + + sd = security_descriptor_initialise(mem_ctx); + if (sd == NULL) return NULL; + + if (owner_sid) { + sd->owner_sid = dom_sid_parse_talloc(mem_ctx, owner_sid); + if (sd->owner_sid == NULL) { + talloc_free(sd); + return NULL; + } + } + if (group_sid) { + sd->group_sid = dom_sid_parse_talloc(mem_ctx, group_sid); + if (sd->group_sid == NULL) { + talloc_free(sd); + return NULL; + } + } + + va_start(ap, group_sid); + while ((sidstr = va_arg(ap, const char *))) { + struct dom_sid *sid; + struct security_ace *ace = talloc_p(sd, struct security_ace); + NTSTATUS status; + + if (ace == NULL) { + talloc_free(sd); + va_end(ap); + return NULL; + } + ace->type = va_arg(ap, unsigned int); + ace->access_mask = va_arg(ap, unsigned int); + ace->flags = 0; + sid = dom_sid_parse_talloc(ace, sidstr); + if (sid == NULL) { + va_end(ap); + talloc_free(sd); + return NULL; + } + ace->trustee = *sid; + status = security_descriptor_dacl_add(sd, ace); + if (!NT_STATUS_IS_OK(status)) { + va_end(ap); + talloc_free(sd); + return NULL; + } + } + va_end(ap); + + return sd; +} -- cgit From 4183b2ac3832cdc2055d7eb3ed7121a9ea91085c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Dec 2004 04:51:56 +0000 Subject: r4037: fixed a bunch of "might be uninitialised" warnings after enabling -O1 in my compile (This used to be commit 0928b1f5b68c858922c3ea6c27ed03b5091c6221) --- source4/libcli/auth/ntlmssp_sign.c | 2 ++ source4/libcli/raw/clisession.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index e2f5237a88..1b391306bc 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -368,6 +368,8 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) recv_sign_const = CLI_SIGN; recv_seal_const = CLI_SEAL; break; + default: + return NT_STATUS_INTERNAL_ERROR; } /** diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index b7802d8065..c92e3ecb0b 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -393,7 +393,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess union smb_sesssetup s2; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); - const char *chosen_oid; + const char *chosen_oid = NULL; s2.generic.level = RAW_SESSSETUP_SPNEGO; s2.spnego.in.bufsize = session->transport->options.max_xmit; -- cgit From 00948a80724ccfe1454bc40fcfcdc2287b4e3f31 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Dec 2004 18:15:39 +0000 Subject: r4044: only send supportedMech when we also send other data metze (This used to be commit 1e0483a8482574fa0f8d7ad31cc4bf4a6155ec52) --- source4/libcli/auth/spnego.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index b6436fe8c6..3af1bc1e81 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -375,23 +375,26 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.responseToken = unwrapped_out; spnego_out.negTokenTarg.mechListMIC = null_data_blob; - + spnego_out.negTokenTarg.supportedMech = NULL; + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - spnego_out.negTokenTarg.supportedMech + spnego_out.negTokenTarg.supportedMech = spnego_state->sub_sec_security->ops->oid; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->state_position = SPNEGO_SERVER_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { - spnego_out.negTokenTarg.supportedMech = NULL; + if (unwrapped_out.data) { + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; + } spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; spnego_state->state_position = SPNEGO_DONE; } else { - spnego_out.negTokenTarg.supportedMech = NULL; spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; DEBUG(1, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); spnego_state->state_position = SPNEGO_DONE; } - + if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); return NT_STATUS_INVALID_PARAMETER; -- cgit From 64b516b10546619d3b1adef7fcc4cfef3ad610f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Dec 2004 18:27:08 +0000 Subject: r4045: readd krb5 support defaulted to disable use: gensec:krb5=yes gensec:ms_krb5=yes to enable it or -k on the client tools on the command line metze (This used to be commit 0ae5794cf44933d2554e0356baaca24c7a784f71) --- source4/libcli/auth/clikrb5.c | 1 + source4/libcli/auth/gensec.m4 | 2 +- source4/libcli/auth/gensec.mk | 2 +- source4/libcli/auth/gensec_krb5.c | 12 ++++++++++-- source4/libcli/auth/kerberos.c | 1 + source4/libcli/auth/kerberos_verify.c | 4 +++- 6 files changed, 17 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index b5158a038a..48e1f88503 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/network.h" #include "system/kerberos.h" +#include "libcli/auth/kerberos.h" #include "system/time.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index dd72d967dd..9b814014ca 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -2,5 +2,5 @@ SMB_MODULE_DEFAULT(gensec_krb5, NOT) if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then /* enable this when krb5 is fully working */ - SMB_MODULE_DEFAULT(gensec_krb5, NOT) + SMB_MODULE_DEFAULT(gensec_krb5, STATIC) fi diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index 30da8aaa0e..66abfd10b7 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -19,7 +19,7 @@ ADD_OBJ_FILES = \ libcli/auth/kerberos.o \ libcli/auth/kerberos_verify.o \ libcli/auth/gssapi_parse.o -REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 +REQUIRED_SUBSYSTEMS = NDR_KRB5PAC EXT_LIB_KRB5 # End MODULE gensec_krb5 ################################################ diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 97025fa6c4..0f1bf8e700 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -512,9 +512,14 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL { char *principal; DATA_BLOB unwrapped_in; - DATA_BLOB unwrapped_out; + DATA_BLOB unwrapped_out = data_blob(NULL, 0); uint8 tok_id[2]; + if (!in.data) { + *out = unwrapped_out; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + /* Parse the GSSAPI wrapping, if it's there... (win2k3 allows it to be omited) */ if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { nt_status = ads_verify_ticket(out_mem_ctx, @@ -544,8 +549,11 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL if (NT_STATUS_IS_OK(nt_status)) { gensec_krb5_state->state_position = GENSEC_KRB5_DONE; /* wrap that up in a nice GSS-API wrapping */ +#ifndef GENSEC_SEND_UNWRAPPED_KRB5 *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REP); - +#else + *out = unwrapped_out; +#endif gensec_krb5_state->peer_principal = talloc_steal(gensec_krb5_state, principal); } return nt_status; diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 50f2e0f24e..9510aaa7fb 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/kerberos.h" +#include "libcli/auth/kerberos.h" #include "system/time.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 6d87cf8d8b..d00394fd79 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -101,7 +101,9 @@ static krb5_error_code ads_keytab_verify_ticket(krb5_context context, krb5_auth_ } DEBUG(10, ("Checking principal: %s\n", princ_name)); /* Look for a CIFS ticket */ - if (!strncasecmp(princ_name, "cifs/", 5) || (!strncasecmp(princ_name, "host/", 5))) { + if (!strncasecmp(princ_name, "cifs/", 5) || + !strncasecmp(princ_name, "host/", 5) || + !strncasecmp(princ_name, "ldap/", 5)) { #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); #else -- cgit From 58c326809a816703dc516c3022c9c4dbb9d09445 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:24:38 +0000 Subject: r4052: fixed a bunch of code to use the type safe _p allocation macros (This used to be commit 80d15fa3402a9d1183467463f6b21c0b674bc442) --- source4/libcli/ldap/ldap_client.c | 4 ++-- source4/libcli/namequery.c | 11 +++++------ source4/libcli/nmblib.c | 13 +++++-------- 3 files changed, 12 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7a72734c57..88c84d880b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -195,7 +195,7 @@ BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, (msg->type == LDAP_TAG_UnbindRequest)) return True; - entry = malloc(sizeof(*entry)); + entry = malloc_p(struct ldap_queue_entry); if (entry == NULL) return False; @@ -243,7 +243,7 @@ static struct ldap_message *recv_from_queue(struct ldap_connection *conn, static void add_search_entry(struct ldap_connection *conn, struct ldap_message *msg) { - struct ldap_queue_entry *e = malloc(sizeof *e); + struct ldap_queue_entry *e = malloc_p(struct ldap_queue_entry); if (e == NULL) return; diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 85270c1001..66154ef8f6 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -63,7 +63,7 @@ static struct node_status *parse_node_status(char *p, int *num_names) if (*num_names == 0) return NULL; - ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names)); + ret = malloc_array_p(struct node_status, *num_names); if (!ret) return NULL; p++; @@ -619,7 +619,7 @@ static BOOL resolve_hosts(const char *name, if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { struct ipv4_addr return_ip; putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = (struct ipv4_addr *)malloc(sizeof(struct ipv4_addr)); + *return_iplist = malloc_p(struct ipv4_addr); if(*return_iplist == NULL) { DEBUG(3,("resolve_hosts: malloc fail !\n")); return False; @@ -657,7 +657,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); if (allzeros || allones || is_address) { - *return_iplist = (struct ipv4_addr *)malloc(sizeof(struct ipv4_addr)); + *return_iplist = malloc_p(struct ipv4_addr); if(*return_iplist == NULL) { DEBUG(3,("internal_resolve_name: malloc fail !\n")); return False; @@ -731,8 +731,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam controllers including the PDC in iplist[1..n]. Iterating over the iplist when the PDC is down will cause two sets of timeouts. */ - if (*return_count && (nodupes_iplist = (struct ipv4_addr *) - malloc(sizeof(struct ipv4_addr) * (*return_count)))) { + if (*return_count && (nodupes_iplist = malloc_array_p(struct ipv4_addr, *return_count))) { int nodupes_count = 0; /* Iterate over return_iplist looking for duplicates */ @@ -1156,7 +1155,7 @@ BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr **ip_ if ( (num_addresses == 0) && !done_auto_lookup ) return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count); - return_iplist = (struct ipv4_addr *)malloc(num_addresses * sizeof(struct ipv4_addr)); + return_iplist = malloc_array_p(struct ipv4_addr, num_addresses); if (return_iplist == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index 06030f9aca..70c6fab8da 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -548,24 +548,21 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) if (nmb->answers) { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->answers = malloc_array_p(struct res_rec, nmb->header.ancount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->answers, (char *)nmb->answers, nmb->header.ancount * sizeof(struct res_rec)); } if (nmb->nsrecs) { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->nsrecs = malloc_array_p(struct res_rec, nmb->header.nscount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, nmb->header.nscount * sizeof(struct res_rec)); } if (nmb->additional) { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->additional = malloc_array_p(struct res_rec, nmb->header.arcount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->additional, (char *)nmb->additional, nmb->header.arcount * sizeof(struct res_rec)); @@ -591,7 +588,7 @@ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) { struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + if(( pkt_copy = malloc_p(struct packet_struct)) == NULL) { DEBUG(0,("copy_dgram_packet: malloc fail.\n")); return NULL; @@ -663,7 +660,7 @@ struct packet_struct *parse_packet(char *buf,int length, struct packet_struct *p; BOOL ok=False; - p = (struct packet_struct *)malloc(sizeof(*p)); + p = malloc_p(struct packet_struct); if (!p) return(NULL); p->next = NULL; -- cgit From e5ce904ddbd6175ba86ed827bf096b76b11b5511 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:42:06 +0000 Subject: r4054: got rid of Realloc(), replacing it with the type safe macro realloc_p() (This used to be commit b0f6e21481745d1b2ced28d9ed6f09f6ffd99562) --- source4/libcli/auth/gensec.c | 4 +++- source4/libcli/namequery.c | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 3cf96de4b3..7243222b6d 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -770,7 +770,9 @@ NTSTATUS gensec_register(const void *_ops) return NT_STATUS_OBJECT_NAME_COLLISION; } - generic_security_ops = Realloc(generic_security_ops, sizeof(generic_security_ops[0]) * (gensec_num_backends+1)); + generic_security_ops = realloc_p(generic_security_ops, + const struct gensec_security_ops *, + gensec_num_backends+1); if (!generic_security_ops) { smb_panic("out of memory in gensec_register"); } diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 66154ef8f6..76fffe0d92 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -400,11 +400,12 @@ struct ipv4_addr *name_query(int fd,const char *name,int name_type, continue; } - tmp_ip_list = (struct ipv4_addr *)Realloc( ip_list, sizeof( ip_list[0] ) - * ( (*count) + nmb2->answers->rdlength/6 ) ); + tmp_ip_list = realloc_p(ip_list, + struct ipv4_addr, + (*count) + nmb2->answers->rdlength/6); if (!tmp_ip_list) { - DEBUG(0,("name_query: Realloc failed.\n")); + DEBUG(0,("name_query: realloc_p failed.\n")); SAFE_FREE(ip_list); } -- cgit From 6e6374cb5bcffb4df8bdb0a83327fff92b61ac84 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 07:20:30 +0000 Subject: r4055: fixed more places to use type safe allocation macros (This used to be commit eec698254f67365f27b4b7569fa982e22472aca1) --- source4/libcli/auth/clikrb5.c | 4 ++-- source4/libcli/auth/spnego_parse.c | 2 +- source4/libcli/ldap/ldap.c | 9 ++++----- source4/libcli/nmblib.c | 4 ++-- source4/libcli/raw/raweas.c | 4 ++-- source4/libcli/raw/rawnotify.c | 3 +-- 6 files changed, 12 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 48e1f88503..7ad8dd7b6c 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -212,7 +212,7 @@ return -1; } - sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + sa = malloc_array_p(struct sockaddr, num_kdcs); if (!sa) { DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); krb5_krbhst_free(ctx, hnd); @@ -220,7 +220,7 @@ return -1; } - *addr_pp = malloc(sizeof(struct sockaddr) * num_kdcs); + *addr_pp = malloc_array_p(struct sockaddr, num_kdcs); memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 825b0a78d2..2cf38728a9 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -49,7 +49,7 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = talloc(NULL, sizeof(*token->mechTypes)); + token->mechTypes = talloc_p(NULL, const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index dd689027f9..076d088ee2 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -130,7 +130,7 @@ static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, if (val && strchr("()&|", *val)) return NULL; - ret = talloc(mem_ctx, sizeof(*ret)); + ret = talloc_p(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -157,8 +157,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, { struct ldap_parse_tree *ret, *next; - ret = talloc(mem_ctx, sizeof(*ret)); - + ret = talloc_p(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -166,7 +165,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, ret->operation = op; ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(mem_ctx, sizeof(*ret->u.list.elements)); + ret->u.list.elements = talloc_p(mem_ctx, struct ldap_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; return NULL; @@ -206,7 +205,7 @@ static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s { struct ldap_parse_tree *ret; - ret = talloc(mem_ctx, sizeof(*ret)); + ret = talloc_p(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c index 70c6fab8da..0a3f72ba74 100644 --- a/source4/libcli/nmblib.c +++ b/source4/libcli/nmblib.c @@ -333,7 +333,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, struct res_rec **recs, int count) { int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + *recs = malloc_array_p(struct res_rec, count); if (!*recs) return(False); memset((char *)*recs,'\0',sizeof(**recs)*count); @@ -523,7 +523,7 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) struct nmb_packet *copy_nmb; struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + if(( pkt_copy = malloc_p(struct packet_struct)) == NULL) { DEBUG(0,("copy_nmb_packet: malloc fail.\n")); return NULL; diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 621181841f..027705b381 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -174,7 +174,7 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, blob2.data = blob->data + ofs; blob2.length = ea_size - ofs; - *eas = talloc_realloc(mem_ctx, *eas, sizeof(**eas) * (n+1)); + *eas = talloc_realloc_p(mem_ctx, *eas, struct ea_struct, n+1); if (! *eas) return NT_STATUS_NO_MEMORY; len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); @@ -219,7 +219,7 @@ NTSTATUS ea_pull_list_chained(const DATA_BLOB *blob, blob2.data = blob->data + ofs + 4; blob2.length = blob->length - (ofs + 4); - *eas = talloc_realloc(mem_ctx, *eas, sizeof(**eas) * (n+1)); + *eas = talloc_realloc_p(mem_ctx, *eas, struct ea_struct, n+1); if (! *eas) return NT_STATUS_NO_MEMORY; len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index ea5fada1ee..918fb788cb 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -73,8 +73,7 @@ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, } /* allocate array */ - parms->out.changes = talloc(mem_ctx, sizeof(parms->out.changes[0]) * - parms->out.num_changes); + parms->out.changes = talloc_array_p(mem_ctx, struct notify_changes, parms->out.num_changes); if (!parms->out.changes) { return NT_STATUS_NO_MEMORY; } -- cgit From 4075e28a4f87993858e630012cffe96e49ff6717 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 13:04:10 +0000 Subject: r4056: modified the access check code based on results from RAW-ACLS test. Also added generic mapping bits for pvfs. We don't pass RAW-ACLS yet, but its close. (This used to be commit c7cbd966d49a5345ea326732587555d209c531fc) --- source4/libcli/security/access_check.c | 45 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 26 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index d8809aebc6..7e70736d09 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -42,13 +42,16 @@ static BOOL sid_active_in_token(struct dom_sid *sid, struct nt_user_token *token /* perform a SEC_FLAG_MAXIMUM_ALLOWED access check */ -static NTSTATUS access_check_max_allowed(struct security_descriptor *sd, - struct nt_user_token *token, - uint32_t *access_granted) +static uint32_t access_check_max_allowed(struct security_descriptor *sd, + struct nt_user_token *token) { uint32_t denied = 0, granted = 0; - int i; + unsigned i; + if (sid_active_in_token(sd->owner_sid, token)) { + granted |= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); + } + for (i = 0;idacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; @@ -67,15 +70,7 @@ static NTSTATUS access_check_max_allowed(struct security_descriptor *sd, } } - granted &= ~denied; - - if (granted == 0) { - return NT_STATUS_ACCESS_DENIED; - } - - *access_granted = granted; - - return NT_STATUS_OK; + return granted & ~denied; } /* @@ -89,16 +84,15 @@ NTSTATUS sec_access_check(struct security_descriptor *sd, int i; uint32_t bits_remaining; - bits_remaining = access_desired; - - /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */ - if (bits_remaining & (SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL)) { - if (sid_active_in_token(sd->owner_sid, token)) { - bits_remaining &= - ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); - } + /* handle the maximum allowed flag */ + if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) { + access_desired |= access_check_max_allowed(sd, token); + access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED; } + *access_granted = access_desired; + bits_remaining = access_desired; + #if 0 /* this is where we should check for the "system security" privilege, once we move to the full security_token and not just the nt_user_token */ @@ -122,9 +116,10 @@ NTSTATUS sec_access_check(struct security_descriptor *sd, return NT_STATUS_ACCESS_DENIED; } - /* handle the maximum allowed case separately */ - if (access_desired == SEC_FLAG_MAXIMUM_ALLOWED) { - return access_check_max_allowed(sd, token, access_granted); + /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */ + if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) && + sid_active_in_token(sd->owner_sid, token)) { + bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); } /* check each ace in turn. */ @@ -156,7 +151,5 @@ NTSTATUS sec_access_check(struct security_descriptor *sd, return NT_STATUS_ACCESS_DENIED; } - *access_granted = access_desired; - return NT_STATUS_OK; } -- cgit From 4127edc1afd702ac3bcb77893ba864eb98729451 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 4 Dec 2004 12:42:40 +0000 Subject: r4062: the RAW-ACLS test now passes. The SEC_STD_DELETE bit is rather strange though - I expect we'll need to tweak that some more. (This used to be commit e3500811b90b8423ee7694609340f394957d1160) --- source4/libcli/security/access_check.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 7e70736d09..425a5c2b6d 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -49,8 +49,9 @@ static uint32_t access_check_max_allowed(struct security_descriptor *sd, unsigned i; if (sid_active_in_token(sd->owner_sid, token)) { - granted |= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); + granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; } + granted |= SEC_STD_DELETE; for (i = 0;idacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; @@ -84,15 +85,17 @@ NTSTATUS sec_access_check(struct security_descriptor *sd, int i; uint32_t bits_remaining; + *access_granted = access_desired; + bits_remaining = access_desired; + /* handle the maximum allowed flag */ if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) { access_desired |= access_check_max_allowed(sd, token); access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED; + *access_granted = access_desired; + bits_remaining = access_desired & ~SEC_STD_DELETE; } - *access_granted = access_desired; - bits_remaining = access_desired; - #if 0 /* this is where we should check for the "system security" privilege, once we move to the full security_token and not just the nt_user_token */ -- cgit From 9112a632f6791ffc3c3c1aadd214cbaba8fe816e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 4 Dec 2004 13:56:25 +0000 Subject: r4063: - change char * -> uint8_t in struct request_buffer - change smbcli_read/write to take void * for the buffers to match read(2)/write(2) all this fixes a lot of gcc-4 warnings metze (This used to be commit b94f92bc6637f748d6f7049f4f9a30b0b8d18a7a) --- source4/libcli/climessage.c | 2 +- source4/libcli/clireadwrite.c | 9 ++++++--- source4/libcli/raw/clisession.c | 2 +- source4/libcli/raw/clisocket.c | 4 ++-- source4/libcli/raw/clitransport.c | 10 +++++----- source4/libcli/raw/clitree.c | 2 +- source4/libcli/raw/rawdate.c | 4 ++-- source4/libcli/raw/rawfile.c | 2 +- source4/libcli/raw/rawnegotiate.c | 2 +- source4/libcli/raw/rawrequest.c | 28 ++++++++++++++-------------- source4/libcli/raw/rawsearch.c | 2 +- source4/libcli/raw/rawtrans.c | 6 +++--- source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/util/smbencrypt.c | 2 +- 14 files changed, 40 insertions(+), 37 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 7e3a50b842..113b752e8b 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -58,7 +58,7 @@ BOOL smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp) req = smbcli_request_setup(tree, SMBsendtxt, 1, 0); SSVAL(req->out.vwv, VWV(0), grp); - smbcli_req_append_bytes(req, msg, len); + smbcli_req_append_bytes(req, (const uint8_t *)msg, len); if (!smbcli_request_send(req) || !smbcli_request_receive(req) || diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 6b6cb2f2a2..4248ac4286 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -25,9 +25,10 @@ /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ -ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, char *buf, off_t offset, +ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset, size_t size) { + uint8_t *buf = _buf; union smb_read parms; int readsize; ssize_t total = 0; @@ -84,8 +85,9 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, char *buf, off_t offset, ****************************************************************************/ ssize_t smbcli_write(struct smbcli_tree *tree, int fnum, uint16_t write_mode, - const uint8_t *buf, off_t offset, size_t size) + const void *_buf, off_t offset, size_t size) { + const uint8_t *buf = _buf; union smb_write parms; int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)); ssize_t total = 0; @@ -129,8 +131,9 @@ ssize_t smbcli_write(struct smbcli_tree *tree, write to a file using a SMBwrite and not bypassing 0 byte writes ****************************************************************************/ ssize_t smbcli_smbwrite(struct smbcli_tree *tree, - int fnum, char *buf, off_t offset, size_t size1) + int fnum, const void *_buf, off_t offset, size_t size1) { + const uint8_t *buf = _buf; union smb_write parms; ssize_t total = 0; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index c92e3ecb0b..7d2b7ad9b8 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -156,7 +156,7 @@ NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req, union smb_sesssetup *parms) { uint16_t len; - char *p; + uint8_t *p; if (!smbcli_request_receive(req)) { return smbcli_request_destroy(req); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 349b4b9a9c..fb9afeab81 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -109,7 +109,7 @@ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) /**************************************************************************** Write to socket. Return amount written. ****************************************************************************/ -ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t len) +ssize_t smbcli_sock_write(struct smbcli_socket *sock, const uint8_t *data, size_t len) { NTSTATUS status; DATA_BLOB blob; @@ -135,7 +135,7 @@ ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t l /**************************************************************************** Read from socket. return amount read ****************************************************************************/ -ssize_t smbcli_sock_read(struct smbcli_socket *sock, char *data, size_t len) +ssize_t smbcli_sock_read(struct smbcli_socket *sock, uint8_t *data, size_t len) { NTSTATUS status; size_t nread; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 52cb4d8beb..0af6df33b2 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -156,7 +156,7 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, struct nmb_name *calling, struct nmb_name *called) { - char *p; + uint8_t *p; int len = NBT_HDR_SIZE; struct smbcli_request *req; @@ -174,13 +174,13 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, /* put in the destination name */ p = req->out.buffer + NBT_HDR_SIZE; - name_mangle(called->name, p, called->name_type); - len += name_len(p); + name_mangle(called->name, (char *)p, called->name_type); + len += name_len((char *)p); /* and my name */ p = req->out.buffer+len; - name_mangle(calling->name, p, calling->name_type); - len += name_len(p); + name_mangle(calling->name, (char *)p, calling->name_type); + len += name_len((char *)p); _smb_setlen(req->out.buffer,len-4); SCVAL(req->out.buffer,0,0x81); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index daa8549099..b9d0ffbc1f 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -85,7 +85,7 @@ struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, union smb ****************************************************************************/ NTSTATUS smb_tree_connect_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_tcon *parms) { - char *p; + uint8_t *p; if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { diff --git a/source4/libcli/raw/rawdate.c b/source4/libcli/raw/rawdate.c index db18a7a194..894eb53528 100644 --- a/source4/libcli/raw/rawdate.c +++ b/source4/libcli/raw/rawdate.c @@ -38,7 +38,7 @@ put a dos date into a buffer (date/time format) This takes GMT time and puts local time in the buffer ********************************************************************/ void raw_push_dos_date2(struct smbcli_transport *transport, - char *buf, int offset, time_t unixdate) + uint8_t *buf, int offset, time_t unixdate) { push_dos_date2(buf, offset, unixdate, transport->negotiate.server_zone); } @@ -48,7 +48,7 @@ put a dos 32 bit "unix like" date into a buffer. This routine takes GMT and converts it to LOCAL time in zone_offset before putting it ********************************************************************/ void raw_push_dos_date3(struct smbcli_transport *transport, - char *buf, int offset, time_t unixdate) + uint8_t *buf, int offset, time_t unixdate) { push_dos_date3(buf, offset, unixdate, transport->negotiate.server_zone); } diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 69b8c6a07c..028d8734e1 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -702,7 +702,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc /* copy in all the locks */ lockp = &parms->lockx.in.locks[0]; for (i = 0; i < lock_count; i++) { - char *p = req->out.data + lck_size * i; + uint8_t *p = req->out.data + lck_size * i; SSVAL(p, 0, lockp[i].pid); if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) { SSVAL(p, 2, 0); /* reserved */ diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 4f7d7b4058..a8cf603d46 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -70,7 +70,7 @@ struct smbcli_request *smb_negprot_send(struct smbcli_transport *transport, int /* setup the protocol strings */ for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) { - smbcli_req_append_bytes(req, "\2", 1); + smbcli_req_append_bytes(req, (const uint8_t *)"\2", 1); smbcli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII); } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index b56bfa9a3c..7aa07bef41 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -187,7 +187,7 @@ struct smbcli_request *smbcli_request_setup(struct smbcli_tree *tree, static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_size) { int delta; - char *buf2; + uint8_t *buf2; delta = new_size - req->out.data_size; if (delta + req->out.size <= req->out.allocated) { @@ -295,7 +295,7 @@ BOOL smbcli_request_receive_more(struct smbcli_request *req) handle oplock break requests from the server - return True if the request was an oplock break */ -BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const char *hdr, const char *vwv) +BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const uint8_t *hdr, const uint8_t *vwv) { /* we must be very fussy about what we consider an oplock break to avoid matching readbraw replies */ @@ -479,7 +479,7 @@ size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *by of bytes consumed in the packet is returned */ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, uint_t flags) + char **dest, const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; @@ -532,7 +532,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c of bytes consumed in the packet is returned */ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, uint_t flags) + char **dest, const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; @@ -545,7 +545,7 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, if (byte_len != -1 && src_len > byte_len) { src_len = byte_len; } - src_len2 = strnlen(src, src_len); + src_len2 = strnlen((const char *)src, src_len); if (src_len2 < src_len - 1) { /* include the termination if we didn't reach the end of the packet */ src_len2++; @@ -575,7 +575,7 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, of bytes consumed in the packet is returned */ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, - char **dest, const char *src, int byte_len, uint_t flags) + char **dest, const uint8_t *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { @@ -592,7 +592,7 @@ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, if byte_len is -1 then limit the blob only by packet size */ -DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len) +DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len) { int src_len; @@ -611,7 +611,7 @@ DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, /* check that a lump of data in a request is within the bounds of the data section of the packet */ -static BOOL smbcli_req_data_oob(struct smbcli_request *req, const char *ptr, uint32_t count) +static BOOL smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count) { /* be careful with wraparound! */ if (ptr < req->in.data || @@ -628,7 +628,7 @@ static BOOL smbcli_req_data_oob(struct smbcli_request *req, const char *ptr, uin return False if any part is outside the data portion of the packet */ -BOOL smbcli_raw_pull_data(struct smbcli_request *req, const char *src, int len, char *dest) +BOOL smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest) { if (len == 0) return True; @@ -673,14 +673,14 @@ NTTIME smbcli_pull_nttime(void *base, uint16_t offset) */ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, DATA_BLOB *blob, const char **dest, - const char *src, int byte_len, uint_t flags) + const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; char *dest2; - if (src < (const char *)blob->data || - src >= (const char *)(blob->data + blob->length)) { + if (src < blob->data || + src >= (blob->data + blob->length)) { *dest = NULL; return 0; } @@ -729,7 +729,7 @@ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, */ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **dest, - const char *src, int byte_len, uint_t flags) + const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; @@ -743,7 +743,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, if (byte_len != -1 && src_len > byte_len) { src_len = byte_len; } - src_len2 = strnlen(src, src_len); + src_len2 = strnlen((const char *)src, src_len); if (src_len2 < src_len - 1) { /* include the termination if we didn't reach the end of the packet */ diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 4907eec70a..d55a47ca26 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -33,7 +33,7 @@ static void smb_raw_search_backend(struct smbcli_request *req, { union smb_search_data search_data; int i; - char *p; + uint8_t *p; if (req->in.data_size < 3 + count*43) { req->status = NT_STATUS_INVALID_PARAMETER; diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 371f50410d..fb8ab4203f 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -29,7 +29,7 @@ static BOOL raw_trans_oob(struct smbcli_request *req, uint_t offset, uint_t count) { - char *ptr; + uint8_t *ptr; if (count == 0) { return False; @@ -208,7 +208,7 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, { int wct = 14 + parms->in.setup_count; struct smbcli_request *req; - char *outdata,*outparam; + uint8_t *outdata,*outparam; int i; int padding; size_t namelen = 0; @@ -460,7 +460,7 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, struct smb_nttrans *parms) { struct smbcli_request *req; - char *outdata, *outparam; + uint8_t *outdata, *outparam; int i; int align = 0; diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index c0c1337312..4204f3b4dc 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -104,7 +104,7 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_ { uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; - unsigned char key_buf[16]; + uint8_t key_buf[16]; /* * Firstly put the sequence number into the first 4 bytes. diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index 9e8a4cd02d..ee423fbbba 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -293,7 +293,7 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO { uint8_t client_chal[8]; DATA_BLOB response = data_blob(NULL, 0); - char long_date[8]; + uint8_t long_date[8]; NTTIME nttime; unix_to_nt_time(&nttime, time(NULL)); -- cgit From 41999d67c1980e0631c4f357d3825cfda9b9fc1a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 Dec 2004 07:43:38 +0000 Subject: r4065: fixed ntstatus->dos error code for NT_STATUS_NO_SUCH_FILE (This used to be commit 19efd83b863a8c94f509d6a933a7d5de43aa95e9) --- source4/libcli/util/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 6849d7d0cd..cc3b960082 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -65,7 +65,7 @@ static const struct { {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, - {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, + {ERRDOS, ERRnofiles, NT_STATUS_NO_SUCH_FILE}, {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, {ERRDOS, 38, NT_STATUS_END_OF_FILE}, {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, -- cgit From 14c65343b052be4766fc27e17488f95fb201cb4f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 Dec 2004 07:53:57 +0000 Subject: r4066: add a mapping for NT_STATUS_NO_MORE_ENTRIES (This used to be commit 335b1c6a52b2e437e7f16a84ba547e5387ef64d1) --- source4/libcli/util/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index cc3b960082..4a57e436c7 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -51,6 +51,7 @@ static const struct { NTSTATUS ntstatus; } ntstatus_to_dos_map[] = { {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, + {ERRDOS, ERRnofiles, NT_STATUS_NO_MORE_ENTRIES}, {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, -- cgit From f99c93ec57691a393b4ae5ba57176b98f33efc17 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 5 Dec 2004 16:29:27 +0000 Subject: r4070: move some defines from asn_1.h to the places they belong to metze (This used to be commit ab2c2f27e1c61516e885f02bf26350f97209057a) --- source4/libcli/auth/gensec.h | 5 +++++ source4/libcli/auth/gensec_krb5.c | 5 ++--- source4/libcli/auth/gensec_ntlmssp.c | 3 +-- source4/libcli/auth/gssapi_parse.c | 7 +++++-- source4/libcli/auth/kerberos.h | 7 +++++++ source4/libcli/auth/spnego.c | 9 ++++----- source4/libcli/auth/spnego_parse.c | 4 ++-- source4/libcli/raw/clisession.c | 5 ++--- 8 files changed, 28 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 23d9861cb7..f8b7e292e8 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -21,6 +21,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define GENSEC_OID_NTLMSSP "1 3 6 1 4 1 311 2 2 10" +#define GENSEC_OID_SPNEGO "1 3 6 1 5 5 2" +#define GENSEC_OID_KERBEROS5 "1 2 840 113554 1 2 2" +#define GENSEC_OID_KERBEROS5_OLD "1 2 840 48018 1 2 2" +#define GENSEC_OID_KERBEROS5_USER2USER "1 2 840 113554 1 2 2 3" struct gensec_security; struct gensec_user { diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 0f1bf8e700..c47d4f26b6 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -29,7 +29,6 @@ #include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -#include "asn_1.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -754,7 +753,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security static const struct gensec_security_ops gensec_krb5_security_ops = { .name = "krb5", .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = OID_KERBEROS5, + .oid = GENSEC_OID_KERBEROS5, .client_start = gensec_krb5_client_start, .server_start = gensec_krb5_server_start, .update = gensec_krb5_update, @@ -766,7 +765,7 @@ static const struct gensec_security_ops gensec_krb5_security_ops = { static const struct gensec_security_ops gensec_ms_krb5_security_ops = { .name = "ms_krb5", .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = OID_KERBEROS5_OLD, + .oid = GENSEC_OID_KERBEROS5_OLD, .client_start = gensec_krb5_client_start, .server_start = gensec_krb5_server_start, .update = gensec_krb5_update, diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 5e55082c6f..147e2359f4 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -23,7 +23,6 @@ #include "includes.h" #include "auth/auth.h" -#include "asn_1.h" struct gensec_ntlmssp_state { struct auth_context *auth_context; @@ -401,7 +400,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .name = "ntlmssp", .sasl_name = "NTLM", .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, - .oid = OID_NTLMSSP, + .oid = GENSEC_OID_NTLMSSP, .client_start = gensec_ntlmssp_client_start, .server_start = gensec_ntlmssp_server_start, .update = gensec_ntlmssp_update, diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c index 529799955d..63bca6d5aa 100644 --- a/source4/libcli/auth/gssapi_parse.c +++ b/source4/libcli/auth/gssapi_parse.c @@ -24,6 +24,9 @@ #include "includes.h" #include "asn_1.h" +#include "system/kerberos.h" +#include "libcli/auth/kerberos.h" +#include "libcli/auth/gensec.h" /* generate a krb5 GSS-API wrapper packet given a ticket @@ -36,7 +39,7 @@ DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *tick ZERO_STRUCT(data); asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data, OID_KERBEROS5); + asn1_write_OID(&data, GENSEC_OID_KERBEROS5); asn1_write(&data, tok_id, 2); asn1_write(&data, ticket->data, ticket->length); @@ -64,7 +67,7 @@ BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, D asn1_load(&data, *blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); - asn1_check_OID(&data, OID_KERBEROS5); + asn1_check_OID(&data, GENSEC_OID_KERBEROS5); data_remaining = asn1_tag_remaining(&data); diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 9d6a5e81ae..3ab71f7875 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -21,6 +21,13 @@ #if defined(HAVE_KRB5) +/* not really ASN.1, but RFC 1964 */ +#define TOK_ID_KRB_AP_REQ "\x01\x00" +#define TOK_ID_KRB_AP_REP "\x02\x00" +#define TOK_ID_KRB_ERROR "\x03\x00" +#define TOK_ID_GSS_GETMIC "\x01\x01" +#define TOK_ID_GSS_WRAP "\x02\x01" + #ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE #define KRB5_KEY_TYPE(k) ((k)->keytype) #define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 3af1bc1e81..a13afbb186 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -24,7 +24,6 @@ #include "includes.h" #include "auth/auth.h" -#include "asn_1.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -218,7 +217,7 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec if (!all_ops[i]->oid) { continue; } - if (strcasecmp(OID_SPNEGO,all_ops[i]->oid) == 0) { + if (strcasecmp(GENSEC_OID_SPNEGO,all_ops[i]->oid) == 0) { continue; } @@ -311,7 +310,7 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec const char **mechTypes = NULL; DATA_BLOB unwrapped_out = data_blob(NULL,0); - mechTypes = gensec_security_oids(out_mem_ctx, OID_SPNEGO); + mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); if (!mechTypes) { DEBUG(1, ("no GENSEC OID backends available\n")); @@ -467,7 +466,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return nt_status; } else { - const char **mechlist = gensec_security_oids(out_mem_ctx, OID_SPNEGO); + const char **mechlist = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); const char *mechListMIC; mechListMIC = talloc_asprintf(out_mem_ctx,"%s$@%s", @@ -712,7 +711,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .name = "spnego", .sasl_name = "GSS-SPNEGO", .auth_type = DCERPC_AUTH_TYPE_SPNEGO, - .oid = OID_SPNEGO, + .oid = GENSEC_OID_SPNEGO, .client_start = gensec_spnego_client_start, .server_start = gensec_spnego_server_start, .update = gensec_spnego_update, diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 2cf38728a9..32e98a4235 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -288,7 +288,7 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) switch (context) { case ASN1_APPLICATION(0): asn1_start_tag(&asn1, ASN1_APPLICATION(0)); - asn1_check_OID(&asn1, OID_SPNEGO); + asn1_check_OID(&asn1, GENSEC_OID_SPNEGO); if (read_negTokenInit(&asn1, &token->negTokenInit)) { token->type = SPNEGO_NEG_TOKEN_INIT; } @@ -321,7 +321,7 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da switch (spnego->type) { case SPNEGO_NEG_TOKEN_INIT: asn1_push_tag(&asn1, ASN1_APPLICATION(0)); - asn1_write_OID(&asn1, OID_SPNEGO); + asn1_write_OID(&asn1, GENSEC_OID_SPNEGO); write_negTokenInit(&asn1, &spnego->negTokenInit); asn1_pop_tag(&asn1); break; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 7d2b7ad9b8..39df8fce02 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -22,7 +22,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "auth/auth.h" -#include "asn_1.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ req = smbcli_request_setup_session(session, cmd, wct, buflen); \ @@ -445,10 +444,10 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess } if (session->transport->negotiate.secblob.length) { - chosen_oid = OID_SPNEGO; + chosen_oid = GENSEC_OID_SPNEGO; } else { /* without a sec blob, means raw NTLMSSP */ - chosen_oid = OID_NTLMSSP; + chosen_oid = GENSEC_OID_NTLMSSP; } status = gensec_start_mech_by_oid(session->gensec, chosen_oid); -- cgit From ad3ee0a81c4b2bf2ae67ba461e936f7777584345 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 6 Dec 2004 07:12:38 +0000 Subject: r4073: - added a set of lsa helper routines to make lsa lookups that are related to filesharing. For example, in order to manipulate ACLs properly its important to be able to call LookupSids, and to be able to lookup what privileges a SID has. - added 3 new commands to smbclient "lookupname", "lookupsid" and "privileges" (This used to be commit 8780c40f0539da72652d17455e98fcaee6d197d1) --- source4/libcli/cliconnect.c | 2 +- source4/libcli/config.mk | 4 + source4/libcli/util/clilsa.c | 299 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/util/clilsa.c (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 2c66a1b5b3..6185ba7b7d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -216,7 +216,7 @@ struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) { struct smbcli_state *cli; - cli = talloc_p(mem_ctx, struct smbcli_state); + cli = talloc_zero_p(mem_ctx, struct smbcli_state); if (cli) { ZERO_STRUCTP(cli); } diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e48e5b5066..853dea7f98 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -13,6 +13,10 @@ ADD_OBJ_FILES = libcli/unexpected.o \ libcli/namecache.o \ libcli/nmblib.o \ libcli/namequery.o +REQUIRED_SUBSYSTEMS = RPC_NDR_LSA + +[SUBSYSTEM::LIBCLI_LSA] +ADD_OBJ_FILES = libcli/util/clilsa.o [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c new file mode 100644 index 0000000000..c3c7f8cc77 --- /dev/null +++ b/source4/libcli/util/clilsa.c @@ -0,0 +1,299 @@ +/* + Unix SMB/CIFS implementation. + + lsa calls for file sharing connections + + Copyright (C) Andrew Tridgell 2004 + + 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. +*/ + +/* + when dealing with ACLs the file sharing client code needs to + sometimes make LSA RPC calls. This code provides an easy interface + for doing those calls. +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_lsa.h" + +struct smblsa_state { + struct dcerpc_pipe *pipe; + struct smbcli_tree *ipc_tree; + struct policy_handle handle; +}; + +/* + establish the lsa pipe connection +*/ +static NTSTATUS smblsa_connect(struct smbcli_state *cli) +{ + struct smblsa_state *lsa; + NTSTATUS status; + struct lsa_OpenPolicy r; + uint16_t system_name = '\\'; + union smb_tcon tcon; + struct lsa_ObjectAttribute attr; + struct lsa_QosInfo qos; + + if (cli->lsa != NULL) { + return NT_STATUS_OK; + } + + lsa = talloc_p(cli, struct smblsa_state); + if (lsa == NULL) { + return NT_STATUS_NO_MEMORY; + } + + lsa->ipc_tree = smbcli_tree_init(cli->session); + if (lsa->ipc_tree == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* connect to IPC$ */ + tcon.generic.level = RAW_TCON_TCONX; + tcon.tconx.in.flags = 0; + tcon.tconx.in.password = data_blob(NULL, 0); + tcon.tconx.in.path = "ipc$"; + tcon.tconx.in.device = "IPC"; + status = smb_tree_connect(lsa->ipc_tree, lsa, &tcon); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + lsa->ipc_tree->tid = tcon.tconx.out.cnum; + + /* open the LSA pipe */ + status = dcerpc_pipe_open_smb(&lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + + /* bind to the LSA pipe */ + status = dcerpc_bind_auth_none(lsa->pipe, DCERPC_LSARPC_UUID, DCERPC_LSARPC_VERSION); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + + + /* open a lsa policy handle */ + qos.len = 0; + qos.impersonation_level = 2; + qos.context_mode = 1; + qos.effective_only = 0; + + attr.len = 0; + attr.root_dir = NULL; + attr.object_name = NULL; + attr.attributes = 0; + attr.sec_desc = NULL; + attr.sec_qos = &qos; + + r.in.system_name = &system_name; + r.in.attr = &attr; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.handle = &lsa->handle; + + status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + + cli->lsa = lsa; + + return NT_STATUS_OK; +} + + +/* + return the set of privileges for the given sid +*/ +NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid, + TALLOC_CTX *mem_ctx, + struct lsa_RightSet *rights) +{ + NTSTATUS status; + struct lsa_EnumAccountRights r; + + status = smblsa_connect(cli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r.in.handle = &cli->lsa->handle; + r.in.sid = sid; + r.out.rights = rights; + + return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r); +} + + +/* + check if a named sid has a particular named privilege +*/ +NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli, + const char *sid_str, + const char *privilege) +{ + struct lsa_RightSet rights; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc(cli, 0); + struct dom_sid *sid; + unsigned i; + + sid = dom_sid_parse_talloc(mem_ctx, sid_str); + if (sid == NULL) { + talloc_free(mem_ctx); + return NT_STATUS_INVALID_SID; + } + + status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + for (i=0;ilsa->handle; + r.in.sids = &sids; + r.in.names = &names; + r.in.level = 1; + r.in.count = &count; + r.out.count = &count; + r.out.names = &names; + + status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx2); + return status; + } + if (names.count != 1) { + talloc_free(mem_ctx2); + return NT_STATUS_UNSUCCESSFUL; + } + + (*name) = talloc_asprintf(mem_ctx, "%s\\%s", + r.out.domains->domains[0].name.string, + names.names[0].name.string); + + talloc_free(mem_ctx2); + + return NT_STATUS_OK; +} + +/* + lookup a name, returning its sid +*/ +NTSTATUS smblsa_lookup_name(struct smbcli_state *cli, + const char *name, + TALLOC_CTX *mem_ctx, + const char **sid_str) +{ + struct lsa_LookupNames r; + struct lsa_TransSidArray sids; + struct lsa_String names; + uint32_t count = 1; + NTSTATUS status; + struct dom_sid *sid; + TALLOC_CTX *mem_ctx2 = talloc(mem_ctx, 0); + uint32_t rid; + + status = smblsa_connect(cli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + sids.count = 0; + sids.sids = NULL; + + names.string = name; + + r.in.handle = &cli->lsa->handle; + r.in.num_names = 1; + r.in.names = &names; + r.in.sids = &sids; + r.in.level = 1; + r.in.count = &count; + r.out.count = &count; + r.out.sids = &sids; + + status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx2); + return status; + } + if (sids.count != 1) { + talloc_free(mem_ctx2); + return NT_STATUS_UNSUCCESSFUL; + } + + sid = r.out.domains->domains[0].sid; + rid = sids.sids[0].rid; + + (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u", + dom_sid_string(mem_ctx2, sid), rid); + + talloc_free(mem_ctx2); + + return NT_STATUS_OK; +} -- cgit From 2a45d1b9780f85b07e21c67a468edc71e90fa7b3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Dec 2004 15:14:42 +0000 Subject: r4077: don't add wrapping to empty blobs metze (This used to be commit e6d83d019dc46ff7ae32e7c8f9f7a3ab7d0cdcf3) --- source4/libcli/auth/gssapi_parse.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c index 63bca6d5aa..e1fb2e9cf5 100644 --- a/source4/libcli/auth/gssapi_parse.c +++ b/source4/libcli/auth/gssapi_parse.c @@ -34,7 +34,11 @@ DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8 tok_id[2]) { struct asn1_data data; - DATA_BLOB ret; + DATA_BLOB ret = data_blob(NULL,0); + + if (!ticket->data) { + return ret; + } ZERO_STRUCT(data); -- cgit From 0ad10aec63201c45b09f91541e9eee17fcf7ede5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Dec 2004 15:44:17 +0000 Subject: r4079: implement the gensec_have_feature() correctly by asking the backend what is actually in use metze (This used to be commit 6f3eb7bc03609108b9e0ea5676fca3d04140e737) --- source4/libcli/auth/gensec.c | 27 ++++++++++++--------------- source4/libcli/auth/gensec.h | 7 ++++--- source4/libcli/auth/gensec_ntlmssp.c | 31 +++++++++++++++++++++++++------ source4/libcli/ldap/ldap_client.c | 2 +- 4 files changed, 42 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 7243222b6d..147d1b12df 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -137,6 +137,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense (*gensec_security)->subcontext = False; (*gensec_security)->want_features = 0; + (*gensec_security)->have_features = 0; return NT_STATUS_OK; } @@ -232,11 +233,11 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { - gensec_want_feature(gensec_security, GENSEC_WANT_SIGN); + gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); } if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { - gensec_want_feature(gensec_security, GENSEC_WANT_SIGN); - gensec_want_feature(gensec_security, GENSEC_WANT_SEAL); + gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); + gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL); } return gensec_start_mech(gensec_security); @@ -310,8 +311,8 @@ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->unseal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } - if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) { - if (gensec_security->want_features & GENSEC_WANT_SIGN) { + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return gensec_check_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, @@ -335,7 +336,7 @@ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->check_packet) { return NT_STATUS_NOT_IMPLEMENTED; } - if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) { + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return NT_STATUS_INVALID_PARAMETER; } @@ -351,8 +352,8 @@ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->seal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } - if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) { - if (gensec_security->want_features & GENSEC_WANT_SIGN) { + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return gensec_sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, @@ -373,7 +374,7 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, if (!gensec_security->ops->sign_packet) { return NT_STATUS_NOT_IMPLEMENTED; } - if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) { + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return NT_STATUS_INVALID_PARAMETER; } @@ -385,7 +386,7 @@ size_t gensec_sig_size(struct gensec_security *gensec_security) if (!gensec_security->ops->sig_size) { return 0; } - if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) { + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return 0; } @@ -398,10 +399,6 @@ NTSTATUS gensec_session_key(struct gensec_security *gensec_security, if (!gensec_security->ops->session_key) { return NT_STATUS_NOT_IMPLEMENTED; } - if (!(gensec_security->want_features & GENSEC_WANT_SESSION_KEY)) { - return NT_STATUS_INVALID_PARAMETER; - } - return gensec_security->ops->session_key(gensec_security, session_key); } @@ -474,7 +471,7 @@ void gensec_want_feature(struct gensec_security *gensec_security, BOOL gensec_have_feature(struct gensec_security *gensec_security, uint32 feature) { - if (gensec_security->want_features & feature) { + if (gensec_security->have_features & feature) { return True; } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index f8b7e292e8..3d645bee82 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -41,9 +41,9 @@ struct gensec_target { const char *service; }; -#define GENSEC_WANT_SESSION_KEY 0x1 -#define GENSEC_WANT_SIGN 0x2 -#define GENSEC_WANT_SEAL 0x4 +#define GENSEC_FEATURE_SESSION_KEY 0x00000001 +#define GENSEC_FEATURE_SIGN 0x00000002 +#define GENSEC_FEATURE_SEAL 0x00000004 /* GENSEC mode */ enum gensec_role @@ -99,6 +99,7 @@ struct gensec_security { enum gensec_role gensec_role; BOOL subcontext; uint32 want_features; + uint32 have_features; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 147e2359f4..07dacfb5e0 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -178,10 +178,10 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur return nt_status; } - if (gensec_security->want_features & GENSEC_WANT_SIGN) { + if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; } - if (gensec_security->want_features & GENSEC_WANT_SEAL) { + if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } @@ -219,7 +219,7 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur return status; } - if (gensec_security->want_features & GENSEC_WANT_SESSION_KEY) { + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { /* * We need to set this to allow a later SetPassword * via the SAMR pipe to succeed. Strange.... We could @@ -231,10 +231,10 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur */ gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; } - if (gensec_security->want_features & GENSEC_WANT_SIGN) { + if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; } - if (gensec_security->want_features & GENSEC_WANT_SEAL) { + if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } @@ -343,8 +343,27 @@ static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, T const DATA_BLOB in, DATA_BLOB *out) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + NTSTATUS status; + + status = ntlmssp_update(gensec_ntlmssp_state->ntlmssp_state, out_mem_ctx, in, out); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { + return status; + } + + if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + gensec_security->have_features |= GENSEC_FEATURE_SIGN; + } + + if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + gensec_security->have_features |= GENSEC_FEATURE_SEAL; + } - return ntlmssp_update(gensec_ntlmssp_state->ntlmssp_state, out_mem_ctx, in, out); + if (gensec_ntlmssp_state->ntlmssp_state->session_key.data) { + gensec_security->have_features |= GENSEC_FEATURE_SESSION_KEY; + } + + return status; } /** diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 88c84d880b..a9b20b4ea8 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -382,7 +382,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha return result; } - gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); status = gensec_set_domain(conn->gensec, domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From 82da9a75d8b3976c79384e89ab248c235fc885e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Dec 2004 15:45:48 +0000 Subject: r4080: missing file from the last commit metze (This used to be commit ea7b496995573426486b7eab5de822d5602d7368) --- source4/libcli/raw/clisession.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 39df8fce02..4f77145d4d 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -413,7 +413,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess goto done; } - gensec_want_feature(session->gensec, GENSEC_WANT_SESSION_KEY); + gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); status = gensec_set_domain(session->gensec, parms->generic.in.domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From 4b7960a091916613ad89e9ef9e4de857b08c8e24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Dec 2004 09:18:56 +0000 Subject: r4084: add some more error codes metze (This used to be commit e5db58526825476fd6d8d80c8ee6c3bca0e23c84) --- source4/libcli/util/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 0e2270d8f6..d81280bff6 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -74,6 +74,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, + { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE }, -- cgit From 6ca874f71ad77c82d6e161a3e4772100de2ad6c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Dec 2004 05:41:19 +0000 Subject: r4147: converted from NT_USER_TOKEN to struct security_token this is mostly just a tidyup, but also adds the privilege_mask, which I will be using shortly in ACL checking. note that I had to move the definition of struct security_token out of security.idl as pidl doesn't yet handle arrays of pointers, and the usual workaround (to use a intermediate structure) would make things too cumbersome for this structure, especially given we never encode it to NDR. (This used to be commit 7b446af09b8050746bfc2c50e9d56aa94397cc1a) --- source4/libcli/auth/gensec_krb5.c | 29 ++++++----- source4/libcli/security/access_check.c | 16 +++--- source4/libcli/security/config.mk | 1 + source4/libcli/security/privilege.c | 84 ++++++++++++++++++++++++++++++++ source4/libcli/security/security_token.c | 15 +----- 5 files changed, 111 insertions(+), 34 deletions(-) create mode 100644 source4/libcli/security/privilege.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index c47d4f26b6..602e42a5ff 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -609,7 +609,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info; - struct nt_user_token *ptoken; + struct security_token *ptoken; struct dom_sid *sid; char *p; char *principal; @@ -684,15 +684,15 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security talloc_free(server_info); - ptoken = talloc_p(session_info, struct nt_user_token); - if (!ptoken) { + ptoken = security_token_initialise(session_info); + if (ptoken == NULL) { return NT_STATUS_NO_MEMORY; } - ptoken->num_sids = 0; - - ptoken->user_sids = talloc_array_p(ptoken, struct dom_sid*, logon_info->groups_count + 2); - if (!ptoken->user_sids) { + ptoken->num_sids = 0; + ptoken->sids = talloc_array_p(ptoken, struct dom_sid *, + logon_info->groups_count + 2); + if (!ptoken->sids) { return NT_STATUS_NO_MEMORY; } @@ -702,21 +702,24 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security sid = dom_sid_dup(server_info, logon_info->dom_sid); server_info->primary_group_sid = dom_sid_add_rid(server_info, sid, logon_info->group_rid); - ptoken->user_sids[0] = talloc_reference(session_info, server_info->user_sid); + ptoken->user_sid = server_info->user_sid; + ptoken->group_sid = server_info->primary_group_sid; + ptoken->sids[0] = talloc_reference(ptoken, ptoken->user_sid); ptoken->num_sids++; - ptoken->user_sids[1] = talloc_reference(session_info, server_info->primary_group_sid); + ptoken->sids[1] = talloc_reference(ptoken, ptoken->group_sid); ptoken->num_sids++; - for (;ptoken->num_sids < (logon_info->groups_count + 2); ptoken->num_sids++) { + for (;ptoken->num_sids < (logon_info->groups_count + 2); + ptoken->num_sids++) { sid = dom_sid_dup(session_info, logon_info->dom_sid); - ptoken->user_sids[ptoken->num_sids] + ptoken->sids[ptoken->num_sids] = dom_sid_add_rid(session_info, sid, logon_info->groups[ptoken->num_sids - 2].rid); } - debug_nt_user_token(DBGC_AUTH, 0, ptoken); + debug_security_token(DBGC_AUTH, 0, ptoken); - session_info->nt_user_token = ptoken; + session_info->security_token = ptoken; } else { TALLOC_CTX *mem_ctx = talloc_named(gensec_krb5_state, 0, "PAC-less session info discovery for %s@%s", username, realm); if (!mem_ctx) { diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 425a5c2b6d..c646ee693b 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -27,11 +27,12 @@ /* check if a sid is in the supplied token */ -static BOOL sid_active_in_token(struct dom_sid *sid, struct nt_user_token *token) +static BOOL sid_active_in_token(const struct dom_sid *sid, + const struct security_token *token) { int i; for (i=0;inum_sids;i++) { - if (dom_sid_equal(sid, token->user_sids[i])) { + if (dom_sid_equal(sid, token->sids[i])) { return True; } } @@ -42,16 +43,15 @@ static BOOL sid_active_in_token(struct dom_sid *sid, struct nt_user_token *token /* perform a SEC_FLAG_MAXIMUM_ALLOWED access check */ -static uint32_t access_check_max_allowed(struct security_descriptor *sd, - struct nt_user_token *token) +static uint32_t access_check_max_allowed(const struct security_descriptor *sd, + const struct security_token *token) { uint32_t denied = 0, granted = 0; unsigned i; if (sid_active_in_token(sd->owner_sid, token)) { - granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; + granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE; } - granted |= SEC_STD_DELETE; for (i = 0;idacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; @@ -77,8 +77,8 @@ static uint32_t access_check_max_allowed(struct security_descriptor *sd, /* the main entry point for access checking. */ -NTSTATUS sec_access_check(struct security_descriptor *sd, - struct nt_user_token *token, +NTSTATUS sec_access_check(const struct security_descriptor *sd, + const struct security_token *token, uint32_t access_desired, uint32_t *access_granted) { diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 900dbe780a..d6896535d6 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -13,6 +13,7 @@ ADD_OBJ_FILES = libcli/security/security_token.o \ libcli/security/security_descriptor.o \ libcli/security/dom_sid.o \ libcli/security/access_check.o \ + libcli/security/privilege.o \ librpc/ndr/ndr_sec.o REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR # End SUBSYSTEM LIB_SECURITY diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c new file mode 100644 index 0000000000..1962aaa374 --- /dev/null +++ b/source4/libcli/security/privilege.c @@ -0,0 +1,84 @@ +/* + Unix SMB/CIFS implementation. + + manipulate privileges + + Copyright (C) Andrew Tridgell 2004 + + 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 "librpc/gen_ndr/ndr_security.h" + + +static const struct { + enum sec_privilege privilege; + const char *name; +} privilege_names[] = { + {SEC_PRIV_SECURITY, "SeSecurityPrivilege"}, + {SEC_PRIV_BACKUP, "SeBackupPrivilege"}, + {SEC_PRIV_RESTORE, "SeRestorePrivilege"}, + {SEC_PRIV_SYSTEMTIME, "SeSystemtimePrivilege"}, + {SEC_PRIV_SHUTDOWN, "SeShutdownPrivilege"}, + {SEC_PRIV_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege"}, + {SEC_PRIV_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege"}, + {SEC_PRIV_DEBUG, "SeDebugPrivilege"}, + {SEC_PRIV_SYSTEM_ENVIRONMENT, "SeSystemEnvironmentPrivilege"}, + {SEC_PRIV_SYSTEM_PROFILE, "SeSystemProfilePrivilege"}, + {SEC_PRIV_PROFILE_SINGLE_PROCESS, "SeProfileSingleProcessPrivilege"}, + {SEC_PRIV_INCREASE_BASE_PRIORITY, "SeIncreaseBasePriorityPrivilege"}, + {SEC_PRIV_LOAD_DRIVER, "SeLoadDriverPrivilege"}, + {SEC_PRIV_CREATE_PAGEFILE, "SeCreatePagefilePrivilege"}, + {SEC_PRIV_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege"}, + {SEC_PRIV_CHANGE_NOTIFY, "SeChangeNotifyPrivilege"}, + {SEC_PRIV_UNDOCK, "SeUndockPrivilege"}, + {SEC_PRIV_MANAGE_VOLUME, "SeManageVolumePrivilege"}, + {SEC_PRIV_IMPERSONATE, "SeImpersonatePrivilege"}, + {SEC_PRIV_CREATE_GLOBAL, "SeCreateGlobalPrivilege"}, + {SEC_PRIV_ENABLE_DELEGATION, "SeEnableDelegationPrivilege"}, + {SEC_PRIV_INTERACTIVE_LOGON, "SeInteractiveLogonRight"}, + {SEC_PRIV_NETWORK_LOGON, "SeNetworkLogonRight"}, + {SEC_PRIV_REMOTE_INTERACTIVE_LOGON, "SeRemoteInteractiveLogonRight"} +}; + + +/* + map a privilege id to the wire string constant +*/ +const char *sec_privilege_name(unsigned int privilege) +{ + int i; + for (i=0;iflags = 0; - st->user_sid = NULL; st->group_sid = NULL; - st->logon_sid = NULL; - st->num_sids = 0; st->sids = NULL; - - st->num_restricted_sids = 0; - st->restricted_sids = NULL; - - st->num_privileges = 0; - st->privileges = NULL; - - st->dacl = NULL; + st->privilege_mask = 0; return st; } -- cgit From 02a9aa08923e348af2cda9829b64a5f98282164d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Dec 2004 12:01:20 +0000 Subject: r4150: - add fns for manipulating the privilege_mask in a security_token - add the hooks in access_check that check the privilege bitmasks for SEC_STD_DELETE and SEC_FLAG_SYSTEM_SECURITY (This used to be commit 0fa3764edcabffe8f7d5e40f0097f97d0c4519c4) --- source4/libcli/security/access_check.c | 15 +++++++++------ source4/libcli/security/privilege.c | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index c646ee693b..4c8bb1bd1f 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -50,7 +50,10 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, unsigned i; if (sid_active_in_token(sd->owner_sid, token)) { - granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE; + granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; + } + if (sec_privilege_check(token, SEC_PRIV_RESTORE)) { + granted |= SEC_STD_DELETE; } for (i = 0;idacl->num_aces; i++) { @@ -96,17 +99,13 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, bits_remaining = access_desired & ~SEC_STD_DELETE; } -#if 0 - /* this is where we should check for the "system security" privilege, once we - move to the full security_token and not just the nt_user_token */ if (access_desired & SEC_FLAG_SYSTEM_SECURITY) { - if (privilege_in_token(SE_PRIVILEGE_SYSTEM_SECURITY, token)) { + if (sec_privilege_check(token, SEC_PRIV_SECURITY)) { bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; } else { return NT_STATUS_ACCESS_DENIED; } } -#endif /* dacl not present allows access */ if (!(sd->type & SEC_DESC_DACL_PRESENT)) { @@ -124,6 +123,10 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, sid_active_in_token(sd->owner_sid, token)) { bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); } + if ((bits_remaining & SEC_STD_DELETE) && + sec_privilege_check(token, SEC_PRIV_RESTORE)) { + bits_remaining &= ~SEC_STD_DELETE; + } /* check each ace in turn. */ for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 1962aaa374..10a51c8b42 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -82,3 +82,27 @@ int sec_privilege_id(const char *name) } return -1; } + + +/* + return True if a security_token has a particular privilege bit set +*/ +BOOL sec_privilege_check(const struct security_token *token, unsigned int privilege) +{ + uint64_t mask = 1; + mask <<= (privilege-1); + if (token->privilege_mask & mask) { + return True; + } + return False; +} + +/* + set a bit in the privilege mask +*/ +void sec_privilege_set(struct security_token *token, unsigned int privilege) +{ + uint64_t mask = 1; + mask <<= (privilege-1); + token->privilege_mask |= mask; +} -- cgit From adbdb055ee08b0aede06ecec34157ecf4f22c9de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Dec 2004 13:19:41 +0000 Subject: r4151: added privilege attribute handling on samdb. pvfs will now honor some privileges on ACLs, and it will be quite easy to add the checks for more privileges in the necessary places, by making calls to sec_privilege_check(). (This used to be commit 3549039d0fbc54f87ae679e7288b82b28713e487) --- source4/libcli/auth/gensec_krb5.c | 7 +++++++ source4/libcli/security/privilege.c | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 602e42a5ff..88e7cdd2e3 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -716,6 +716,13 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security = dom_sid_add_rid(session_info, sid, logon_info->groups[ptoken->num_sids - 2].rid); } + + /* setup any privileges for this token */ + nt_status = samdb_privilege_setup(ptoken); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(ptoken); + return nt_status; + } debug_security_token(DBGC_AUTH, 0, ptoken); diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 10a51c8b42..93599598db 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -85,12 +85,22 @@ int sec_privilege_id(const char *name) /* - return True if a security_token has a particular privilege bit set + return a privilege mask given a privilege id */ -BOOL sec_privilege_check(const struct security_token *token, unsigned int privilege) +uint64_t sec_privilege_mask(unsigned int privilege) { uint64_t mask = 1; mask <<= (privilege-1); + return mask; +} + + +/* + return True if a security_token has a particular privilege bit set +*/ +BOOL sec_privilege_check(const struct security_token *token, unsigned int privilege) +{ + uint64_t mask = sec_privilege_mask(privilege); if (token->privilege_mask & mask) { return True; } @@ -102,7 +112,5 @@ BOOL sec_privilege_check(const struct security_token *token, unsigned int privil */ void sec_privilege_set(struct security_token *token, unsigned int privilege) { - uint64_t mask = 1; - mask <<= (privilege-1); - token->privilege_mask |= mask; + token->privilege_mask |= sec_privilege_mask(privilege); } -- cgit From fbd8c61ff7a7c41d16c400ddb87ad290f4af167d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 2004 10:48:21 +0000 Subject: r4173: - new t2open code, that can cope with "create with EAs". Many thanks to kukks on #samba-technical for the sniffs that allowed me to work this out - much simpler ntvfs open generic mapping code - added t2open create with EA torture test to RAW-OPEN test (This used to be commit a56d95ad89b4f32a05974c4fe9a816d67aa369e3) --- source4/libcli/raw/clisession.c | 2 +- source4/libcli/raw/rawfile.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 4f77145d4d..519f112ceb 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -51,7 +51,7 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) capabilities = transport->negotiate.capabilities; - flags2 = FLAGS2_LONG_PATH_COMPONENTS; + flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES; if (capabilities & CAP_UNICODE) { flags2 |= FLAGS2_UNICODE_STRINGS; diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 028d8734e1..bfd96bd360 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -366,10 +366,10 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags); SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode); - SSVAL(t2.in.params.data, VWV(2), 0); /* reserved */ + SSVAL(t2.in.params.data, VWV(2), parms->t2open.in.search_attrs); SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs); raw_push_dos_date(tree->session->transport, - t2.in.params.data, VWV(4), parms->t2open.in.write_time); + t2.in.params.data, VWV(4), parms->t2open.in.write_time); SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func); SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size); SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout); @@ -377,8 +377,8 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, SSVAL(t2.in.params.data, VWV(13), 0); smbcli_blob_append_string(tree->session, mem_ctx, - &t2.in.params, parms->t2open.in.fname, - STR_TERMINATE); + &t2.in.params, parms->t2open.in.fname, + STR_TERMINATE); ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas); @@ -414,7 +414,7 @@ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ parms->t2open.out.ftype = SVAL(t2.out.params.data, VWV(7)); parms->t2open.out.devstate = SVAL(t2.out.params.data, VWV(8)); parms->t2open.out.action = SVAL(t2.out.params.data, VWV(9)); - parms->t2open.out.unknown = SVAL(t2.out.params.data, VWV(10)); + parms->t2open.out.file_id = SVAL(t2.out.params.data, VWV(10)); return NT_STATUS_OK; } @@ -433,7 +433,7 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope case RAW_OPEN_OPEN: SETUP_REQUEST(SMBopen, 2, 0); - SSVAL(req->out.vwv, VWV(0), parms->openold.in.flags); + SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode); SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs); smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE); break; -- cgit From a7c70d4c5e11c515f1d09b88a83fb79baaf47e15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Dec 2004 11:37:47 +0000 Subject: r4177: add some more error codes metze (This used to be commit e624bb52886db80a3600b79494ad1150592efebe) --- source4/libcli/util/doserr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index d81280bff6..ee2ca25435 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -74,7 +74,10 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, + { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, + { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, -- cgit From 275df9a5c3b1ade9f2467870c3628a2a896c004c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 2004 23:57:59 +0000 Subject: r4182: fixed trans2 mkdir, allowing mkdir with an initial EA list (This used to be commit 7d981c29c28391813c7f93245f64b3ee108378a4) --- source4/libcli/raw/rawfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index bfd96bd360..4a11fd3834 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -122,7 +122,7 @@ static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); - t2.in.max_param = 0; + t2.in.max_param = 2; t2.in.max_data = 0; t2.in.max_setup = 0; t2.in.flags = 0; @@ -135,7 +135,7 @@ static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */ smbcli_blob_append_string(tree->session, mem_ctx, - &t2.in.params, parms->t2mkdir.in.path, 0); + &t2.in.params, parms->t2mkdir.in.path, STR_TERMINATE); ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); -- cgit From c80d77cdb8ab4b519c7c688cf4d0bf793a361424 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Dec 2004 05:51:01 +0000 Subject: r4196: - added server side code for lsa_LookupPrivDisplayName - added english descriptions of privileges. We should add other languages in the future. (This used to be commit 3eee8b7c13de3ffe7c5a87d6f1ebdcc66ff391eb) --- source4/libcli/security/privilege.c | 136 +++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 93599598db..aa01dc2c65 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -27,31 +27,103 @@ static const struct { enum sec_privilege privilege; const char *name; + const char *display_name; } privilege_names[] = { - {SEC_PRIV_SECURITY, "SeSecurityPrivilege"}, - {SEC_PRIV_BACKUP, "SeBackupPrivilege"}, - {SEC_PRIV_RESTORE, "SeRestorePrivilege"}, - {SEC_PRIV_SYSTEMTIME, "SeSystemtimePrivilege"}, - {SEC_PRIV_SHUTDOWN, "SeShutdownPrivilege"}, - {SEC_PRIV_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege"}, - {SEC_PRIV_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege"}, - {SEC_PRIV_DEBUG, "SeDebugPrivilege"}, - {SEC_PRIV_SYSTEM_ENVIRONMENT, "SeSystemEnvironmentPrivilege"}, - {SEC_PRIV_SYSTEM_PROFILE, "SeSystemProfilePrivilege"}, - {SEC_PRIV_PROFILE_SINGLE_PROCESS, "SeProfileSingleProcessPrivilege"}, - {SEC_PRIV_INCREASE_BASE_PRIORITY, "SeIncreaseBasePriorityPrivilege"}, - {SEC_PRIV_LOAD_DRIVER, "SeLoadDriverPrivilege"}, - {SEC_PRIV_CREATE_PAGEFILE, "SeCreatePagefilePrivilege"}, - {SEC_PRIV_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege"}, - {SEC_PRIV_CHANGE_NOTIFY, "SeChangeNotifyPrivilege"}, - {SEC_PRIV_UNDOCK, "SeUndockPrivilege"}, - {SEC_PRIV_MANAGE_VOLUME, "SeManageVolumePrivilege"}, - {SEC_PRIV_IMPERSONATE, "SeImpersonatePrivilege"}, - {SEC_PRIV_CREATE_GLOBAL, "SeCreateGlobalPrivilege"}, - {SEC_PRIV_ENABLE_DELEGATION, "SeEnableDelegationPrivilege"}, - {SEC_PRIV_INTERACTIVE_LOGON, "SeInteractiveLogonRight"}, - {SEC_PRIV_NETWORK_LOGON, "SeNetworkLogonRight"}, - {SEC_PRIV_REMOTE_INTERACTIVE_LOGON, "SeRemoteInteractiveLogonRight"} + {SEC_PRIV_SECURITY, + "SeSecurityPrivilege", + "System security"}, + + {SEC_PRIV_BACKUP, + "SeBackupPrivilege", + "Backup files and directories"}, + + {SEC_PRIV_RESTORE, + "SeRestorePrivilege", + "Restore files and directories"}, + + {SEC_PRIV_SYSTEMTIME, + "SeSystemtimePrivilege", + "Set the system clock"}, + + {SEC_PRIV_SHUTDOWN, + "SeShutdownPrivilege", + "Shutdown the system"}, + + {SEC_PRIV_REMOTE_SHUTDOWN, + "SeRemoteShutdownPrivilege", + "Shutdown the system remotely"}, + + {SEC_PRIV_TAKE_OWNERSHIP, + "SeTakeOwnershipPrivilege", + "Take ownership of files and directories"}, + + {SEC_PRIV_DEBUG, + "SeDebugPrivilege", + "Debug processes"}, + + {SEC_PRIV_SYSTEM_ENVIRONMENT, + "SeSystemEnvironmentPrivilege", + "Modify system environment"}, + + {SEC_PRIV_SYSTEM_PROFILE, + "SeSystemProfilePrivilege", + "Profile the system"}, + + {SEC_PRIV_PROFILE_SINGLE_PROCESS, + "SeProfileSingleProcessPrivilege", + "Profile one process"}, + + {SEC_PRIV_INCREASE_BASE_PRIORITY, + "SeIncreaseBasePriorityPrivilege", + "Increase base priority"}, + + {SEC_PRIV_LOAD_DRIVER, + "SeLoadDriverPrivilege", + "Load drivers"}, + + {SEC_PRIV_CREATE_PAGEFILE, + "SeCreatePagefilePrivilege", + "Create page files"}, + + {SEC_PRIV_INCREASE_QUOTA, + "SeIncreaseQuotaPrivilege", + "Increase quota"}, + + {SEC_PRIV_CHANGE_NOTIFY, + "SeChangeNotifyPrivilege", + "Register for change notify"}, + + {SEC_PRIV_UNDOCK, + "SeUndockPrivilege", + "Undock devices"}, + + {SEC_PRIV_MANAGE_VOLUME, + "SeManageVolumePrivilege", + "Manage system volumes"}, + + {SEC_PRIV_IMPERSONATE, + "SeImpersonatePrivilege", + "Impersonate users"}, + + {SEC_PRIV_CREATE_GLOBAL, + "SeCreateGlobalPrivilege", + "Create global"}, + + {SEC_PRIV_ENABLE_DELEGATION, + "SeEnableDelegationPrivilege", + "Enable Delegation"}, + + {SEC_PRIV_INTERACTIVE_LOGON, + "SeInteractiveLogonRight", + "Interactive logon"}, + + {SEC_PRIV_NETWORK_LOGON, + "SeNetworkLogonRight", + "Network logon"}, + + {SEC_PRIV_REMOTE_INTERACTIVE_LOGON, + "SeRemoteInteractiveLogonRight", + "Remote Interactive logon"} }; @@ -69,6 +141,22 @@ const char *sec_privilege_name(unsigned int privilege) return NULL; } +/* + map a privilege id to a privilege display name. Return NULL if not found + + TODO: this should use language mappings +*/ +const char *sec_privilege_display_name(int privilege, uint16_t *language) +{ + int i; + for (i=0;i Date: Tue, 14 Dec 2004 06:31:20 +0000 Subject: r4202: added smbclient commands "addprivileges" and "delprivileges" for easily adding/removing privileges from users (This used to be commit 8764909c05c4829d1e4f7eaf8c18e8ef1e53645f) --- source4/libcli/util/clilsa.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index c3c7f8cc77..4204adcc07 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -297,3 +297,49 @@ NTSTATUS smblsa_lookup_name(struct smbcli_state *cli, return NT_STATUS_OK; } + + +/* + add a set of privileges to the given sid +*/ +NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid, + TALLOC_CTX *mem_ctx, + struct lsa_RightSet *rights) +{ + NTSTATUS status; + struct lsa_AddAccountRights r; + + status = smblsa_connect(cli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r.in.handle = &cli->lsa->handle; + r.in.sid = sid; + r.in.rights = rights; + + return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r); +} + +/* + remove a set of privileges from the given sid +*/ +NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid, + TALLOC_CTX *mem_ctx, + struct lsa_RightSet *rights) +{ + NTSTATUS status; + struct lsa_RemoveAccountRights r; + + status = smblsa_connect(cli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r.in.handle = &cli->lsa->handle; + r.in.sid = sid; + r.in.unknown = 0; + r.in.rights = rights; + + return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r); +} -- cgit From 62d803c4901fcd8c4724aae0356e87ee9443e208 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Dec 2004 12:25:23 +0000 Subject: r4228: make sure the caller knows the packet is in error when a signing error occurs (This used to be commit 5e13571e6b9f5eb35f710c2c8bd85b5569665613) --- source4/libcli/raw/clitransport.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 0af6df33b2..dde77eaeea 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -416,6 +416,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) transport->error.etype = ETYPE_SOCKET; transport->error.e.socket_error = SOCKET_READ_BAD_SIG; req->state = SMBCLI_REQUEST_ERROR; + req->status = NT_STATUS_ACCESS_DENIED; goto error; }; -- cgit From 7bb5587097d7af1c42dab683c68afa06b35b7872 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Dec 2004 12:29:04 +0000 Subject: r4229: - added support for multi-part SMBtrans and SMBtrans2 requests in the client code. This was essential to test the multi-part server code (which I will commit soon) - when the request state is an error, ensure that req->status is not NT_STATUS_OK (This used to be commit ef502c403044b68ccdff15b1a94d447d0f53473d) --- source4/libcli/raw/rawrequest.c | 15 ++++-- source4/libcli/raw/rawtrans.c | 109 +++++++++++++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 7aa07bef41..5c35618e00 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -48,8 +48,11 @@ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) DLIST_REMOVE(req->transport->pending_recv, req); } - /* ahh, its so nice to destroy a complex structure in such a - simple way! */ + if (req->state == SMBCLI_REQUEST_ERROR && + NT_STATUS_IS_OK(req->status)) { + req->status = NT_STATUS_INTERNAL_ERROR; + } + status = req->status; talloc_free(req); return status; @@ -95,7 +98,7 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran setup a SMB packet at transport level */ struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport, - uint8_t command, uint_t wct, uint_t buflen) + uint8_t command, uint_t wct, uint_t buflen) { struct smbcli_request *req; @@ -119,8 +122,10 @@ struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *t SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES); SSVAL(req->out.hdr,HDR_FLG2, 0); - /* assign a mid */ - req->mid = smbcli_transport_next_mid(transport); + if (command != SMBtranss && command != SMBtranss2) { + /* assign a mid */ + req->mid = smbcli_transport_next_mid(transport); + } /* copy the pid, uid and mid to the request */ SSVAL(req->out.hdr, HDR_PID, 0); diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index fb8ab4203f..ba80d59819 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -20,8 +20,10 @@ */ #include "includes.h" +#include "dlinklist.h" #include "libcli/raw/libcliraw.h" +#define TORTURE_TRANS_DATA 0 /* check out of bounds for incoming data @@ -198,20 +200,21 @@ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, return smb_raw_trans2_recv(req, mem_ctx, parms); } -/**************************************************************************** - trans/trans2 raw async interface - only BLOBs used in this interface. - note that this doesn't yet support multi-part requests -****************************************************************************/ + +/* + trans/trans2 raw async interface - only BLOBs used in this interface. +*/ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, - struct smb_trans2 *parms, - uint8_t command) + struct smb_trans2 *parms, + uint8_t command) { int wct = 14 + parms->in.setup_count; - struct smbcli_request *req; + struct smbcli_request *req, *req2; uint8_t *outdata,*outparam; int i; int padding; size_t namelen = 0; + uint16_t data_disp, data_length, max_data; if (command == SMBtrans) padding = 1; @@ -236,6 +239,19 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, /* make sure we don't leak data via the padding */ memset(req->out.data, 0, padding); + data_length = parms->in.data.length; + + max_data = smb_raw_max_trans_data(tree, parms->in.params.length); + if (max_data < data_length) { + data_length = max_data; + } + +#if TORTURE_TRANS_DATA + if (data_length > 1) { + data_length /= 2; + } +#endif + /* primary request */ SSVAL(req->out.vwv,VWV(0),parms->in.params.length); SSVAL(req->out.vwv,VWV(1),parms->in.data.length); @@ -247,7 +263,7 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, SSVAL(req->out.vwv,VWV(8),0); /* reserved */ SSVAL(req->out.vwv,VWV(9),parms->in.params.length); SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)+namelen); - SSVAL(req->out.vwv,VWV(11),parms->in.data.length); + SSVAL(req->out.vwv,VWV(11),data_length); SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)+namelen); SSVAL(req->out.vwv,VWV(13),parms->in.setup_count); for (i=0;iin.setup_count;i++) { @@ -257,22 +273,88 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, smbcli_req_append_blob(req, &parms->in.params); } if (parms->in.data.data) { - smbcli_req_append_blob(req, &parms->in.data); + DATA_BLOB data; + data.data = parms->in.data.data; + data.length = data_length; + smbcli_req_append_blob(req, &data); } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } + + data_disp = data_length; + + + if (data_disp != parms->in.data.length) { + /* TODO: this should be done asynchronously .... */ + if (!smbcli_request_receive(req) || + !NT_STATUS_IS_OK(req->status)) { + return req; + } + + req->state = SMBCLI_REQUEST_RECV; + DLIST_ADD(req->transport->pending_recv, req); + } + + + while (data_disp != parms->in.data.length) { + data_length = parms->in.data.length - data_disp; + + max_data = smb_raw_max_trans_data(tree, 0); + if (max_data < data_length) { + data_length = max_data; + } + +#if TORTURE_TRANS_DATA + if (data_length > 1) { + data_length /= 2; + } +#endif + + req2 = smbcli_request_setup(tree, command+1, 9, data_length); + if (!req2) { + return NULL; + } + req2->mid = req->mid; + SSVAL(req2->out.hdr, HDR_MID, req2->mid); + + outdata = req2->out.data; + + SSVAL(req2->out.vwv,VWV(0), parms->in.params.length); + SSVAL(req2->out.vwv,VWV(1), parms->in.data.length); + SSVAL(req2->out.vwv,VWV(2), 0); + SSVAL(req2->out.vwv,VWV(3), 0); + SSVAL(req2->out.vwv,VWV(4), 0); + SSVAL(req2->out.vwv,VWV(5), data_length); + SSVAL(req2->out.vwv,VWV(6), PTR_DIFF(outdata,req2->out.hdr)); + SSVAL(req2->out.vwv,VWV(7), data_disp); + SSVAL(req2->out.vwv,VWV(8), 0xFFFF); + + memcpy(req2->out.data, parms->in.data.data + data_disp, data_length); + + data_disp += data_length; + + req2->one_way_request = 1; + + if (!smbcli_request_send(req2)) { + smbcli_request_destroy(req2); + return NULL; + } + + req->seq_num = req2->seq_num; + } + return req; } -/**************************************************************************** - trans/trans2 raw async interface - only BLOBs used in this interface. -note that this doesn't yet support multi-part requests -****************************************************************************/ +/* + trans/trans2 raw async interface - only BLOBs used in this interface. + note that this doesn't yet support multi-part requests +*/ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, struct smb_trans2 *parms) { @@ -312,6 +394,7 @@ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, return smb_raw_trans_recv(req, mem_ctx, parms); } + /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ -- cgit From 3b8e83a8c8f32ca658841f1fae344399a48d66a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 04:51:23 +0000 Subject: r4243: a sniff from kukks showed that the ea_set interface in trans2 setfileinfo allows for multiple EAs to be set at once. This fixes all the ea code to allow for that. (This used to be commit b26828bef5d55e5eef0e34a164e76292df45e207) --- source4/libcli/raw/raweas.c | 4 ++-- source4/libcli/raw/rawsetfileinfo.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 027705b381..14d4557995 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -147,8 +147,8 @@ uint_t ea_pull_struct(const DATA_BLOB *blob, pull a ea_list from a buffer */ NTSTATUS ea_pull_list(const DATA_BLOB *blob, - TALLOC_CTX *mem_ctx, - uint_t *num_eas, struct ea_struct **eas) + TALLOC_CTX *mem_ctx, + uint_t *num_eas, struct ea_struct **eas) { int n; uint32_t ea_size, ofs; diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 76756971ae..9576bdf356 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -56,8 +56,8 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, return True; case RAW_SFILEINFO_EA_SET: - NEED_BLOB(ea_list_size(1, &parms->ea_set.in.ea)); - ea_put_list(blob->data, 1, &parms->ea_set.in.ea); + NEED_BLOB(ea_list_size(parms->ea_set.in.num_eas, parms->ea_set.in.eas)); + ea_put_list(blob->data, parms->ea_set.in.num_eas, parms->ea_set.in.eas); return True; case RAW_SFILEINFO_BASIC_INFO: -- cgit From b706555b3a4ed3c8d459ae86b4c332fa41041f57 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 22:47:49 +0000 Subject: r4261: added the RAW_FILEINFO_EA_LIST trans2 qfileinfo and qpathinfo level. Interestingly, this level did now show up on our trans2 scanner previously as we didn't have the FLAGS2_EXTENDED_ATTRIBUTES bit set in the client code. Now that we set that bit, new levels appear in windows servers. (This used to be commit 0b76d405a73e924dc2706f28bbf1084a59c9b393) --- source4/libcli/raw/raweas.c | 116 +++++++++++++++++++++++++++++++++++++++ source4/libcli/raw/rawfileinfo.c | 64 +++++++++++++++++---- 2 files changed, 170 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 14d4557995..ec8bacdf64 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -36,6 +36,19 @@ uint_t ea_list_size(uint_t num_eas, struct ea_struct *eas) return total; } +/* + work out how many bytes on the wire a ea name list will consume. +*/ +static uint_t ea_name_list_size(uint_t num_names, struct ea_name *eas) +{ + uint_t total = 4; + int i; + for (i=0;ilength < 2) { + return 0; + } + + nlen = CVAL(blob->data, 0); + + if (nlen+2 > blob->length) { + return 0; + } + + ea->name.s = talloc_strndup(mem_ctx, (const char *)(blob->data+1), nlen); + ea->name.private_length = nlen; + + return nlen+2; +} + + +/* + pull a ea_name list from a buffer +*/ +NTSTATUS ea_pull_name_list(const DATA_BLOB *blob, + TALLOC_CTX *mem_ctx, + uint_t *num_names, struct ea_name **ea_names) +{ + int n; + uint32_t ea_size, ofs; + + if (blob->length < 4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + ea_size = IVAL(blob->data, 0); + if (ea_size > blob->length) { + return NT_STATUS_INVALID_PARAMETER; + } + + ofs = 4; + n = 0; + *num_names = 0; + *ea_names = NULL; + + while (ofs < ea_size) { + uint_t len; + DATA_BLOB blob2; + + blob2.data = blob->data + ofs; + blob2.length = ea_size - ofs; + + *ea_names = talloc_realloc_p(mem_ctx, *ea_names, struct ea_name, n+1); + if (! *ea_names) return NT_STATUS_NO_MEMORY; + + len = ea_pull_name(&blob2, mem_ctx, &(*ea_names)[n]); + if (len == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + ofs += len; + n++; + } + + *num_names = n; + + return NT_STATUS_OK; +} + + +/* + put a ea_name list into a data blob +*/ +BOOL ea_push_name_list(TALLOC_CTX *mem_ctx, + DATA_BLOB *data, uint_t num_names, struct ea_name *eas) +{ + int i; + uint32_t ea_size; + uint32_t off; + + ea_size = ea_name_list_size(num_names, eas); + + *data = data_blob_talloc(mem_ctx, NULL, ea_size); + if (data->data == NULL) { + return False; + } + + SIVAL(data->data, 0, ea_size); + off = 4; + for (i=0;idata, off, nlen); + memcpy(data->data+off+1, eas[i].name.s, nlen+1); + off += 1+nlen+1; + } + + return True; +} diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 6f875f51a7..8f694a23d8 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -79,6 +79,12 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->ea_size.out.ea_size = IVAL(blob->data, 22); return NT_STATUS_OK; + case RAW_FILEINFO_EA_LIST: + FINFO_CHECK_MIN_SIZE(4); + return ea_pull_list(blob, mem_ctx, + &parms->ea_list.out.num_eas, + &parms->ea_list.out.eas); + case RAW_FILEINFO_ALL_EAS: FINFO_CHECK_MIN_SIZE(4); return ea_pull_list(blob, mem_ctx, @@ -280,7 +286,9 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, Very raw query file info - returns param/data blobs - (async send) ****************************************************************************/ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree, - uint16_t fnum, uint16_t info_level) + uint16_t fnum, + uint16_t info_level, + DATA_BLOB data) { struct smb_trans2 tp; uint16_t setup = TRANSACT2_QFILEINFO; @@ -291,7 +299,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre tp.in.flags = 0; tp.in.timeout = 0; tp.in.setup_count = 1; - tp.in.data = data_blob(NULL, 0); + tp.in.data = data; tp.in.max_param = 2; tp.in.max_data = smb_raw_max_trans_data(tree, 2); tp.in.setup = &setup; @@ -332,8 +340,9 @@ static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req, Very raw query path info - returns param/data blobs (async send) ****************************************************************************/ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree, - const char *fname, - uint16_t info_level) + const char *fname, + uint16_t info_level, + DATA_BLOB data) { struct smb_trans2 tp; uint16_t setup = TRANSACT2_QPATHINFO; @@ -344,7 +353,7 @@ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tre tp.in.flags = 0; tp.in.timeout = 0; tp.in.setup_count = 1; - tp.in.data = data_blob(NULL, 0); + tp.in.data = data; tp.in.max_param = 2; tp.in.max_data = smb_raw_max_trans_data(tree, 2); tp.in.setup = &setup; @@ -463,6 +472,9 @@ failed: struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { + DATA_BLOB data; + struct smbcli_request *req; + /* pass off the non-trans2 level to specialised functions */ if (parms->generic.level == RAW_FILEINFO_GETATTRE) { return smb_raw_getattrE_send(tree, parms); @@ -474,9 +486,24 @@ struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree, return NULL; } - return smb_raw_fileinfo_blob_send(tree, - parms->generic.in.fnum, - parms->generic.level); + data = data_blob(NULL, 0); + + if (parms->generic.level == RAW_FILEINFO_EA_LIST) { + if (!ea_push_name_list(tree, + &data, + parms->ea_list.in.num_names, + parms->ea_list.in.ea_names)) { + return NULL; + } + } + + req = smb_raw_fileinfo_blob_send(tree, + parms->generic.in.fnum, + parms->generic.level, data); + + data_blob_free(&data); + + return req; } /**************************************************************************** @@ -525,6 +552,9 @@ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { + DATA_BLOB data; + struct smbcli_request *req; + if (parms->generic.level == RAW_FILEINFO_GETATTR) { return smb_raw_getattr_send(tree, parms); } @@ -532,8 +562,22 @@ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, return NULL; } - return smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname, - parms->generic.level); + data = data_blob(NULL, 0); + + if (parms->generic.level == RAW_FILEINFO_EA_LIST) { + if (!ea_push_name_list(tree, + &data, + parms->ea_list.in.num_names, + parms->ea_list.in.ea_names)) { + return NULL; + } + } + + req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname, + parms->generic.level, data); + data_blob_free(&data); + + return req; } /**************************************************************************** -- cgit From ed42a64901ba0a7ad8cbaac582600688af1b7d72 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Dec 2004 04:38:43 +0000 Subject: r4263: added support for the trans2 RAW_SEARCH_EA_LIST information level. This is quite a strange level that we've never seen before, but is used by the os2 workplace shell. note w2k screws up this level when unicode is negotiated, so it only passes the RAW-SEARCH test when you force non-unicode (This used to be commit 25189b8fbf6515d573e3398dc9fca56505dc37b9) --- source4/libcli/raw/rawfileinfo.c | 2 +- source4/libcli/raw/rawsearch.c | 61 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 8f694a23d8..ad7b9b900a 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -550,7 +550,7 @@ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, Query path info (async send) ****************************************************************************/ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, - union smb_fileinfo *parms) + union smb_fileinfo *parms) { DATA_BLOB data; struct smbcli_request *req; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index d55a47ca26..3c271253e5 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -210,6 +210,15 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, tp.in.max_param = 10; tp.in.max_data = smb_raw_max_trans_data(tree, 10); tp.in.setup = &setup; + + if (info_level == RAW_SEARCH_EA_LIST) { + if (!ea_push_name_list(mem_ctx, + &tp.in.data, + io->t2ffirst.in.num_names, + io->t2ffirst.in.ea_names)) { + return NT_STATUS_NO_MEMORY; + } + } tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); if (!tp.in.params.data) { @@ -223,7 +232,7 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, SIVAL(tp.in.params.data, 8, io->t2ffirst.in.storage_type); smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, - io->t2ffirst.in.pattern, STR_TERMINATE); + io->t2ffirst.in.pattern, STR_TERMINATE); status = smb_raw_trans2(tree, mem_ctx, &tp); if (!NT_STATUS_IS_OK(status)) { @@ -262,6 +271,15 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, tp.in.max_param = 10; tp.in.max_data = smb_raw_max_trans_data(tree, 10); tp.in.setup = &setup; + + if (info_level == RAW_SEARCH_EA_LIST) { + if (!ea_push_name_list(mem_ctx, + &tp.in.data, + io->t2fnext.in.num_names, + io->t2fnext.in.ea_names)) { + return NT_STATUS_NO_MEMORY; + } + } tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); if (!tp.in.params.data) { @@ -306,6 +324,9 @@ static int parse_trans2_search(struct smbcli_tree *tree, union smb_search_data *data) { uint_t len, ofs; + uint32_t ea_size; + DATA_BLOB eablob; + NTSTATUS status; switch (level) { case RAW_SEARCH_GENERIC: @@ -360,6 +381,44 @@ static int parse_trans2_search(struct smbcli_tree *tree, 26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN); return len + 27 + 1; + case RAW_SEARCH_EA_LIST: + if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { + if (blob->length < 4) return -1; + data->ea_list.resume_key = IVAL(blob->data, 0); + blob->data += 4; + blob->length -= 4; + } + if (blob->length < 28) return -1; + data->ea_list.create_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 0); + data->ea_list.access_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 4); + data->ea_list.write_time = raw_pull_dos_date2(tree->session->transport, + blob->data + 8); + data->ea_list.size = IVAL(blob->data, 12); + data->ea_list.alloc_size = IVAL(blob->data, 16); + data->ea_list.attrib = SVAL(blob->data, 20); + ea_size = IVAL(blob->data, 22); + if (ea_size > 0xFFFF) { + return -1; + } + eablob.data = blob->data + 22; + eablob.length = ea_size; + if (eablob.length > blob->length - 24) { + return -1; + } + status = ea_pull_list(&eablob, mem_ctx, + &data->ea_list.eas.num_eas, + &data->ea_list.eas.eas); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, + &data->ea_list.name, + 22+ea_size, 23+ea_size, + STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN); + return len + ea_size + 23 + 1; + case RAW_SEARCH_DIRECTORY_INFO: if (blob->length < 65) return -1; ofs = IVAL(blob->data, 0); -- cgit From fa4271fb39d593fd4516e8ee32234299ffd31967 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Dec 2004 11:45:37 +0000 Subject: r4315: use the remote hosts max_xmit, not the local hosts, in calculating max trans2 data sizes (This used to be commit 827008cfebf29d081b457ba7162d89c8150cb24b) --- source4/libcli/raw/rawtrans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index ba80d59819..95555c3a82 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -626,5 +626,5 @@ NTSTATUS smb_raw_nttrans(struct smbcli_tree *tree, */ size_t smb_raw_max_trans_data(struct smbcli_tree *tree, size_t param_size) { - return tree->session->transport->options.max_xmit - (70 + param_size); + return tree->session->transport->negotiate.max_xmit - (70 + param_size); } -- cgit From 101d0333a333cee6d3fc33cb4655976145fb87e8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Dec 2004 11:47:08 +0000 Subject: r4316: - now that the trans2 code properly supports multi-part requests, we can set a maximum sized max_data in libcli trans2 code - fixed string termination in the EA_LIST trans2 findfirst level (This used to be commit a2a5f147f4faac8a48ff8f1b3e5f1334c92575bb) --- source4/libcli/raw/rawacl.c | 2 +- source4/libcli/raw/rawfileinfo.c | 4 ++-- source4/libcli/raw/rawfsinfo.c | 2 +- source4/libcli/raw/rawsearch.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 253a3cbbe7..97e0212137 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -34,7 +34,7 @@ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, nt.in.max_setup = 0; nt.in.max_param = 4; - nt.in.max_data = smb_raw_max_trans_data(tree, 4); + nt.in.max_data = 0xFFFF; nt.in.setup_count = 0; nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; nt.in.setup = NULL; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index ad7b9b900a..3befb8ee4d 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -301,7 +301,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre tp.in.setup_count = 1; tp.in.data = data; tp.in.max_param = 2; - tp.in.max_data = smb_raw_max_trans_data(tree, 2); + tp.in.max_data = 0xFFFF; tp.in.setup = &setup; tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); @@ -355,7 +355,7 @@ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tre tp.in.setup_count = 1; tp.in.data = data; tp.in.max_param = 2; - tp.in.max_data = smb_raw_max_trans_data(tree, 2); + tp.in.max_data = 0xFFFF; tp.in.setup = &setup; tp.in.params = data_blob_talloc(mem_ctx, NULL, 6); diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 7cec93b6bc..fd99c4aeb9 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -78,7 +78,7 @@ static struct smbcli_request *smb_raw_qfsinfo_send(struct smbcli_tree *tree, tp.in.timeout = 0; tp.in.setup_count = 1; tp.in.max_param = 0; - tp.in.max_data = smb_raw_max_trans_data(tree, 0); + tp.in.max_data = 0xFFFF; tp.in.setup = &setup; tp.in.data = data_blob(NULL, 0); tp.in.timeout = 0; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 3c271253e5..90715ca8e2 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -208,7 +208,7 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); tp.in.max_param = 10; - tp.in.max_data = smb_raw_max_trans_data(tree, 10); + tp.in.max_data = 0xFFFF; tp.in.setup = &setup; if (info_level == RAW_SEARCH_EA_LIST) { @@ -269,7 +269,7 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); tp.in.max_param = 10; - tp.in.max_data = smb_raw_max_trans_data(tree, 10); + tp.in.max_data = 0xFFFF; tp.in.setup = &setup; if (info_level == RAW_SEARCH_EA_LIST) { @@ -416,7 +416,7 @@ static int parse_trans2_search(struct smbcli_tree *tree, len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, &data->ea_list.name, 22+ea_size, 23+ea_size, - STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN); + STR_LEN8BIT | STR_NOALIGN); return len + ea_size + 23 + 1; case RAW_SEARCH_DIRECTORY_INFO: -- cgit From 72249717272819d9fb73d4a67a4c546db4ac3f2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Dec 2004 12:39:39 +0000 Subject: r4325: add the GENSEC_FEATURE_DCE_STYLE flag this will be used by krb5 dcerpc auth metze (This used to be commit 04dc7fb9b24a1e38f31559ec6032701a176209ae) --- source4/libcli/auth/gensec.c | 1 + source4/libcli/auth/gensec.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 147d1b12df..8009df4e40 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -232,6 +232,7 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type)); return NT_STATUS_INVALID_PARAMETER; } + gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE); if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 3d645bee82..9162c935b2 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -44,6 +44,7 @@ struct gensec_target { #define GENSEC_FEATURE_SESSION_KEY 0x00000001 #define GENSEC_FEATURE_SIGN 0x00000002 #define GENSEC_FEATURE_SEAL 0x00000004 +#define GENSEC_FEATURE_DCE_STYLE 0x00000008 /* GENSEC mode */ enum gensec_role -- cgit From 4def245b7959900cd7f6c3dc336ab7209cb2d5dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Dec 2004 15:01:53 +0000 Subject: r4326: fix memory leak metze (This used to be commit 1ceeb77fc716729c69f2dba4a84579c366eefa1c) --- source4/libcli/auth/spnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index a13afbb186..01757a0487 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -479,7 +479,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_out.type = SPNEGO_NEG_TOKEN_INIT; spnego_out.negTokenInit.mechTypes = mechlist; spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = data_blob(mechListMIC, strlen(mechListMIC)); + spnego_out.negTokenInit.mechListMIC = data_blob_string_const(mechListMIC); spnego_out.negTokenInit.mechToken = unwrapped_out; if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { -- cgit From ae42636167f82fee7fb38338dec605521162b5c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 23 Dec 2004 02:23:42 +0000 Subject: r4338: reuse netlogon structs in the krb5 PAC that simplifies the code a lot... also add a note: we should fail the krb5 auth if there's no PAC present (when heimdal is ready for that:-) metze (This used to be commit 532641a7003d23b034a253d166482f18c2de6191) --- source4/libcli/auth/gensec_krb5.c | 124 ++++++-------------------------------- 1 file changed, 19 insertions(+), 105 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 88e7cdd2e3..9323580e92 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -223,7 +223,7 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, return status; } #endif - DEBUG(0,("account_name: %s [%s]\n",logon_info->account_name.string, logon_info->full_name.string)); + DEBUG(0,("account_name: %s [%s]\n",logon_info->info3.base.account_name.string, logon_info->info3.base.full_name.string)); *logon_info_out = logon_info; return status; @@ -609,8 +609,6 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info; - struct security_token *ptoken; - struct dom_sid *sid; char *p; char *principal; const char *username; @@ -633,119 +631,35 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some - * kind... */ + * kind... + * + * when heimdal can generate the PAC, we should fail if there's + * no PAC present + */ if (NT_STATUS_IS_OK(nt_status)) { - nt_status = make_server_info(gensec_krb5_state, &server_info, gensec_krb5_state->peer_principal); + union netr_Validation validation; + validation.sam3 = &logon_info->info3; + nt_status = make_server_info_netlogon_validation(gensec_krb5_state, + username, + &server_info, + 3, + &validation); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } - - server_info->guest = False; - - if (logon_info->account_name.string) { - server_info->account_name - = talloc_reference(server_info, - logon_info->account_name.string); - } else { - server_info->account_name = talloc_strdup(server_info, username); - } - - server_info->domain = talloc_reference(server_info, - logon_info->dom_name.string); - server_info->realm = talloc_strdup(server_info, realm); - server_info->full_name = talloc_reference(server_info, - logon_info->full_name.string); - server_info->logon_script = talloc_reference(server_info, - logon_info->logon_script.string); - server_info->profile_path = talloc_reference(server_info, - logon_info->profile_path.string); - server_info->home_directory = talloc_reference(server_info, - logon_info->home_directory.string); - server_info->home_drive = talloc_reference(server_info, - logon_info->home_drive.string); - - server_info->logon_count = logon_info->logon_count; - /* TODO: bad password count */ - - server_info->acct_flags = logon_info->acct_flags; - - if (!server_info->domain || !server_info->account_name || !server_info->realm) { - free_server_info(&server_info); - return NT_STATUS_NO_MEMORY; - } - - /* references the server_info into the session_info */ - nt_status = make_session_info(gensec_krb5_state, server_info, &session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - free_server_info(&server_info); - return nt_status; - } - - talloc_free(server_info); - - ptoken = security_token_initialise(session_info); - if (ptoken == NULL) { - return NT_STATUS_NO_MEMORY; - } - - ptoken->num_sids = 0; - ptoken->sids = talloc_array_p(ptoken, struct dom_sid *, - logon_info->groups_count + 2); - if (!ptoken->sids) { - return NT_STATUS_NO_MEMORY; - } - - - sid = dom_sid_dup(server_info, logon_info->dom_sid); - server_info->user_sid = dom_sid_add_rid(server_info, sid, logon_info->user_rid); - sid = dom_sid_dup(server_info, logon_info->dom_sid); - server_info->primary_group_sid = dom_sid_add_rid(server_info, sid, logon_info->group_rid); - - ptoken->user_sid = server_info->user_sid; - ptoken->group_sid = server_info->primary_group_sid; - ptoken->sids[0] = talloc_reference(ptoken, ptoken->user_sid); - ptoken->num_sids++; - ptoken->sids[1] = talloc_reference(ptoken, ptoken->group_sid); - ptoken->num_sids++; - - for (;ptoken->num_sids < (logon_info->groups_count + 2); - ptoken->num_sids++) { - sid = dom_sid_dup(session_info, logon_info->dom_sid); - ptoken->sids[ptoken->num_sids] - = dom_sid_add_rid(session_info, sid, - logon_info->groups[ptoken->num_sids - 2].rid); - } - - /* setup any privileges for this token */ - nt_status = samdb_privilege_setup(ptoken); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(ptoken); - return nt_status; - } - - debug_security_token(DBGC_AUTH, 0, ptoken); - - session_info->security_token = ptoken; } else { - TALLOC_CTX *mem_ctx = talloc_named(gensec_krb5_state, 0, "PAC-less session info discovery for %s@%s", username, realm); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } nt_status = sam_get_server_info(username, realm, gensec_krb5_state, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - - /* references the server_info into the session_info */ - nt_status = make_session_info(gensec_krb5_state, server_info, &session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); return nt_status; } + } - talloc_free(mem_ctx); + /* references the server_info into the session_info */ + nt_status = make_session_info(gensec_krb5_state, server_info, &session_info); + talloc_free(server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } talloc_free(principal); -- cgit From 44113c4de1ae06a78a940782dc762b6576310d0d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 Dec 2004 09:54:23 +0000 Subject: r4355: More work from the elves on Christmas eve: - Update Samba4's kerberos code to match the 'salting' changes in Samba3 (and many other cleanups by jra). - Move GENSEC into the modern era of talloc destructors. This avoids many of the memory leaks in this code, as we now can't somehow 'forget' to call the end routine. - This required fixing some of the talloc hierarchies. - The new krb5 seems more sensitive to getting the service name right, so start actually setting the service name on the krb5 context. Andrew Bartlett (This used to be commit 278bf1a61a6da6ef955a12c13d7b1a0357cebf1f) --- source4/libcli/auth/clikrb5.c | 98 ++++-- source4/libcli/auth/gensec.c | 28 +- source4/libcli/auth/gensec.h | 1 - source4/libcli/auth/gensec_krb5.c | 29 +- source4/libcli/auth/gensec_ntlmssp.c | 52 +-- source4/libcli/auth/kerberos.c | 643 ++++++++++++++++++++++++++++++++-- source4/libcli/auth/kerberos.h | 15 +- source4/libcli/auth/kerberos_verify.c | 184 +++++----- source4/libcli/auth/ntlmssp.c | 3 + source4/libcli/auth/spnego.c | 49 ++- 10 files changed, 891 insertions(+), 211 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 7ad8dd7b6c..122f9510e7 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -71,11 +71,11 @@ pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else - __ERROR__XX__UNKNOWN_ADDRTYPE +#error UNKNOWN_ADDRTYPE #endif -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) - int create_kerberos_key_from_string(krb5_context context, +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) && defined(HAVE_KRB5_ENCRYPT_BLOCK) + int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -96,7 +96,7 @@ return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string(krb5_context context, + int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -114,9 +114,30 @@ salt, key); } #else - __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#error UNKNOWN_CREATE_KEY_FUNCTIONS #endif + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + krb5_principal salt_princ = NULL; + int ret; + /* + * Check if we've determined that the KDC is salting keys for this + * principal/enctype in a non-obvious way. If it is, try to match + * its behavior. + */ + salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype); + ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype); + if (salt_princ) { + krb5_free_principal(context, salt_princ); + } + return ret; +} + #if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) @@ -190,7 +211,7 @@ krb5_error_code rc; int num_kdcs, i; struct sockaddr *sa; - struct addrinfo **ai; + struct addrinfo *ai; *addr_pp = NULL; *naddrs = 0; @@ -220,16 +241,15 @@ return -1; } - *addr_pp = malloc_array_p(struct sockaddr, num_kdcs); - memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs ); for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { #if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO) - rc = krb5_krbhst_get_addrinfo(ctx, hinfo, ai); + rc = krb5_krbhst_get_addrinfo(ctx, hinfo, &ai); if (rc) { DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc))); - return rc; + continue; } #endif if (hinfo->ai && hinfo->ai->ai_family == AF_INET) @@ -251,6 +271,42 @@ } #endif + void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) +{ +#if defined(HAVE_KRB5_FREE_DATA_CONTENTS) + if (pdata->data) { + krb5_free_data_contents(context, pdata); + } +#else + SAFE_FREE(pdata->data); +#endif +} + + void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) +{ +#if defined(HAVE_KRB5_KEYBLOCK_IN_CREDS) + KRB5_KEY_TYPE((&pcreds->keyblock)) = enctype; +#elif defined(HAVE_KRB5_SESSION_IN_CREDS) + KRB5_KEY_TYPE((&pcreds->session)) = enctype; +#else +#error UNKNOWN_KEYBLOCK_MEMBER_IN_KRB5_CREDS_STRUCT +#endif +} + + BOOL kerberos_compatible_enctypes(krb5_context context, + krb5_enctype enctype1, + krb5_enctype enctype2) +{ +#if defined(HAVE_KRB5_C_ENCTYPE_COMPARE) + krb5_boolean similar = 0; + + krb5_c_enctype_compare(context, enctype1, enctype2, &similar); + return similar ? True : False; +#elif defined(HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS) + return krb5_enctypes_compatible_keys(context, enctype1, enctype2) ? True : False; +#endif +} + static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) @@ -279,13 +335,13 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, we're using creds obtained outside of our exectuable */ if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { - DEBUG(5, ("We do not remove creds from a FILE ccache\n")); + DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a FILE ccache\n")); return False; } retval = krb5_cc_remove_cred(context, ccache, 0, credsp); if (retval) { - DEBUG(1, ("krb5_cc_remove_cred failed, err %s\n", + DEBUG(1, ("ads_cleanup_expired_creds: krb5_cc_remove_cred failed, err %s\n", error_message(retval))); /* If we have an error in this, we want to display it, but continue as though we deleted it */ @@ -296,7 +352,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ - krb5_error_code ads_krb5_mk_req(krb5_context context, +krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, const char *principal, @@ -314,7 +370,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, retval = krb5_parse_name(context, principal, &server); if (retval) { - DEBUG(1,("Failed to parse principal %s\n", principal)); + DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); return retval; } @@ -327,7 +383,9 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, } if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { - DEBUG(10,("krb5_cc_get_principal failed (%s)\n", + /* This can commonly fail on smbd startup with no ticket in the cache. + * Report at higher level than 1. */ + DEBUG(3,("ads_krb5_mk_req: krb5_cc_get_principal failed (%s)\n", error_message(retval))); goto cleanup_creds; } @@ -335,7 +393,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, while(!creds_ready) { if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", principal, error_message(retval))); goto cleanup_creds; } @@ -344,7 +402,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, if ((unsigned)credsp->times.starttime > time(NULL)) { time_t t = time(NULL); int time_offset =(unsigned)credsp->times.starttime-t; - DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + DEBUG(4,("ads_krb5_mk_req: Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(context, t + time_offset + 1, 0); } @@ -366,7 +424,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { - DEBUG(1,("krb5_mk_req_extended failed (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", error_message(retval))); } @@ -378,13 +436,9 @@ cleanup_creds: cleanup_princ: krb5_free_principal(context, server); - if (mem_ctx) { - talloc_destroy(mem_ctx); - } return retval; } - #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) { diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 8009df4e40..7e33a159f9 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -147,10 +147,11 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense * @note Used by SPENGO in particular, for the actual implementation mechanism */ -NTSTATUS gensec_subcontext_start(struct gensec_security *parent, +NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, + struct gensec_security *parent, struct gensec_security **gensec_security) { - (*gensec_security) = talloc_p(parent, struct gensec_security); + (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; } @@ -444,10 +445,6 @@ void gensec_end(struct gensec_security **gensec_security) if (!*gensec_security) { return; } - if ((*gensec_security)->ops) { - (*gensec_security)->ops->end(*gensec_security); - } - (*gensec_security)->private_data = NULL; talloc_free(*gensec_security); *gensec_security = NULL; @@ -646,7 +643,7 @@ NTSTATUS gensec_set_password(struct gensec_security *gensec_security, const char *password) { gensec_security->user.password = talloc_strdup(gensec_security, password); - if (!gensec_security->user.password) { + if (password && !gensec_security->user.password) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; @@ -713,6 +710,20 @@ const char *gensec_get_target_service(struct gensec_security *gensec_security) return "host"; } +const char *gensec_get_target_principal(struct gensec_security *gensec_security) +{ + const char *mechListMIC; + + if (gensec_security->target.principal) { + return gensec_security->target.principal; + } + + mechListMIC = talloc_asprintf(gensec_security,"%s$@%s", + lp_netbios_name(), + lp_realm()); + return mechListMIC; +} + /** * Set a password callback, if the gensec module we use demands a password */ @@ -741,7 +752,8 @@ NTSTATUS gensec_get_password(struct gensec_security *gensec_security, } } if (!gensec_security->password_callback) { - return NT_STATUS_INVALID_PARAMETER; + *password = NULL; + return NT_STATUS_OK; } return gensec_security->password_callback(gensec_security, mem_ctx, password); } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 9162c935b2..2b44f0d902 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -84,7 +84,6 @@ struct gensec_security_ops { NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); NTSTATUS (*session_info)(struct gensec_security *gensec_security, struct auth_session_info **session_info); - void (*end)(struct gensec_security *gensec_security); }; #define GENSEC_INTERFACE_VERSION 0 diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 9323580e92..9d4a2f6b0e 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -229,9 +229,9 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, return status; } -static void gensec_krb5_end(struct gensec_security *gensec_security) +static int gensec_krb5_destory(void *ptr) { - struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + struct gensec_krb5_state *gensec_krb5_state = ptr; if (gensec_krb5_state->ticket.length) { /* Hmm, early heimdal dooesn't have this - correct call would be krb5_data_free */ @@ -255,12 +255,9 @@ static void gensec_krb5_end(struct gensec_security *gensec_security) if (gensec_krb5_state->krb5_context) { krb5_free_context(gensec_krb5_state->krb5_context); } - - talloc_free(gensec_krb5_state); - gensec_security->private_data = NULL; + return 0; } - static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) { struct gensec_krb5_state *gensec_krb5_state; @@ -282,6 +279,8 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) gensec_krb5_state->session_key = data_blob(NULL, 0); gensec_krb5_state->pac = data_blob(NULL, 0); + talloc_set_destructor(gensec_krb5_state, gensec_krb5_destory); + ret = krb5_init_context(&gensec_krb5_state->krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", error_message(ret))); @@ -401,8 +400,8 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } ret = kerberos_kinit_password_cc(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache, - gensec_get_client_principal(gensec_security, gensec_security), - password, NULL, &kdc_time); + gensec_get_client_principal(gensec_security, gensec_security), + password, NULL, &kdc_time); /* cope with ticket being in the future due to clock skew */ if ((unsigned)kdc_time > time(NULL)) { @@ -439,8 +438,9 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security * or NT_STATUS_OK if the user is authenticated. */ -static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) +static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) { struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; krb5_error_code ret = 0; @@ -524,7 +524,8 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL nt_status = ads_verify_ticket(out_mem_ctx, gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context, - lp_realm(), &in, + lp_realm(), + gensec_get_target_service(gensec_security), &in, &principal, &pac, &unwrapped_out, &gensec_krb5_state->krb5_keyblock); } else { @@ -532,7 +533,9 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL nt_status = ads_verify_ticket(out_mem_ctx, gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_auth_context, - lp_realm(), &unwrapped_in, + lp_realm(), + gensec_get_target_service(gensec_security), + &unwrapped_in, &principal, &pac, &unwrapped_out, &gensec_krb5_state->krb5_keyblock); } @@ -683,7 +686,6 @@ static const struct gensec_security_ops gensec_krb5_security_ops = { .update = gensec_krb5_update, .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, - .end = gensec_krb5_end }; static const struct gensec_security_ops gensec_ms_krb5_security_ops = { @@ -695,7 +697,6 @@ static const struct gensec_security_ops gensec_ms_krb5_security_ops = { .update = gensec_krb5_update, .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, - .end = gensec_krb5_end }; diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 07dacfb5e0..cf8019402c 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -142,6 +142,23 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, return nt_status; } +static int gensec_ntlmssp_destroy(void *ptr) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ptr; + + if (gensec_ntlmssp_state->ntlmssp_state) { + ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state); + } + + if (gensec_ntlmssp_state->auth_context) { + free_auth_context(&gensec_ntlmssp_state->auth_context); + } + if (gensec_ntlmssp_state->server_info) { + free_server_info(&gensec_ntlmssp_state->server_info); + } + return 0; +} + static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) { struct gensec_ntlmssp_state *gensec_ntlmssp_state; @@ -155,6 +172,8 @@ static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->auth_context = NULL; gensec_ntlmssp_state->server_info = NULL; + talloc_set_destructor(gensec_ntlmssp_state, gensec_ntlmssp_destroy); + gensec_security->private_data = gensec_ntlmssp_state; return NT_STATUS_OK; } @@ -173,7 +192,7 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur gensec_ntlmssp_state = gensec_security->private_data; - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(gensec_security, + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(gensec_ntlmssp_state, &gensec_ntlmssp_state->ntlmssp_state))) { return nt_status; } @@ -186,7 +205,7 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur } ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; - nt_status = make_auth_context_subsystem(gensec_security, &gensec_ntlmssp_state->auth_context); + nt_status = make_auth_context_subsystem(gensec_ntlmssp_state, &gensec_ntlmssp_state->auth_context); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -213,7 +232,7 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur } gensec_ntlmssp_state = gensec_security->private_data; - status = ntlmssp_client_start(gensec_security, + status = ntlmssp_client_start(gensec_ntlmssp_state, &gensec_ntlmssp_state->ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { return status; @@ -250,9 +269,11 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur return status; } - status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (gensec_security->user.name) { + status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } if (password) { @@ -397,24 +418,6 @@ static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_secur return NT_STATUS_OK; } -static void gensec_ntlmssp_end(struct gensec_security *gensec_security) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - if (gensec_ntlmssp_state->ntlmssp_state) { - ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state); - } - - if (gensec_ntlmssp_state->auth_context) { - free_auth_context(&gensec_ntlmssp_state->auth_context); - } - if (gensec_ntlmssp_state->server_info) { - free_server_info(&gensec_ntlmssp_state->server_info); - } - talloc_free(gensec_ntlmssp_state); - gensec_security->private_data = NULL; -} - static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .name = "ntlmssp", .sasl_name = "NTLM", @@ -430,7 +433,6 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .unseal_packet = gensec_ntlmssp_unseal_packet, .session_key = gensec_ntlmssp_session_key, .session_info = gensec_ntlmssp_session_info, - .end = gensec_ntlmssp_end }; diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 9510aaa7fb..a8d9d75a1e 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -3,8 +3,9 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - - + Copyright (C) Nalin Dahyabhai 2004. + Copyright (C) Jeremy Allison 2004. + 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 @@ -24,9 +25,12 @@ #include "system/kerberos.h" #include "libcli/auth/kerberos.h" #include "system/time.h" +#include "secrets.h" #ifdef HAVE_KRB5 +#define LIBADS_CCACHE_NAME "MEMORY:libads" + /* we use a prompter to avoid a crash bug in the kerberos libs when dealing with empty passwords @@ -41,7 +45,7 @@ kerb_prompter(krb5_context ctx, void *data, { if (num_prompts == 0) return 0; - memset(prompts[0].reply->data, 0, prompts[0].reply->length); + memset(prompts[0].reply->data, '\0', prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); @@ -54,10 +58,12 @@ kerb_prompter(krb5_context ctx, void *data, } /* - simulate a kinit, putting the tgt in the default cache location - remus@snapserver.com + simulate a kinit, putting the tgt in the given credentials cache. + Orignally by remus@snapserver.com */ - int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, const char *principal, const char *password, time_t *expire_time, time_t *kdc_time) + int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, + const char *principal, const char *password, + time_t *expire_time, time_t *kdc_time) { krb5_error_code code = 0; krb5_principal me; @@ -103,15 +109,21 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } - /* - simulate a kinit, putting the tgt in the default cache location - remus@snapserver.com + simulate a kinit, putting the tgt in the given credentials cache. + If cache_name == NULL place in default cache location. + + Orignally by remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time, time_t *kdc_time) +int kerberos_kinit_password(const char *principal, + const char *password, + int time_offset, + time_t *expire_time, + const char *cache_name, + time_t *kdc_time) { + int code; krb5_context ctx = NULL; - krb5_error_code code = 0; krb5_ccache cc = NULL; if ((code = krb5_init_context(&ctx))) @@ -121,21 +133,19 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - if ((code = krb5_cc_default(ctx, &cc))) { + if ((code = krb5_cc_resolve(ctx, cache_name ? + cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); return code; } - if ((code = kerberos_kinit_password_cc(ctx, cc, principal, password, expire_time, kdc_time))) { - krb5_cc_close(ctx, cc); - krb5_free_context(ctx); - return code; - } + code = kerberos_kinit_password_cc(ctx, cc, principal, password, expire_time, kdc_time); - return 0; -} - + krb5_cc_close(ctx, cc); + krb5_free_context(ctx); + return code; +} /* run kinit to setup our ccache */ int ads_kinit_password(ADS_STRUCT *ads) @@ -151,7 +161,8 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire, NULL); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, + &ads->auth.expire, NULL, NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -168,7 +179,8 @@ int ads_kdestroy(const char *cc_name) krb5_ccache cc = NULL; if ((code = krb5_init_context (&ctx))) { - DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", + error_message(code))); return code; } @@ -179,19 +191,600 @@ int ads_kdestroy(const char *cc_name) } } else { if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", - code)); + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n", + error_message(code))); krb5_free_context(ctx); return code; } } if ((code = krb5_cc_destroy (ctx, cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", + error_message(code))); } krb5_free_context (ctx); return code; } +/************************************************************************ + Routine to fetch the salting principal for a service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + ************************************************************************/ + +static char *kerberos_secrets_fetch_salting_principal(const char *service, int enctype) +{ + char *ret = NULL; + +#if 0 + asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); + if (!key) { + return NULL; + } + ret = (char *)secrets_fetch(key, NULL); + SAFE_FREE(key); +#endif + return ret; +} + +/************************************************************************ + Routine to get the salting principal for this service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + Caller must free if return is not null. + ************************************************************************/ + +krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, + krb5_principal host_princ, + int enctype) +{ + char *unparsed_name = NULL, *salt_princ_s = NULL; + krb5_principal ret_princ = NULL; + + if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + return (krb5_principal)NULL; + } + + if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { + krb5_free_unparsed_name(context, unparsed_name); + return (krb5_principal)NULL; + } + + if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { + krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(salt_princ_s); + return (krb5_principal)NULL; + } + krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(salt_princ_s); + return ret_princ; +} + +/************************************************************************ + Routine to set the salting principal for this service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + Setting principal to NULL deletes this entry. + ************************************************************************/ + + BOOL kerberos_secrets_store_salting_principal(const char *service, + int enctype, + const char *principal) +{ + char *key = NULL; + BOOL ret = False; + krb5_context context = NULL; + krb5_principal princ = NULL; + char *princ_s = NULL; + char *unparsed_name = NULL; + + krb5_init_context(&context); + if (!context) { + return False; + } + if (strchr_m(service, '@')) { + asprintf(&princ_s, "%s", service); + } else { + asprintf(&princ_s, "%s@%s", service, lp_realm()); + } + + if (krb5_parse_name(context, princ_s, &princ) != 0) { + goto out; + + } + if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { + goto out; + } + + asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); + if (!key) { + goto out; + } + +#if 0 + if ((principal != NULL) && (strlen(principal) > 0)) { + ret = secrets_store(key, principal, strlen(principal) + 1); + } else { + ret = secrets_delete(key); + } +#endif + + out: + + SAFE_FREE(key); + SAFE_FREE(princ_s); + + if (unparsed_name) { + krb5_free_unparsed_name(context, unparsed_name); + } + if (context) { + krb5_free_context(context); + } + + return ret; +} + +/************************************************************************ + Routine to get initial credentials as a service ticket for the local machine. + Returns a buffer initialized with krb5_mk_req_extended. + ************************************************************************/ + +static krb5_error_code get_service_ticket(krb5_context ctx, + krb5_ccache ccache, + const char *service_principal, + int enctype, + krb5_data *p_outbuf) +{ + krb5_creds creds, *new_creds = NULL; + char *service_s = NULL; + char *machine_account = NULL, *password = NULL; + krb5_data in_data; + krb5_auth_context auth_context = NULL; + krb5_error_code err = 0; + + ZERO_STRUCT(creds); + + asprintf(&machine_account, "%s$@%s", lp_netbios_name(), lp_realm()); + if (machine_account == NULL) { + goto out; + } + password = secrets_fetch_machine_password(lp_workgroup()); + if (password == NULL) { + goto out; + } + if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME, NULL)) != 0) { + DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", + machine_account, + lp_realm(), + error_message(err))); + goto out; + } + + /* Ok - the above call has gotten a TGT. Now we need to get a service + ticket to ourselves. */ + + /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ + kerberos_set_creds_enctype(&creds, enctype); + + if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { + DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", + error_message(err))); + goto out; + } + + if (strchr_m(service_principal, '@')) { + asprintf(&service_s, "%s", service_principal); + } else { + asprintf(&service_s, "%s@%s", service_principal, lp_realm()); + } + + if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { + DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", + service_s, error_message(err))); + goto out; + } + + if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { + DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", + service_s, enctype, error_message(err))); + goto out; + } + + memset(&in_data, '\0', sizeof(in_data)); + if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, + new_creds, p_outbuf)) != 0) { + DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", + error_message(err))); + goto out; + } + + out: + + if (auth_context) { + krb5_auth_con_free(ctx, auth_context); + } + if (new_creds) { + krb5_free_creds(ctx, new_creds); + } + if (creds.server) { + krb5_free_principal(ctx, creds.server); + } + if (creds.client) { + krb5_free_principal(ctx, creds.client); + } + + SAFE_FREE(service_s); + SAFE_FREE(password); + SAFE_FREE(machine_account); + return err; +} + +/************************************************************************ + Check if the machine password can be used in conjunction with the salting_principal + to generate a key which will successfully decrypt the AP_REQ already + gotten as a message to the local machine. + ************************************************************************/ + +static BOOL verify_service_password(krb5_context ctx, + int enctype, + const char *salting_principal, + krb5_data *in_data) +{ + BOOL ret = False; + krb5_principal salting_kprinc = NULL; + krb5_ticket *ticket = NULL; + krb5_keyblock key; + krb5_data passdata; + char *salting_s = NULL; + char *machine_account = NULL, *password = NULL; + krb5_auth_context auth_context = NULL; + krb5_error_code err; + + memset(&passdata, '\0', sizeof(passdata)); + memset(&key, '\0', sizeof(key)); + + asprintf(&machine_account, "%s$@%s", lp_netbios_name(), lp_realm()); + if (machine_account == NULL) { + goto out; + } + password = secrets_fetch_machine_password(lp_workgroup()); + if (password == NULL) { + goto out; + } + + if (strchr_m(salting_principal, '@')) { + asprintf(&salting_s, "%s", salting_principal); + } else { + asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); + } + + if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { + DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", + salting_s, error_message(err))); + goto out; + } + + passdata.length = strlen(password); + passdata.data = (char*)password; + if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { + DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", + enctype, error_message(err))); + goto out; + } + + if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { + DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); + goto out; + } + + if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { + DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); + goto out; + } + + if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { + DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", + (unsigned int)enctype, salting_s)); + ret = True; + } + + out: + + memset(&passdata, 0, sizeof(passdata)); + krb5_free_keyblock_contents(ctx, &key); + if (ticket != NULL) { + krb5_free_ticket(ctx, ticket); + } + if (salting_kprinc) { + krb5_free_principal(ctx, salting_kprinc); + } + SAFE_FREE(salting_s); + SAFE_FREE(password); + SAFE_FREE(machine_account); + return ret; +} + +/************************************************************************ + * + * From the current draft of kerberos-clarifications: + * + * It is not possible to reliably generate a user's key given a pass + * phrase without contacting the KDC, since it will not be known + * whether alternate salt or parameter values are required. + * + * And because our server has a password, we have this exact problem. We + * make multiple guesses as to which principal name provides the salt which + * the KDC is using. + * + ************************************************************************/ + +static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, + krb5_context ctx, + krb5_ccache ccache, + krb5_enctype enctype, + krb5_enctype *enctypes) +{ + char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; + krb5_error_code err = 0; + krb5_data outbuf; + int i, j; + + memset(&outbuf, '\0', sizeof(outbuf)); + + /* Check that the service_principal is useful. */ + if ((service_principal == NULL) || (strlen(service_principal) == 0)) { + return; + } + + /* Generate our first guess -- the principal as-given. */ + asprintf(&salting_principals[0], "%s", service_principal); + if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { + return; + } + + /* Generate our second guess -- the computer's principal, as Win2k3. */ + asprintf(&second_principal, "host/%s.%s", lp_netbios_name(), lp_realm()); + if (second_principal != NULL) { + strlower_m(second_principal); + asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); + SAFE_FREE(second_principal); + } + if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { + goto out; + } + + /* Generate our third guess -- the computer's principal, as Win2k. */ + asprintf(&second_principal, "HOST/%s", lp_netbios_name()); + if (second_principal != NULL) { + strlower_m(second_principal + 5); + asprintf(&salting_principals[2], "%s@%s", + second_principal, lp_realm()); + SAFE_FREE(second_principal); + } + if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { + goto out; + } + + /* Get a service ticket for ourselves into our memory ccache. */ + /* This will commonly fail if there is no principal by that name (and we're trying + many names). So don't print a debug 0 error. */ + + if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { + DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", + error_message(err))); + goto out; + } + + /* At this point we have a message to ourselves, salted only the KDC knows how. We + have to work out what that salting is. */ + + /* Try and find the correct salting principal. */ + for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { + if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { + break; + } + } + + /* If we failed to get a match, return. */ + if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { + goto out; + } + + /* If we succeeded, store the principal for use for all enctypes which + * share the same cipher and string-to-key function. Doing this here + * allows servers which just pass a keytab to krb5_rd_req() to work + * correctly. */ + for (j = 0; enctypes[j] != 0; j++) { + if (enctype != enctypes[j]) { + /* If this enctype isn't compatible with the one which + * we used, skip it. */ + + if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) + continue; + } + /* If the principal which gives us the proper salt is the one + * which we would normally guess, don't bother noting anything + * in the secrets tdb. */ + if (strcmp(service_principal, salting_principals[i]) != 0) { + kerberos_secrets_store_salting_principal(service_principal, + enctypes[j], + salting_principals[i]); + } + } + + out : + + kerberos_free_data_contents(ctx, &outbuf); + SAFE_FREE(salting_principals[0]); + SAFE_FREE(salting_principals[1]); + SAFE_FREE(salting_principals[2]); + SAFE_FREE(second_principal); +} + +/************************************************************************ + Go through all the possible enctypes for this principal. + ************************************************************************/ + +static void kerberos_derive_salting_principal_direct(krb5_context context, + krb5_ccache ccache, + krb5_enctype *enctypes, + char *service_principal) +{ + int i; + + /* Try for each enctype separately, because the rules are + * different for different enctypes. */ + for (i = 0; enctypes[i] != 0; i++) { + /* Delete secrets entry first. */ + kerberos_secrets_store_salting_principal(service_principal, 0, NULL); +#ifdef ENCTYPE_ARCFOUR_HMAC + if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { + /* Of course this'll always work, so just save + * ourselves the effort. */ + continue; + } +#endif + /* Try to figure out what's going on with this + * principal. */ + kerberos_derive_salting_principal_for_enctype(service_principal, + context, + ccache, + enctypes[i], + enctypes); + } +} + +/************************************************************************ + Wrapper function for the above. + ************************************************************************/ + +BOOL kerberos_derive_salting_principal(char *service_principal) +{ + krb5_context context = NULL; + krb5_enctype *enctypes = NULL; + krb5_ccache ccache = NULL; + krb5_error_code ret = 0; + + initialize_krb5_error_table(); + if ((ret = krb5_init_context(&context)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", + error_message(ret))); + return False; + } + if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", + error_message(ret))); + goto out; + } + + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + goto out; + } + + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); + + out: + if (enctypes) { + free_kerberos_etypes(context, enctypes); + } + if (ccache) { + krb5_cc_destroy(context, ccache); + } + if (context) { + krb5_free_context(context); + } + + return ret ? False : True; +} + +/************************************************************************ + Core function to try and determine what salt is being used for any keytab + keys. + ************************************************************************/ + +BOOL kerberos_derive_cifs_salting_principals(void) +{ + fstring my_fqdn; + char *service = NULL; + krb5_context context = NULL; + krb5_enctype *enctypes = NULL; + krb5_ccache ccache = NULL; + krb5_error_code ret = 0; + BOOL retval = False; + + initialize_krb5_error_table(); + if ((ret = krb5_init_context(&context)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", + error_message(ret))); + return False; + } + if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", + error_message(ret))); + goto out; + } + + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + goto out; + } + + if (asprintf(&service, "%s$", lp_netbios_name()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "cifs/%s", lp_netbios_name()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s", lp_netbios_name()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "cifs/%s.%s", lp_netbios_name(), lp_realm()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s.%s", lp_netbios_name(), lp_realm()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + name_to_fqdn(my_fqdn, lp_netbios_name()); + if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s", my_fqdn) != -1) { + strlower_m(service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); + SAFE_FREE(service); + } + + retval = True; + + out: + if (enctypes) { + free_kerberos_etypes(context, enctypes); + } + if (ccache) { + krb5_cc_destroy(context, ccache); + } + if (context) { + krb5_free_context(context); + } + return retval; +} #endif diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 3ab71f7875..9bb6d22eb6 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -61,6 +61,7 @@ const krb5_data *krb5_princ_component(krb5_context context, krb5_principal princ /* Samba wrapper function for krb5 functionality. */ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr); int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); +int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); @@ -74,13 +75,23 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_data *outbuf); DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, krb5_ticket *tkt); + NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, krb5_auth_context auth_context, - const char *realm, const DATA_BLOB *ticket, + const char *realm, const char *service, + const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep, krb5_keyblock *keyblock); -int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, const char *principal, const char *password, time_t *expire_time, time_t *kdc_time); +int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, + const char *principal, const char *password, + time_t *expire_time, time_t *kdc_time); +krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, + krb5_principal host_princ, + int enctype); +void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype); +BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2); +void kerberos_free_data_contents(krb5_context context, krb5_data *pdata); #endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index d00394fd79..92980f1122 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -29,6 +29,9 @@ #ifdef HAVE_KRB5 +#if !defined(HAVE_KRB5_PRINC_COMPONENT) +const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int ); +#endif static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) { DATA_BLOB out; @@ -65,21 +68,23 @@ static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) ads_keytab_add_entry function for details. ***********************************************************************************/ -static krb5_error_code ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, - krb5_keyblock *keyblock) +static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, + krb5_auth_context auth_context, + const char *service, + const DATA_BLOB *ticket, krb5_data *p_packet, + krb5_ticket **pp_tkt, + krb5_keyblock *keyblock) { krb5_error_code ret = 0; - + BOOL auth_ok = False; krb5_keytab keytab = NULL; - krb5_kt_cursor cursor; - krb5_keytab_entry kt_entry; - char *princ_name = NULL; - - ZERO_STRUCT(kt_entry); - ZERO_STRUCT(cursor); - - ZERO_STRUCTP(keyblock); + char *my_fqdn; + fstring my_name; + fstring my_Fqdn, my_NAME; + char *p_fqdn; + char *host_princ_s[18]; + krb5_principal host_princ; + int i; ret = krb5_kt_default(context, &keytab); if (ret) { @@ -87,73 +92,74 @@ static krb5_error_code ads_keytab_verify_ticket(krb5_context context, krb5_auth_ goto out; } - ret = krb5_kt_start_seq_get(context, keytab, &cursor); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); - goto out; + /* Generate the list of principal names which we expect clients might + * want to use for authenticating to the file service. */ + + fstrcpy(my_name, lp_netbios_name()); + strlower_m(my_name); + + fstrcpy(my_NAME, lp_netbios_name()); + strupper_m(my_NAME); + + my_fqdn = name_to_fqdn(mem_ctx, lp_netbios_name()); + strlower_m(my_fqdn); + + p_fqdn = strchr_m(my_fqdn, '.'); + fstrcpy(my_Fqdn, my_NAME); + if (p_fqdn) { + fstrcat(my_Fqdn, p_fqdn); } - while (!(ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor))) { - ret = krb5_unparse_name(context, kt_entry.principal, &princ_name); + asprintf(&host_princ_s[0], "%s$@%s", my_name, lp_realm()); + asprintf(&host_princ_s[1], "%s$@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[2], "host/%s@%s", my_name, lp_realm()); + asprintf(&host_princ_s[3], "host/%s@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); + asprintf(&host_princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); + asprintf(&host_princ_s[6], "HOST/%s@%s", my_name, lp_realm()); + asprintf(&host_princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); + asprintf(&host_princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); + asprintf(&host_princ_s[10], "%s/%s@%s", service, my_name, lp_realm()); + asprintf(&host_princ_s[11], "%s/%s@%s", service, my_NAME, lp_realm()); + asprintf(&host_princ_s[12], "%s/%s@%s", service, my_fqdn, lp_realm()); + asprintf(&host_princ_s[13], "%s/%s@%s", service, my_Fqdn, lp_realm()); + asprintf(&host_princ_s[14], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_name, lp_realm()); + asprintf(&host_princ_s[15], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_NAME, lp_realm()); + asprintf(&host_princ_s[16], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_fqdn, lp_realm()); + asprintf(&host_princ_s[17], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_Fqdn, lp_realm()); + + /* Now try to verify the ticket using the key associated with each of + * the principals which we think clients will expect us to be + * participating as. */ + for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { + host_princ = NULL; + ret = krb5_parse_name(context, host_princ_s[i], &host_princ); if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n", + host_princ_s[i], error_message(ret))); goto out; } - DEBUG(10, ("Checking principal: %s\n", princ_name)); - /* Look for a CIFS ticket */ - if (!strncasecmp(princ_name, "cifs/", 5) || - !strncasecmp(princ_name, "host/", 5) || - !strncasecmp(princ_name, "ldap/", 5)) { -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK - krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); -#else - krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.key); -#endif - - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - - ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt); - if (!ret) { - unsigned int keytype; - krb5_free_unparsed_name(context, princ_name); - princ_name = NULL; -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK - keytype = (unsigned int) kt_entry.keyblock.keytype; - copy_EncryptionKey(&kt_entry.keyblock, keyblock); -#else - keytype = (unsigned int) kt_entry.key.enctype; - /* TODO: copy the keyblock on MIT krb5*/ -#endif - DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", - keytype)); - - break; - } - } - krb5_free_unparsed_name(context, princ_name); - princ_name = NULL; + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + *pp_tkt = NULL; + ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt); + krb5_free_principal(context, host_princ); + if (ret) { + DEBUG(0, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); + } else { + DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i])); + auth_ok = True; + break; + } } - if (ret && ret != KRB5_KT_END) { - /* This failed because something went wrong, not because the keytab file was empty. */ - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_next_entry failed (%s)\n", error_message(ret))); - } else if (ret == KRB5_KT_END) { - DEBUG(10, ("ads_keytab_verify_ticket: no keytab entry found: %s\n", error_message(ret))); - } else { - DEBUG(10, ("ads_keytab_verify_ticket: keytab entry found: %s\n", princ_name)); + + for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { + SAFE_FREE(host_princ_s[i]); } + out: - if (princ_name) { - krb5_free_unparsed_name(context, princ_name); - } - { - krb5_kt_cursor zero_csr; - ZERO_STRUCT(zero_csr); - if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { - krb5_kt_end_seq_get(context, keytab, &cursor); - } - } if (keytab) { krb5_kt_close(context, keytab); } @@ -165,10 +171,12 @@ static krb5_error_code ads_keytab_verify_ticket(krb5_context context, krb5_auth_ Try to verify a ticket using the secrets.tdb. ***********************************************************************************/ -static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, - krb5_principal host_princ, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, - krb5_keyblock *keyblock) +static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, + krb5_auth_context auth_context, + krb5_principal host_princ, + const DATA_BLOB *ticket, krb5_data *p_packet, + krb5_ticket **pp_tkt, + krb5_keyblock *keyblock) { krb5_error_code ret = 0; char *password_s = NULL; @@ -250,12 +258,13 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_auth ***********************************************************************************/ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, - krb5_context context, - krb5_auth_context auth_context, - const char *realm, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep, - krb5_keyblock *keyblock) + krb5_context context, + krb5_auth_context auth_context, + const char *realm, const char *service, + const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data, + DATA_BLOB *ap_rep, + krb5_keyblock *keyblock) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_data packet; @@ -267,8 +276,6 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_auth char *host_princ_s = NULL; BOOL got_replay_mutex = False; - char *myname; - char *malloc_principal; ZERO_STRUCT(packet); @@ -279,9 +286,8 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_auth like. We have to go through all this to allow us to store the secret internally, instead of using /etc/krb5.keytab */ - myname = name_to_fqdn(mem_ctx, lp_netbios_name()); - strlower_m(myname); - asprintf(&host_princ_s, "host/%s@%s", myname, lp_realm()); + asprintf(&host_princ_s, "%s$", lp_netbios_name()); + strlower_m(host_princ_s); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", @@ -316,11 +322,13 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_auth goto out; } - ret = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, keyblock); + ret = ads_keytab_verify_ticket(mem_ctx, context, auth_context, + service, ticket, &packet, &tkt, keyblock); if (ret) { DEBUG(10, ("ads_secrets_verify_ticket: using host principal: [%s]\n", host_princ_s)); - ret = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &packet, &tkt, keyblock); + ret = ads_secrets_verify_ticket(mem_ctx, context, auth_context, + host_princ, ticket, + &packet, &tkt, keyblock); } release_server_mutex(); diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 5d61361d69..bee93985ac 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -146,6 +146,9 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) { ntlmssp_state->user = talloc_strdup(ntlmssp_state, user); + if (!user) { + ntlmssp_state->user = NULL; + } if (!ntlmssp_state->user) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 01757a0487..988d0b32a5 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -44,6 +44,17 @@ struct spnego_state { struct gensec_security *sub_sec_security; }; + +static int gensec_spnego_destroy(void *ptr) +{ + struct spnego_state *spnego_state = ptr; + + if (spnego_state->sub_sec_security) { + gensec_end(&spnego_state->sub_sec_security); + } + return 0; +} + static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; @@ -57,6 +68,8 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi spnego_state->state_position = SPNEGO_CLIENT_START; spnego_state->sub_sec_security = NULL; + talloc_set_destructor(spnego_state, gensec_spnego_destroy); + gensec_security->private_data = spnego_state; return NT_STATUS_OK; } @@ -74,6 +87,8 @@ static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_securi spnego_state->state_position = SPNEGO_SERVER_START; spnego_state->sub_sec_security = NULL; + talloc_set_destructor(spnego_state, gensec_spnego_destroy); + gensec_security->private_data = spnego_state; return NT_STATUS_OK; } @@ -221,7 +236,8 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec continue; } - nt_status = gensec_subcontext_start(gensec_security, + nt_status = gensec_subcontext_start(spnego_state, + gensec_security, &spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -257,7 +273,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ DATA_BLOB null_data_blob = data_blob(NULL,0); for (i=0; mechType && mechType[i]; i++) { - nt_status = gensec_subcontext_start(gensec_security, + nt_status = gensec_subcontext_start(spnego_state, + gensec_security, &spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { break; @@ -317,7 +334,8 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec return NT_STATUS_INVALID_PARAMETER; } - nt_status = gensec_subcontext_start(gensec_security, + nt_status = gensec_subcontext_start(spnego_state, + gensec_security, &spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -467,19 +485,12 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return nt_status; } else { const char **mechlist = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); - const char *mechListMIC; - - mechListMIC = talloc_asprintf(out_mem_ctx,"%s$@%s", - lp_netbios_name(), - lp_realm()); - if (!mechListMIC) { - return NT_STATUS_NO_MEMORY; - } spnego_out.type = SPNEGO_NEG_TOKEN_INIT; spnego_out.negTokenInit.mechTypes = mechlist; spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = data_blob_string_const(mechListMIC); + spnego_out.negTokenInit.mechListMIC + = data_blob_string_const(gensec_get_target_principal(gensec_security)); spnego_out.negTokenInit.mechToken = unwrapped_out; if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { @@ -694,19 +705,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } -static void gensec_spnego_end(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->sub_sec_security) { - gensec_end(&spnego_state->sub_sec_security); - } - - talloc_free(spnego_state); - - gensec_security->private_data = NULL; -} - static const struct gensec_security_ops gensec_spnego_security_ops = { .name = "spnego", .sasl_name = "GSS-SPNEGO", @@ -722,7 +720,6 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .unseal_packet = gensec_spnego_unseal_packet, .session_key = gensec_spnego_session_key, .session_info = gensec_spnego_session_info, - .end = gensec_spnego_end }; NTSTATUS gensec_spnego_init(void) -- cgit From 90b299603f7a8bc03617ae08d2fd7063d249bd24 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 Dec 2004 09:57:44 +0000 Subject: r4356: Allow anonymous connections to use NTLMSSP. The silly bugs that prevented this are gone. Andrew Bartlett (This used to be commit 87dad5ec538abad93d621078a82f162675847f9f) --- source4/libcli/raw/clitree.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index b9d0ffbc1f..777279f5f9 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -223,7 +223,6 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, setup.generic.in.password = NULL; setup.generic.in.user = ""; setup.generic.in.domain = ""; - setup.generic.in.capabilities &= ~CAP_EXTENDED_SECURITY; } else { setup.generic.in.password = password; setup.generic.in.user = user; -- cgit From 06275d6197f05ad01f2ec5571698fba79cdd68bb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 Dec 2004 10:56:23 +0000 Subject: r4357: Return a more sensible error code if a NULL (as opposed to the valid "") username is asked for. Andrew Bartlett (This used to be commit 9c9055603e1171e204f67b019900339f88414841) --- source4/libcli/auth/ntlmssp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index bee93985ac..6ece0f6df6 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -145,10 +145,11 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) { - ntlmssp_state->user = talloc_strdup(ntlmssp_state, user); if (!user) { - ntlmssp_state->user = NULL; + /* it should be at least "" */ + return NT_STATUS_INVALID_PARAMETER; } + ntlmssp_state->user = talloc_strdup(ntlmssp_state, user); if (!ntlmssp_state->user) { return NT_STATUS_NO_MEMORY; } -- cgit From 0f1444b77232d59aaa025fa44e5b88c4aabaf877 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 Dec 2004 23:02:39 +0000 Subject: r4358: At metze's request, the Christmas elves have removed gensec_end in favor of talloc_free(). Andrew Bartlett (This used to be commit 1933cd12fbaed56e13f2386b19de6ade99bf9478) --- source4/libcli/auth/gensec.c | 10 ---------- source4/libcli/auth/spnego.c | 39 ++++++++++++++++----------------------- 2 files changed, 16 insertions(+), 33 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 7e33a159f9..75086f9281 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -440,16 +440,6 @@ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_ return gensec_security->ops->update(gensec_security, out_mem_ctx, in, out); } -void gensec_end(struct gensec_security **gensec_security) -{ - if (!*gensec_security) { - return; - } - - talloc_free(*gensec_security); - *gensec_security = NULL; -} - /** * Set the requirement for a certain feature on the connection * diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 988d0b32a5..5cce0f9e17 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -45,16 +45,6 @@ struct spnego_state { }; -static int gensec_spnego_destroy(void *ptr) -{ - struct spnego_state *spnego_state = ptr; - - if (spnego_state->sub_sec_security) { - gensec_end(&spnego_state->sub_sec_security); - } - return 0; -} - static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; @@ -68,8 +58,6 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi spnego_state->state_position = SPNEGO_CLIENT_START; spnego_state->sub_sec_security = NULL; - talloc_set_destructor(spnego_state, gensec_spnego_destroy); - gensec_security->private_data = spnego_state; return NT_STATUS_OK; } @@ -87,8 +75,6 @@ static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_securi spnego_state->state_position = SPNEGO_SERVER_START; spnego_state->sub_sec_security = NULL; - talloc_set_destructor(spnego_state, gensec_spnego_destroy); - gensec_security->private_data = spnego_state; return NT_STATUS_OK; } @@ -246,8 +232,9 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, all_ops[i]->oid); if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); - continue; + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; + continue; } nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, in, out); @@ -255,7 +242,8 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec spnego_state->state_position = SPNEGO_FALLBACK; return nt_status; } - gensec_end(&spnego_state->sub_sec_security); + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; } DEBUG(1, ("Failed to parse SPNEGO request\n")); return NT_STATUS_INVALID_PARAMETER; @@ -283,7 +271,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, mechType[i]); if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; continue; } @@ -302,7 +291,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - gensec_end(&spnego_state->sub_sec_security); + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; } return nt_status; } @@ -344,8 +334,9 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, mechTypes[0]); if (!NT_STATUS_IS_OK(nt_status)) { - gensec_end(&spnego_state->sub_sec_security); - return nt_status; + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; + return nt_status; } nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, in, &unwrapped_out); @@ -367,7 +358,8 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec spnego_state->state_position = SPNEGO_CLIENT_TARG; return nt_status; } - gensec_end(&spnego_state->sub_sec_security); + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; DEBUG(1, ("Failed to setup SPNEGO netTokenInit request\n")); return NT_STATUS_INVALID_PARAMETER; @@ -515,7 +507,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!in.length) { /* client to produce negTokenInit */ - return gensec_spnego_client_negTokenInit(gensec_security, spnego_state, out_mem_ctx, in, out); + return gensec_spnego_client_negTokenInit(gensec_security, spnego_state, + out_mem_ctx, in, out); } len = spnego_read_data(in, &spnego); -- cgit From 24f209e89934cd9c522e2225e47cd6788834ba1f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 25 Dec 2004 14:12:31 +0000 Subject: r4361: fix the build metze (This used to be commit 78b2af77e9e4b97c698d6d9e680207b1df289cb4) --- source4/libcli/raw/clisession.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 519f112ceb..dcc0c8adbe 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -410,7 +410,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess status = gensec_client_start(session, &session->gensec); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); - goto done; + return status; } gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); @@ -505,7 +505,8 @@ done: parms->generic.out.lanman = s2.spnego.out.lanman; parms->generic.out.domain = s2.spnego.out.domain; } else { - gensec_end(&session->gensec); + talloc_free(session->gensec); + session->gensec = NULL; DEBUG(1, ("Failed to login with %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); return status; } -- cgit From 5e4e61c8276d5f0a4a2d4c6cbc20047554096227 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Dec 2004 08:13:01 +0000 Subject: r4364: - added support for testing of chained SMB operations in smbtorture - added test for chained OpenX/ReadX, simulating the OS/2 workplace shell - fixed a bug in handling chained fnum in openx and ntcreatex in the server (yes, I'm on holiday, but this bug was annoying me ....) (This used to be commit b3b8958a18e302b815d98c0e3879e404bced6a08) --- source4/libcli/raw/rawfile.c | 78 ++++++++++++++++++++++++++++++++++++++- source4/libcli/raw/rawreadwrite.c | 5 +-- source4/libcli/raw/rawrequest.c | 63 ++++++++++++++++++++++++++++++- 3 files changed, 140 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 4a11fd3834..11be8ffba7 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -29,7 +29,6 @@ if (!req) return NULL; \ } while (0) - /**************************************************************************** Rename a file - async interface ****************************************************************************/ @@ -426,6 +425,7 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope { int len; struct smbcli_request *req = NULL; + BOOL bigoffset = False; switch (parms->generic.level) { case RAW_OPEN_T2OPEN: @@ -507,6 +507,42 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope case RAW_OPEN_NTTRANS_CREATE: return smb_raw_nttrans_create_send(tree, parms); + + + case RAW_OPEN_OPENX_READX: + SETUP_REQUEST(SMBopenX, 15, 0); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags); + SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode); + SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs); + SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(6), parms->openxreadx.in.write_time); + SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func); + SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size); + SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout); + SIVAL(req->out.vwv, VWV(13),0); + smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE); + + if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { + bigoffset = True; + } + + smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0); + + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), 0); + SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset); + SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF); + SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt); + SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16); + SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining); + if (bigoffset) { + SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32); + } + break; } if (!smbcli_request_send(req)) { @@ -522,6 +558,8 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope ****************************************************************************/ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) { + NTSTATUS status; + if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { goto failed; @@ -602,6 +640,44 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_NTTRANS_CREATE: return smb_raw_nttrans_create_recv(req, mem_ctx, parms); + + case RAW_OPEN_OPENX_READX: + SMBCLI_CHECK_MIN_WCT(req, 15); + parms->openxreadx.out.fnum = SVAL(req->in.vwv, VWV(2)); + parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3)); + parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport, + req->in.vwv + VWV(4)); + parms->openxreadx.out.size = IVAL(req->in.vwv, VWV(6)); + parms->openxreadx.out.access = SVAL(req->in.vwv, VWV(8)); + parms->openxreadx.out.ftype = SVAL(req->in.vwv, VWV(9)); + parms->openxreadx.out.devstate = SVAL(req->in.vwv, VWV(10)); + parms->openxreadx.out.action = SVAL(req->in.vwv, VWV(11)); + parms->openxreadx.out.unique_fid = IVAL(req->in.vwv, VWV(12)); + if (req->in.wct >= 19) { + parms->openxreadx.out.access_mask = IVAL(req->in.vwv, VWV(15)); + parms->openxreadx.out.unknown = IVAL(req->in.vwv, VWV(17)); + } else { + parms->openxreadx.out.access_mask = 0; + parms->openxreadx.out.unknown = 0; + } + + status = smbcli_chained_advance(req); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + SMBCLI_CHECK_WCT(req, 12); + parms->openxreadx.out.remaining = SVAL(req->in.vwv, VWV(2)); + parms->openxreadx.out.compaction_mode = SVAL(req->in.vwv, VWV(3)); + parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5)); + if (parms->openxreadx.out.nread > + MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) || + !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), + parms->openxreadx.out.nread, + parms->openxreadx.out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + break; } failed: diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 8381c7b2b0..d9fe3fdce0 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -27,7 +27,6 @@ if (!req) return NULL; \ } while (0) - /**************************************************************************** low level read operation (async send) ****************************************************************************/ @@ -74,7 +73,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea bigoffset = True; } SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); - SSVAL(req->out.vwv, VWV(0), 0xFF); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->readx.in.fnum); SIVAL(req->out.vwv, VWV(3), parms->readx.in.offset); @@ -228,7 +227,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr bigoffset = True; } SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); - SSVAL(req->out.vwv, VWV(0), 0xFF); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->writex.in.fnum); SIVAL(req->out.vwv, VWV(3), parms->writex.in.offset); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 5c35618e00..178ccdbf48 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -168,8 +168,8 @@ struct smbcli_request *smbcli_request_setup_session(struct smbcli_session *sessi setup a request for tree based commands */ struct smbcli_request *smbcli_request_setup(struct smbcli_tree *tree, - uint8_t command, - uint_t wct, uint_t buflen) + uint8_t command, + uint_t wct, uint_t buflen) { struct smbcli_request *req; @@ -181,6 +181,7 @@ struct smbcli_request *smbcli_request_setup(struct smbcli_tree *tree, return req; } + /* grow the allocation of the data buffer portion of a reply packet. Note that as this can reallocate the packet buffer this @@ -246,6 +247,64 @@ static void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) } +/* + setup a chained reply in req->out with the given word count and + initial data buffer size. +*/ +NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req, + uint8_t command, + uint_t wct, uint_t buflen) +{ + uint_t new_size = 1 + (wct*2) + 2 + buflen; + + SSVAL(req->out.vwv, VWV(0), command); + SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE); + + smbcli_req_grow_allocation(req, req->out.data_size + new_size); + + req->out.vwv = req->out.buffer + req->out.size + 1; + SCVAL(req->out.vwv, -1, wct); + SSVAL(req->out.vwv, VWV(wct), buflen); + + req->out.size += new_size; + + return NT_STATUS_OK; +} + +/* + aadvance to the next chained reply in a request +*/ +NTSTATUS smbcli_chained_advance(struct smbcli_request *req) +{ + uint8_t *buffer; + + if (CVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE) { + return NT_STATUS_NOT_FOUND; + } + + buffer = req->in.hdr + SVAL(req->in.vwv, VWV(1)); + + if (buffer + 3 > req->in.buffer + req->in.size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + req->in.vwv = buffer + 1; + req->in.wct = CVAL(buffer, 0); + if (buffer + 3 + req->in.wct*2 > req->in.buffer + req->in.size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + req->in.data = req->in.vwv + 2 + req->in.wct * 2; + req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct)); + + if (buffer + 3 + req->in.wct*2 + req->in.data_size > + req->in.buffer + req->in.size) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + return NT_STATUS_OK; +} + + /* send a message */ -- cgit From ecabb2dce5a7e651664ddaf47385cd792fb53347 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Dec 2004 23:59:22 +0000 Subject: r4385: Set the correct target service. Andrew Bartlett (This used to be commit 722f59c7c8d09f548d9325c6051d6687d7aa16c2) --- source4/libcli/ldap/ldap_client.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index a9b20b4ea8..b405b4f417 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -412,6 +412,13 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha goto done; } + status = gensec_set_target_service(conn->gensec, "ldap"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", -- cgit From e3da3b48b16bc6f166034189d2907d6ffa11a07a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 29 Dec 2004 00:03:34 +0000 Subject: r4386: Grr, fix copy-and-paste bug. Andrew Bartlett (This used to be commit 13aa88ed65a8914000cccbecf80929db3df65037) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index b405b4f417..77356cbe70 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -414,7 +414,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha status = gensec_set_target_service(conn->gensec, "ldap"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", nt_errstr(status))); goto done; } -- cgit From 66b8ff22e0a37e217333799a3b42e06c594d3976 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Dec 2004 06:53:15 +0000 Subject: r4388: - allow ACE flags to be specified in security_descriptor_create() - added a test for all combinations of the inheritance ACE flags and how they are propogated to child directories and files (This used to be commit fdb38c8e4b6279137892402b21d2d52e1921e456) --- source4/libcli/security/security_descriptor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 1c63478ab2..ab81a2e5b9 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -223,6 +223,7 @@ BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, SID_AUTHENTICATED_USERS, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, NULL); that would create a sd with one ACE */ @@ -266,7 +267,7 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, } ace->type = va_arg(ap, unsigned int); ace->access_mask = va_arg(ap, unsigned int); - ace->flags = 0; + ace->flags = va_arg(ap, unsigned int); sid = dom_sid_parse_talloc(ace, sidstr); if (sid == NULL) { va_end(ap); -- cgit From 8631bf2bcc4ce79e2448a7463c8ea7a6b7695c4e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 02:27:16 +0000 Subject: r4404: check for SEC_ACE_FLAG_INHERIT_ONLY in the "maximum allowed" logic (This used to be commit e4ee8b776ba164a89afca43de20c166ccbfddb99) --- source4/libcli/security/access_check.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 4c8bb1bd1f..c8a546682a 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -59,6 +59,10 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, for (i = 0;idacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; + if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + continue; + } + if (!sid_active_in_token(&ace->trustee, token)) { continue; } -- cgit From 3450ed666c50ec908557213672ff6b1b4534e9c1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 11:24:49 +0000 Subject: r4413: login failure doesn't warrant a level 1 debug (its filling my logs during torture tests) (This used to be commit b9284c16dc37bf14fceeaa694e82f36a38b0dd93) --- source4/libcli/auth/spnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 5cce0f9e17..4f1dc57e9d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -400,7 +400,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec spnego_state->state_position = SPNEGO_DONE; } else { spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; - DEBUG(1, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); + DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); spnego_state->state_position = SPNEGO_DONE; } -- cgit From b5b1c52a9850de18e756cdd073cf5f44f26882fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Dec 2004 20:34:20 +0000 Subject: r4419: move security_token stuff to the libcli/security/ and debug privileges metze (This used to be commit c981808ed4cfa63c7ba7c4f9190b6b14f74bab40) --- source4/libcli/security/access_check.c | 2 +- source4/libcli/security/dom_sid.c | 2 +- source4/libcli/security/privilege.c | 2 +- source4/libcli/security/security.h | 36 ++++++++ source4/libcli/security/security_descriptor.c | 2 +- source4/libcli/security/security_token.c | 119 +++++++++++++++++++++++++- 6 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 source4/libcli/security/security.h (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index c8a546682a..55749f085e 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "libcli/security/security.h" /* diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 108e2f5500..368278708a 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "libcli/security/security.h" /***************************************************************** Compare the auth portion of two sids. diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index aa01dc2c65..ed98e9ce32 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "libcli/security/security.h" static const struct { diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h new file mode 100644 index 0000000000..b11d10f6f6 --- /dev/null +++ b/source4/libcli/security/security.h @@ -0,0 +1,36 @@ +/* + Unix SMB/CIFS implementation. + + security utility functions + + Copyright (C) Andrew Tridgell 2004 + + 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. +*/ + +#ifndef _SAMBA_SECURITY_H +#define _SAMBA_SECURITY_H + +#include "librpc/gen_ndr/ndr_security.h" + +struct security_token { + struct dom_sid *user_sid; + struct dom_sid *group_sid; + uint32_t num_sids; + struct dom_sid **sids; + uint64_t privilege_mask; +}; + +#endif /* _SAMBA_SECURITY_H */ diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index ab81a2e5b9..509ec1f343 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "libcli/security/security.h" /* return a blank security descriptor (no owners, dacl or sacl) diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index a8ce989de7..7bd533dbee 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "libcli/security/security.h" /* return a blank security token @@ -43,3 +43,120 @@ struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx) return st; } + +/**************************************************************************** + Create the SID list for this user. +****************************************************************************/ +NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, + struct dom_sid *user_sid, struct dom_sid *group_sid, + int n_groupSIDs, struct dom_sid **groupSIDs, + BOOL is_guest, struct security_token **token) +{ + struct security_token *ptoken; + int i; + NTSTATUS status; + + ptoken = security_token_initialise(mem_ctx); + if (ptoken == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ptoken->sids = talloc_array_p(ptoken, struct dom_sid *, n_groupSIDs + 5); + if (!ptoken->sids) { + return NT_STATUS_NO_MEMORY; + } + + ptoken->user_sid = user_sid; + ptoken->group_sid = group_sid; + ptoken->privilege_mask = 0; + + ptoken->sids[0] = user_sid; + ptoken->sids[1] = group_sid; + + /* + * Finally add the "standard" SIDs. + * The only difference between guest and "anonymous" (which we + * don't really support) is the addition of Authenticated_Users. + */ + ptoken->sids[2] = dom_sid_parse_talloc(mem_ctx, SID_WORLD); + ptoken->sids[3] = dom_sid_parse_talloc(mem_ctx, SID_NT_NETWORK); + ptoken->sids[4] = dom_sid_parse_talloc(mem_ctx, + is_guest?SID_BUILTIN_GUESTS: + SID_NT_AUTHENTICATED_USERS); + ptoken->num_sids = 5; + + for (i = 0; i < n_groupSIDs; i++) { + size_t check_sid_idx; + for (check_sid_idx = 1; + check_sid_idx < ptoken->num_sids; + check_sid_idx++) { + if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { + break; + } + } + + if (check_sid_idx == ptoken->num_sids) { + ptoken->sids[ptoken->num_sids++] = groupSIDs[i]; + } + } + + /* setup the privilege mask for this token */ + status = samdb_privilege_setup(ptoken); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ptoken); + return status; + } + + security_token_debug(10, ptoken); + + *token = ptoken; + + return NT_STATUS_OK; +} + +/**************************************************************************** + prints a struct security_token to debug output. +****************************************************************************/ +void security_token_debug(int dbg_lev, const struct security_token *token) +{ + TALLOC_CTX *mem_ctx; + int i; + uint_t privilege; + + if (!token) { + DEBUG(dbg_lev, ("Security token: (NULL)\n")); + return; + } + + mem_ctx = talloc_init("security_token_debug()"); + if (!mem_ctx) { + return; + } + + DEBUG(dbg_lev, ("Security token of user %s\n", + dom_sid_string(mem_ctx, token->user_sid) )); + DEBUGADD(dbg_lev, (" SIDs (%lu):\n", + (unsigned long)token->num_sids)); + for (i = 0; i < token->num_sids; i++) { + DEBUGADD(dbg_lev, (" SID[%3lu]: %s\n", (unsigned long)i, + dom_sid_string(mem_ctx, token->sids[i]))); + } + + DEBUGADD(dbg_lev, (" Privileges (0x%08X%08X):\n", + (uint32_t)((token->privilege_mask & 0xFFFFFFFF00000000LL) >> 32), + (uint32_t)(token->privilege_mask & 0x00000000FFFFFFFFLL))); + + if (token->privilege_mask) { + i = 0; + for (privilege = 0; privilege < 64; privilege++) { + uint64_t mask = sec_privilege_mask(privilege); + + if (token->privilege_mask & mask) { + DEBUGADD(dbg_lev, (" Privilege[%3lu]: %s\n", (unsigned long)i++, + sec_privilege_name(privilege))); + } + } + } + + talloc_destroy(mem_ctx); +} -- cgit From a696713b43a0da1d9a224201d0803f5d4d7e2a99 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 Dec 2004 03:55:37 +0000 Subject: r4429: the owner of a file always gets SEC_STD_DELETE (This used to be commit 81630d3014c8cbd970bc917e3e9aef337fa211cd) --- source4/libcli/security/access_check.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 55749f085e..632b9bdf32 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -50,9 +50,8 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, unsigned i; if (sid_active_in_token(sd->owner_sid, token)) { - granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; - } - if (sec_privilege_check(token, SEC_PRIV_RESTORE)) { + granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE; + } else if (sec_privilege_check(token, SEC_PRIV_RESTORE)) { granted |= SEC_STD_DELETE; } @@ -122,10 +121,10 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, return NT_STATUS_ACCESS_DENIED; } - /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */ - if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) && + /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */ + if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) && sid_active_in_token(sd->owner_sid, token)) { - bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); + bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE); } if ((bits_remaining & SEC_STD_DELETE) && sec_privilege_check(token, SEC_PRIV_RESTORE)) { -- cgit From cb25806d8dcdbf45f6de3b1a86e1c40ee3711fee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Dec 2004 04:45:13 +0000 Subject: r4431: add WERR_NET_NAME_NOT_FOUND metze (This used to be commit 74e65680fa9a6b8f04c6ae62ec1da49659879fb5) --- source4/libcli/util/doserr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index ee2ca25435..aff46bc8bf 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -59,7 +59,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, - { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, + { "WERR_STATUS_MORE_ENTRIES", WERR_STATUS_MORE_ENTRIES }, + { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, { "WERR_DFS_NO_SUCH_SHARE", WERR_DFS_NO_SUCH_SHARE }, { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, -- cgit From 7ac62a7b133cac8915fe10272c1045d7aa4dc7fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Dec 2004 07:21:31 +0000 Subject: r4435: add another error code metze (This used to be commit 02861f63052c48fc85c6694ad8164cc6cc5443d4) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index aff46bc8bf..a9acb7335c 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -61,6 +61,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES", WERR_STATUS_MORE_ENTRIES }, { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, + { "WERR_DEVICE_NOT_SHARED", WERR_DEVICE_NOT_SHARED }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, { "WERR_DFS_NO_SUCH_SHARE", WERR_DFS_NO_SUCH_SHARE }, { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, -- cgit From e6365b8950ccc986d1b4450148f1c837bb1cd2cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 31 Dec 2004 07:43:08 +0000 Subject: r4441: gensec_krb5 update: - Use more of the clikrb5.c wrapper calls - Don't use the session keytab if we kinit for the user. Andrew Bartlett (This used to be commit e15dbee00628475d5e1c1f329a7f9b199bc36360) --- source4/libcli/auth/gensec_krb5.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 9d4a2f6b0e..c01520bb2f 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -234,10 +234,7 @@ static int gensec_krb5_destory(void *ptr) struct gensec_krb5_state *gensec_krb5_state = ptr; if (gensec_krb5_state->ticket.length) { - /* Hmm, early heimdal dooesn't have this - correct call would be krb5_data_free */ -#ifdef HAVE_KRB5_FREE_DATA_CONTENTS - krb5_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); -#endif + kerberos_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); } if (gensec_krb5_state->krb5_ccache) { /* current heimdal - 0.6.3, which we need anyway, fixes segfaults here */ @@ -334,7 +331,10 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_krb5_state = gensec_security->private_data; gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; - /* TODO: This is effecivly a static/global variable... */ + /* TODO: This is effecivly a static/global variable... + + TODO: If the user set a username, we should use an in-memory CCACHE (see below) + */ ret = krb5_cc_default(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_ccache); if (ret) { DEBUG(1,("krb5_cc_default failed (%s)\n", @@ -391,6 +391,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security case ENOENT: { char *password; + char *ccache_string; time_t kdc_time = 0; nt_status = gensec_get_password(gensec_security, gensec_security, @@ -398,9 +399,23 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } + + /* this string should be unique */ + ccache_string = talloc_asprintf(gensec_krb5_state, "MEMORY:%s:%s:%s", + gensec_get_client_principal(gensec_security, gensec_krb5_state), + gensec_get_target_principal(gensec_security, gensec_krb5_state), + generate_random_str(gensec_krb5_state, 16)); + + ret = krb5_cc_resolve(gensec_krb5_state->krb5_context, ccache_string, &gensec_krb5_state->krb5_ccache); + if (ret) { + DEBUG(1,("failed to generate a new krb5 keytab (%s): %s\n", + ccache_string, + error_message(ret))); + return NT_STATUS_INTERNAL_ERROR; + } ret = kerberos_kinit_password_cc(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache, - gensec_get_client_principal(gensec_security, gensec_security), + gensec_get_client_principal(gensec_security, gensec_krb5_state), password, NULL, &kdc_time); /* cope with ticket being in the future due to clock skew */ -- cgit From 75ccd299cd5a5d7d1b76e2d8c6dfa82d6bfe838a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 Dec 2004 08:54:07 +0000 Subject: r4446: attempt to fix the build - andrew, can you check I've done this right? (This used to be commit 9f0bf657aeee86d859742fb4da3a0f806e7060b6) --- source4/libcli/auth/gensec_krb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index c01520bb2f..86e76c5586 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -403,7 +403,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security /* this string should be unique */ ccache_string = talloc_asprintf(gensec_krb5_state, "MEMORY:%s:%s:%s", gensec_get_client_principal(gensec_security, gensec_krb5_state), - gensec_get_target_principal(gensec_security, gensec_krb5_state), + gensec_get_target_principal(gensec_security), generate_random_str(gensec_krb5_state, 16)); ret = krb5_cc_resolve(gensec_krb5_state->krb5_context, ccache_string, &gensec_krb5_state->krb5_ccache); -- cgit From 9a6671cf9529fd7817c5ef266da3d3bea46a88c0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 31 Dec 2004 22:45:11 +0000 Subject: r4459: GENSEC refinements: In developing a GSSAPI plugin for GENSEC, it became clear that the API needed to change: - GSSAPI exposes only a wrap() and unwrap() interface, and determines the location of the signature itself. - The 'have feature' API did not correctly function in the recursive SPNEGO environment. As such, NTLMSSP has been updated to support these methods. The LDAP client and server have been updated to use the new wrap() and unwrap() methods, and now pass the LDAP-* tests in our smbtorture. (Unfortunely I still get valgrind warnings, in the code that was previously unreachable). Andrew Bartlett (This used to be commit 9923c3bc1b5a6e93a5996aadb039bd229e888ac6) --- source4/libcli/auth/gensec.c | 30 +++++++-- source4/libcli/auth/gensec.h | 11 +++- source4/libcli/auth/gensec_krb5.c | 12 ++++ source4/libcli/auth/gensec_ntlmssp.c | 117 ++++++++++++++++++++++++++++++++++- source4/libcli/auth/spnego.c | 53 +++++++++++++++- 5 files changed, 212 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 75086f9281..79cd98a076 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -137,7 +137,6 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense (*gensec_security)->subcontext = False; (*gensec_security)->want_features = 0; - (*gensec_security)->have_features = 0; return NT_STATUS_OK; } @@ -395,6 +394,28 @@ size_t gensec_sig_size(struct gensec_security *gensec_security) return gensec_security->ops->sig_size(gensec_security); } +NTSTATUS gensec_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + if (!gensec_security->ops->wrap) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return gensec_security->ops->wrap(gensec_security, mem_ctx, in, out); +} + +NTSTATUS gensec_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + if (!gensec_security->ops->unwrap) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return gensec_security->ops->unwrap(gensec_security, mem_ctx, in, out); +} + NTSTATUS gensec_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { @@ -459,11 +480,10 @@ void gensec_want_feature(struct gensec_security *gensec_security, BOOL gensec_have_feature(struct gensec_security *gensec_security, uint32 feature) { - if (gensec_security->have_features & feature) { - return True; + if (!gensec_security->ops->have_feature) { + return False; } - - return False; + return gensec_security->ops->have_feature(gensec_security, feature); } /** diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 2b44f0d902..7c462414ff 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -81,9 +81,19 @@ struct gensec_security_ops { uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig); + NTSTATUS (*wrap)(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out); + NTSTATUS (*unwrap)(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out); NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); NTSTATUS (*session_info)(struct gensec_security *gensec_security, struct auth_session_info **session_info); + BOOL (*have_feature)(struct gensec_security *gensec_security, + uint32 feature); }; #define GENSEC_INTERFACE_VERSION 0 @@ -99,7 +109,6 @@ struct gensec_security { enum gensec_role gensec_role; BOOL subcontext; uint32 want_features; - uint32 have_features; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 86e76c5586..f55006c644 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -691,6 +691,16 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security return nt_status; } +static BOOL gensec_krb5_have_feature(struct gensec_security *gensec_security, + uint32 feature) +{ + if (feature & GENSEC_FEATURE_SESSION_KEY) { + return True; + } + + return False; +} + static const struct gensec_security_ops gensec_krb5_security_ops = { .name = "krb5", @@ -701,6 +711,7 @@ static const struct gensec_security_ops gensec_krb5_security_ops = { .update = gensec_krb5_update, .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, + .have_feature = gensec_krb5_have_feature, }; static const struct gensec_security_ops gensec_ms_krb5_security_ops = { @@ -712,6 +723,7 @@ static const struct gensec_security_ops gensec_ms_krb5_security_ops = { .update = gensec_krb5_update, .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, + .have_feature = gensec_krb5_have_feature, }; diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index cf8019402c..10b71ca8b0 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -28,6 +28,7 @@ struct gensec_ntlmssp_state { struct auth_context *auth_context; struct auth_serversupplied_info *server_info; struct ntlmssp_state *ntlmssp_state; + uint32 have_features; }; @@ -171,6 +172,7 @@ static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->ntlmssp_state = NULL; gensec_ntlmssp_state->auth_context = NULL; gensec_ntlmssp_state->server_info = NULL; + gensec_ntlmssp_state->have_features = 0; talloc_set_destructor(gensec_ntlmssp_state, gensec_ntlmssp_destroy); @@ -341,6 +343,99 @@ static size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security) return NTLMSSP_SIG_SIZE; } +static NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + DATA_BLOB sig; + NTSTATUS nt_status; + + if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + + *out = data_blob_talloc(mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE); + memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length); + + nt_status = ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, + out->data + NTLMSSP_SIG_SIZE, + out->length - NTLMSSP_SIG_SIZE, + out->data + NTLMSSP_SIG_SIZE, + out->length - NTLMSSP_SIG_SIZE, + &sig); + + if (NT_STATUS_IS_OK(nt_status)) { + memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE); + } + return nt_status; + + } else if ((gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) + || (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + + *out = data_blob_talloc(mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE); + memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length); + + nt_status = ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, + out->data + NTLMSSP_SIG_SIZE, + out->length - NTLMSSP_SIG_SIZE, + out->data + NTLMSSP_SIG_SIZE, + out->length - NTLMSSP_SIG_SIZE, + &sig); + + if (NT_STATUS_IS_OK(nt_status)) { + memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE); + } + return nt_status; + + } else { + *out = *in; + return NT_STATUS_OK; + } +} + + +static NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + DATA_BLOB sig; + + if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + if (in->length < NTLMSSP_SIG_SIZE) { + return NT_STATUS_INVALID_PARAMETER; + } + sig.data = in->data; + sig.length = NTLMSSP_SIG_SIZE; + + *out = data_blob_talloc(mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); + + return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, + out->data, out->length, + out->data, out->length, + &sig); + + } else if ((gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) + || (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + if (in->length < NTLMSSP_SIG_SIZE) { + return NT_STATUS_INVALID_PARAMETER; + } + sig.data = in->data; + sig.length = NTLMSSP_SIG_SIZE; + + *out = data_blob_talloc(mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); + + return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, + out->data, out->length, + out->data, out->length, + &sig); + } else { + *out = *in; + return NT_STATUS_OK; + } +} + static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { @@ -371,17 +466,19 @@ static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, T if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { return status; } + + gensec_ntlmssp_state->have_features = 0; if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { - gensec_security->have_features |= GENSEC_FEATURE_SIGN; + gensec_ntlmssp_state->have_features |= GENSEC_FEATURE_SIGN; } if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { - gensec_security->have_features |= GENSEC_FEATURE_SEAL; + gensec_ntlmssp_state->have_features |= GENSEC_FEATURE_SEAL; } if (gensec_ntlmssp_state->ntlmssp_state->session_key.data) { - gensec_security->have_features |= GENSEC_FEATURE_SESSION_KEY; + gensec_ntlmssp_state->have_features |= GENSEC_FEATURE_SESSION_KEY; } return status; @@ -418,6 +515,17 @@ static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_secur return NT_STATUS_OK; } +static BOOL gensec_ntlmssp_have_feature(struct gensec_security *gensec_security, + uint32 feature) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + if (gensec_ntlmssp_state->have_features & feature) { + return True; + } + + return False; +} + static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .name = "ntlmssp", .sasl_name = "NTLM", @@ -431,8 +539,11 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .sign_packet = gensec_ntlmssp_sign_packet, .check_packet = gensec_ntlmssp_check_packet, .unseal_packet = gensec_ntlmssp_unseal_packet, + .wrap = gensec_ntlmssp_wrap, + .unwrap = gensec_ntlmssp_unwrap, .session_key = gensec_ntlmssp_session_key, .session_info = gensec_ntlmssp_session_info, + .have_feature = gensec_ntlmssp_have_feature }; diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 4f1dc57e9d..f13bbc11b4 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -162,6 +162,40 @@ static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_securit sig); } +static NTSTATUS gensec_spnego_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct spnego_state *spnego_state = gensec_security->private_data; + + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + DEBUG(1, ("gensec_spnego_wrap: wrong state for wrap\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_wrap(spnego_state->sub_sec_security, + mem_ctx, in, out); +} + +static NTSTATUS gensec_spnego_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct spnego_state *spnego_state = gensec_security->private_data; + + if (spnego_state->state_position != SPNEGO_DONE + && spnego_state->state_position != SPNEGO_FALLBACK) { + DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_unwrap(spnego_state->sub_sec_security, + mem_ctx, in, out); +} + static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -357,11 +391,11 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; spnego_state->state_position = SPNEGO_CLIENT_TARG; return nt_status; - } + } talloc_free(spnego_state->sub_sec_security); spnego_state->sub_sec_security = NULL; - DEBUG(1, ("Failed to setup SPNEGO netTokenInit request\n")); + DEBUG(1, ("Failed to setup SPNEGO negTokenInit request: %s\n", nt_errstr(nt_status))); return NT_STATUS_INVALID_PARAMETER; } @@ -698,6 +732,18 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } +static BOOL gensec_spnego_have_feature(struct gensec_security *gensec_security, + uint32 feature) +{ + struct spnego_state *spnego_state = gensec_security->private_data; + if (!spnego_state->sub_sec_security) { + return False; + } + + return gensec_have_feature(spnego_state->sub_sec_security, + feature); +} + static const struct gensec_security_ops gensec_spnego_security_ops = { .name = "spnego", .sasl_name = "GSS-SPNEGO", @@ -711,8 +757,11 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .sig_size = gensec_spnego_sig_size, .check_packet = gensec_spnego_check_packet, .unseal_packet = gensec_spnego_unseal_packet, + .wrap = gensec_spnego_wrap, + .unwrap = gensec_spnego_unwrap, .session_key = gensec_spnego_session_key, .session_info = gensec_spnego_session_info, + .have_feature = gensec_spnego_have_feature }; NTSTATUS gensec_spnego_init(void) -- cgit From 740ee4a8977512c03800ef88603cf65fd044443b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Jan 2005 00:19:08 +0000 Subject: r4460: Add a new GENSEC module: gensec_gssapi (disabled by default, set parametric option: gensec:gssapi=yes to enable). This module backs directly onto GSSAPI, and allows us to sign and seal GSSAPI/Krb5 connections in particular. This avoids me reinventing the entire GSSAPI wheel. Currently a lot of things are left as default - we will soon start specifiying OIDs as well as passwords (it uses the keytab only at the moment). Tested with our LDAP-* torture tests against Win2k3. My hope is to use this module to access the new SPNEGO implementation in Heimdal, to avoid having to standards-verify our own. Andrew Bartlett (This used to be commit 14b650c85db14a9bf97e24682b2643b63c51ff35) --- source4/libcli/auth/gensec.mk | 10 ++ source4/libcli/auth/gensec_gssapi.c | 336 ++++++++++++++++++++++++++++++++++++ source4/libcli/auth/spnego.c | 28 ++- source4/libcli/ldap/ldap_client.c | 10 +- 4 files changed, 375 insertions(+), 9 deletions(-) create mode 100644 source4/libcli/auth/gensec_gssapi.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index 66abfd10b7..b66006ce4f 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -23,6 +23,16 @@ REQUIRED_SUBSYSTEMS = NDR_KRB5PAC EXT_LIB_KRB5 # End MODULE gensec_krb5 ################################################ +################################################ +# Start MODULE gensec_gssapi +[MODULE::gensec_gssapi] +SUBSYSTEM = GENSEC +INIT_FUNCTION = gensec_gssapi_init +INIT_OBJ_FILES = libcli/auth/gensec_gssapi.o +REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 +# End MODULE gensec_gssapi +################################################ + ################################################ # Start MODULE gensec_spnego [MODULE::gensec_spnego] diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c new file mode 100644 index 0000000000..c41c3fb2bc --- /dev/null +++ b/source4/libcli/auth/gensec_gssapi.c @@ -0,0 +1,336 @@ +/* + Unix SMB/CIFS implementation. + + Kerberos backend for GENSEC + + Copyright (C) Andrew Bartlett 2004 + + 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 "system/kerberos.h" +#include "system/time.h" +#include "libcli/auth/kerberos.h" +#include "auth/auth.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +struct gensec_gssapi_state { + gss_ctx_id_t gssapi_context; + struct gss_channel_bindings_struct *input_chan_bindings; + gss_name_t server_name; + gss_name_t client_name; + int want_flags, got_flags; +}; +static int gensec_gssapi_destory(void *ptr) +{ + struct gensec_gssapi_state *gensec_gssapi_state = ptr; + OM_uint32 maj_stat, min_stat; + + if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { + maj_stat = gss_delete_sec_context (&min_stat, + &gensec_gssapi_state->gssapi_context, + GSS_C_NO_BUFFER); + } + + if (gensec_gssapi_state->server_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->server_name); + } + if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); + } + return 0; +} + +static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) +{ + struct gensec_gssapi_state *gensec_gssapi_state; + + gensec_gssapi_state = talloc_p(gensec_security, struct gensec_gssapi_state); + if (!gensec_gssapi_state) { + return NT_STATUS_NO_MEMORY; + } + + gensec_security->private_data = gensec_gssapi_state; + + gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT; + gensec_gssapi_state->server_name = GSS_C_NO_NAME; + gensec_gssapi_state->client_name = GSS_C_NO_NAME; + + talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); + + /* TODO: Fill in channel bindings */ + gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; + + gensec_gssapi_state->want_flags = 0; + gensec_gssapi_state->got_flags = 0; + + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { + /* GSSAPI won't give us the session keys */ + return NT_STATUS_INVALID_PARAMETER; + } + if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { + gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; + } + if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { + gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; + } + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + struct gensec_gssapi_state *gensec_gssapi_state; + + nt_status = gensec_gssapi_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_gssapi_state = gensec_security->private_data; + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) +{ + struct gensec_gssapi_state *gensec_gssapi_state; + NTSTATUS nt_status; + gss_buffer_desc name_token; + OM_uint32 maj_stat, min_stat; + + nt_status = gensec_gssapi_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_gssapi_state = gensec_security->private_data; + + name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), + gensec_get_target_hostname(gensec_security)); + DEBUG(0, ("name: %s\n", (char *)name_token.value)); + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &gensec_gssapi_state->server_name); + + + if (maj_stat) { + return NT_STATUS_UNSUCCESSFUL; + } + return NT_STATUS_OK; +} + + + +/** + * Next state function for the GSSAPI GENSEC mechanism + * + * @param gensec_gssapi_state GSSAPI State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + OM_uint32 maj_stat, min_stat; + OM_uint32 min_stat2; + gss_buffer_desc input_token, output_token; + + input_token.length = in.length; + input_token.value = in.data; + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + { + maj_stat = gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->server_name, + GSS_C_NO_OID, + gensec_gssapi_state->want_flags, + 0, + gensec_gssapi_state->input_chan_bindings, + &input_token, + NULL, + &output_token, + &gensec_gssapi_state->got_flags, /* ret flags */ + NULL); + break; + } + case GENSEC_SERVER: + { + maj_stat = gss_accept_sec_context(&min_stat, + gensec_gssapi_state->gssapi_context, + GSS_C_NO_CREDENTIAL, + &input_token, + gensec_gssapi_state->input_chan_bindings, + &gensec_gssapi_state->client_name, + NULL /* mech oid */, + &output_token, + &gensec_gssapi_state->got_flags, + NULL, + NULL); + break; + } + default: + return NT_STATUS_INVALID_PARAMETER; + + } + + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat2, &output_token); + + if (maj_stat == GSS_S_COMPLETE) { + return NT_STATUS_OK; + } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + gss_buffer_desc msg1, msg2; + OM_uint32 msg_ctx = 0; + + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + DEBUG(1, ("gensec_gssapi_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); + gss_release_buffer(&min_stat2, &msg1); + gss_release_buffer(&min_stat2, &msg2); + + return nt_status; + } + +} + +static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + input_token.length = in->length; + input_token.value = in->data; + + maj_stat = gss_wrap(&min_stat, + gensec_gssapi_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + input_token.length = in->length; + input_token.value = in->data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gssapi_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, + uint32 feature) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + if (feature & GENSEC_FEATURE_SIGN) { + return gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG; + } + if (feature & GENSEC_FEATURE_SEAL) { + return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG; + } + return False; +} + +static const struct gensec_security_ops gensec_gssapi_security_ops = { + .name = "gssapi", + .oid = GENSEC_OID_KERBEROS5, + .client_start = gensec_gssapi_client_start, + .server_start = gensec_gssapi_server_start, + .update = gensec_gssapi_update, + .wrap = gensec_gssapi_wrap, + .unwrap = gensec_gssapi_unwrap, + .have_feature = gensec_gssapi_have_feature + +}; + +NTSTATUS gensec_gssapi_init(void) +{ + NTSTATUS ret; + + ret = gensec_register(&gensec_gssapi_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_gssapi_security_ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index f13bbc11b4..8b4be6eb75 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -42,6 +42,7 @@ struct spnego_state { enum spnego_message_type expected_packet; enum spnego_state_position state_position; struct gensec_security *sub_sec_security; + BOOL no_response_expected; }; @@ -57,6 +58,7 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_CLIENT_START; spnego_state->sub_sec_security = NULL; + spnego_state->no_response_expected = False; gensec_security->private_data = spnego_state; return NT_STATUS_OK; @@ -74,6 +76,7 @@ static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_securi spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_SERVER_START; spnego_state->sub_sec_security = NULL; + spnego_state->no_response_expected = False; gensec_security->private_data = spnego_state; return NT_STATUS_OK; @@ -374,7 +377,7 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec } nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, in, &unwrapped_out); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_IS_OK(nt_status) || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { struct spnego_data spnego_out; spnego_out.type = SPNEGO_NEG_TOKEN_INIT; spnego_out.negTokenInit.mechTypes = mechTypes; @@ -390,7 +393,12 @@ static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec /* set next state */ spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; spnego_state->state_position = SPNEGO_CLIENT_TARG; - return nt_status; + + if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->no_response_expected = True; + } + + return NT_STATUS_MORE_PROCESSING_REQUIRED; } talloc_free(spnego_state->sub_sec_security); spnego_state->sub_sec_security = NULL; @@ -601,6 +609,10 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA /* set next state */ spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; spnego_state->state_position = SPNEGO_CLIENT_TARG; + + if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->no_response_expected = True; + } return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -672,10 +684,14 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_ACCESS_DENIED; } - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); + if (spnego_state->no_response_expected) { + nt_status = NT_STATUS_OK; + } else { + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + } if (NT_STATUS_IS_OK(nt_status) diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 77356cbe70..9ca9e4b5c4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -459,9 +459,13 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha break; } - status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.secblob, - &output); + if (!NT_STATUS_IS_OK(status)) { + status = gensec_update(conn->gensec, mem_ctx, + response->r.BindResponse.SASL.secblob, + &output); + } else { + output.length = 0; + } talloc_free(response); } -- cgit From 3b182e2bf4024e789645e78ec5847771faaffd6f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 2 Jan 2005 03:10:28 +0000 Subject: r4470: Try not to have GSSAPI built unless we detected krb5. We should split these tests out a bit, but for now it's an indicator we can use. Andrew Bartlett (This used to be commit 2b0605dbaee18da4ebb676fc292b324d21805ef7) --- source4/libcli/auth/gensec.m4 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 9b814014ca..9e9b04a695 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -1,6 +1,8 @@ SMB_MODULE_DEFAULT(gensec_krb5, NOT) +SMB_MODULE_DEFAULT(gensec_gssapi, NOT) if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then /* enable this when krb5 is fully working */ SMB_MODULE_DEFAULT(gensec_krb5, STATIC) + SMB_MODULE_DEFAULT(gensec_gssapi, STATIC) fi -- cgit From 0dcd4645961c5d672b9526538eaddf0503db793a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 2 Jan 2005 23:53:14 +0000 Subject: r4494: Allow gensec_gssapi to use the SPNEGO mech provided by Heimdal (off by default at this point), and include the GSSAPI OIDs in our source, per advice by lha that this is easier than getting the includes right. Andrew Bartlett (This used to be commit 9ff8b2b4d12d364084df5c95a752ce2a0546053d) --- source4/libcli/auth/gensec_gssapi.c | 51 ++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index c41c3fb2bc..432d59ef24 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -36,6 +36,7 @@ struct gensec_gssapi_state { gss_name_t server_name; gss_name_t client_name; int want_flags, got_flags; + const gss_OID_desc *gss_oid; }; static int gensec_gssapi_destory(void *ptr) { @@ -91,6 +92,19 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; } + if (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) { + static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = + {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; + + gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; + } else if (strcmp(gensec_security->ops->oid, GENSEC_OID_SPNEGO) == 0) { + static const gss_OID_desc gensec_gss_spnego_mechanism_oid_desc = + {6, (void *)discard_const_p(char, "\x2b\x06\x01\x05\x05\x02")}; + gensec_gssapi_state->gss_oid = &gensec_gss_spnego_mechanism_oid_desc; + } else { + return NT_STATUS_INVALID_PARAMETER; + } + return NT_STATUS_OK; } @@ -162,7 +176,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, OM_uint32 maj_stat, min_stat; OM_uint32 min_stat2; gss_buffer_desc input_token, output_token; - + gss_OID gss_oid_p; input_token.length = in.length; input_token.value = in.data; @@ -173,7 +187,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, GSS_C_NO_CREDENTIAL, &gensec_gssapi_state->gssapi_context, gensec_gssapi_state->server_name, - GSS_C_NO_OID, + discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), gensec_gssapi_state->want_flags, 0, gensec_gssapi_state->input_chan_bindings, @@ -192,11 +206,12 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &input_token, gensec_gssapi_state->input_chan_bindings, &gensec_gssapi_state->client_name, - NULL /* mech oid */, + &gss_oid_p, &output_token, &gensec_gssapi_state->got_flags, NULL, NULL); + gensec_gssapi_state->gss_oid = gss_oid_p; break; } default: @@ -309,8 +324,10 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, return False; } -static const struct gensec_security_ops gensec_gssapi_security_ops = { - .name = "gssapi", +/* As a server, this could in theory accept any GSSAPI mech */ +static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { + .name = "gssapi_krb5", + .sasl_name = "GSSAPI", .oid = GENSEC_OID_KERBEROS5, .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, @@ -321,14 +338,34 @@ static const struct gensec_security_ops gensec_gssapi_security_ops = { }; +static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { + .name = "gssapi_spnego", + .sasl_name = "GSS-SPNEGO", + .oid = GENSEC_OID_SPNEGO, + .client_start = gensec_gssapi_client_start, + .server_start = gensec_gssapi_server_start, + .update = gensec_gssapi_update, + .wrap = gensec_gssapi_wrap, + .unwrap = gensec_gssapi_unwrap, + .have_feature = gensec_gssapi_have_feature + +}; + NTSTATUS gensec_gssapi_init(void) { NTSTATUS ret; - ret = gensec_register(&gensec_gssapi_security_ops); + ret = gensec_register(&gensec_gssapi_krb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_gssapi_krb5_security_ops.name)); + return ret; + } + + ret = gensec_register(&gensec_gssapi_spnego_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_gssapi_security_ops.name)); + gensec_gssapi_spnego_security_ops.name)); return ret; } -- cgit From 8eb981c90a6094b15d4b71cc14fee4f23c713cf8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Jan 2005 06:23:02 +0000 Subject: r4499: Almost make our Samba4 server pass the RPC-SAMLOGON torture test. I just need to fix a couple of NTLMv2 issues before we can fully pass, and put this in test_rpc.sh, as a 'should pass' test. Andrew Bartlett (This used to be commit 4b52409e385366d87724bb79f4fad4803e8ecfec) --- source4/libcli/auth/credentials.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index a61660d776..8cae71180c 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -273,6 +273,7 @@ void creds_server_init(struct creds_CredentialState *creds, } *initial_credential = creds->server; + creds->negotiate_flags = negotiate_flags; } /* @@ -290,10 +291,14 @@ BOOL creds_server_check(const struct creds_CredentialState *creds, return True; } -BOOL creds_server_step_check(struct creds_CredentialState *creds, +NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, struct netr_Authenticator *received_authenticator, struct netr_Authenticator *return_authenticator) { + if (!received_authenticator || !return_authenticator) { + return NT_STATUS_INVALID_PARAMETER; + } + /* TODO: this may allow the a replay attack on a non-signed connection. Should we check that this is increasing? */ creds->sequence = received_authenticator->timestamp; @@ -301,9 +306,9 @@ BOOL creds_server_step_check(struct creds_CredentialState *creds, if (creds_server_check(creds, &received_authenticator->cred)) { return_authenticator->cred = creds->server; return_authenticator->timestamp = creds->sequence; - return True; + return NT_STATUS_OK; } else { ZERO_STRUCTP(return_authenticator); - return False; + return NT_STATUS_ACCESS_DENIED; } } -- cgit From c8ba520c5a66f2d4a4d95baf366a2194a752e9c5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Jan 2005 07:08:14 +0000 Subject: r4500: Allow GENSEC modules to be disabled by setting a flag on their module definition, not by hardcoded reference in loadparm.c Andrew Bartlett (This used to be commit 43558eaf7604d2bb0187e0d1ba0686935a965ad7) --- source4/libcli/auth/gensec.c | 2 +- source4/libcli/auth/gensec.h | 1 + source4/libcli/auth/gensec_gssapi.c | 6 ++++-- source4/libcli/auth/gensec_krb5.c | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 79cd98a076..c052f61c8c 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -778,7 +778,7 @@ NTSTATUS gensec_register(const void *_ops) { const struct gensec_security_ops *ops = _ops; - if (!lp_parm_bool(-1, "gensec", ops->name, True)) { + if (!lp_parm_bool(-1, "gensec", ops->name, !ops->disabled_by_default)) { DEBUG(2,("gensec subsystem %s is disabled\n", ops->name)); return NT_STATUS_OK; } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 7c462414ff..8ee6abcd44 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -94,6 +94,7 @@ struct gensec_security_ops { struct auth_session_info **session_info); BOOL (*have_feature)(struct gensec_security *gensec_security, uint32 feature); + BOOL disabled_by_default; }; #define GENSEC_INTERFACE_VERSION 0 diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index 432d59ef24..f30d3c5c62 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -334,7 +334,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .update = gensec_gssapi_update, .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, - .have_feature = gensec_gssapi_have_feature + .have_feature = gensec_gssapi_have_feature, + .disabled_by_default = True }; @@ -347,7 +348,8 @@ static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { .update = gensec_gssapi_update, .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, - .have_feature = gensec_gssapi_have_feature + .have_feature = gensec_gssapi_have_feature, + .disabled_by_default = True }; diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index f55006c644..ce51cef894 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -712,6 +712,7 @@ static const struct gensec_security_ops gensec_krb5_security_ops = { .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, .have_feature = gensec_krb5_have_feature, + .disabled_by_default = True }; static const struct gensec_security_ops gensec_ms_krb5_security_ops = { @@ -724,6 +725,7 @@ static const struct gensec_security_ops gensec_ms_krb5_security_ops = { .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, .have_feature = gensec_krb5_have_feature, + .disabled_by_default = True }; -- cgit From 5e94b016f06355289eabcd163678127988421a52 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Jan 2005 09:00:37 +0000 Subject: r4504: Setting .enabled = True on modules we know are good (and we want on be default) seems neater. Andrew Bartlett (This used to be commit 18850c66b7c8ac5e8caf08151dbb9b72cf93230f) --- source4/libcli/auth/gensec.c | 2 +- source4/libcli/auth/gensec.h | 2 +- source4/libcli/auth/gensec_gssapi.c | 5 ++--- source4/libcli/auth/gensec_krb5.c | 4 ++-- source4/libcli/auth/gensec_ntlmssp.c | 3 ++- source4/libcli/auth/spnego.c | 3 ++- 6 files changed, 10 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index c052f61c8c..4a328d6d1c 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -778,7 +778,7 @@ NTSTATUS gensec_register(const void *_ops) { const struct gensec_security_ops *ops = _ops; - if (!lp_parm_bool(-1, "gensec", ops->name, !ops->disabled_by_default)) { + if (!lp_parm_bool(-1, "gensec", ops->name, ops->enabled)) { DEBUG(2,("gensec subsystem %s is disabled\n", ops->name)); return NT_STATUS_OK; } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 8ee6abcd44..434f3fdb4d 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -94,7 +94,7 @@ struct gensec_security_ops { struct auth_session_info **session_info); BOOL (*have_feature)(struct gensec_security *gensec_security, uint32 feature); - BOOL disabled_by_default; + BOOL enabled; }; #define GENSEC_INTERFACE_VERSION 0 diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index f30d3c5c62..690d36e798 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -335,7 +335,7 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .disabled_by_default = True + .enabled = False }; @@ -349,8 +349,7 @@ static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .disabled_by_default = True - + .enabled = False }; NTSTATUS gensec_gssapi_init(void) diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index ce51cef894..0ab32318aa 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -712,7 +712,7 @@ static const struct gensec_security_ops gensec_krb5_security_ops = { .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, .have_feature = gensec_krb5_have_feature, - .disabled_by_default = True + .enabled = False }; static const struct gensec_security_ops gensec_ms_krb5_security_ops = { @@ -725,7 +725,7 @@ static const struct gensec_security_ops gensec_ms_krb5_security_ops = { .session_key = gensec_krb5_session_key, .session_info = gensec_krb5_session_info, .have_feature = gensec_krb5_have_feature, - .disabled_by_default = True + .enabled = False }; diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 10b71ca8b0..53d0104259 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -543,7 +543,8 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .unwrap = gensec_ntlmssp_unwrap, .session_key = gensec_ntlmssp_session_key, .session_info = gensec_ntlmssp_session_info, - .have_feature = gensec_ntlmssp_have_feature + .have_feature = gensec_ntlmssp_have_feature, + .enabled = True }; diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 8b4be6eb75..31dd5aa47d 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -777,7 +777,8 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .unwrap = gensec_spnego_unwrap, .session_key = gensec_spnego_session_key, .session_info = gensec_spnego_session_info, - .have_feature = gensec_spnego_have_feature + .have_feature = gensec_spnego_have_feature, + .enabled = True }; NTSTATUS gensec_spnego_init(void) -- cgit From 5e9a136908fdc2955f8554fee83fff4c93ec998a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 5 Jan 2005 03:21:45 +0000 Subject: r4530: Start adding a bit of Doxygen compatible documentation comments to GENSEC. Andrew Bartlett (This used to be commit c7acea9d5a097b51693f41de93274b857f7be0e3) --- source4/libcli/auth/gensec.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 4a328d6d1c..fb638a9000 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -115,8 +115,11 @@ const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) return oid_list; } -/* - note that memory context is the parent context to hang this gensec context off. It may be NULL. +/** + Start the GENSEC system, returning a context pointer. + @param mem_ctx The parent TALLOC memory context. + @param gensec_security Returned GENSEC context pointer. + @note The mem_ctx is only a parent and may be NULL. */ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { @@ -142,7 +145,9 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense /** * Start a GENSEC subcontext, with a copy of the properties of the parent - * + * @param mem_ctx The parent TALLOC memory context. + * @param parent The parent GENSEC context + * @param gensec_security Returned GENSEC context pointer. * @note Used by SPENGO in particular, for the actual implementation mechanism */ @@ -164,6 +169,12 @@ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/** + Start the GENSEC system, in client mode, returning a context pointer. + @param mem_ctx The parent TALLOC memory context. + @param gensec_security Returned GENSEC context pointer. + @note The mem_ctx is only a parent and may be NULL. +*/ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { NTSTATUS status; @@ -179,6 +190,12 @@ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense return status; } +/** + Start the GENSEC system, in server mode, returning a context pointer. + @param mem_ctx The parent TALLOC memory context. + @param gensec_security Returned GENSEC context pointer. + @note The mem_ctx is only a parent and may be NULL. +*/ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { NTSTATUS status; @@ -222,6 +239,9 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) /** * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number + * @param gensec_security GENSEC context pointer. + * @param auth_type DCERPC auth type + * @param auth_level DCERPC auth level */ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, -- cgit From e1944a3d6d2d4e8772c17891486bbcb992c7096a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 5 Jan 2005 10:21:08 +0000 Subject: r4531: Include the OID locally, as it seems to be hard to get the includes right. Andrew Bartlett (This used to be commit a742ea1e1221058ae6a99e317fbf18c80bc49aed) --- source4/libcli/auth/gensec_gssapi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index 690d36e798..0b5bd01194 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -130,6 +130,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gss_buffer_desc name_token; OM_uint32 maj_stat, min_stat; + gss_OID_desc hostbased = {10, + (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12" + "\x01\x02\x01\x04")}; + nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -144,7 +148,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi maj_stat = gss_import_name (&min_stat, &name_token, - GSS_C_NT_HOSTBASED_SERVICE, + &hostbased, &gensec_gssapi_state->server_name); -- cgit From cc55aef7c116d03ba2817625b0ba9edb378525e3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jan 2005 02:32:43 +0000 Subject: r4547: - added talloc_new(ctx) macro that is a neater form of the common talloc(ctx, 0) call. - cleaned up some talloc usage in various files I'd like to get to the point that we have no calls to talloc(), at which point we will rename talloc_p() to talloc(), to encourage everyone to use the typesafe functions. (This used to be commit e6c81d7c9f8a6938947d3c1c8a971a0d6d50b67a) --- source4/libcli/clilist.c | 4 ++-- source4/libcli/raw/rawfile.c | 2 +- source4/libcli/util/clilsa.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 8b05b98e0e..ec103dbfa4 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -119,7 +119,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.dirlist_len = 0; state.total_received = 0; - state.dirlist = talloc(state.mem_ctx, 0); + state.dirlist = talloc_new(state.mem_ctx); mask = talloc_strdup(state.mem_ctx, Mask); if (level == RAW_SEARCH_GENERIC) { @@ -263,7 +263,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.dirlist_len = 0; state.total_received = 0; - state.dirlist = talloc(state.mem_ctx, 0); + state.dirlist = talloc_new(state.mem_ctx); mask = talloc_strdup(state.mem_ctx, Mask); while (1) { diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 11be8ffba7..e0b54cacc3 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -259,7 +259,7 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr { struct smb_nttrans nt; uint8_t *params; - TALLOC_CTX *mem_ctx = talloc(tree, 0); + TALLOC_CTX *mem_ctx = talloc_new(tree); uint16_t fname_len; DATA_BLOB sd_blob, ea_blob; struct smbcli_request *req; diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 4204adcc07..843d45607b 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -153,7 +153,7 @@ NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli, { struct lsa_RightSet rights; NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc(cli, 0); + TALLOC_CTX *mem_ctx = talloc_new(cli); struct dom_sid *sid; unsigned i; @@ -195,7 +195,7 @@ NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli, uint32_t count = 1; NTSTATUS status; struct dom_sid *sid; - TALLOC_CTX *mem_ctx2 = talloc(mem_ctx, 0); + TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx); status = smblsa_connect(cli); if (!NT_STATUS_IS_OK(status)) { @@ -255,7 +255,7 @@ NTSTATUS smblsa_lookup_name(struct smbcli_state *cli, uint32_t count = 1; NTSTATUS status; struct dom_sid *sid; - TALLOC_CTX *mem_ctx2 = talloc(mem_ctx, 0); + TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx); uint32_t rid; status = smblsa_connect(cli); -- cgit From ddc10d4d37984246a6547e34a32d629c689c40d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jan 2005 03:06:58 +0000 Subject: r4549: got rid of a lot more uses of plain talloc(), instead using talloc_size() or talloc_array_p() where appropriate. also fixed a memory leak in pvfs_copy_file() (failed to free a memory context) (This used to be commit 89b74b53546e1570b11b3702f40bee58aed8c503) --- source4/libcli/auth/ntlmssp.c | 2 +- source4/libcli/ldap/ldap.c | 8 ++++---- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/raw/clitransport.c | 4 ++-- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/raw/rawtrans.c | 8 ++++---- source4/libcli/security/dom_sid.c | 2 +- source4/libcli/util/asn1.c | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 6ece0f6df6..7f4a86e274 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -109,7 +109,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) { - uint8_t *chal = talloc(ntlmssp_state, 8); + uint8_t *chal = talloc_size(ntlmssp_state, 8); generate_random_buffer(chal, 8); return chal; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 076d088ee2..b2a6bd957a 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -660,7 +660,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob) { - char *result = talloc(mem_ctx, blob.length+1); + char *result = talloc_size(mem_ctx, blob.length+1); memcpy(result, blob.data, blob.length); result[blob.length] = '\0'; return result; @@ -859,7 +859,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen != 0) { - char *pw = talloc(msg->mem_ctx, pwlen+1); + char *pw = talloc_size(msg->mem_ctx, pwlen+1); asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -1040,7 +1040,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); - dn = talloc(msg->mem_ctx, len+1); + dn = talloc_size(msg->mem_ctx, len+1); if (dn == NULL) break; asn1_read(data, dn, len); @@ -1073,7 +1073,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); - newsup = talloc(msg->mem_ctx, len+1); + newsup = talloc_size(msg->mem_ctx, len+1); if (newsup == NULL) break; asn1_read(data, newsup, len); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 9ca9e4b5c4..84fd0f1d64 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -649,7 +649,7 @@ BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, if (!ldap_find_single_value(msg, attr, &blob)) return False; - *value = talloc(mem_ctx, blob.length+1); + *value = talloc_size(mem_ctx, blob.length+1); if (*value == NULL) return False; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index dde77eaeea..63ff1e4409 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -462,8 +462,8 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) if (transport->recv_buffer.received == NBT_HDR_SIZE) { /* we've got a full header */ transport->recv_buffer.req_size = smb_len(transport->recv_buffer.header) + NBT_HDR_SIZE; - transport->recv_buffer.buffer = talloc(transport, - NBT_HDR_SIZE+transport->recv_buffer.req_size); + transport->recv_buffer.buffer = talloc_size(transport, + NBT_HDR_SIZE+transport->recv_buffer.req_size); if (transport->recv_buffer.buffer == NULL) { smbcli_transport_dead(transport); return; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 178ccdbf48..b74f066ef4 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -83,7 +83,7 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran /* over allocate by a small amount */ req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; - req->out.buffer = talloc(req, req->out.allocated); + req->out.buffer = talloc_size(req, req->out.allocated); if (!req->out.buffer) { return NULL; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 95555c3a82..0ccecdc2d4 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -87,7 +87,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, /* allocate it */ if (total_data != 0) { - tdata = talloc(mem_ctx, total_data); + tdata = talloc_size(mem_ctx, total_data); if (!tdata) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); req->status = NT_STATUS_NO_MEMORY; @@ -97,7 +97,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, } if (total_param != 0) { - tparam = talloc(mem_ctx, total_param); + tparam = talloc_size(mem_ctx, total_param); if (!tparam) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); req->status = NT_STATUS_NO_MEMORY; @@ -111,7 +111,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, if (parms->out.setup_count > 0) { int i; - parms->out.setup = talloc(mem_ctx, 2 * parms->out.setup_count); + parms->out.setup = talloc_array(mem_ctx, 2, parms->out.setup_count, "setup"); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; return smbcli_request_destroy(req); @@ -439,7 +439,7 @@ NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req, if (parms->out.setup_count > 0) { int i; - parms->out.setup = talloc(mem_ctx, 2 * parms->out.setup_count); + parms->out.setup = talloc_array(mem_ctx, 2, parms->out.setup_count, "setup"); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; return smbcli_request_destroy(req); diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 368278708a..d76f9fa239 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -98,7 +98,7 @@ char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) } maxlen = sid->num_auths * 11 + 25; - ret = talloc(mem_ctx, maxlen); + ret = talloc_size(mem_ctx, maxlen); if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); ia = (sid->id_auth[5]) + diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 2bf29f9161..52ba0225c9 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -424,7 +424,7 @@ BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, len = b; } - buf = talloc(NULL, len); + buf = talloc_size(NULL, len); if (buf == NULL) return False; @@ -548,7 +548,7 @@ BOOL asn1_read_GeneralString(struct asn1_data *data, char **s) data->has_error = True; return False; } - *s = talloc(NULL, len+1); + *s = talloc_size(NULL, len+1); if (! *s) { data->has_error = True; return False; -- cgit From 07731930577152b1e8bcec59fd5ee6be443f0c02 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 6 Jan 2005 12:10:54 +0000 Subject: r4565: Make the order of the initialisation more sensible. Andrew Bartlett (This used to be commit 5598cda08b46e61695b753e049288a0b498502c4) --- source4/libcli/auth/gensec_ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 53d0104259..a91c2817af 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -534,10 +534,10 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .client_start = gensec_ntlmssp_client_start, .server_start = gensec_ntlmssp_server_start, .update = gensec_ntlmssp_update, - .seal_packet = gensec_ntlmssp_seal_packet, .sig_size = gensec_ntlmssp_sig_size, .sign_packet = gensec_ntlmssp_sign_packet, .check_packet = gensec_ntlmssp_check_packet, + .seal_packet = gensec_ntlmssp_seal_packet, .unseal_packet = gensec_ntlmssp_unseal_packet, .wrap = gensec_ntlmssp_wrap, .unwrap = gensec_ntlmssp_unwrap, -- cgit From 9278473ea456bd7f45f1465e7112540f611c177c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 03:43:59 +0000 Subject: r4589: forgot to commit the new NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED error code (This used to be commit f4337c988c15dc84e3cfd77b628e92a0996717ea) --- source4/libcli/util/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index eac7989800..d2d87eeb1c 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -536,6 +536,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, + { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } -- cgit From 11ce2cfd70df264c5c91b4daaa9a01c5abc673b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 04:39:16 +0000 Subject: r4591: - converted the other _p talloc functions to not need _p - added #if TALLOC_DEPRECATED around the _p functions - fixes the code that broke from the above while doing this I fixed quite a number of places that were incorrectly using the non type-safe talloc functions to use the type safe ones. Some were even doing multiplies for array allocation, which is potentially unsafe. (This used to be commit 6e7754abd0c225527fb38363996a6e241b87b37e) --- source4/libcli/auth/spnego_parse.c | 6 +++--- source4/libcli/clilist.c | 11 ++++++----- source4/libcli/ldap/ldap_ldif.c | 2 +- source4/libcli/raw/rawnotify.c | 2 +- source4/libcli/raw/rawrequest.c | 4 ++-- source4/libcli/raw/rawtrans.c | 4 ++-- source4/libcli/util/asn1.c | 2 +- 7 files changed, 16 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 32e98a4235..78a94a6a44 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -52,9 +52,9 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit token->mechTypes = talloc_p(NULL, const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { - token->mechTypes = - talloc_realloc(NULL, token->mechTypes, (i + 2) * - sizeof(*token->mechTypes)); + token->mechTypes = talloc_realloc(NULL, + token->mechTypes, + const char *, i+2); asn1_read_OID(asn1, token->mechTypes + i); if (token->mechTypes[i]) { talloc_steal(token->mechTypes, diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index ec103dbfa4..77fd760837 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -81,13 +81,13 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) /* add file info to the dirlist pool */ tdl = talloc_realloc(state, state->dirlist, - state->dirlist_len + sizeof(struct clilist_file_info)); - + struct clilist_file_info, + state->dirlist_len + 1); if (!tdl) { return False; } state->dirlist = tdl; - state->dirlist_len += sizeof(struct clilist_file_info); + state->dirlist_len++; interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]); @@ -227,13 +227,14 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) /* add file info to the dirlist pool */ tdl = talloc_realloc(state, state->dirlist, - state->dirlist_len + sizeof(struct clilist_file_info)); + struct clilist_file_info, + state->dirlist_len + 1); if (!tdl) { return False; } state->dirlist = tdl; - state->dirlist_len += sizeof(struct clilist_file_info); + state->dirlist_len++; interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]); diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index c276b7e917..809c75cf96 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -52,7 +52,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); if (!c2) { errno = ENOMEM; return NULL; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 918fb788cb..e48545419f 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -73,7 +73,7 @@ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, } /* allocate array */ - parms->out.changes = talloc_array_p(mem_ctx, struct notify_changes, parms->out.num_changes); + parms->out.changes = talloc_array(mem_ctx, struct notify_changes, parms->out.num_changes); if (!parms->out.changes) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index b74f066ef4..8093b298bb 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -203,7 +203,7 @@ static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_si /* we need to realloc */ req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION; - buf2 = talloc_realloc(req, req->out.buffer, req->out.allocated); + buf2 = talloc_realloc(req, req->out.buffer, uint8_t, req->out.allocated); if (buf2 == NULL) { smb_panic("out of memory in req_grow_allocation"); } @@ -950,7 +950,7 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, max_len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; - blob->data = talloc_realloc(mem_ctx, blob->data, blob->length + max_len); + blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, blob->length + max_len); if (!blob->data) { return 0; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 0ccecdc2d4..118ac5e3fd 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -111,7 +111,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, if (parms->out.setup_count > 0) { int i; - parms->out.setup = talloc_array(mem_ctx, 2, parms->out.setup_count, "setup"); + parms->out.setup = talloc_array(mem_ctx, uint16_t, parms->out.setup_count); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; return smbcli_request_destroy(req); @@ -439,7 +439,7 @@ NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req, if (parms->out.setup_count > 0) { int i; - parms->out.setup = talloc_array(mem_ctx, 2, parms->out.setup_count, "setup"); + parms->out.setup = talloc_array(mem_ctx, uint16_t, parms->out.setup_count); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; return smbcli_request_destroy(req); diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 52ba0225c9..de14eb0e57 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -33,7 +33,7 @@ BOOL asn1_write(struct asn1_data *data, const void *p, int len) if (data->has_error) return False; if (data->length < data->ofs+len) { uint8_t *newp; - newp = talloc_realloc(NULL, data->data, data->ofs+len); + newp = talloc_realloc(NULL, data->data, uint8_t, data->ofs+len); if (!newp) { asn1_free(data); data->has_error = True; -- cgit From 6836f5d0b167027908da9a08b9b219520997b563 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Jan 2005 08:34:05 +0000 Subject: r4616: the first phase in the addition of proper support for dcerpc_alter_context and multiple context_ids in the dcerpc client library. This stage does the following: - split "struct dcerpc_pipe" into two parts, the main part being "struct dcerpc_connection", which contains all the parts not dependent on the context, and "struct dcerpc_pipe" which has the context dependent part. This is similar to the layering in libcli_*() for SMB - disable the current dcerpc_alter code. I've used a #warning until i get the 2nd phase finished. I don't know how portable #warning is, but it won't be long before I add full alter context support anyway, so it won't last long - cleanup the allocation of dcerpc_pipe structures. The previous code was quite awkward. (This used to be commit 4004c69937be7e5dae56f9567ca607f982d395d3) --- source4/libcli/util/clilsa.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 843d45607b..c032af0abc 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -76,8 +76,14 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } lsa->ipc_tree->tid = tcon.tconx.out.cnum; + lsa->pipe = dcerpc_pipe_init(lsa); + if (lsa->pipe == NULL) { + talloc_free(lsa); + return NT_STATUS_NO_MEMORY; + } + /* open the LSA pipe */ - status = dcerpc_pipe_open_smb(&lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME); + status = dcerpc_pipe_open_smb(lsa->pipe->conn, lsa->ipc_tree, DCERPC_LSARPC_NAME); if (!NT_STATUS_IS_OK(status)) { talloc_free(lsa); return status; -- cgit From e74b3ed6f195e66cb5fa0f387cea0f59fb66711b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Jan 2005 11:32:12 +0000 Subject: r4618: - tidied up the alter_context client code a bit - there is no alter_nak or alter_ack packet, its all done in an alter_response - auto-allocated the contex_ids - tried to fix up the dcom code to work again with alter_context. Jelmer, please take a look :) (This used to be commit dd1c54add8884376601f2f8a56c01bfb8add030c) --- source4/libcli/util/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index d2d87eeb1c..9317f0e37a 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -537,6 +537,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, + { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } -- cgit From 46a32687da249174a666d9166fccbe705c8beba0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 9 Jan 2005 12:55:25 +0000 Subject: r4620: - add interface functions to the auth subsystem so that callers doesn't need to use function pointers anymore - make the module init much easier - a lot of cleanups don't try to read the diff in auth/ better read the new files it passes test_echo.sh and test_rpc.sh abartlet: please fix spelling fixes metze (This used to be commit 3c0d16b8236451f2cfd38fc3db8ae2906106d847) --- source4/libcli/auth/gensec_krb5.c | 61 ++++++------ source4/libcli/auth/gensec_ntlmssp.c | 154 +++++++++++-------------------- source4/libcli/security/security_token.c | 45 +++++---- 3 files changed, 108 insertions(+), 152 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 0ab32318aa..aaf892e1e6 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -6,6 +6,7 @@ Copyright (C) Andrew Bartlett 2004 Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 + Copyright (C) Stefan Metzmacher 2004-2005 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 @@ -30,9 +31,6 @@ #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - enum GENSEC_KRB5_STATE { GENSEC_KRB5_SERVER_START, GENSEC_KRB5_CLIENT_START, @@ -620,7 +618,7 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, } static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, - struct auth_session_info **session_info_out) + struct auth_session_info **_session_info) { NTSTATUS nt_status; struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; @@ -629,20 +627,22 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security struct PAC_LOGON_INFO *logon_info; char *p; char *principal; - const char *username; + const char *account_name; const char *realm; - *session_info_out = NULL; - principal = talloc_strdup(gensec_krb5_state, gensec_krb5_state->peer_principal); + NT_STATUS_HAVE_NO_MEMORY(principal); + p = strchr(principal, '@'); if (p) { *p = '\0'; + p++; + realm = p; + } else { + realm = lp_realm(); } - p++; - username = principal; - realm = p; - + account_name = principal; + /* decode and verify the pac */ nt_status = gensec_krb5_decode_pac(gensec_krb5_state, &logon_info, gensec_krb5_state->pac, gensec_krb5_state); @@ -659,36 +659,33 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security union netr_Validation validation; validation.sam3 = &logon_info->info3; nt_status = make_server_info_netlogon_validation(gensec_krb5_state, - username, - &server_info, - 3, - &validation); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + account_name, + 3, &validation, + &server_info); + talloc_free(principal); + NT_STATUS_NOT_OK_RETURN(nt_status); } else { - nt_status = sam_get_server_info(username, realm, gensec_krb5_state, &server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + DATA_BLOB user_sess_key = data_blob(NULL, 0); + DATA_BLOB lm_sess_key = data_blob(NULL, 0); + /* TODO: should we pass the krb5 session key in here? */ + nt_status = sam_get_server_info(gensec_krb5_state, account_name, realm, + user_sess_key, lm_sess_key, + &server_info); + talloc_free(principal); + NT_STATUS_NOT_OK_RETURN(nt_status); } /* references the server_info into the session_info */ - nt_status = make_session_info(gensec_krb5_state, server_info, &session_info); + nt_status = auth_generate_session_info(gensec_krb5_state, server_info, &session_info); talloc_free(server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - talloc_free(principal); + NT_STATUS_NOT_OK_RETURN(nt_status); nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key); + NT_STATUS_NOT_OK_RETURN(nt_status); - session_info->workstation = NULL; + *_session_info = session_info; - *session_info_out = session_info; - - return nt_status; + return NT_STATUS_OK; } static BOOL gensec_krb5_have_feature(struct gensec_security *gensec_security, diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index a91c2817af..ae97803ef7 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Tridgell 2003 Copyright (C) Andrew Bartlett 2004 + Copyright (C) Stefan Metzmacher 2005 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 @@ -40,8 +41,15 @@ struct gensec_ntlmssp_state { static const uint8_t *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + NTSTATUS status; + const uint8_t *chal; + + status = auth_get_challenge(gensec_ntlmssp_state->auth_context, &chal); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } - return gensec_ntlmssp_state->auth_context->get_ntlm_challenge(gensec_ntlmssp_state->auth_context); + return chal; } /** @@ -53,7 +61,7 @@ static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_s { struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; - return gensec_ntlmssp_state->auth_context->challenge_may_be_modified; + return auth_challenge_may_be_modified(gensec_ntlmssp_state->auth_context); } /** @@ -62,20 +70,20 @@ static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_s */ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) { + NTSTATUS nt_status; struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; struct auth_context *auth_context = gensec_ntlmssp_state->auth_context; + const uint8_t *chal; - SMB_ASSERT(challenge->length == 8); + if (challenge->length != 8) { + return NT_STATUS_INVALID_PARAMETER; + } - auth_context->challenge = data_blob_talloc(auth_context, - challenge->data, challenge->length); + chal = challenge->data; - auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)"; + nt_status = auth_context_set_challenge(auth_context, chal, "NTLMSSP callback (NTLM2)"); - DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by)); - DEBUG(5, ("challenge is: \n")); - dump_data(5, auth_context->challenge.data, auth_context->challenge.length); - return NT_STATUS_OK; + return nt_status; } /** @@ -90,44 +98,21 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, struct auth_usersupplied_info *user_info = NULL; NTSTATUS nt_status; -#if 0 - /* the client has given us its machine name (which we otherwise would not get on port 445). - we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ - - set_remote_machine_name(gensec_ntlmssp_state->ntlmssp_state->workstation, True); - - /* setup the string used by %U */ - /* sub_set_smb_name checks for weird internally */ - sub_set_smb_name(gensec_ntlmssp_state->ntlmssp_state->user); - - reload_services(True); - -#endif - nt_status = make_user_info_map(ntlmssp_state, - &user_info, + nt_status = make_user_info_map(ntlmssp_state, gensec_ntlmssp_state->ntlmssp_state->user, gensec_ntlmssp_state->ntlmssp_state->domain, gensec_ntlmssp_state->ntlmssp_state->workstation, gensec_ntlmssp_state->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->lm_resp : NULL, gensec_ntlmssp_state->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->nt_resp : NULL, - NULL, NULL, NULL, - True); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = gensec_ntlmssp_state-> - auth_context->check_ntlm_password(gensec_ntlmssp_state->auth_context, - user_info, - gensec_ntlmssp_state, - &gensec_ntlmssp_state->server_info); + NULL, NULL, NULL, True, + &user_info); + NT_STATUS_NOT_OK_RETURN(nt_status); - free_user_info(&user_info); + nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, gensec_ntlmssp_state, + user_info, &gensec_ntlmssp_state->server_info); + talloc_free(user_info); + NT_STATUS_NOT_OK_RETURN(nt_status); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } if (gensec_ntlmssp_state->server_info->user_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length)); *user_session_key = data_blob_talloc(ntlmssp_state, @@ -151,12 +136,6 @@ static int gensec_ntlmssp_destroy(void *ptr) ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state); } - if (gensec_ntlmssp_state->auth_context) { - free_auth_context(&gensec_ntlmssp_state->auth_context); - } - if (gensec_ntlmssp_state->server_info) { - free_server_info(&gensec_ntlmssp_state->server_info); - } return 0; } @@ -183,21 +162,16 @@ static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) { NTSTATUS nt_status; - NTSTATUS status; struct ntlmssp_state *ntlmssp_state; struct gensec_ntlmssp_state *gensec_ntlmssp_state; - status = gensec_ntlmssp_start(gensec_security); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + nt_status = gensec_ntlmssp_start(gensec_security); + NT_STATUS_NOT_OK_RETURN(nt_status); gensec_ntlmssp_state = gensec_security->private_data; - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(gensec_ntlmssp_state, - &gensec_ntlmssp_state->ntlmssp_state))) { - return nt_status; - } + nt_status = ntlmssp_server_start(gensec_ntlmssp_state, &gensec_ntlmssp_state->ntlmssp_state); + NT_STATUS_NOT_OK_RETURN(nt_status); if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; @@ -206,19 +180,17 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; - nt_status = make_auth_context_subsystem(gensec_ntlmssp_state, &gensec_ntlmssp_state->auth_context); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = auth_context_create(gensec_ntlmssp_state, lp_auth_methods(), &gensec_ntlmssp_state->auth_context); + NT_STATUS_NOT_OK_RETURN(nt_status); + ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; ntlmssp_state->auth_context = gensec_ntlmssp_state; ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; ntlmssp_state->check_password = auth_ntlmssp_check_password; ntlmssp_state->server_role = lp_server_role(); - + return NT_STATUS_OK; } @@ -226,19 +198,15 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur { struct gensec_ntlmssp_state *gensec_ntlmssp_state; char *password = NULL; - - NTSTATUS status; - status = gensec_ntlmssp_start(gensec_security); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NTSTATUS nt_status; + + nt_status = gensec_ntlmssp_start(gensec_security); + NT_STATUS_NOT_OK_RETURN(nt_status); gensec_ntlmssp_state = gensec_security->private_data; - status = ntlmssp_client_start(gensec_ntlmssp_state, - &gensec_ntlmssp_state->ntlmssp_state); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + nt_status = ntlmssp_client_start(gensec_ntlmssp_state, + &gensec_ntlmssp_state->ntlmssp_state); + NT_STATUS_NOT_OK_RETURN(nt_status); if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { /* @@ -259,36 +227,27 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, - gensec_security->user.domain); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + nt_status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, + gensec_security->user.domain); + NT_STATUS_NOT_OK_RETURN(nt_status); - status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, - gensec_security->user.name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + nt_status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, + gensec_security->user.name); + NT_STATUS_NOT_OK_RETURN(nt_status); if (gensec_security->user.name) { - status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + nt_status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password); + NT_STATUS_NOT_OK_RETURN(nt_status); } if (password) { - status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, - password); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password); + NT_STATUS_NOT_OK_RETURN(nt_status); } gensec_security->private_data = gensec_ntlmssp_state; - return status; + return NT_STATUS_OK; } /* @@ -499,19 +458,14 @@ static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_secur { NTSTATUS nt_status; struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - nt_status = make_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info); + NT_STATUS_NOT_OK_RETURN(nt_status); (*session_info)->session_key = data_blob_talloc(*session_info, gensec_ntlmssp_state->ntlmssp_state->session_key.data, gensec_ntlmssp_state->ntlmssp_state->session_key.length); - (*session_info)->workstation = talloc_strdup(*session_info, - gensec_ntlmssp_state->ntlmssp_state->workstation); - return NT_STATUS_OK; } diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 7bd533dbee..b9baf796df 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -4,6 +4,7 @@ security descriptror utility functions Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2005 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 @@ -48,42 +49,46 @@ struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx) Create the SID list for this user. ****************************************************************************/ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, - struct dom_sid *user_sid, struct dom_sid *group_sid, - int n_groupSIDs, struct dom_sid **groupSIDs, - BOOL is_guest, struct security_token **token) + struct dom_sid *user_sid, + struct dom_sid *group_sid, + int n_groupSIDs, + struct dom_sid **groupSIDs, + BOOL is_authenticated, + struct security_token **token) { struct security_token *ptoken; int i; NTSTATUS status; ptoken = security_token_initialise(mem_ctx); - if (ptoken == NULL) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(ptoken); ptoken->sids = talloc_array_p(ptoken, struct dom_sid *, n_groupSIDs + 5); - if (!ptoken->sids) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); - ptoken->user_sid = user_sid; - ptoken->group_sid = group_sid; + ptoken->user_sid = talloc_reference(ptoken, user_sid); + ptoken->group_sid = talloc_reference(ptoken, group_sid); ptoken->privilege_mask = 0; - ptoken->sids[0] = user_sid; - ptoken->sids[1] = group_sid; + ptoken->sids[0] = ptoken->user_sid; + ptoken->sids[1] = ptoken->group_sid; /* * Finally add the "standard" SIDs. - * The only difference between guest and "anonymous" (which we - * don't really support) is the addition of Authenticated_Users. + * The only difference between guest and "anonymous" + * is the addition of Authenticated_Users. */ ptoken->sids[2] = dom_sid_parse_talloc(mem_ctx, SID_WORLD); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); ptoken->sids[3] = dom_sid_parse_talloc(mem_ctx, SID_NT_NETWORK); - ptoken->sids[4] = dom_sid_parse_talloc(mem_ctx, - is_guest?SID_BUILTIN_GUESTS: - SID_NT_AUTHENTICATED_USERS); - ptoken->num_sids = 5; + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]); + ptoken->num_sids = 4; + + if (is_authenticated) { + ptoken->sids[4] = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHENTICATED_USERS); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); + ptoken->num_sids++; + } for (i = 0; i < n_groupSIDs; i++) { size_t check_sid_idx; @@ -96,7 +101,7 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, } if (check_sid_idx == ptoken->num_sids) { - ptoken->sids[ptoken->num_sids++] = groupSIDs[i]; + ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken, groupSIDs[i]); } } -- cgit From 7db9de3ea9d0b3693aea08b3050f378a4ca9cf0b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Jan 2005 10:48:19 +0000 Subject: r4635: Fix NTLMSSP to return NT_STATUS_OK when it has constructed the auth token in the client (the final token in the negotiation). Consequential fixes in the SPNEGO code, which now uses the out.length as the indicator of 'I need to send something to the other side'. Merge the NTLM and SPNEGO DCE-RPC authentication routines in the client. Fix the RPC-MULTIBIND test consequent to this merge. Andrew Bartlett (This used to be commit 43e3516fc03008e97ebb4ad1a0cde464303f43c6) --- source4/libcli/auth/ntlmssp.c | 5 ++-- source4/libcli/auth/spnego.c | 61 ++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 32 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 7f4a86e274..a9fb66d41e 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -1257,13 +1257,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->expected_state = NTLMSSP_DONE; - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { + nt_status = ntlmssp_sign_init(ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); return nt_status; } - return NT_STATUS_MORE_PROCESSING_REQUIRED; + return nt_status; } NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 31dd5aa47d..84bd7ce42c 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -685,24 +685,34 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } if (spnego_state->no_response_expected) { - nt_status = NT_STATUS_OK; + if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { + DEBUG(1,("gensec_update ok but not accepted\n")); + nt_status = NT_STATUS_INVALID_PARAMETER; + } else { + nt_status = NT_STATUS_OK; + } } else { nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, spnego.negTokenTarg.responseToken, &unwrapped_out); - } - - - if (NT_STATUS_IS_OK(nt_status) - && (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) { - DEBUG(1,("gensec_update ok but not accepted\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; + + if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->no_response_expected = True; + } } spnego_free_data(&spnego); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) + && !NT_STATUS_IS_OK(nt_status)) { + DEBUG(1, ("SPNEGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); + return nt_status; + } + + if (unwrapped_out.length) { /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; @@ -716,30 +726,21 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } spnego_state->state_position = SPNEGO_CLIENT_TARG; - } else if (NT_STATUS_IS_OK(nt_status)) { + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + /* all done - server has accepted, and we agree */ - - if (unwrapped_out.length) { - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; - spnego_out.negTokenTarg.supportedMech = NULL; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } else { - *out = null_data_blob; - } + *out = null_data_blob; - spnego_state->state_position = SPNEGO_DONE; - } else { - DEBUG(1, ("SPNEGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); + if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { + /* unless of course it did not accept */ + DEBUG(1,("gensec_update ok but not accepted\n")); + nt_status = NT_STATUS_INVALID_PARAMETER; + } } + + spnego_state->state_position = SPNEGO_DONE; + return nt_status; } case SPNEGO_DONE: -- cgit From e8c06b9221d9818042ea8a08efccfc88f17a9e3e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Jan 2005 12:30:13 +0000 Subject: r4641: Push a few more details into the schannel ldb, and into the credentials struct it maintains. Clearly much of this will be replaced with some system to pass and store the session_info, as that is the 'right way' to handle this. Andrew Bartlett (This used to be commit c6fcb33a887fbf0c0b42c3bc331df942a985128c) --- source4/libcli/auth/credentials.c | 8 ++++++-- source4/libcli/auth/credentials.h | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 8cae71180c..18ce6fec1b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -292,13 +292,17 @@ BOOL creds_server_check(const struct creds_CredentialState *creds, } NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, - struct netr_Authenticator *received_authenticator, - struct netr_Authenticator *return_authenticator) + struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator) { if (!received_authenticator || !return_authenticator) { return NT_STATUS_INVALID_PARAMETER; } + if (!creds) { + return NT_STATUS_ACCESS_DENIED; + } + /* TODO: this may allow the a replay attack on a non-signed connection. Should we check that this is increasing? */ creds->sequence = received_authenticator->timestamp; diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 30114fe7fa..01206bc282 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -27,6 +27,9 @@ struct creds_CredentialState { struct netr_Credential seed; struct netr_Credential client; struct netr_Credential server; + uint16_t secure_channel_type; + char *computer_name; + char *account_name; }; -- cgit From fd4831f1f088e1c00c2a037e200440e309014afd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Jan 2005 17:28:36 +0000 Subject: r4650: - make more use of bitmap and enum's - move some structs out of misc.idl metze (This used to be commit b6543a6e3057b5588ec50a2ebf6c7c932209efe6) --- source4/libcli/auth/credentials.h | 4 ++-- source4/libcli/auth/ntlmssp.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 01206bc282..ffefcc0305 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "librpc/gen_ndr/ndr_netlogon.h" + struct creds_CredentialState { uint32_t negotiate_flags; uint8_t session_key[16]; @@ -32,8 +34,6 @@ struct creds_CredentialState { char *account_name; }; - - /* for the timebeing, use the same neg flags as Samba3. */ /* The 7 here seems to be required to get Win2k not to downgrade us to NT4. Actually, anything other than 1ff would seem to do... */ diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index a6d1510450..e8a2356e2c 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "librpc/gen_ndr/ndr_samr.h" + /* NTLMSSP mode */ enum ntlmssp_role { -- cgit From 28236430f4b0114d9539967fa9c10bfd69c38774 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Jan 2005 22:53:52 +0000 Subject: r4658: (grr, commited wrong file last time). We really should have a seperate structure for this (the ARCFOUR sbox), but for now, get the declaration right. Andrew Bartlett (This used to be commit 2e16f3a8d31954fdfe4a8832637fcd9191ecab96) --- source4/libcli/util/smbdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 4e4222b9e6..016bd59501 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -365,7 +365,7 @@ void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int } /* initialise the arcfour sbox with key */ -void arcfour_init(uint8_t s_box[256], const DATA_BLOB *key) +void arcfour_init(uint8_t s_box[258], const DATA_BLOB *key) { int ind; uint8_t j = 0; -- cgit From a249198d539685be5cb97e179e85ae00dbba8c83 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 11 Jan 2005 14:04:58 +0000 Subject: r4682: A LDB-based secrets implementation in Samba4. This uses LDB (a local secrets.ldb and the global samdb) to fill out the secrets from an LSA perspective. Some small changes to come, but the bulk of the work is now done. A re-provision is required after this change. Andrew Bartlett (This used to be commit ded33033521a6a1c7ea80758c5c5aeeebb182a51) --- source4/libcli/auth/session.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 91eee9ce81..9b4132a490 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -113,18 +113,18 @@ char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) sess_crypt_blob(&out, blob, session_key, False); - slen = IVAL(out.data, 0); - if (slen > blob->length - 8) { - DEBUG(0,("Invalid crypt length %d\n", slen)); - return NULL; - } - if (IVAL(out.data, 4) != 1) { DEBUG(0,("Unexpected revision number %d in session crypted string\n", IVAL(out.data, 4))); return NULL; } + slen = IVAL(out.data, 0); + if (slen > blob->length - 8) { + DEBUG(0,("Invalid crypt length %d\n", slen)); + return NULL; + } + ret = strndup((const char *)(out.data+8), slen); data_blob_free(&out); @@ -169,42 +169,43 @@ DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_ } /* - a convenient wrapper around sess_crypt_blob() for strings, using the LSA convention - - caller should free the returned string + Decrypt a DATA_BLOB using the LSA convention */ -DATA_BLOB sess_decrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const DATA_BLOB *session_key) +NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DATA_BLOB *session_key, + DATA_BLOB *ret) { DATA_BLOB out; int slen; - DATA_BLOB ret; if (blob->length < 8) { - return data_blob(NULL, 0); + return NT_STATUS_INVALID_PARAMETER; } out = data_blob_talloc(mem_ctx, NULL, blob->length); if (!out.data) { - return data_blob(NULL, 0); + return NT_STATUS_NO_MEMORY; } sess_crypt_blob(&out, blob, session_key, False); + if (IVAL(out.data, 4) != 1) { + DEBUG(0,("Unexpected revision number %d in session crypted string\n", + IVAL(out.data, 4))); + return NT_STATUS_UNKNOWN_REVISION; + } + slen = IVAL(out.data, 0); if (slen > blob->length - 8) { DEBUG(0,("Invalid crypt length %d\n", slen)); - return data_blob(NULL, 0); + return NT_STATUS_WRONG_PASSWORD; } - if (IVAL(out.data, 4) != 1) { - DEBUG(0,("Unexpected revision number %d in session crypted string\n", - IVAL(out.data, 4))); - return data_blob(NULL, 0); + *ret = data_blob_talloc(mem_ctx, out.data+8, slen); + if (!ret->data) { + return NT_STATUS_NO_MEMORY; } - - ret = data_blob_talloc(mem_ctx, out.data+8, slen); data_blob_free(&out); - return ret; + return NT_STATUS_OK; } -- cgit From 899f610fb49f78a5c147f263926d6be3f889e328 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 11 Jan 2005 20:20:27 +0000 Subject: r4692: Make the client SPNEGO code bail out in a couple more cases. Andrew Bartlett (This used to be commit a062ac122c402fb2cf31eb8e76f4077b1f33b8eb) --- source4/libcli/auth/spnego.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 84bd7ce42c..f7221b7458 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -686,7 +686,10 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (spnego_state->no_response_expected) { if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - DEBUG(1,("gensec_update ok but not accepted\n")); + DEBUG(3,("GENSEC SPNEGO: client GENSEC accepted, but server rejected (bad password?)\n")); + nt_status = NT_STATUS_INVALID_PARAMETER; + } else if (spnego.negTokenTarg.responseToken.length) { + DEBUG(2,("GENSEC SPNEGO: client GENSEC accepted, but server continued negotiation!\n")); nt_status = NT_STATUS_INVALID_PARAMETER; } else { nt_status = NT_STATUS_OK; -- cgit From 1d795fa57b9f0b9c23cecfe0329a5e551ea903ee Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Jan 2005 07:03:29 +0000 Subject: r4700: first attempt at a composite async function, smb_composite_loadfile(), which combineds ntcreatex, readx and close into a single call that behaves just like a normal libcli async call. (This used to be commit 516f68fb054f0717f0429e031aa820776ecc6597) --- source4/libcli/composite/composite.h | 72 +++++++++ source4/libcli/composite/loadfile.c | 289 +++++++++++++++++++++++++++++++++++ source4/libcli/config.m4 | 1 + source4/libcli/config.mk | 5 +- 4 files changed, 366 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/composite/composite.h create mode 100644 source4/libcli/composite/loadfile.c (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h new file mode 100644 index 0000000000..895c88a4f6 --- /dev/null +++ b/source4/libcli/composite/composite.h @@ -0,0 +1,72 @@ +/* + Unix SMB/CIFS implementation. + + SMB composite request interfaces + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +/* + this defines the structures associated with "composite" + requests. Composite requests are libcli requests that are internally + implemented as multiple libcli/raw/ calls, but can be treated as a + single call via these composite calls. The composite calls are + particularly designed to be used in async applications +*/ + + +struct smbcli_composite { + /* the external state - will be queried by the caller */ + enum smbcli_request_state state; + + /* the internal stage */ + uint16_t stage; + + /* the currently running sub-request */ + struct smbcli_request *req; + + /* the current requests parameter block */ + void *req_parms; + + /* the parameters of the whole composite function */ + void *composite_parms; + + /* status code when finished */ + NTSTATUS status; + + /* information on what to do on completion */ + struct { + void (*fn)(struct smbcli_composite *); + void *private; + } async; + +}; + + +/* + a composite open/read(s)/close request that loads a whole file + into memory. Used as a demo of the composite system. +*/ +struct smb_composite_loadfile { + struct { + const char *fname; + } in; + struct { + uint8_t *data; + uint32_t size; + } out; +}; diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c new file mode 100644 index 0000000000..1bf1fd5403 --- /dev/null +++ b/source4/libcli/composite/loadfile.c @@ -0,0 +1,289 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for loading a whole file into memory +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE}; + + +static void loadfile_handler(struct smbcli_request *req); + + +/* + setup for the close +*/ +static NTSTATUS setup_close(struct smbcli_composite *c, + struct smbcli_tree *tree, uint16_t fnum) +{ + union smb_close *io_close; + + /* nothing to read, setup the close */ + io_close = talloc(c, union smb_close); + NT_STATUS_HAVE_NO_MEMORY(io_close); + + io_close->close.level = RAW_CLOSE_CLOSE; + io_close->close.in.fnum = fnum; + io_close->close.in.write_time = 0; + + c->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(c->req); + + /* call the handler again when the close is done */ + c->stage = LOADFILE_CLOSE; + c->req->async.fn = loadfile_handler; + c->req->async.private = c; + c->req_parms = io_close; + + return NT_STATUS_OK; +} + +/* + called when the open is done - pull the results and setup for the + first readx, or close if the file is zero size +*/ +static NTSTATUS loadfile_open(struct smbcli_composite *c, + struct smb_composite_loadfile *io) +{ + union smb_open *io_open = c->req_parms; + struct smbcli_tree *tree = c->req->tree; + union smb_read *io_read; + NTSTATUS status; + + status = smb_raw_open_recv(c->req, c, io_open); + NT_STATUS_NOT_OK_RETURN(status); + + /* don't allow stupidly large loads */ + if (io_open->ntcreatex.out.size > 100*1000*1000) { + return NT_STATUS_INSUFFICIENT_RESOURCES; + } + + /* allocate space for the file data */ + io->out.size = io_open->ntcreatex.out.size; + io->out.data = talloc_array(c, uint8_t, io->out.size); + NT_STATUS_HAVE_NO_MEMORY(io->out.data); + + if (io->out.size == 0) { + return setup_close(c, tree, io_open->ntcreatex.out.fnum); + } + + /* setup for the read */ + io_read = talloc(c, union smb_read); + NT_STATUS_HAVE_NO_MEMORY(io_read); + + io_read->readx.level = RAW_READ_READX; + io_read->readx.in.fnum = io_open->ntcreatex.out.fnum; + io_read->readx.in.offset = 0; + io_read->readx.in.mincnt = MIN(32768, io->out.size); + io_read->readx.in.maxcnt = io_read->readx.in.mincnt; + io_read->readx.in.remaining = 0; + io_read->readx.out.data = io->out.data; + + c->req = smb_raw_read_send(tree, io_read); + NT_STATUS_HAVE_NO_MEMORY(c->req); + + /* call the handler again when the first read is done */ + c->stage = LOADFILE_READ; + c->req->async.fn = loadfile_handler; + c->req->async.private = c; + c->req_parms = io_read; + talloc_free(io_open); + + return NT_STATUS_OK; +} + + +/* + called when a read is done - pull the results and setup for the + next read, or close if the file is all done +*/ +static NTSTATUS loadfile_read(struct smbcli_composite *c, + struct smb_composite_loadfile *io) +{ + union smb_read *io_read = c->req_parms; + struct smbcli_tree *tree = c->req->tree; + NTSTATUS status; + + status = smb_raw_read_recv(c->req, io_read); + NT_STATUS_NOT_OK_RETURN(status); + + /* we might be done */ + if (io_read->readx.in.offset + + io_read->readx.out.nread == io->out.size) { + return setup_close(c, tree, io_read->readx.in.fnum); + } + + /* setup for the next read */ + io_read->readx.in.offset += io_read->readx.out.nread; + io_read->readx.in.mincnt = MIN(32768, io->out.size - io_read->readx.in.offset); + io_read->readx.out.data = io->out.data + io_read->readx.in.offset; + + c->req = smb_raw_read_send(tree, io_read); + NT_STATUS_HAVE_NO_MEMORY(c->req); + + /* call the handler again when the read is done */ + c->req->async.fn = loadfile_handler; + c->req->async.private = c; + + return NT_STATUS_OK; +} + +/* + called when the close is done, check the status and cleanup +*/ +static NTSTATUS loadfile_close(struct smbcli_composite *c, + struct smb_composite_loadfile *io) +{ + NTSTATUS status; + + status = smbcli_request_simple_recv(c->req); + NT_STATUS_NOT_OK_RETURN(status); + + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); + } + + return NT_STATUS_OK; +} + + +/* + handler for completion of a sub-request in loadfile +*/ +static void loadfile_handler(struct smbcli_request *req) +{ + struct smbcli_composite *c = req->async.private; + struct smb_composite_loadfile *io = c->composite_parms; + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (c->stage) { + case LOADFILE_OPEN: + c->status = loadfile_open(c, io); + break; + + case LOADFILE_READ: + c->status = loadfile_read(c, io); + break; + + case LOADFILE_CLOSE: + c->status = loadfile_close(c, io); + break; + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + if (c->async.fn) { + c->async.fn(c); + } + } +} + +/* + composite loadfile call - does an openx followed by a number of readx calls, + followed by a close +*/ +struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, + struct smb_composite_loadfile *io) +{ + struct smbcli_composite *c; + union smb_open *io_open; + + c = talloc_zero(tree, struct smbcli_composite); + if (c == NULL) goto failed; + + c->state = SMBCLI_REQUEST_SEND; + c->stage = LOADFILE_OPEN; + c->composite_parms = io; + + /* setup for the open */ + io_open = talloc_zero(c, union smb_open); + if (io_open == NULL) goto failed; + + io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io_open->ntcreatex.in.access_mask = SEC_FILE_READ_DATA; + io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io_open->ntcreatex.in.fname = io->in.fname; + + /* send the open on its way */ + c->req = smb_raw_open_send(tree, io_open); + if (c->req == NULL) goto failed; + + /* setup the callback handler */ + c->req->async.fn = loadfile_handler; + c->req->async.private = c; + c->req_parms = io_open; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + composite loadfile call - recv side +*/ +NTSTATUS smb_composite_loadfile_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + if (!c) return NT_STATUS_NO_MEMORY; + + while (c->state < SMBCLI_REQUEST_DONE) { + if (event_loop_once(c->req->transport->event.ctx) != 0) { + return NT_STATUS_UNSUCCESSFUL; + } + } + + if (NT_STATUS_IS_OK(c->status)) { + struct smb_composite_loadfile *io = c->composite_parms; + talloc_steal(mem_ctx, io->out.data); + } + + status = c->status; + talloc_free(c); + + return status; +} + + +/* + composite loadfile call - sync interface +*/ +NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_composite_loadfile *io) +{ + struct smbcli_composite *c = smb_composite_loadfile_send(tree, io); + return smb_composite_loadfile_recv(c, mem_ctx); +} diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index d0d8f3015b..1c29a9599f 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -27,3 +27,4 @@ SMB_SUBSYSTEM(LIBCLI_RAW,[], libcli/raw/rawacl.o libcli/raw/rawdate.o], [${LIBCLI_RAW_LIBS}]) + diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 853dea7f98..4907ca9c72 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -18,5 +18,8 @@ REQUIRED_SUBSYSTEMS = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_LSA] ADD_OBJ_FILES = libcli/util/clilsa.o +[SUBSYSTEM::LIBCLI_COMPOSITE] +ADD_OBJ_FILES = libcli/composite/loadfile.o + [SUBSYSTEM::LIBCLI] -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB LIBCLI_COMPOSITE -- cgit From fef48c0cc8b58536ed2f3338fc7c790a846f305d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Jan 2005 07:19:15 +0000 Subject: r4701: remove debugs metze (This used to be commit 9db0d19413beb4a0a0b48f4223600ff8dff33728) --- source4/libcli/util/smbencrypt.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index ee423fbbba..bd2aae3db1 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -486,8 +486,6 @@ BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, /* Password cannot be longer than the size of the password buffer */ if ( (byte_len < 0) || (byte_len > 512)) { - DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); - DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); return False; } -- cgit From 287515fd3db1932f06d56da3bb388a7efc1120eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Jan 2005 11:43:18 +0000 Subject: r4710: added a smb_composite_savefile() function, and expanded the test suite a little (This used to be commit ef4dbc443dbdebc4160209ed3f23cbb97109c414) --- source4/libcli/composite/composite.c | 45 ++++++ source4/libcli/composite/composite.h | 16 +- source4/libcli/composite/loadfile.c | 12 +- source4/libcli/composite/savefile.c | 284 +++++++++++++++++++++++++++++++++++ source4/libcli/config.mk | 5 +- 5 files changed, 350 insertions(+), 12 deletions(-) create mode 100644 source4/libcli/composite/composite.c create mode 100644 source4/libcli/composite/savefile.c (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c new file mode 100644 index 0000000000..f7e23cd4bc --- /dev/null +++ b/source4/libcli/composite/composite.c @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + composite API helper functions +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" + + +/* + block until a composite function has completed, then return the status +*/ +NTSTATUS smb_composite_wait(struct smbcli_composite *c) +{ + if (c == NULL) return NT_STATUS_NO_MEMORY; + + while (c->state < SMBCLI_REQUEST_DONE) { + if (event_loop_once(c->req->transport->event.ctx) != 0) { + return NT_STATUS_UNSUCCESSFUL; + } + } + + return c->status; +} + + diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 895c88a4f6..7b9477a942 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -45,6 +45,9 @@ struct smbcli_composite { /* the parameters of the whole composite function */ void *composite_parms; + /* a private pointer for use by the composite code */ + void *private; + /* status code when finished */ NTSTATUS status; @@ -53,7 +56,6 @@ struct smbcli_composite { void (*fn)(struct smbcli_composite *); void *private; } async; - }; @@ -70,3 +72,15 @@ struct smb_composite_loadfile { uint32_t size; } out; }; + +/* + a composite open/write(s)/close request that saves a whole file from + memory. Used as a demo of the composite system. +*/ +struct smb_composite_savefile { + struct { + const char *fname; + uint8_t *data; + uint32_t size; + } in; +}; diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index 1bf1fd5403..61260aa963 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -257,22 +257,14 @@ NTSTATUS smb_composite_loadfile_recv(struct smbcli_composite *c, TALLOC_CTX *mem { NTSTATUS status; - if (!c) return NT_STATUS_NO_MEMORY; + status = smb_composite_wait(c); - while (c->state < SMBCLI_REQUEST_DONE) { - if (event_loop_once(c->req->transport->event.ctx) != 0) { - return NT_STATUS_UNSUCCESSFUL; - } - } - - if (NT_STATUS_IS_OK(c->status)) { + if (NT_STATUS_IS_OK(status)) { struct smb_composite_loadfile *io = c->composite_parms; talloc_steal(mem_ctx, io->out.data); } - status = c->status; talloc_free(c); - return status; } diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c new file mode 100644 index 0000000000..dc9ee2f9ec --- /dev/null +++ b/source4/libcli/composite/savefile.c @@ -0,0 +1,284 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for saving a whole file from memory +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE}; + + +static void savefile_handler(struct smbcli_request *req); + +struct savefile_state { + off_t total_written; +}; + + +/* + setup for the close +*/ +static NTSTATUS setup_close(struct smbcli_composite *c, + struct smbcli_tree *tree, uint16_t fnum) +{ + union smb_close *io_close; + + /* nothing to write, setup the close */ + io_close = talloc(c, union smb_close); + NT_STATUS_HAVE_NO_MEMORY(io_close); + + io_close->close.level = RAW_CLOSE_CLOSE; + io_close->close.in.fnum = fnum; + io_close->close.in.write_time = 0; + + c->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(c->req); + + /* call the handler again when the close is done */ + c->stage = SAVEFILE_CLOSE; + c->req->async.fn = savefile_handler; + c->req->async.private = c; + c->req_parms = io_close; + + return NT_STATUS_OK; +} + +/* + called when the open is done - pull the results and setup for the + first writex, or close if the file is zero size +*/ +static NTSTATUS savefile_open(struct smbcli_composite *c, + struct smb_composite_savefile *io) +{ + union smb_open *io_open = c->req_parms; + struct smbcli_tree *tree = c->req->tree; + union smb_write *io_write; + NTSTATUS status; + uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; + + status = smb_raw_open_recv(c->req, c, io_open); + NT_STATUS_NOT_OK_RETURN(status); + + if (io->in.size == 0) { + return setup_close(c, tree, io_open->ntcreatex.out.fnum); + } + + /* setup for the first write */ + io_write = talloc(c, union smb_write); + NT_STATUS_HAVE_NO_MEMORY(io_write); + + io_write->writex.level = RAW_WRITE_WRITEX; + io_write->writex.in.fnum = io_open->ntcreatex.out.fnum; + io_write->writex.in.offset = 0; + io_write->writex.in.wmode = 0; + io_write->writex.in.remaining = 0; + io_write->writex.in.count = MIN(max_xmit - 100, io->in.size); + io_write->writex.in.data = io->in.data; + + c->req = smb_raw_write_send(tree, io_write); + NT_STATUS_HAVE_NO_MEMORY(c->req); + + /* call the handler again when the first write is done */ + c->stage = SAVEFILE_WRITE; + c->req->async.fn = savefile_handler; + c->req->async.private = c; + c->req_parms = io_write; + talloc_free(io_open); + + return NT_STATUS_OK; +} + + +/* + called when a write is done - pull the results and setup for the + next write, or close if the file is all done +*/ +static NTSTATUS savefile_write(struct smbcli_composite *c, + struct smb_composite_savefile *io) +{ + union smb_write *io_write = c->req_parms; + struct smbcli_tree *tree = c->req->tree; + struct savefile_state *state = c->private; + NTSTATUS status; + uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; + + status = smb_raw_write_recv(c->req, io_write); + NT_STATUS_NOT_OK_RETURN(status); + + state->total_written += io_write->writex.out.nwritten; + + /* we might be done */ + if (io_write->writex.out.nwritten != io_write->writex.in.count || + state->total_written == io->in.size) { + return setup_close(c, tree, io_write->writex.in.fnum); + } + + /* setup for the next write */ + io_write->writex.in.offset = state->total_written; + io_write->writex.in.count = MIN(max_xmit - 100, io->in.size - state->total_written); + io_write->writex.in.data = io->in.data + state->total_written; + + c->req = smb_raw_write_send(tree, io_write); + NT_STATUS_HAVE_NO_MEMORY(c->req); + + /* call the handler again when the write is done */ + c->req->async.fn = savefile_handler; + c->req->async.private = c; + + return NT_STATUS_OK; +} + +/* + called when the close is done, check the status and cleanup +*/ +static NTSTATUS savefile_close(struct smbcli_composite *c, + struct smb_composite_savefile *io) +{ + NTSTATUS status; + struct savefile_state *state = c->private; + + status = smbcli_request_simple_recv(c->req); + NT_STATUS_NOT_OK_RETURN(status); + + if (state->total_written != io->in.size) { + return NT_STATUS_DISK_FULL; + } + + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); + } + + return NT_STATUS_OK; +} + + +/* + handler for completion of a sub-request in savefile +*/ +static void savefile_handler(struct smbcli_request *req) +{ + struct smbcli_composite *c = req->async.private; + struct smb_composite_savefile *io = c->composite_parms; + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (c->stage) { + case SAVEFILE_OPEN: + c->status = savefile_open(c, io); + break; + + case SAVEFILE_WRITE: + c->status = savefile_write(c, io); + break; + + case SAVEFILE_CLOSE: + c->status = savefile_close(c, io); + break; + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + if (c->async.fn) { + c->async.fn(c); + } + } +} + +/* + composite savefile call - does an openx followed by a number of writex calls, + followed by a close +*/ +struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, + struct smb_composite_savefile *io) +{ + struct smbcli_composite *c; + union smb_open *io_open; + struct savefile_state *state; + + c = talloc_zero(tree, struct smbcli_composite); + if (c == NULL) goto failed; + + c->state = SMBCLI_REQUEST_SEND; + c->stage = SAVEFILE_OPEN; + c->composite_parms = io; + + state = talloc(c, struct savefile_state); + if (state == NULL) goto failed; + + state->total_written = 0; + + /* setup for the open */ + io_open = talloc_zero(c, union smb_open); + if (io_open == NULL) goto failed; + + io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io_open->ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; + io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io_open->ntcreatex.in.fname = io->in.fname; + + /* send the open on its way */ + c->req = smb_raw_open_send(tree, io_open); + if (c->req == NULL) goto failed; + + /* setup the callback handler */ + c->req->async.fn = savefile_handler; + c->req->async.private = c; + c->req_parms = io_open; + c->private = state; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + composite savefile call - recv side +*/ +NTSTATUS smb_composite_savefile_recv(struct smbcli_composite *c) +{ + NTSTATUS status; + status = smb_composite_wait(c); + talloc_free(c); + return status; +} + + +/* + composite savefile call - sync interface +*/ +NTSTATUS smb_composite_savefile(struct smbcli_tree *tree, + struct smb_composite_savefile *io) +{ + struct smbcli_composite *c = smb_composite_savefile_send(tree, io); + return smb_composite_savefile_recv(c); +} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 4907ca9c72..40eecca0f9 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -19,7 +19,10 @@ REQUIRED_SUBSYSTEMS = RPC_NDR_LSA ADD_OBJ_FILES = libcli/util/clilsa.o [SUBSYSTEM::LIBCLI_COMPOSITE] -ADD_OBJ_FILES = libcli/composite/loadfile.o +ADD_OBJ_FILES = \ + libcli/composite/composite.o \ + libcli/composite/loadfile.o \ + libcli/composite/savefile.o [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB LIBCLI_COMPOSITE -- cgit From 592fce7fb149ca5e82b14d9c8f13a4da1babe2b7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Jan 2005 18:49:10 +0000 Subject: r4726: - use the name tcon and tid instead of conn and cnum - make use of talloc destructors metze (This used to be commit 8308da6ce4a95f8c10e22949ef00e9e64f2dbb85) --- source4/libcli/cliconnect.c | 2 +- source4/libcli/raw/clitree.c | 6 +++--- source4/libcli/util/clilsa.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 6185ba7b7d..a0ba5ae0a1 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -140,7 +140,7 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, status = smb_tree_connect(cli->tree, mem_ctx, &tcon); - cli->tree->tid = tcon.tconx.out.cnum; + cli->tree->tid = tcon.tconx.out.tid; talloc_free(mem_ctx); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 777279f5f9..0f56c0fe2e 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -96,12 +96,12 @@ NTSTATUS smb_tree_connect_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, case RAW_TCON_TCON: SMBCLI_CHECK_WCT(req, 2); parms->tcon.out.max_xmit = SVAL(req->in.vwv, VWV(0)); - parms->tcon.out.cnum = SVAL(req->in.vwv, VWV(1)); + parms->tcon.out.tid = SVAL(req->in.vwv, VWV(1)); break; case RAW_TCON_TCONX: ZERO_STRUCT(parms->tconx.out); - parms->tconx.out.cnum = SVAL(req->in.hdr, HDR_TID); + parms->tconx.out.tid = SVAL(req->in.hdr, HDR_TID); if (req->in.wct >= 4) { parms->tconx.out.options = SVAL(req->in.vwv, VWV(3)); } @@ -274,7 +274,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, return status; } - tree->tid = tcon.tconx.out.cnum; + tree->tid = tcon.tconx.out.tid; if (tcon.tconx.out.dev_type) { tree->device = talloc_strdup(tree, tcon.tconx.out.dev_type); } diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index c032af0abc..eac6984254 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -74,7 +74,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) talloc_free(lsa); return status; } - lsa->ipc_tree->tid = tcon.tconx.out.cnum; + lsa->ipc_tree->tid = tcon.tconx.out.tid; lsa->pipe = dcerpc_pipe_init(lsa); if (lsa->pipe == NULL) { -- cgit From 4e4afdb94685388f56061a5cc188a5f5b8e1ae52 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 10:29:43 +0000 Subject: r4754: tidied up the composite function infrastructure to make it easier to have composite functions that are not made up of functions that operate on smbcli_request structures. (This used to be commit 4f6055b4fb7e287a29544ff1ca4e22f698efc478) --- source4/libcli/composite/composite.c | 2 +- source4/libcli/composite/composite.h | 5 ++- source4/libcli/composite/loadfile.c | 59 +++++++++++++++++++++--------------- source4/libcli/composite/savefile.c | 45 ++++++++++++++++----------- 4 files changed, 67 insertions(+), 44 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index f7e23cd4bc..d4eb5a9323 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -34,7 +34,7 @@ NTSTATUS smb_composite_wait(struct smbcli_composite *c) if (c == NULL) return NT_STATUS_NO_MEMORY; while (c->state < SMBCLI_REQUEST_DONE) { - if (event_loop_once(c->req->transport->event.ctx) != 0) { + if (event_loop_once(c->event_ctx) != 0) { return NT_STATUS_UNSUCCESSFUL; } } diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 7b9477a942..6bffc63211 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -37,7 +37,7 @@ struct smbcli_composite { uint16_t stage; /* the currently running sub-request */ - struct smbcli_request *req; + void *req; /* the current requests parameter block */ void *req_parms; @@ -51,6 +51,9 @@ struct smbcli_composite { /* status code when finished */ NTSTATUS status; + /* the event context we are using */ + struct event_context *event_ctx; + /* information on what to do on completion */ struct { void (*fn)(struct smbcli_composite *); diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index 61260aa963..d8311e9151 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -40,6 +40,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { union smb_close *io_close; + struct smbcli_request *req; /* nothing to read, setup the close */ io_close = talloc(c, union smb_close); @@ -49,14 +50,15 @@ static NTSTATUS setup_close(struct smbcli_composite *c, io_close->close.in.fnum = fnum; io_close->close.in.write_time = 0; - c->req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(c->req); + req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the close is done */ - c->stage = LOADFILE_CLOSE; - c->req->async.fn = loadfile_handler; - c->req->async.private = c; + req->async.fn = loadfile_handler; + req->async.private = c; c->req_parms = io_close; + c->req = req; + c->stage = LOADFILE_CLOSE; return NT_STATUS_OK; } @@ -69,11 +71,12 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, struct smb_composite_loadfile *io) { union smb_open *io_open = c->req_parms; - struct smbcli_tree *tree = c->req->tree; + struct smbcli_request *req = c->req; + struct smbcli_tree *tree = req->tree; union smb_read *io_read; NTSTATUS status; - status = smb_raw_open_recv(c->req, c, io_open); + status = smb_raw_open_recv(req, c, io_open); NT_STATUS_NOT_OK_RETURN(status); /* don't allow stupidly large loads */ @@ -102,14 +105,16 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, io_read->readx.in.remaining = 0; io_read->readx.out.data = io->out.data; - c->req = smb_raw_read_send(tree, io_read); - NT_STATUS_HAVE_NO_MEMORY(c->req); + req = smb_raw_read_send(tree, io_read); + NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the first read is done */ - c->stage = LOADFILE_READ; - c->req->async.fn = loadfile_handler; - c->req->async.private = c; + req->async.fn = loadfile_handler; + req->async.private = c; c->req_parms = io_read; + c->req = req; + c->stage = LOADFILE_READ; + talloc_free(io_open); return NT_STATUS_OK; @@ -124,10 +129,11 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, struct smb_composite_loadfile *io) { union smb_read *io_read = c->req_parms; - struct smbcli_tree *tree = c->req->tree; + struct smbcli_request *req = c->req; + struct smbcli_tree *tree = req->tree; NTSTATUS status; - status = smb_raw_read_recv(c->req, io_read); + status = smb_raw_read_recv(req, io_read); NT_STATUS_NOT_OK_RETURN(status); /* we might be done */ @@ -141,12 +147,13 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, io_read->readx.in.mincnt = MIN(32768, io->out.size - io_read->readx.in.offset); io_read->readx.out.data = io->out.data + io_read->readx.in.offset; - c->req = smb_raw_read_send(tree, io_read); - NT_STATUS_HAVE_NO_MEMORY(c->req); + req = smb_raw_read_send(tree, io_read); + NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the read is done */ - c->req->async.fn = loadfile_handler; - c->req->async.private = c; + req->async.fn = loadfile_handler; + req->async.private = c; + c->req = req; return NT_STATUS_OK; } @@ -158,8 +165,9 @@ static NTSTATUS loadfile_close(struct smbcli_composite *c, struct smb_composite_loadfile *io) { NTSTATUS status; + struct smbcli_request *req = c->req; - status = smbcli_request_simple_recv(c->req); + status = smbcli_request_simple_recv(req); NT_STATUS_NOT_OK_RETURN(status); c->state = SMBCLI_REQUEST_DONE; @@ -212,13 +220,14 @@ struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, { struct smbcli_composite *c; union smb_open *io_open; + struct smbcli_request *req; c = talloc_zero(tree, struct smbcli_composite); if (c == NULL) goto failed; c->state = SMBCLI_REQUEST_SEND; - c->stage = LOADFILE_OPEN; c->composite_parms = io; + c->event_ctx = tree->session->transport->socket->event.ctx; /* setup for the open */ io_open = talloc_zero(c, union smb_open); @@ -234,13 +243,15 @@ struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, io_open->ntcreatex.in.fname = io->in.fname; /* send the open on its way */ - c->req = smb_raw_open_send(tree, io_open); - if (c->req == NULL) goto failed; + req = smb_raw_open_send(tree, io_open); + if (req == NULL) goto failed; /* setup the callback handler */ - c->req->async.fn = loadfile_handler; - c->req->async.private = c; + req->async.fn = loadfile_handler; + req->async.private = c; c->req_parms = io_open; + c->req = req; + c->stage = LOADFILE_OPEN; return c; diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index dc9ee2f9ec..af9d81b16b 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -44,6 +44,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { union smb_close *io_close; + struct smbcli_request *req = c->req; /* nothing to write, setup the close */ io_close = talloc(c, union smb_close); @@ -53,14 +54,15 @@ static NTSTATUS setup_close(struct smbcli_composite *c, io_close->close.in.fnum = fnum; io_close->close.in.write_time = 0; - c->req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(c->req); + req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the close is done */ c->stage = SAVEFILE_CLOSE; - c->req->async.fn = savefile_handler; - c->req->async.private = c; + req->async.fn = savefile_handler; + req->async.private = c; c->req_parms = io_close; + c->req = req; return NT_STATUS_OK; } @@ -73,7 +75,8 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, struct smb_composite_savefile *io) { union smb_open *io_open = c->req_parms; - struct smbcli_tree *tree = c->req->tree; + struct smbcli_request *req = c->req; + struct smbcli_tree *tree = req->tree; union smb_write *io_write; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; @@ -97,14 +100,15 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, io_write->writex.in.count = MIN(max_xmit - 100, io->in.size); io_write->writex.in.data = io->in.data; - c->req = smb_raw_write_send(tree, io_write); - NT_STATUS_HAVE_NO_MEMORY(c->req); + req = smb_raw_write_send(tree, io_write); + NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the first write is done */ c->stage = SAVEFILE_WRITE; - c->req->async.fn = savefile_handler; - c->req->async.private = c; + req->async.fn = savefile_handler; + req->async.private = c; c->req_parms = io_write; + c->req = req; talloc_free(io_open); return NT_STATUS_OK; @@ -119,7 +123,8 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, struct smb_composite_savefile *io) { union smb_write *io_write = c->req_parms; - struct smbcli_tree *tree = c->req->tree; + struct smbcli_request *req = c->req; + struct smbcli_tree *tree = req->tree; struct savefile_state *state = c->private; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; @@ -140,12 +145,13 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, io_write->writex.in.count = MIN(max_xmit - 100, io->in.size - state->total_written); io_write->writex.in.data = io->in.data + state->total_written; - c->req = smb_raw_write_send(tree, io_write); - NT_STATUS_HAVE_NO_MEMORY(c->req); + req = smb_raw_write_send(tree, io_write); + NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the write is done */ - c->req->async.fn = savefile_handler; - c->req->async.private = c; + req->async.fn = savefile_handler; + req->async.private = c; + c->req = req; return NT_STATUS_OK; } @@ -217,6 +223,7 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, struct smbcli_composite *c; union smb_open *io_open; struct savefile_state *state; + struct smbcli_request *req; c = talloc_zero(tree, struct smbcli_composite); if (c == NULL) goto failed; @@ -224,6 +231,7 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, c->state = SMBCLI_REQUEST_SEND; c->stage = SAVEFILE_OPEN; c->composite_parms = io; + c->event_ctx = tree->session->transport->socket->event.ctx; state = talloc(c, struct savefile_state); if (state == NULL) goto failed; @@ -244,14 +252,15 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, io_open->ntcreatex.in.fname = io->in.fname; /* send the open on its way */ - c->req = smb_raw_open_send(tree, io_open); - if (c->req == NULL) goto failed; + req = smb_raw_open_send(tree, io_open); + if (req == NULL) goto failed; /* setup the callback handler */ - c->req->async.fn = savefile_handler; - c->req->async.private = c; + req->async.fn = savefile_handler; + req->async.private = c; c->req_parms = io_open; c->private = state; + c->req = req; return c; -- cgit From da19be9a76447461857aa3bd6189a5a1bd7d78c2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 10:30:58 +0000 Subject: r4755: the recent change in the definition of lp_passwordserver() breaks this old code, so I'm just removing it, as it needs replacing anyway (This used to be commit cae7748d675e35bfb89b81349624258bc76fac1a) --- source4/libcli/namequery.c | 127 ------------------------------------------ source4/libcli/namequery_dc.c | 77 ------------------------- 2 files changed, 204 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 76fffe0d92..c440a604c7 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -1102,130 +1102,3 @@ BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr *ip) return True; } -/******************************************************** - Get the IP address list of the domain controllers for - a domain. -*********************************************************/ - -BOOL get_dc_list(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr **ip_list, int *count, int *ordered) -{ - - *ordered = False; - - /* If it's our domain then use the 'password server' parameter. */ - - if (strequal(domain, lp_workgroup())) { - const char *p; - const char *pserver = lp_passwordserver(); /* UNIX charset. */ - fstring name; - int num_addresses = 0; - int local_count, i, j; - struct ipv4_addr *return_iplist = NULL; - struct ipv4_addr *auto_ip_list = NULL; - BOOL done_auto_lookup = False; - int auto_count = 0; - - - if (!*pserver) - return internal_resolve_name(mem_ctx, - domain, 0x1C, ip_list, count); - - p = pserver; - - /* - * if '*' appears in the "password server" list then add - * an auto lookup to the list of manually configured - * DC's. If any DC is listed by name, then the list should be - * considered to be ordered - */ - - while (next_token(&p,name,LIST_SEP,sizeof(name))) { - if (strequal(name, "*")) { - if ( internal_resolve_name(mem_ctx, domain, 0x1C, &auto_ip_list, &auto_count) ) - num_addresses += auto_count; - done_auto_lookup = True; - DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); - } - else - num_addresses++; - } - - /* if we have no addresses and haven't done the auto lookup, then - just return the list of DC's */ - - if ( (num_addresses == 0) && !done_auto_lookup ) - return internal_resolve_name(mem_ctx, domain, 0x1C, ip_list, count); - - return_iplist = malloc_array_p(struct ipv4_addr, num_addresses); - - if (return_iplist == NULL) { - DEBUG(3,("get_dc_list: malloc fail !\n")); - return False; - } - - p = pserver; - local_count = 0; - - /* fill in the return list now with real IP's */ - - while ( (local_count 1) ) { - qsort(ip_list, count, sizeof(struct ipv4_addr), QSORT_CAST ip_compare); - } - - for (i = 0; i < count; i++) { - if (is_zero_ip(ip_list[i])) - continue; - - if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { - dc_ip = ip_list[i]; - goto done; - } - } - - - SAFE_FREE(ip_list); - - return False; -done: - /* We have the netbios name and IP address of a domain controller. - Ideally we should sent a SAMLOGON request to determine whether - the DC is alive and kicking. If we can catch a dead DC before - performing a smbcli_connect() we can avoid a 30-second timeout. */ - - DEBUG(3, ("rpc_find_dc: Returning DC %s (%s) for domain %s\n", srv_name, - inet_ntoa(dc_ip), domain)); - - *ip_out = dc_ip; - - SAFE_FREE(ip_list); - - return True; -} - -- cgit From e89fd49df7e63dcf37ee1aa7e2f50965851725c9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 10:38:12 +0000 Subject: r4757: added the ability of the clisocket level of libcli to handle async socket connections. This was complicated by a few factors: - it meant moving the event context from clitransport to clisocket, so lots of structures changed - we need to asynchronously handle connection to lists of port numbers, not just one port number. The code internally tries each port in the list in turn, without ever blocking - the man page on how connect() is supposed to work asynchronously doesn't work in practice (now why doesn't this surprise me?). The getsockopt() for SOL_ERROR is supposed to retrieve the error, but in fact the next (unrelated) connect() call on the same socket also gets an error, though not the right error. To work around this I need to tear down the whole socket between each attempted port. I hate posix. Note that clisocket.c still does a blocking name resolution call in smbcli_sock_connect_byname(). That will be fixed when we add the async NBT resolution code. Also note that I arranged things so that every SMB connection is now async internally, so using plain smbclient or smbtorture tests all the async features of this new code. (This used to be commit 468f8ebbfdbdf37c757fdc4863626aa9946a8870) --- source4/libcli/raw/clisocket.c | 244 ++++++++++++++++++++++++++++++-------- source4/libcli/raw/clitransport.c | 33 ++---- source4/libcli/raw/libcliraw.h | 31 ++--- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/util/errormap.c | 2 +- 5 files changed, 221 insertions(+), 91 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index fb9afeab81..d20dc4bf25 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. SMB client socket context management functions - Copyright (C) Andrew Tridgell 1994-2003 + + Copyright (C) Andrew Tridgell 1994-2005 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify @@ -20,7 +21,18 @@ */ #include "includes.h" +#include "events.h" #include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" + +/* + this private structure is used during async connection handling +*/ +struct clisocket_connect { + int *iports; + struct smbcli_socket *sock; + const char *dest_host; +}; /* create a smbcli_socket context @@ -29,61 +41,210 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) { struct smbcli_socket *sock; - sock = talloc_p(mem_ctx, struct smbcli_socket); + sock = talloc_zero(mem_ctx, struct smbcli_socket); if (!sock) { return NULL; } - ZERO_STRUCTP(sock); - sock->sock = NULL; - sock->port = 0; - - /* 20 second default timeout */ - sock->timeout = 20000; - sock->hostname = NULL; + sock->event.ctx = event_context_init(sock); + if (sock->event.ctx == NULL) { + talloc_free(sock); + return NULL; + } return sock; } +static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, + const char *hostaddr, int port); + /* - connect a smbcli_socket context to an IP/port pair - if port is 0 then choose 445 then 139 + handle socket write events during an async connect. These happen when the OS + has either completed the connect() or has returned an error */ -BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct ipv4_addr *ip, int port) +static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, + struct timeval t, uint16_t flags) { - NTSTATUS status; + struct smbcli_composite *c = fde->private; + struct clisocket_connect *conn = c->private; + int i; + + c->status = socket_connect_complete(conn->sock->sock, 0); + if (NT_STATUS_IS_OK(c->status)) { + socket_set_option(conn->sock->sock, lp_socket_options(), NULL); + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); + } + return; + } - if (port == 0) { - int i; - const char **ports = lp_smb_ports(); - for (i=0;ports[i];i++) { - port = atoi(ports[i]); - if (port != 0 && smbcli_sock_connect(sock, ip, port)) { - return True; + /* that port failed - try the next port */ + for (i=c->stage+1;conn->iports[i];i++) { + c->stage = i; + c->status = smbcli_sock_connect_one(conn->sock, + conn->dest_host, + conn->iports[i]); + if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + conn->sock->event.fde->private = c; + return; + } + if (NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); } + return; } - return False; } - status = socket_create("ip", SOCKET_TYPE_STREAM, &sock->sock, 0); - if (!NT_STATUS_IS_OK(status)) { - return False; + c->state = SMBCLI_REQUEST_ERROR; + if (c->async.fn) { + c->async.fn(c); } - talloc_steal(sock, sock->sock); +} - status = socket_connect(sock->sock, NULL, 0, sys_inet_ntoa(*ip), port, 0); - if (!NT_STATUS_IS_OK(status)) { + +/* + try to connect to the given address/port +*/ +static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, + const char *hostaddr, int port) +{ + struct fd_event fde; + NTSTATUS status; + + if (sock->sock) { talloc_free(sock->sock); sock->sock = NULL; - return False; } - sock->dest_ip = *ip; + if (sock->event.fde) { + event_remove_fd(sock->event.ctx, sock->event.fde); + sock->event.fde = NULL; + } + + status = socket_create("ip", SOCKET_TYPE_STREAM, &sock->sock, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + talloc_steal(sock, sock->sock); + + /* we initially look for write - see the man page on + non-blocking connect */ + fde.fd = socket_get_fd(sock->sock); + fde.flags = EVENT_FD_WRITE; + fde.handler = smbcli_sock_connect_handler; + fde.private = sock; + + sock->event.fde = event_add_fd(sock->event.ctx, &fde); sock->port = port; + set_blocking(fde.fd, False); + + return socket_connect(sock->sock, NULL, 0, hostaddr, port, 0); +} + - socket_set_option(sock->sock, lp_socket_options(), NULL); +/* + connect a smbcli_socket context to an IP/port pair + if port is 0 then choose 445 then 139 + + this is the async send side of the interface +*/ +struct smbcli_composite *smbcli_sock_connect_send(struct smbcli_socket *sock, + struct ipv4_addr *ip, int port) +{ + struct smbcli_composite *c; + struct clisocket_connect *conn; + int i; + + c = talloc_zero(sock, struct smbcli_composite); + if (c == NULL) return NULL; + + c->event_ctx = sock->event.ctx; + + conn = talloc(c, struct clisocket_connect); + if (conn == NULL) goto failed; + + conn->sock = sock; + + /* work out what ports we will try */ + if (port == 0) { + const char **ports = lp_smb_ports(); + for (i=0;ports[i];i++) /* noop */ ; + conn->iports = talloc_array(c, int, i+1); + if (conn->iports == NULL) goto failed; + for (i=0;ports[i];i++) { + conn->iports[i] = atoi(ports[i]); + } + conn->iports[i] = 0; + } else { + conn->iports = talloc_array(c, int, 2); + if (conn->iports == NULL) goto failed; + conn->iports[0] = port; + conn->iports[1] = 0; + } - return True; + conn->dest_host = talloc_strdup(c, sys_inet_ntoa(*ip)); + if (conn->dest_host == NULL) goto failed; + + c->private = conn; + c->state = SMBCLI_REQUEST_SEND; + + /* startup the connect process for each port in turn until one + succeeds or tells us that it is pending */ + for (i=0;conn->iports[i];i++) { + c->stage = i; + conn->sock->port = conn->iports[i]; + c->status = smbcli_sock_connect_one(sock, + conn->dest_host, + conn->iports[i]); + if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + sock->event.fde->private = c; + return c; + } + if (NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_DONE; + return c; + } + } + + c->state = SMBCLI_REQUEST_ERROR; + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + finish a smbcli_sock_connect_send() operation +*/ +NTSTATUS smbcli_sock_connect_recv(struct smbcli_composite *c) +{ + NTSTATUS status; + status = smb_composite_wait(c); + talloc_free(c); + return status; +} + +/* + connect a smbcli_socket context to an IP/port pair + if port is 0 then choose the ports listed in smb.conf (normally 445 then 139) + + sync version of the function +*/ +NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, struct ipv4_addr *ip, int port) +{ + struct smbcli_composite *c; + + c = smbcli_sock_connect_send(sock, ip, port); + if (c == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return smbcli_sock_connect_recv(c); } @@ -153,6 +314,7 @@ ssize_t smbcli_sock_read(struct smbcli_socket *sock, uint8_t *data, size_t len) return nread; } + /**************************************************************************** resolve a hostname and connect ****************************************************************************/ @@ -161,14 +323,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in int name_type = 0x20; struct ipv4_addr ip; char *name, *p; - BOOL ret; - -#if 0 - if (getenv("LIBSMB_PROG")) { - sock->fd = sock_exec(getenv("LIBSMB_PROG")); - return sock->fd != -1; - } -#endif + NTSTATUS status; name = talloc_strdup(sock, host); @@ -179,17 +334,12 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in } if (!resolve_name(name, name, &ip, name_type)) { - talloc_free(name); return False; } - ret = smbcli_sock_connect(sock, &ip, port); + sock->hostname = name; - if (ret) { - sock->hostname = talloc_steal(sock, name); - } else { - talloc_free(name); - } + status = smbcli_sock_connect(sock, &ip, port); - return ret; + return NT_STATUS_IS_OK(status); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 63ff1e4409..855543d670 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -53,8 +53,8 @@ static int transport_destructor(void *ptr) struct smbcli_transport *transport = ptr; smbcli_transport_dead(transport); - event_remove_fd(transport->event.ctx, transport->event.fde); - event_remove_timed(transport->event.ctx, transport->event.te); + event_remove_fd(transport->socket->event.ctx, transport->socket->event.fde); + event_remove_timed(transport->socket->event.ctx, transport->socket->event.te); return 0; } @@ -64,19 +64,12 @@ static int transport_destructor(void *ptr) struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) { struct smbcli_transport *transport; - struct fd_event fde; transport = talloc_p(sock, struct smbcli_transport); if (!transport) return NULL; ZERO_STRUCTP(transport); - transport->event.ctx = event_context_init(transport); - if (transport->event.ctx == NULL) { - talloc_free(transport); - return NULL; - } - transport->socket = talloc_reference(transport, sock); transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(); @@ -89,13 +82,11 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) ZERO_STRUCT(transport->called); - fde.fd = socket_get_fd(sock->sock); - fde.flags = EVENT_FD_READ; - fde.handler = smbcli_transport_event_handler; - fde.private = transport; - fde.ref_count = 1; - - transport->event.fde = event_add_fd(transport->event.ctx, &fde); + /* take over event handling from the socket layer - it only + handles events up until we are connected */ + transport->socket->event.fde->handler = smbcli_transport_event_handler; + transport->socket->event.fde->private = transport; + transport->socket->event.fde->flags = EVENT_FD_READ; talloc_set_destructor(transport, transport_destructor); @@ -138,7 +129,7 @@ void smbcli_transport_dead(struct smbcli_transport *transport) */ static void smbcli_transport_write_enable(struct smbcli_transport *transport) { - transport->event.fde->flags |= EVENT_FD_WRITE; + transport->socket->event.fde->flags |= EVENT_FD_WRITE; } /* @@ -146,7 +137,7 @@ static void smbcli_transport_write_enable(struct smbcli_transport *transport) */ static void smbcli_transport_write_disable(struct smbcli_transport *transport) { - transport->event.fde->flags &= ~EVENT_FD_WRITE; + transport->socket->event.fde->flags &= ~EVENT_FD_WRITE; } /**************************************************************************** @@ -254,14 +245,14 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, transport->idle.private = private; transport->idle.period = period; - if (transport->event.te != NULL) { - event_remove_timed(transport->event.ctx, transport->event.te); + if (transport->socket->event.te != NULL) { + event_remove_timed(transport->socket->event.ctx, transport->socket->event.te); } te.next_event = timeval_current_ofs(0, period); te.handler = idle_handler; te.private = transport; - transport->event.te = event_add_timed(transport->event.ctx, &te); + transport->socket->event.te = event_add_timed(transport->socket->event.ctx, &te); } /* diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 51b50fdcb9..4047a5d369 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -61,24 +61,20 @@ struct smbcli_negotiate { /* this is the context for a SMB socket associated with the socket itself */ struct smbcli_socket { - struct ipv4_addr dest_ip; - /* dest hostname (which may or may not be a DNS name) */ - char *hostname; + struct socket_context *sock; - /* the port used */ + /* what port we ended up connected to */ int port; - - struct socket_context *sock; - /* a count of the number of packets we have received. We - * actually only care about zero/non-zero at this stage */ - uint_t pkt_count; + /* the hostname we connected to */ + const char *hostname; - /* the network address of the client */ - char *client_addr; - - /* timeout for socket operations in milliseconds. */ - int timeout; + /* the event handle for waiting for socket IO */ + struct { + struct event_context *ctx; + struct fd_event *fde; + struct timed_event *te; + } event; }; /* @@ -164,13 +160,6 @@ struct smbcli_transport { size_t received; uint8_t *buffer; } recv_buffer; - - /* the event handle for waiting for socket IO */ - struct { - struct event_context *ctx; - struct fd_event *fde; - struct timed_event *te; - } event; }; /* this is the context for the user */ diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 8093b298bb..7fb12dcf80 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -333,7 +333,7 @@ BOOL smbcli_request_receive(struct smbcli_request *req) /* keep receiving packets until this one is replied to */ while (req->state <= SMBCLI_REQUEST_RECV) { - if (event_loop_once(req->transport->event.ctx) != 0) { + if (event_loop_once(req->transport->socket->event.ctx) != 0) { return False; } } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 4a57e436c7..b99ab3d2fe 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1497,7 +1497,7 @@ struct unix_error_map { const struct unix_error_map unix_nt_errmap[] = { { EAGAIN, STATUS_MORE_ENTRIES }, { EINTR, STATUS_MORE_ENTRIES }, - { EINPROGRESS, STATUS_MORE_ENTRIES }, + { EINPROGRESS, NT_STATUS_MORE_PROCESSING_REQUIRED }, { EPERM, NT_STATUS_ACCESS_DENIED }, { EACCES, NT_STATUS_ACCESS_DENIED }, { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND }, -- cgit From 61a3d370b98ca4b75cd61e22f0d6b0f3fb7561b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 11:58:52 +0000 Subject: r4758: - added async support to the session request code - added async support to the negprot client code - removed two unused parameters from smbcli_full_connection() code - converted smbclient to use smbcli_full_connection() rather than reinventing everything itself (This used to be commit 71cbe2873473e039b4511511302cb63f1c50bce8) --- source4/libcli/cliconnect.c | 35 ++++++++++++++++++---- source4/libcli/raw/clisession.c | 4 +-- source4/libcli/raw/clitransport.c | 61 ++++++++++++++++++++++++++++----------- source4/libcli/raw/clitree.c | 14 +++++---- source4/libcli/raw/rawnegotiate.c | 36 ++++++++++++++--------- 5 files changed, 105 insertions(+), 45 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index a0ba5ae0a1..4d46d1d23c 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -57,7 +57,7 @@ BOOL smbcli_transport_establish(struct smbcli_state *cli, /* wrapper around smb_raw_negotiate() */ NTSTATUS smbcli_negprot(struct smbcli_state *cli) { - return smb_raw_negotiate(cli->transport); + return smb_raw_negotiate(cli->transport, lp_maxprotocol()); } /* wrapper around smb_raw_session_setup() */ @@ -155,14 +155,11 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_state **ret_cli, const char *myname, const char *host, - struct ipv4_addr *ip, const char *sharename, const char *devtype, const char *username, const char *domain, - const char *password, - uint_t flags, - BOOL *retry) + const char *password) { struct smbcli_tree *tree; NTSTATUS status; @@ -231,3 +228,31 @@ void smbcli_shutdown(struct smbcli_state *cli) { talloc_free(cli); } + +/* + parse a //server/share type UNC name +*/ +BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, + const char **hostname, const char **sharename) +{ + char *p; + + if (strncmp(unc_name, "\\\\", 2) && + strncmp(unc_name, "//", 2)) { + return False; + } + + *hostname = talloc_strdup(mem_ctx, &unc_name[2]); + p = strchr_m(&(*hostname)[2],'/'); + if (!p) { + p = strchr_m(&(*hostname)[2],'\\'); + if (!p) return False; + } + *p = 0; + *sharename = talloc_strdup(mem_ctx, p+1); + + return True; +} + + + diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index dcc0c8adbe..322d27688e 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -38,16 +38,14 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) uint16_t flags2; uint32_t capabilities; - session = talloc_p(transport, struct smbcli_session); + session = talloc_zero(transport, struct smbcli_session); if (!session) { return NULL; } - ZERO_STRUCTP(session); session->transport = talloc_reference(session, transport); session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; - capabilities = transport->negotiate.capabilities; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 855543d670..fc9de577ee 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -140,12 +140,12 @@ static void smbcli_transport_write_disable(struct smbcli_transport *transport) transport->socket->event.fde->flags &= ~EVENT_FD_WRITE; } -/**************************************************************************** -send a session request (if appropriate) -****************************************************************************/ -BOOL smbcli_transport_connect(struct smbcli_transport *transport, - struct nmb_name *calling, - struct nmb_name *called) +/* + send a session request +*/ +struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport, + struct nmb_name *calling, + struct nmb_name *called) { uint8_t *p; int len = NBT_HDR_SIZE; @@ -155,13 +155,10 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, transport->called = *called; } - /* 445 doesn't have session request */ - if (transport->socket->port == 445) { - return True; - } - /* allocate output buffer */ - req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + 2*nbt_mangled_name_len()); + req = smbcli_request_setup_nonsmb(transport, + NBT_HDR_SIZE + 2*nbt_mangled_name_len()); + if (req == NULL) return NULL; /* put in the destination name */ p = req->out.buffer + NBT_HDR_SIZE; @@ -176,15 +173,27 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, _smb_setlen(req->out.buffer,len-4); SCVAL(req->out.buffer,0,0x81); - if (!smbcli_request_send(req) || - !smbcli_request_receive(req)) { + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); + return NULL; + } + + return req; +} + +/* + finish a smbcli_transport_connect() +*/ +BOOL smbcli_transport_connect_recv(struct smbcli_request *req) +{ + if (!smbcli_request_receive(req)) { smbcli_request_destroy(req); return False; } - + if (CVAL(req->in.buffer,0) != 0x82) { - transport->error.etype = ETYPE_NBT; - transport->error.e.nbt_error = CVAL(req->in.buffer,4); + req->transport->error.etype = ETYPE_NBT; + req->transport->error.e.nbt_error = CVAL(req->in.buffer,4); smbcli_request_destroy(req); return False; } @@ -194,6 +203,24 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, } +/* + send a session request (if needed) +*/ +BOOL smbcli_transport_connect(struct smbcli_transport *transport, + struct nmb_name *calling, + struct nmb_name *called) +{ + struct smbcli_request *req; + + if (transport->socket->port == 445) { + return True; + } + + req = smbcli_transport_connect_send(transport, + calling, called); + return smbcli_transport_connect_recv(req); +} + /**************************************************************************** get next mid in sequence ****************************************************************************/ diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 0f56c0fe2e..cc7fefd084 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -34,12 +34,11 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) { struct smbcli_tree *tree; - tree = talloc_p(session, struct smbcli_tree); + tree = talloc_zero(session, struct smbcli_tree); if (!tree) { return NULL; } - ZERO_STRUCTP(tree); tree->session = talloc_reference(tree, session); return tree; @@ -48,7 +47,8 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) /**************************************************************************** Send a tconX (async send) ****************************************************************************/ -struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, union smb_tcon *parms) +struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, + union smb_tcon *parms) { struct smbcli_request *req = NULL; @@ -83,7 +83,8 @@ struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, union smb /**************************************************************************** Send a tconX (async recv) ****************************************************************************/ -NTSTATUS smb_tree_connect_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_tcon *parms) +NTSTATUS smb_tree_connect_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, + union smb_tcon *parms) { uint8_t *p; @@ -124,7 +125,8 @@ failed: /**************************************************************************** Send a tconX (sync interface) ****************************************************************************/ -NTSTATUS smb_tree_connect(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_tcon *parms) +NTSTATUS smb_tree_connect(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, + union smb_tcon *parms) { struct smbcli_request *req = smb_tree_connect_send(tree, parms); return smb_tree_connect_recv(req, mem_ctx, parms); @@ -203,7 +205,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, /* negotiate protocol options with the server */ - status = smb_raw_negotiate(transport); + status = smb_raw_negotiate(transport, lp_maxprotocol()); if (!NT_STATUS_IS_OK(status)) { talloc_free(transport); return status; diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index a8cf603d46..d2d6b66d59 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. + SMB client negotiate context management functions - Copyright (C) Andrew Tridgell 1994-1998 + + Copyright (C) Andrew Tridgell 1994-2005 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify @@ -40,10 +42,11 @@ static const struct { {PROTOCOL_NT1,"NT LM 0.12"}, }; -/**************************************************************************** - Send a negprot command. -****************************************************************************/ -struct smbcli_request *smb_negprot_send(struct smbcli_transport *transport, int maxprotocol) +/* + Send a negprot command. +*/ +struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport, + int maxprotocol) { struct smbcli_request *req; int i; @@ -82,19 +85,14 @@ struct smbcli_request *smb_negprot_send(struct smbcli_transport *transport, int return req; } -/**************************************************************************** +/* Send a negprot command. -****************************************************************************/ -NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) +*/ +NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) { - struct smbcli_request *req; + struct smbcli_transport *transport = req->transport; int protocol; - req = smb_negprot_send(transport, lp_maxprotocol()); - if (!req) { - return NT_STATUS_UNSUCCESSFUL; - } - if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { return smbcli_request_destroy(req); @@ -183,3 +181,13 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport) failed: return smbcli_request_destroy(req); } + + +/* + Send a negprot command (sync interface) +*/ +NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, int maxprotocol) +{ + struct smbcli_request *req = smb_raw_negotiate_send(transport, maxprotocol); + return smb_raw_negotiate_recv(req); +} -- cgit From 8ea26bf2fdad4440d65b020943e19128c34c4ed9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 01:21:18 +0000 Subject: r4765: simplify the async socket code to always go via the event handler rather than short-circuiting in the unlikely event the OS returns an immediate success on a non-blocking connect (This used to be commit db4380717041485e216f965103f9e803518b45c3) --- source4/libcli/raw/clisocket.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index d20dc4bf25..851cf67caa 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -85,17 +85,11 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even c->status = smbcli_sock_connect_one(conn->sock, conn->dest_host, conn->iports[i]); - if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_IS_OK(c->status) || + NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { conn->sock->event.fde->private = c; return; } - if (NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_DONE; - if (c->async.fn) { - c->async.fn(c); - } - return; - } } c->state = SMBCLI_REQUEST_ERROR; @@ -153,7 +147,7 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, this is the async send side of the interface */ struct smbcli_composite *smbcli_sock_connect_send(struct smbcli_socket *sock, - struct ipv4_addr *ip, int port) + const char *host_addr, int port) { struct smbcli_composite *c; struct clisocket_connect *conn; @@ -186,7 +180,7 @@ struct smbcli_composite *smbcli_sock_connect_send(struct smbcli_socket *sock, conn->iports[1] = 0; } - conn->dest_host = talloc_strdup(c, sys_inet_ntoa(*ip)); + conn->dest_host = talloc_strdup(c, host_addr); if (conn->dest_host == NULL) goto failed; c->private = conn; @@ -200,14 +194,11 @@ struct smbcli_composite *smbcli_sock_connect_send(struct smbcli_socket *sock, c->status = smbcli_sock_connect_one(sock, conn->dest_host, conn->iports[i]); - if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_IS_OK(c->status) || + NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { sock->event.fde->private = c; return c; } - if (NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_DONE; - return c; - } } c->state = SMBCLI_REQUEST_ERROR; @@ -235,11 +226,11 @@ NTSTATUS smbcli_sock_connect_recv(struct smbcli_composite *c) sync version of the function */ -NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, struct ipv4_addr *ip, int port) +NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port) { struct smbcli_composite *c; - c = smbcli_sock_connect_send(sock, ip, port); + c = smbcli_sock_connect_send(sock, host_addr, port); if (c == NULL) { return NT_STATUS_NO_MEMORY; } @@ -339,7 +330,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in sock->hostname = name; - status = smbcli_sock_connect(sock, &ip, port); + status = smbcli_sock_connect(sock, sys_inet_ntoa(ip), port); return NT_STATUS_IS_OK(status); } -- cgit From eec22cfe2fe8cf46190761369016382a274426c6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 01:22:08 +0000 Subject: r4767: handle the different NBT session request refusals, and map them to reasonable NT_STATUS values (This used to be commit b193a9cb0c851a4ec55ad9956a815be93eea35e4) --- source4/libcli/raw/clitransport.c | 51 +++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index fc9de577ee..14c0779968 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -181,25 +181,54 @@ struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *tr return req; } +/* + map a session request error to a NTSTATUS + */ +static NTSTATUS map_session_refused_error(uint8_t error) +{ + switch (error) { + case 0x80: + case 0x81: + return NT_STATUS_REMOTE_NOT_LISTENING; + case 0x82: + return NT_STATUS_RESOURCE_NAME_NOT_FOUND; + case 0x83: + return NT_STATUS_REMOTE_RESOURCES; + } + return NT_STATUS_UNEXPECTED_IO_ERROR; +} + + /* finish a smbcli_transport_connect() */ -BOOL smbcli_transport_connect_recv(struct smbcli_request *req) +NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req) { + NTSTATUS status; + if (!smbcli_request_receive(req)) { smbcli_request_destroy(req); - return False; + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } - if (CVAL(req->in.buffer,0) != 0x82) { - req->transport->error.etype = ETYPE_NBT; - req->transport->error.e.nbt_error = CVAL(req->in.buffer,4); - smbcli_request_destroy(req); - return False; + switch (CVAL(req->in.buffer,0)) { + case 0x82: + status = NT_STATUS_OK; + break; + case 0x83: + status = map_session_refused_error(CVAL(req->in.buffer,4)); + break; + case 0x84: + DEBUG(1,("Warning: session retarget not supported\n")); + status = NT_STATUS_NOT_SUPPORTED; + break; + default: + status = NT_STATUS_UNEXPECTED_IO_ERROR; + break; } smbcli_request_destroy(req); - return True; + return status; } @@ -211,14 +240,16 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, struct nmb_name *called) { struct smbcli_request *req; - + NTSTATUS status; + if (transport->socket->port == 445) { return True; } req = smbcli_transport_connect_send(transport, calling, called); - return smbcli_transport_connect_recv(req); + status = smbcli_transport_connect_recv(req); + return NT_STATUS_IS_OK(status); } /**************************************************************************** -- cgit From 1e776edfc546f01341f153daa80e4155e5ff9855 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 01:28:11 +0000 Subject: r4769: added a smb_composite_connect() function that provides a simple async interface to a complete SMB connection setup. Internally it does: - socket connection - session request (if needed) - negprot - session setup - tcon This is the first example of a composite function that builds on other composite components (the socket connection is a composite function, which is used as a building block for this function). I think this will be quite common in composite functions in the future, building up ever more complex composite functions from smaller building blocks, while hiding the details from the caller. There are two things missing from this now. The first is async name resolution routines (wins, bcast, DNS etc), and the second is that this code currently only does a NT1 style session setup. I'll work on adding spnego and old style session setup support next. (This used to be commit 6bc9e17f5c5236f662c7c8f308d03e6d97379b23) --- source4/libcli/composite/composite.h | 28 +++ source4/libcli/composite/connect.c | 409 +++++++++++++++++++++++++++++++++++ source4/libcli/config.mk | 3 +- source4/libcli/raw/clisession.c | 6 +- source4/libcli/raw/clitree.c | 34 +++ 5 files changed, 476 insertions(+), 4 deletions(-) create mode 100644 source4/libcli/composite/connect.c (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 6bffc63211..dce4e4e109 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -87,3 +87,31 @@ struct smb_composite_savefile { uint32_t size; } in; }; + + +/* + a composite request for a full connection to a remote server. Includes + + - socket establishment + - session request + - negprot + - session setup + - tree connect +*/ +struct smb_composite_connect { + struct { + const char *dest_host; + int port; + const char *called_name; + const char *calling_name; + const char *service; + const char *service_type; + const char *user; + const char *domain; + const char *password; + } in; + struct { + struct smbcli_tree *tree; + } out; +}; + diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c new file mode 100644 index 0000000000..310084d0b1 --- /dev/null +++ b/source4/libcli/composite/connect.c @@ -0,0 +1,409 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for making a full SMB connection +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" + +/* the stages of this call */ +enum connect_stage {CONNECT_SOCKET, + CONNECT_SESSION_REQUEST, + CONNECT_NEGPROT, + CONNECT_SESSION_SETUP, + CONNECT_TCON}; + +struct connect_state { + struct smbcli_socket *sock; + struct smbcli_transport *transport; + struct smbcli_session *session; +}; + + +static void request_handler(struct smbcli_request *); +static void composite_handler(struct smbcli_composite *); + +/* + setup a negprot send +*/ +static NTSTATUS connect_send_negprot(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = c->private; + struct smbcli_request *req; + + req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); + NT_STATUS_HAVE_NO_MEMORY(req); + + req->async.fn = request_handler; + req->async.private = c; + c->stage = CONNECT_NEGPROT; + c->req = req; + + return NT_STATUS_OK; +} + + +/* + a tree connect request has competed +*/ +static NTSTATUS connect_tcon(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct smbcli_request *req = c->req; + union smb_tcon *io_tcon = c->req_parms; + NTSTATUS status; + + status = smb_tree_connect_recv(req, c, io_tcon); + NT_STATUS_NOT_OK_RETURN(status); + + io->out.tree->tid = io_tcon->tconx.out.tid; + if (io_tcon->tconx.out.dev_type) { + io->out.tree->device = talloc_strdup(io->out.tree, + io_tcon->tconx.out.dev_type); + } + if (io_tcon->tconx.out.fs_type) { + io->out.tree->fs_type = talloc_strdup(io->out.tree, + io_tcon->tconx.out.fs_type); + } + + /* all done! */ + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); + } + + return NT_STATUS_OK; +} + + +/* + a session setup request has competed +*/ +static NTSTATUS connect_session_setup(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = c->private; + struct smbcli_request *req = c->req; + union smb_sesssetup *io_setup = c->req_parms; + union smb_tcon *io_tcon; + NTSTATUS status; + + status = smb_raw_session_setup_recv(req, c, io_setup); + NT_STATUS_NOT_OK_RETURN(status); + + state->session->vuid = io_setup->nt1.out.vuid; + + /* setup for a tconx */ + io->out.tree = smbcli_tree_init(state->session); + NT_STATUS_HAVE_NO_MEMORY(io->out.tree); + + io_tcon = talloc(c, union smb_tcon); + NT_STATUS_HAVE_NO_MEMORY(io_tcon); + + /* connect to a share using a tree connect */ + io_tcon->generic.level = RAW_TCON_TCONX; + io_tcon->tconx.in.flags = 0; + io_tcon->tconx.in.password = data_blob(NULL, 0); + + io_tcon->tconx.in.path = talloc_asprintf(io_tcon, + "\\\\%s\\%s", + io->in.called_name, + io->in.service); + NT_STATUS_HAVE_NO_MEMORY(io_tcon->tconx.in.path); + if (!io->in.service_type) { + io_tcon->tconx.in.device = "?????"; + } else { + io_tcon->tconx.in.device = io->in.service_type; + } + + req = smb_tree_connect_send(io->out.tree, io_tcon); + NT_STATUS_HAVE_NO_MEMORY(req); + + req->async.fn = request_handler; + req->async.private = c; + c->req_parms = io_tcon; + c->req = req; + c->stage = CONNECT_TCON; + + return NT_STATUS_OK; +} + +/* + form an encrypted lanman password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB lanman_blob(const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob(NULL, 24); + SMBencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + form an encrypted NT password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob(NULL, 24); + SMBNTencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + a negprot request has competed +*/ +static NTSTATUS connect_negprot(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = c->private; + struct smbcli_request *req = c->req; + NTSTATUS status; + union smb_sesssetup *io_setup; + + status = smb_raw_negotiate_recv(req); + NT_STATUS_NOT_OK_RETURN(status); + + /* next step is a session setup */ + state->session = smbcli_session_init(state->transport); + NT_STATUS_HAVE_NO_MEMORY(state->session); + + /* get rid of the extra reference to the transport */ + talloc_free(state->transport); + + io_setup = talloc(c, union smb_sesssetup); + NT_STATUS_HAVE_NO_MEMORY(io_setup); + + /* prepare a session setup to establish a security context */ + io_setup->nt1.level = RAW_SESSSETUP_NT1; + io_setup->nt1.in.bufsize = state->session->transport->options.max_xmit; + io_setup->nt1.in.mpx_max = state->session->transport->options.max_mux; + io_setup->nt1.in.vc_num = 1; + io_setup->nt1.in.sesskey = state->transport->negotiate.sesskey; + io_setup->nt1.in.capabilities = state->transport->negotiate.capabilities; + io_setup->nt1.in.domain = io->in.domain; + io_setup->nt1.in.user = io->in.user; + io_setup->nt1.in.os = "Unix"; + io_setup->nt1.in.lanman = "Samba"; + + if (!io->in.password) { + io_setup->nt1.in.password1 = data_blob(NULL, 0); + io_setup->nt1.in.password2 = data_blob(NULL, 0); + } else if (state->session->transport->negotiate.sec_mode & + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + io_setup->nt1.in.password1 = lanman_blob(io->in.password, + state->transport->negotiate.secblob); + io_setup->nt1.in.password2 = nt_blob(io->in.password, + state->transport->negotiate.secblob); + smb_session_use_nt1_session_keys(state->session, io->in.password, &io_setup->nt1.in.password2); + + } else { + io_setup->nt1.in.password1 = data_blob(io->in.password, + strlen(io->in.password)); + io_setup->nt1.in.password2 = data_blob(NULL, 0); + } + + req = smb_raw_session_setup_send(state->session, io_setup); + NT_STATUS_HAVE_NO_MEMORY(req); + + req->async.fn = request_handler; + req->async.private = c; + c->req_parms = io_setup; + c->req = req; + c->stage = CONNECT_SESSION_SETUP; + + return NT_STATUS_OK; +} + + +/* + a session request operation has competed +*/ +static NTSTATUS connect_session_request(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct smbcli_request *req = c->req; + NTSTATUS status; + + status = smbcli_transport_connect_recv(req); + NT_STATUS_NOT_OK_RETURN(status); + + /* next step is a negprot */ + return connect_send_negprot(c, io); +} + +/* + a socket connection operation has competed +*/ +static NTSTATUS connect_socket(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = c->private; + NTSTATUS status; + struct smbcli_request *req; + struct nmb_name calling, called; + + status = smbcli_sock_connect_recv(c->req); + NT_STATUS_NOT_OK_RETURN(status); + + /* the socket is up - we can initialise the smbcli transport layer */ + state->transport = smbcli_transport_init(state->sock); + NT_STATUS_HAVE_NO_MEMORY(state->transport); + + /* we have a connected socket - next step is a session + request, if needed. Port 445 doesn't need it, so it goes + straight to the negprot */ + if (state->sock->port == 445) { + return connect_send_negprot(c, io); + } + + make_nmb_name(&calling, io->in.calling_name, 0x0); + choose_called_name(&called, io->in.called_name, 0x20); + + req = smbcli_transport_connect_send(state->transport, &calling, &called); + NT_STATUS_HAVE_NO_MEMORY(req); + + req->async.fn = request_handler; + req->async.private = c; + c->stage = CONNECT_SESSION_REQUEST; + c->req = req; + + return NT_STATUS_OK; +} + + + +/* + handle and dispatch state transitions +*/ +static void state_handler(struct smbcli_composite *c) +{ + struct smb_composite_connect *io = c->composite_parms; + + switch (c->stage) { + case CONNECT_SOCKET: + c->status = connect_socket(c, io); + break; + case CONNECT_SESSION_REQUEST: + c->status = connect_session_request(c, io); + break; + case CONNECT_NEGPROT: + c->status = connect_negprot(c, io); + break; + case CONNECT_SESSION_SETUP: + c->status = connect_session_setup(c, io); + break; + case CONNECT_TCON: + c->status = connect_tcon(c, io); + break; + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + if (c->async.fn) { + c->async.fn(c); + } + } +} + + +/* + handler for completion of a smbcli_request sub-request +*/ +static void request_handler(struct smbcli_request *req) +{ + struct smbcli_composite *c = req->async.private; + return state_handler(c); +} + +/* + handler for completion of a smbcli_composite sub-request +*/ +static void composite_handler(struct smbcli_composite *req) +{ + struct smbcli_composite *c = req->async.private; + return state_handler(c); +} + +/* + a function to establish a smbcli_tree from scratch +*/ +struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect *io) +{ + struct smbcli_composite *c, *req; + struct connect_state *state; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct connect_state); + if (state == NULL) goto failed; + + state->sock = smbcli_sock_init(state); + if (state->sock == NULL) goto failed; + + c->state = SMBCLI_REQUEST_SEND; + c->composite_parms = io; + c->stage = CONNECT_SOCKET; + c->event_ctx = state->sock->event.ctx; + c->private = state; + + req = smbcli_sock_connect_send(state->sock, io->in.dest_host, io->in.port); + if (req == NULL) goto failed; + + req->async.private = c; + req->async.fn = composite_handler; + c->req = req; + + return c; +failed: + talloc_free(c); + return NULL; +} + +/* + recv half of async composite connect code +*/ +NTSTATUS smb_composite_connect_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = smb_composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct smb_composite_connect *io = c->composite_parms; + talloc_steal(mem_ctx, io->out.tree); + } + + talloc_free(c); + return status; +} + +/* + sync version of smb_composite_connect +*/ +NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx) +{ + struct smbcli_composite *c = smb_composite_connect_send(io); + return smb_composite_connect_recv(c, mem_ctx); +} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 40eecca0f9..3d4c3a8566 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -22,7 +22,8 @@ ADD_OBJ_FILES = libcli/util/clilsa.o ADD_OBJ_FILES = \ libcli/composite/composite.o \ libcli/composite/loadfile.o \ - libcli/composite/savefile.o + libcli/composite/savefile.o \ + libcli/composite/connect.o [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB LIBCLI_COMPOSITE diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 322d27688e..46236217ea 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -256,8 +256,8 @@ void smbcli_session_set_user_session_key(struct smbcli_session *session, /* setup signing for a NT1 style session setup */ -static void use_nt1_session_keys(struct smbcli_session *session, - const char *password, const DATA_BLOB *nt_response) +void smb_session_use_nt1_session_keys(struct smbcli_session *session, + const char *password, const DATA_BLOB *nt_response) { struct smbcli_transport *transport = session->transport; uint8_t nt_hash[16]; @@ -352,7 +352,7 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct smbcli_session *session session->transport->negotiate.secblob); s2.nt1.in.password2 = nt_blob(parms->generic.in.password, session->transport->negotiate.secblob); - use_nt1_session_keys(session, parms->generic.in.password, &s2.nt1.in.password2); + smb_session_use_nt1_session_keys(session, parms->generic.in.password, &s2.nt1.in.password2); } else { s2.nt1.in.password1 = data_blob(parms->generic.in.password, diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index cc7fefd084..7339ca07f1 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ @@ -289,3 +290,36 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, *ret_tree = tree; return NT_STATUS_OK; } + + +/* + a convenient function to establish a smbcli_tree from scratch +*/ +NTSTATUS async_smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, + struct smbcli_tree **ret_tree, + const char *my_name, + const char *dest_host, int port, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password) +{ + struct smb_composite_connect io; + NTSTATUS status; + + io.in.dest_host = dest_host; + io.in.port = port; + io.in.called_name = dest_host; + io.in.calling_name = my_name; + io.in.service = service; + io.in.service_type = service_type; + io.in.user = user; + io.in.domain = domain; + io.in.password = password; + + status = smb_composite_connect(&io, parent_ctx); + if (NT_STATUS_IS_OK(status)) { + *ret_tree = io.out.tree; + } + + return status; +} -- cgit From 7cbc768376ed0a839afca64aeea99cd53d0fbc6f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 11:15:08 +0000 Subject: r4777: added a smb_composite_sesssetup() async composite function. This encapsulates all the different session setup methods, including the multi-pass spnego code. I have hooked this into all the places that previously used the RAW_SESSSETUP_GENERIC method, and have removed the old RAW_SESSSETUP_GENERIC code from clisession.c and clitree.c. A nice side effect is that these two modules are now very simple again, back to being "raw" session setup handling, which was what was originally intended. I have also used this to replace the session setup code in the smb_composite_connect() code, and used that to build a very simple replacement for smbcli_tree_full_connection(). As a result, smbclient, smbtorture and all our other SMB connection code now goes via these composite async functions. That should give them a good workout! (This used to be commit 080d0518bc7d6fd4bc3ef783e7d4d2e3275d0799) --- source4/libcli/cliconnect.c | 28 +-- source4/libcli/composite/composite.h | 17 ++ source4/libcli/composite/connect.c | 88 ++------ source4/libcli/composite/sesssetup.c | 403 +++++++++++++++++++++++++++++++++++ source4/libcli/config.mk | 3 +- source4/libcli/raw/clisession.c | 358 +------------------------------ source4/libcli/raw/clisocket.c | 2 + source4/libcli/raw/clitransport.c | 3 +- source4/libcli/raw/clitree.c | 147 +------------ 9 files changed, 473 insertions(+), 576 deletions(-) create mode 100644 source4/libcli/composite/sesssetup.c (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 4d46d1d23c..0f916d1eb1 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -21,6 +21,7 @@ #include "includes.h" #include "system/filesys.h" #include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" /* wrapper around smbcli_sock_connect() @@ -66,7 +67,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, const char *password, const char *domain) { - union smb_sesssetup setup; + struct smb_composite_sesssetup setup; NTSTATUS status; TALLOC_CTX *mem_ctx; @@ -77,27 +78,26 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, mem_ctx = talloc_init("smbcli_session_setup"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; - setup.generic.level = RAW_SESSSETUP_GENERIC; - setup.generic.in.sesskey = cli->transport->negotiate.sesskey; - setup.generic.in.capabilities = cli->transport->negotiate.capabilities; + setup.in.sesskey = cli->transport->negotiate.sesskey; + setup.in.capabilities = cli->transport->negotiate.capabilities; if (!user || !user[0]) { - setup.generic.in.password = NULL; - setup.generic.in.user = ""; - setup.generic.in.domain = ""; - setup.generic.in.capabilities &= ~CAP_EXTENDED_SECURITY; + setup.in.password = NULL; + setup.in.user = ""; + setup.in.domain = ""; + setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; } else { if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { - setup.generic.in.password = password; + setup.in.password = password; } else { - setup.generic.in.password = NULL; + setup.in.password = NULL; } - setup.generic.in.user = user; - setup.generic.in.domain = domain; + setup.in.user = user; + setup.in.domain = domain; } - status = smb_raw_session_setup(cli->session, mem_ctx, &setup); + status = smb_composite_sesssetup(cli->session, &setup); - cli->session->vuid = setup.generic.out.vuid; + cli->session->vuid = setup.out.vuid; talloc_free(mem_ctx); diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index dce4e4e109..321d3be943 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -115,3 +115,20 @@ struct smb_composite_connect { } out; }; + +/* + generic session setup interface that takes care of which + session setup varient to use +*/ +struct smb_composite_sesssetup { + struct { + uint32_t sesskey; + uint32_t capabilities; + const char *password; + const char *user; + const char *domain; + } in; + struct { + uint16_t vuid; + } out; +}; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 310084d0b1..c51c8d48fd 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -103,15 +103,16 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, struct smb_composite_connect *io) { struct connect_state *state = c->private; - struct smbcli_request *req = c->req; - union smb_sesssetup *io_setup = c->req_parms; + struct smbcli_composite *req = c->req; + struct smbcli_request *req2; + struct smb_composite_sesssetup *io_setup = c->req_parms; union smb_tcon *io_tcon; NTSTATUS status; - status = smb_raw_session_setup_recv(req, c, io_setup); + status = smb_composite_sesssetup_recv(req); NT_STATUS_NOT_OK_RETURN(status); - state->session->vuid = io_setup->nt1.out.vuid; + state->session->vuid = io_setup->out.vuid; /* setup for a tconx */ io->out.tree = smbcli_tree_init(state->session); @@ -136,40 +137,18 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, io_tcon->tconx.in.device = io->in.service_type; } - req = smb_tree_connect_send(io->out.tree, io_tcon); - NT_STATUS_HAVE_NO_MEMORY(req); + req2 = smb_tree_connect_send(io->out.tree, io_tcon); + NT_STATUS_HAVE_NO_MEMORY(req2); - req->async.fn = request_handler; - req->async.private = c; + req2->async.fn = request_handler; + req2->async.private = c; c->req_parms = io_tcon; - c->req = req; + c->req = req2; c->stage = CONNECT_TCON; return NT_STATUS_OK; } -/* - form an encrypted lanman password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB lanman_blob(const char *pass, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob(NULL, 24); - SMBencrypt(pass, challenge.data, blob.data); - return blob; -} - -/* - form an encrypted NT password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob(NULL, 24); - SMBNTencrypt(pass, challenge.data, blob.data); - return blob; -} - /* a negprot request has competed */ @@ -178,8 +157,9 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, { struct connect_state *state = c->private; struct smbcli_request *req = c->req; + struct smbcli_composite *req2; NTSTATUS status; - union smb_sesssetup *io_setup; + struct smb_composite_sesssetup *io_setup; status = smb_raw_negotiate_recv(req); NT_STATUS_NOT_OK_RETURN(status); @@ -191,45 +171,23 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, /* get rid of the extra reference to the transport */ talloc_free(state->transport); - io_setup = talloc(c, union smb_sesssetup); + io_setup = talloc(c, struct smb_composite_sesssetup); NT_STATUS_HAVE_NO_MEMORY(io_setup); /* prepare a session setup to establish a security context */ - io_setup->nt1.level = RAW_SESSSETUP_NT1; - io_setup->nt1.in.bufsize = state->session->transport->options.max_xmit; - io_setup->nt1.in.mpx_max = state->session->transport->options.max_mux; - io_setup->nt1.in.vc_num = 1; - io_setup->nt1.in.sesskey = state->transport->negotiate.sesskey; - io_setup->nt1.in.capabilities = state->transport->negotiate.capabilities; - io_setup->nt1.in.domain = io->in.domain; - io_setup->nt1.in.user = io->in.user; - io_setup->nt1.in.os = "Unix"; - io_setup->nt1.in.lanman = "Samba"; - - if (!io->in.password) { - io_setup->nt1.in.password1 = data_blob(NULL, 0); - io_setup->nt1.in.password2 = data_blob(NULL, 0); - } else if (state->session->transport->negotiate.sec_mode & - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - io_setup->nt1.in.password1 = lanman_blob(io->in.password, - state->transport->negotiate.secblob); - io_setup->nt1.in.password2 = nt_blob(io->in.password, - state->transport->negotiate.secblob); - smb_session_use_nt1_session_keys(state->session, io->in.password, &io_setup->nt1.in.password2); + io_setup->in.sesskey = state->transport->negotiate.sesskey; + io_setup->in.capabilities = state->transport->negotiate.capabilities; + io_setup->in.domain = io->in.domain; + io_setup->in.user = io->in.user; + io_setup->in.password = io->in.password; - } else { - io_setup->nt1.in.password1 = data_blob(io->in.password, - strlen(io->in.password)); - io_setup->nt1.in.password2 = data_blob(NULL, 0); - } + req2 = smb_composite_sesssetup_send(state->session, io_setup); + NT_STATUS_HAVE_NO_MEMORY(req2); - req = smb_raw_session_setup_send(state->session, io_setup); - NT_STATUS_HAVE_NO_MEMORY(req); - - req->async.fn = request_handler; - req->async.private = c; + req2->async.fn = composite_handler; + req2->async.private = c; c->req_parms = io_setup; - c->req = req; + c->req = req2; c->stage = CONNECT_SESSION_SETUP; return NT_STATUS_OK; diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c new file mode 100644 index 0000000000..062235670e --- /dev/null +++ b/source4/libcli/composite/sesssetup.c @@ -0,0 +1,403 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for making handling a generic async session setup +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "auth/auth.h" + + +struct sesssetup_state { + union smb_sesssetup setup; + NTSTATUS session_key_err; +}; + + +/* + form an encrypted lanman password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB lanman_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); + SMBencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + form an encrypted NT password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); + SMBNTencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + store the user session key for a transport +*/ +static void set_user_session_key(struct smbcli_session *session, + const DATA_BLOB *session_key) +{ + session->user_session_key = data_blob_talloc(session, + session_key->data, + session_key->length); +} + +/* + setup signing for a NT1 style session setup +*/ +static void use_nt1_session_keys(struct smbcli_session *session, + const char *password, const DATA_BLOB *nt_response) +{ + struct smbcli_transport *transport = session->transport; + uint8_t nt_hash[16]; + DATA_BLOB session_key = data_blob_talloc(session, NULL, 16); + + E_md4hash(password, nt_hash); + SMBsesskeygen_ntv1(nt_hash, session_key.data); + + smbcli_transport_simple_set_signing(transport, session_key, *nt_response); + + set_user_session_key(session, &session_key); + data_blob_free(&session_key); +} + + +/* + handler for completion of a smbcli_request sub-request +*/ +static void request_handler(struct smbcli_request *req) +{ + struct smbcli_composite *c = req->async.private; + struct sesssetup_state *state = c->private; + struct smb_composite_sesssetup *io = c->composite_parms; + struct smbcli_session *session = req->session; + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB null_data_blob = data_blob(NULL, 0); + + c->status = smb_raw_session_setup_recv(req, state, &state->setup); + + switch (state->setup.old.level) { + case RAW_SESSSETUP_OLD: + io->out.vuid = state->setup.old.out.vuid; + break; + + case RAW_SESSSETUP_NT1: + io->out.vuid = state->setup.nt1.out.vuid; + break; + + case RAW_SESSSETUP_SPNEGO: + session->vuid = io->out.vuid = state->setup.spnego.out.vuid; + if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(c->status)) { + break; + } + c->status = gensec_update(session->gensec, state, + state->setup.spnego.out.secblob, + &state->setup.spnego.in.secblob); + if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(c->status)) { + break; + } + if (state->setup.spnego.in.secblob.length == 0) { + break; + } + + /* we need to do another round of session setup. We keep going until both sides + are happy */ + state->session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(state->session_key_err)) { + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } + + req = smb_raw_session_setup_send(session, &state->setup); + req->async.fn = request_handler; + req->async.private = c; + c->req = req; + return; + } + + /* enforce the local signing required flag */ + if (NT_STATUS_IS_OK(c->status) && io->in.user && io->in.user[0]) { + if (!session->transport->negotiate.sign_info.doing_signing + && session->transport->negotiate.sign_info.mandatory_signing) { + DEBUG(0, ("SMB signing required, but server does not support it\n")); + c->status = NT_STATUS_ACCESS_DENIED; + } + } + + if (NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_DONE; + } else { + c->state = SMBCLI_REQUEST_ERROR; + } + if (c->async.fn) { + c->async.fn(c); + } +} + + +/* + send a nt1 style session setup +*/ +static struct smbcli_request *session_setup_nt1(struct smbcli_composite *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io) +{ + struct sesssetup_state *state = c->private; + + state->setup.nt1.level = RAW_SESSSETUP_NT1; + state->setup.nt1.in.bufsize = session->transport->options.max_xmit; + state->setup.nt1.in.mpx_max = session->transport->options.max_mux; + state->setup.nt1.in.vc_num = 1; + state->setup.nt1.in.sesskey = io->in.sesskey; + state->setup.nt1.in.capabilities = io->in.capabilities; + state->setup.nt1.in.domain = io->in.domain; + state->setup.nt1.in.user = io->in.user; + state->setup.nt1.in.os = "Unix"; + state->setup.nt1.in.lanman = "Samba"; + + if (!io->in.password) { + state->setup.nt1.in.password1 = data_blob(NULL, 0); + state->setup.nt1.in.password2 = data_blob(NULL, 0); + } else if (session->transport->negotiate.sec_mode & + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + state->setup.nt1.in.password1 = lanman_blob(state, io->in.password, + session->transport->negotiate.secblob); + state->setup.nt1.in.password2 = nt_blob(state, io->in.password, + session->transport->negotiate.secblob); + use_nt1_session_keys(session, io->in.password, &state->setup.nt1.in.password2); + } else { + state->setup.nt1.in.password1 = data_blob_talloc(state, io->in.password, strlen(io->in.password)); + state->setup.nt1.in.password2 = data_blob(NULL, 0); + } + + return smb_raw_session_setup_send(session, &state->setup); +} + + +/* + old style session setup (pre NT1 protocol level) +*/ +static struct smbcli_request *session_setup_old(struct smbcli_composite *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io) +{ + struct sesssetup_state *state = c->private; + + state->setup.old.level = RAW_SESSSETUP_OLD; + state->setup.old.in.bufsize = session->transport->options.max_xmit; + state->setup.old.in.mpx_max = session->transport->options.max_mux; + state->setup.old.in.vc_num = 1; + state->setup.old.in.sesskey = io->in.sesskey; + state->setup.old.in.domain = io->in.domain; + state->setup.old.in.user = io->in.user; + state->setup.old.in.os = "Unix"; + state->setup.old.in.lanman = "Samba"; + + if (!io->in.password) { + state->setup.old.in.password = data_blob(NULL, 0); + } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + state->setup.old.in.password = lanman_blob(state, io->in.password, + session->transport->negotiate.secblob); + } else { + state->setup.old.in.password = data_blob_talloc(state, + io->in.password, + strlen(io->in.password)); + } + + return smb_raw_session_setup_send(session, &state->setup); +} + + +/* + old style session setup (pre NT1 protocol level) +*/ +static struct smbcli_request *session_setup_spnego(struct smbcli_composite *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io) +{ + struct sesssetup_state *state = c->private; + NTSTATUS status; + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB null_data_blob = data_blob(NULL, 0); + const char *chosen_oid = NULL; + + state->setup.spnego.level = RAW_SESSSETUP_SPNEGO; + state->setup.spnego.in.bufsize = session->transport->options.max_xmit; + state->setup.spnego.in.mpx_max = session->transport->options.max_mux; + state->setup.spnego.in.vc_num = 1; + state->setup.spnego.in.sesskey = io->in.sesskey; + state->setup.spnego.in.capabilities = io->in.capabilities; + state->setup.spnego.in.domain = io->in.domain; + state->setup.spnego.in.os = "Unix"; + state->setup.spnego.in.lanman = "Samba"; + state->setup.spnego.out.vuid = session->vuid; + + smbcli_temp_set_signing(session->transport); + + status = gensec_client_start(session, &session->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); + return NULL; + } + + gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); + + status = gensec_set_domain(session->gensec, io->in.domain); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", + io->in.domain, nt_errstr(status))); + return NULL; + } + + status = gensec_set_username(session->gensec, io->in.user); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", + io->in.user, nt_errstr(status))); + return NULL; + } + + status = gensec_set_password(session->gensec, io->in.password); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + nt_errstr(status))); + return NULL; + } + + status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + return NULL; + } + + if (session->transport->negotiate.secblob.length) { + chosen_oid = GENSEC_OID_SPNEGO; + } else { + /* without a sec blob, means raw NTLMSSP */ + chosen_oid = GENSEC_OID_NTLMSSP; + } + + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + return NULL; + } + + status = gensec_update(session->gensec, state, + session->transport->negotiate.secblob, + &state->setup.spnego.in.secblob); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + return NULL; + } + + state->session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(state->session_key_err)) { + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } + + return smb_raw_session_setup_send(session, &state->setup); +} + + +/* + composite session setup function that hides the details of all the + different session setup varients, including the multi-pass nature of + the spnego varient +*/ +struct smbcli_composite *smb_composite_sesssetup_send(struct smbcli_session *session, + struct smb_composite_sesssetup *io) +{ + struct smbcli_composite *c; + struct sesssetup_state *state; + struct smbcli_request *req = NULL; + + c = talloc_zero(session, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct sesssetup_state); + if (state == NULL) goto failed; + + c->state = SMBCLI_REQUEST_SEND; + c->req_parms = io; + c->private = state; + c->event_ctx = session->transport->socket->event.ctx; + c->composite_parms = io; + + /* no session setup at all in earliest protocol varients */ + if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { + ZERO_STRUCT(io->out); + c->state = SMBCLI_REQUEST_DONE; + return c; + } + + /* see what session setup interface we will use */ + if (session->transport->negotiate.protocol < PROTOCOL_NT1) { + req = session_setup_old(c, session, io); + } else if (!session->transport->options.use_spnego || + !(io->in.capabilities & CAP_EXTENDED_SECURITY)) { + req = session_setup_nt1(c, session, io); + } else { + req = session_setup_spnego(c, session, io); + } + + if (req == NULL) goto failed; + + req->async.fn = request_handler; + req->async.private = c; + c->req = req; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + receive a composite session setup reply +*/ +NTSTATUS smb_composite_sesssetup_recv(struct smbcli_composite *c) +{ + NTSTATUS status; + status = smb_composite_wait(c); + talloc_free(c); + return status; +} + +/* + sync version of smb_composite_sesssetup +*/ +NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io) +{ + struct smbcli_composite *c = smb_composite_sesssetup_send(session, io); + return smb_composite_sesssetup_recv(c); +} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 3d4c3a8566..0c4ba5cef0 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -23,7 +23,8 @@ ADD_OBJ_FILES = \ libcli/composite/composite.o \ libcli/composite/loadfile.o \ libcli/composite/savefile.o \ - libcli/composite/connect.o + libcli/composite/connect.o \ + libcli/composite/sesssetup.o [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB LIBCLI_COMPOSITE diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 46236217ea..ed50601c25 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. SMB client session context management functions - Copyright (C) Andrew Tridgell 1994-1998 + + Copyright (C) Andrew Tridgell 1994-2005 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify @@ -76,11 +77,7 @@ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session { struct smbcli_request *req = NULL; - switch (parms->generic.level) { - case RAW_SESSSETUP_GENERIC: - /* handled elsewhere */ - return NULL; - + switch (parms->old.level) { case RAW_SESSSETUP_OLD: SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); @@ -164,11 +161,7 @@ NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req, return smbcli_request_destroy(req); } - switch (parms->generic.level) { - case RAW_SESSSETUP_GENERIC: - /* handled elsewhere */ - return NT_STATUS_INVALID_LEVEL; - + switch (parms->old.level) { case RAW_SESSSETUP_OLD: SMBCLI_CHECK_WCT(req, 3); ZERO_STRUCT(parms->old.out); @@ -220,353 +213,14 @@ failed: return smbcli_request_destroy(req); } -/* - form an encrypted lanman password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB lanman_blob(const char *pass, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob(NULL, 24); - SMBencrypt(pass, challenge.data, blob.data); - return blob; -} - -/* - form an encrypted NT password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob(NULL, 24); - SMBNTencrypt(pass, challenge.data, blob.data); - return blob; -} - -/* - store the user session key for a transport -*/ -void smbcli_session_set_user_session_key(struct smbcli_session *session, - const DATA_BLOB *session_key) -{ - session->user_session_key = data_blob_talloc(session, - session_key->data, - session_key->length); -} /* - setup signing for a NT1 style session setup -*/ -void smb_session_use_nt1_session_keys(struct smbcli_session *session, - const char *password, const DATA_BLOB *nt_response) -{ - struct smbcli_transport *transport = session->transport; - uint8_t nt_hash[16]; - DATA_BLOB session_key = data_blob(NULL, 16); - - E_md4hash(password, nt_hash); - SMBsesskeygen_ntv1(nt_hash, session_key.data); - - smbcli_transport_simple_set_signing(transport, session_key, *nt_response); - - smbcli_session_set_user_session_key(session, &session_key); - data_blob_free(&session_key); -} - -/**************************************************************************** - Perform a session setup (sync interface) using generic interface and the old - style sesssetup call -****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic_old(struct smbcli_session *session, - TALLOC_CTX *mem_ctx, - union smb_sesssetup *parms) -{ - NTSTATUS status; - union smb_sesssetup s2; - - /* use the old interface */ - s2.generic.level = RAW_SESSSETUP_OLD; - s2.old.in.bufsize = session->transport->options.max_xmit; - s2.old.in.mpx_max = session->transport->options.max_mux; - s2.old.in.vc_num = 1; - s2.old.in.sesskey = parms->generic.in.sesskey; - s2.old.in.domain = parms->generic.in.domain; - s2.old.in.user = parms->generic.in.user; - s2.old.in.os = "Unix"; - s2.old.in.lanman = "Samba"; - - if (!parms->generic.in.password) { - s2.old.in.password = data_blob(NULL, 0); - } else if (session->transport->negotiate.sec_mode & - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - s2.old.in.password = lanman_blob(parms->generic.in.password, - session->transport->negotiate.secblob); - } else { - s2.old.in.password = data_blob(parms->generic.in.password, - strlen(parms->generic.in.password)); - } - - status = smb_raw_session_setup(session, mem_ctx, &s2); - - data_blob_free(&s2.old.in.password); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - parms->generic.out.vuid = s2.old.out.vuid; - parms->generic.out.os = s2.old.out.os; - parms->generic.out.lanman = s2.old.out.lanman; - parms->generic.out.domain = s2.old.out.domain; - - return NT_STATUS_OK; -} - -/**************************************************************************** - Perform a session setup (sync interface) using generic interface and the NT1 - style sesssetup call -****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic_nt1(struct smbcli_session *session, - TALLOC_CTX *mem_ctx, - union smb_sesssetup *parms) -{ - NTSTATUS status; - union smb_sesssetup s2; - - s2.generic.level = RAW_SESSSETUP_NT1; - s2.nt1.in.bufsize = session->transport->options.max_xmit; - s2.nt1.in.mpx_max = session->transport->options.max_mux; - s2.nt1.in.vc_num = 1; - s2.nt1.in.sesskey = parms->generic.in.sesskey; - s2.nt1.in.capabilities = parms->generic.in.capabilities; - s2.nt1.in.domain = parms->generic.in.domain; - s2.nt1.in.user = parms->generic.in.user; - s2.nt1.in.os = "Unix"; - s2.nt1.in.lanman = "Samba"; - - if (!parms->generic.in.password) { - s2.nt1.in.password1 = data_blob(NULL, 0); - s2.nt1.in.password2 = data_blob(NULL, 0); - } else if (session->transport->negotiate.sec_mode & - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - s2.nt1.in.password1 = lanman_blob(parms->generic.in.password, - session->transport->negotiate.secblob); - s2.nt1.in.password2 = nt_blob(parms->generic.in.password, - session->transport->negotiate.secblob); - smb_session_use_nt1_session_keys(session, parms->generic.in.password, &s2.nt1.in.password2); - - } else { - s2.nt1.in.password1 = data_blob(parms->generic.in.password, - strlen(parms->generic.in.password)); - s2.nt1.in.password2 = data_blob(NULL, 0); - } - - status = smb_raw_session_setup(session, mem_ctx, &s2); - - data_blob_free(&s2.nt1.in.password1); - data_blob_free(&s2.nt1.in.password2); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - parms->generic.out.vuid = s2.nt1.out.vuid; - parms->generic.out.os = s2.nt1.out.os; - parms->generic.out.lanman = s2.nt1.out.lanman; - parms->generic.out.domain = s2.nt1.out.domain; - - return NT_STATUS_OK; -} - -/**************************************************************************** - Perform a session setup (sync interface) using generic interface and the SPNEGO - style sesssetup call -****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *session, - TALLOC_CTX *mem_ctx, - union smb_sesssetup *parms) -{ - NTSTATUS status; - NTSTATUS session_key_err = NT_STATUS_NO_USER_SESSION_KEY; - union smb_sesssetup s2; - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB null_data_blob = data_blob(NULL, 0); - const char *chosen_oid = NULL; - - s2.generic.level = RAW_SESSSETUP_SPNEGO; - s2.spnego.in.bufsize = session->transport->options.max_xmit; - s2.spnego.in.mpx_max = session->transport->options.max_mux; - s2.spnego.in.vc_num = 1; - s2.spnego.in.sesskey = parms->generic.in.sesskey; - s2.spnego.in.capabilities = parms->generic.in.capabilities; - s2.spnego.in.domain = parms->generic.in.domain; - s2.spnego.in.os = "Unix"; - s2.spnego.in.lanman = "Samba"; - s2.spnego.out.vuid = session->vuid; - - smbcli_temp_set_signing(session->transport); - - status = gensec_client_start(session, &session->gensec); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); - return status; - } - - gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); - - status = gensec_set_domain(session->gensec, parms->generic.in.domain); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", - parms->generic.in.domain, nt_errstr(status))); - goto done; - } - - status = gensec_set_username(session->gensec, parms->generic.in.user); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", - parms->generic.in.user, nt_errstr(status))); - goto done; - } - - status = gensec_set_password(session->gensec, parms->generic.in.password); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client password: %s\n", - nt_errstr(status))); - goto done; - } - - status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto done; - } - - if (session->transport->negotiate.secblob.length) { - chosen_oid = GENSEC_OID_SPNEGO; - } else { - /* without a sec blob, means raw NTLMSSP */ - chosen_oid = GENSEC_OID_NTLMSSP; - } - - status = gensec_start_mech_by_oid(session->gensec, chosen_oid); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - goto done; - } - - status = gensec_update(session->gensec, mem_ctx, - session->transport->negotiate.secblob, - &s2.spnego.in.secblob); - - while(1) { - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - break; - } - - if (!NT_STATUS_IS_OK(session_key_err)) { - session_key_err = gensec_session_key(session->gensec, &session_key); - } - if (NT_STATUS_IS_OK(session_key_err)) { - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); - } - - if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) { - break; - } - - session->vuid = s2.spnego.out.vuid; - status = smb_raw_session_setup(session, mem_ctx, &s2); - session->vuid = UID_FIELD_INVALID; - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - break; - } - - status = gensec_update(session->gensec, mem_ctx, - s2.spnego.out.secblob, - &s2.spnego.in.secblob); - - } - -done: - if (NT_STATUS_IS_OK(status)) { - if (!NT_STATUS_IS_OK(session_key_err)) { - DEBUG(1, ("Failed to get user session key: %s\n", nt_errstr(session_key_err))); - return session_key_err; - } - - smbcli_session_set_user_session_key(session, &session_key); - - parms->generic.out.vuid = s2.spnego.out.vuid; - parms->generic.out.os = s2.spnego.out.os; - parms->generic.out.lanman = s2.spnego.out.lanman; - parms->generic.out.domain = s2.spnego.out.domain; - } else { - talloc_free(session->gensec); - session->gensec = NULL; - DEBUG(1, ("Failed to login with %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return status; - } - - return status; -} - -/**************************************************************************** - Perform a session setup (sync interface) using generic interface -****************************************************************************/ -static NTSTATUS smb_raw_session_setup_generic(struct smbcli_session *session, - TALLOC_CTX *mem_ctx, - union smb_sesssetup *parms) -{ - if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { - /* no session setup at all in earliest protocols */ - ZERO_STRUCT(parms->generic.out); - return NT_STATUS_OK; - } - - /* see if we need to use the original session setup interface */ - if (session->transport->negotiate.protocol < PROTOCOL_NT1) { - return smb_raw_session_setup_generic_old(session, mem_ctx, parms); - } - - /* see if we should use the NT1 interface */ - if (!session->transport->options.use_spnego || - !(parms->generic.in.capabilities & CAP_EXTENDED_SECURITY)) { - return smb_raw_session_setup_generic_nt1(session, mem_ctx, parms); - } - - /* default to using SPNEGO/NTLMSSP */ - return smb_raw_session_setup_generic_spnego(session, mem_ctx, parms); -} - - -/**************************************************************************** Perform a session setup (sync interface) -this interface allows for RAW_SESSSETUP_GENERIC to auto-select session -setup variant based on negotiated protocol options -****************************************************************************/ +*/ NTSTATUS smb_raw_session_setup(struct smbcli_session *session, TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { - struct smbcli_request *req; - - if (parms->generic.level == RAW_SESSSETUP_GENERIC) { - NTSTATUS ret = smb_raw_session_setup_generic(session, mem_ctx, parms); - - if (NT_STATUS_IS_OK(ret) - && parms->generic.in.user - && *parms->generic.in.user) { - if (!session->transport->negotiate.sign_info.doing_signing - && session->transport->negotiate.sign_info.mandatory_signing) { - DEBUG(0, ("SMB signing required, but server does not support it\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - return ret; - } - - req = smb_raw_session_setup_send(session, parms); + struct smbcli_request *req = smb_raw_session_setup_send(session, parms); return smb_raw_session_setup_recv(req, mem_ctx, parms); } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 851cf67caa..ad1c6a13b8 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -1,5 +1,6 @@ /* Unix SMB/CIFS implementation. + SMB client socket context management functions Copyright (C) Andrew Tridgell 1994-2005 @@ -72,6 +73,7 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even c->status = socket_connect_complete(conn->sock->sock, 0); if (NT_STATUS_IS_OK(c->status)) { socket_set_option(conn->sock->sock, lp_socket_options(), NULL); + conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_host); c->state = SMBCLI_REQUEST_DONE; if (c->async.fn) { c->async.fn(c); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 14c0779968..55a7e25f72 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. SMB client transport context management functions - Copyright (C) Andrew Tridgell 1994-2003 + + Copyright (C) Andrew Tridgell 1994-2005 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 7339ca07f1..c6b3fa5ad9 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. + SMB client tree context management functions - Copyright (C) Andrew Tridgell 1994-1998 + + Copyright (C) Andrew Tridgell 1994-2005 Copyright (C) James Myers 2003 This program is free software; you can redistribute it and/or modify @@ -152,8 +154,7 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) /* - a convenient function to establish a smbcli_tree from scratch, using reasonable default - parameters + a convenient function to establish a smbcli_tree from scratch */ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_tree **ret_tree, @@ -162,146 +163,6 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, const char *service, const char *service_type, const char *user, const char *domain, const char *password) -{ - struct smbcli_socket *sock; - struct smbcli_transport *transport; - struct smbcli_session *session; - struct smbcli_tree *tree; - NTSTATUS status; - struct nmb_name calling; - struct nmb_name called; - union smb_sesssetup setup; - union smb_tcon tcon; - TALLOC_CTX *mem_ctx; - char *in_path = NULL; - - *ret_tree = NULL; - - sock = smbcli_sock_init(parent_ctx); - if (!sock) { - return NT_STATUS_NO_MEMORY; - } - - /* open a TCP socket to the server */ - if (!smbcli_sock_connect_byname(sock, dest_host, port)) { - talloc_free(sock); - DEBUG(2,("Failed to establish socket connection - %s\n", strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; - } - - transport = smbcli_transport_init(sock); - talloc_free(sock); - if (!transport) { - return NT_STATUS_NO_MEMORY; - } - - /* send a NBT session request, if applicable */ - make_nmb_name(&calling, my_name, 0x0); - choose_called_name(&called, dest_host, 0x20); - - if (!smbcli_transport_connect(transport, &calling, &called)) { - talloc_free(transport); - return NT_STATUS_UNSUCCESSFUL; - } - - - /* negotiate protocol options with the server */ - status = smb_raw_negotiate(transport, lp_maxprotocol()); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(transport); - return status; - } - - session = smbcli_session_init(transport); - talloc_free(transport); - if (!session) { - return NT_STATUS_NO_MEMORY; - } - - /* prepare a session setup to establish a security context */ - setup.generic.level = RAW_SESSSETUP_GENERIC; - setup.generic.in.sesskey = transport->negotiate.sesskey; - setup.generic.in.capabilities = transport->negotiate.capabilities; - if (!user || !user[0]) { - setup.generic.in.password = NULL; - setup.generic.in.user = ""; - setup.generic.in.domain = ""; - } else { - setup.generic.in.password = password; - setup.generic.in.user = user; - setup.generic.in.domain = domain; - } - - mem_ctx = talloc_init("tcon"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - status = smb_raw_session_setup(session, mem_ctx, &setup); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(session); - talloc_free(mem_ctx); - return status; - } - - session->vuid = setup.generic.out.vuid; - - tree = smbcli_tree_init(session); - talloc_free(session); - if (!tree) { - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - /* connect to a share using a tree connect */ - tcon.generic.level = RAW_TCON_TCONX; - tcon.tconx.in.flags = 0; - tcon.tconx.in.password = data_blob(NULL, 0); - asprintf(&in_path, "\\\\%s\\%s", dest_host, service); - tcon.tconx.in.path = in_path; - if (!service_type) { - if (strequal(service, "IPC$")) - service_type = "IPC"; - else - service_type = "?????"; - } - tcon.tconx.in.device = service_type; - - status = smb_tree_connect(tree, mem_ctx, &tcon); - - SAFE_FREE(in_path); - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tree); - talloc_free(mem_ctx); - return status; - } - - tree->tid = tcon.tconx.out.tid; - if (tcon.tconx.out.dev_type) { - tree->device = talloc_strdup(tree, tcon.tconx.out.dev_type); - } - if (tcon.tconx.out.fs_type) { - tree->fs_type = talloc_strdup(tree, tcon.tconx.out.fs_type); - } - - talloc_free(mem_ctx); - - *ret_tree = tree; - return NT_STATUS_OK; -} - - -/* - a convenient function to establish a smbcli_tree from scratch -*/ -NTSTATUS async_smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, - struct smbcli_tree **ret_tree, - const char *my_name, - const char *dest_host, int port, - const char *service, const char *service_type, - const char *user, const char *domain, - const char *password) { struct smb_composite_connect io; NTSTATUS status; -- cgit From ab0fa0ba90b139231b9f345291ef8a655991765e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 11:45:49 +0000 Subject: r4778: I forgot to set the session key for the spnego path. Fixed. (This used to be commit 870af4e2f2055013424d9dbe2df2c51faa810eec) --- source4/libcli/composite/sesssetup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 062235670e..597c8d7923 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -130,6 +130,7 @@ static void request_handler(struct smbcli_request *req) are happy */ state->session_key_err = gensec_session_key(session->gensec, &session_key); if (NT_STATUS_IS_OK(state->session_key_err)) { + set_user_session_key(session, &session_key); smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } -- cgit From 99d30a901f04eac38922112c00a211e8fdb575a5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 21:58:28 +0000 Subject: r4782: volker quite rightly pointed out that there is too much of a proliferation of void* in the composite code. This removes two of the void* pointers from the main composite structure. (This used to be commit 5a89a5ed0fa022fb380bf72065904633270f34aa) --- source4/libcli/composite/composite.h | 6 -- source4/libcli/composite/connect.c | 81 +++++++++++++------------- source4/libcli/composite/loadfile.c | 106 ++++++++++++++++++----------------- source4/libcli/composite/savefile.c | 54 +++++++++--------- source4/libcli/composite/sesssetup.c | 14 ++--- 5 files changed, 131 insertions(+), 130 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 321d3be943..2e50d0b1ed 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -39,12 +39,6 @@ struct smbcli_composite { /* the currently running sub-request */ void *req; - /* the current requests parameter block */ - void *req_parms; - - /* the parameters of the whole composite function */ - void *composite_parms; - /* a private pointer for use by the composite code */ void *private; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index c51c8d48fd..aa5afae9e9 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -36,6 +36,9 @@ struct connect_state { struct smbcli_socket *sock; struct smbcli_transport *transport; struct smbcli_session *session; + struct smb_composite_connect *io; + union smb_tcon *io_tcon; + struct smb_composite_sesssetup *io_setup; }; @@ -69,21 +72,21 @@ static NTSTATUS connect_send_negprot(struct smbcli_composite *c, static NTSTATUS connect_tcon(struct smbcli_composite *c, struct smb_composite_connect *io) { + struct connect_state *state = c->private; struct smbcli_request *req = c->req; - union smb_tcon *io_tcon = c->req_parms; NTSTATUS status; - status = smb_tree_connect_recv(req, c, io_tcon); + status = smb_tree_connect_recv(req, c, state->io_tcon); NT_STATUS_NOT_OK_RETURN(status); - io->out.tree->tid = io_tcon->tconx.out.tid; - if (io_tcon->tconx.out.dev_type) { + io->out.tree->tid = state->io_tcon->tconx.out.tid; + if (state->io_tcon->tconx.out.dev_type) { io->out.tree->device = talloc_strdup(io->out.tree, - io_tcon->tconx.out.dev_type); + state->io_tcon->tconx.out.dev_type); } - if (io_tcon->tconx.out.fs_type) { + if (state->io_tcon->tconx.out.fs_type) { io->out.tree->fs_type = talloc_strdup(io->out.tree, - io_tcon->tconx.out.fs_type); + state->io_tcon->tconx.out.fs_type); } /* all done! */ @@ -105,44 +108,41 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, struct connect_state *state = c->private; struct smbcli_composite *req = c->req; struct smbcli_request *req2; - struct smb_composite_sesssetup *io_setup = c->req_parms; - union smb_tcon *io_tcon; NTSTATUS status; status = smb_composite_sesssetup_recv(req); NT_STATUS_NOT_OK_RETURN(status); - state->session->vuid = io_setup->out.vuid; + state->session->vuid = state->io_setup->out.vuid; /* setup for a tconx */ io->out.tree = smbcli_tree_init(state->session); NT_STATUS_HAVE_NO_MEMORY(io->out.tree); - io_tcon = talloc(c, union smb_tcon); - NT_STATUS_HAVE_NO_MEMORY(io_tcon); + state->io_tcon = talloc(c, union smb_tcon); + NT_STATUS_HAVE_NO_MEMORY(state->io_tcon); /* connect to a share using a tree connect */ - io_tcon->generic.level = RAW_TCON_TCONX; - io_tcon->tconx.in.flags = 0; - io_tcon->tconx.in.password = data_blob(NULL, 0); + state->io_tcon->generic.level = RAW_TCON_TCONX; + state->io_tcon->tconx.in.flags = 0; + state->io_tcon->tconx.in.password = data_blob(NULL, 0); - io_tcon->tconx.in.path = talloc_asprintf(io_tcon, + state->io_tcon->tconx.in.path = talloc_asprintf(state->io_tcon, "\\\\%s\\%s", io->in.called_name, io->in.service); - NT_STATUS_HAVE_NO_MEMORY(io_tcon->tconx.in.path); + NT_STATUS_HAVE_NO_MEMORY(state->io_tcon->tconx.in.path); if (!io->in.service_type) { - io_tcon->tconx.in.device = "?????"; + state->io_tcon->tconx.in.device = "?????"; } else { - io_tcon->tconx.in.device = io->in.service_type; + state->io_tcon->tconx.in.device = io->in.service_type; } - req2 = smb_tree_connect_send(io->out.tree, io_tcon); + req2 = smb_tree_connect_send(io->out.tree, state->io_tcon); NT_STATUS_HAVE_NO_MEMORY(req2); req2->async.fn = request_handler; req2->async.private = c; - c->req_parms = io_tcon; c->req = req2; c->stage = CONNECT_TCON; @@ -159,7 +159,6 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, struct smbcli_request *req = c->req; struct smbcli_composite *req2; NTSTATUS status; - struct smb_composite_sesssetup *io_setup; status = smb_raw_negotiate_recv(req); NT_STATUS_NOT_OK_RETURN(status); @@ -171,22 +170,21 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, /* get rid of the extra reference to the transport */ talloc_free(state->transport); - io_setup = talloc(c, struct smb_composite_sesssetup); - NT_STATUS_HAVE_NO_MEMORY(io_setup); + state->io_setup = talloc(c, struct smb_composite_sesssetup); + NT_STATUS_HAVE_NO_MEMORY(state->io_setup); /* prepare a session setup to establish a security context */ - io_setup->in.sesskey = state->transport->negotiate.sesskey; - io_setup->in.capabilities = state->transport->negotiate.capabilities; - io_setup->in.domain = io->in.domain; - io_setup->in.user = io->in.user; - io_setup->in.password = io->in.password; + state->io_setup->in.sesskey = state->transport->negotiate.sesskey; + state->io_setup->in.capabilities = state->transport->negotiate.capabilities; + state->io_setup->in.domain = io->in.domain; + state->io_setup->in.user = io->in.user; + state->io_setup->in.password = io->in.password; - req2 = smb_composite_sesssetup_send(state->session, io_setup); + req2 = smb_composite_sesssetup_send(state->session, state->io_setup); NT_STATUS_HAVE_NO_MEMORY(req2); req2->async.fn = composite_handler; req2->async.private = c; - c->req_parms = io_setup; c->req = req2; c->stage = CONNECT_SESSION_SETUP; @@ -256,23 +254,23 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, */ static void state_handler(struct smbcli_composite *c) { - struct smb_composite_connect *io = c->composite_parms; - + struct connect_state *state = c->private; + switch (c->stage) { case CONNECT_SOCKET: - c->status = connect_socket(c, io); + c->status = connect_socket(c, state->io); break; case CONNECT_SESSION_REQUEST: - c->status = connect_session_request(c, io); + c->status = connect_session_request(c, state->io); break; case CONNECT_NEGPROT: - c->status = connect_negprot(c, io); + c->status = connect_negprot(c, state->io); break; case CONNECT_SESSION_SETUP: - c->status = connect_session_setup(c, io); + c->status = connect_session_setup(c, state->io); break; case CONNECT_TCON: - c->status = connect_tcon(c, io); + c->status = connect_tcon(c, state->io); break; } @@ -320,8 +318,9 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect state->sock = smbcli_sock_init(state); if (state->sock == NULL) goto failed; + state->io = io; + c->state = SMBCLI_REQUEST_SEND; - c->composite_parms = io; c->stage = CONNECT_SOCKET; c->event_ctx = state->sock->event.ctx; c->private = state; @@ -349,8 +348,8 @@ NTSTATUS smb_composite_connect_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ status = smb_composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct smb_composite_connect *io = c->composite_parms; - talloc_steal(mem_ctx, io->out.tree); + struct connect_state *state = c->private; + talloc_steal(mem_ctx, state->io->out.tree); } talloc_free(c); diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index d8311e9151..e219707bc0 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -32,6 +32,11 @@ enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE}; static void loadfile_handler(struct smbcli_request *req); +struct loadfile_state { + struct smb_composite_loadfile *io; + union smb_open *io_open; + union smb_read *io_read; +}; /* setup for the close @@ -39,8 +44,8 @@ static void loadfile_handler(struct smbcli_request *req); static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { - union smb_close *io_close; struct smbcli_request *req; + union smb_close *io_close; /* nothing to read, setup the close */ io_close = talloc(c, union smb_close); @@ -56,7 +61,6 @@ static NTSTATUS setup_close(struct smbcli_composite *c, /* call the handler again when the close is done */ req->async.fn = loadfile_handler; req->async.private = c; - c->req_parms = io_close; c->req = req; c->stage = LOADFILE_CLOSE; @@ -70,52 +74,50 @@ static NTSTATUS setup_close(struct smbcli_composite *c, static NTSTATUS loadfile_open(struct smbcli_composite *c, struct smb_composite_loadfile *io) { - union smb_open *io_open = c->req_parms; + struct loadfile_state *state = c->private; struct smbcli_request *req = c->req; struct smbcli_tree *tree = req->tree; - union smb_read *io_read; NTSTATUS status; - status = smb_raw_open_recv(req, c, io_open); + status = smb_raw_open_recv(req, c, state->io_open); NT_STATUS_NOT_OK_RETURN(status); /* don't allow stupidly large loads */ - if (io_open->ntcreatex.out.size > 100*1000*1000) { + if (state->io_open->ntcreatex.out.size > 100*1000*1000) { return NT_STATUS_INSUFFICIENT_RESOURCES; } /* allocate space for the file data */ - io->out.size = io_open->ntcreatex.out.size; + io->out.size = state->io_open->ntcreatex.out.size; io->out.data = talloc_array(c, uint8_t, io->out.size); NT_STATUS_HAVE_NO_MEMORY(io->out.data); if (io->out.size == 0) { - return setup_close(c, tree, io_open->ntcreatex.out.fnum); + return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); } /* setup for the read */ - io_read = talloc(c, union smb_read); - NT_STATUS_HAVE_NO_MEMORY(io_read); + state->io_read = talloc(c, union smb_read); + NT_STATUS_HAVE_NO_MEMORY(state->io_read); - io_read->readx.level = RAW_READ_READX; - io_read->readx.in.fnum = io_open->ntcreatex.out.fnum; - io_read->readx.in.offset = 0; - io_read->readx.in.mincnt = MIN(32768, io->out.size); - io_read->readx.in.maxcnt = io_read->readx.in.mincnt; - io_read->readx.in.remaining = 0; - io_read->readx.out.data = io->out.data; - - req = smb_raw_read_send(tree, io_read); + state->io_read->readx.level = RAW_READ_READX; + state->io_read->readx.in.fnum = state->io_open->ntcreatex.out.fnum; + state->io_read->readx.in.offset = 0; + state->io_read->readx.in.mincnt = MIN(32768, io->out.size); + state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; + state->io_read->readx.in.remaining = 0; + state->io_read->readx.out.data = io->out.data; + + req = smb_raw_read_send(tree, state->io_read); NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the first read is done */ req->async.fn = loadfile_handler; req->async.private = c; - c->req_parms = io_read; c->req = req; c->stage = LOADFILE_READ; - talloc_free(io_open); + talloc_free(state->io_open); return NT_STATUS_OK; } @@ -128,26 +130,26 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, static NTSTATUS loadfile_read(struct smbcli_composite *c, struct smb_composite_loadfile *io) { - union smb_read *io_read = c->req_parms; + struct loadfile_state *state = c->private; struct smbcli_request *req = c->req; struct smbcli_tree *tree = req->tree; NTSTATUS status; - status = smb_raw_read_recv(req, io_read); + status = smb_raw_read_recv(req, state->io_read); NT_STATUS_NOT_OK_RETURN(status); /* we might be done */ - if (io_read->readx.in.offset + - io_read->readx.out.nread == io->out.size) { - return setup_close(c, tree, io_read->readx.in.fnum); + if (state->io_read->readx.in.offset + + state->io_read->readx.out.nread == io->out.size) { + return setup_close(c, tree, state->io_read->readx.in.fnum); } /* setup for the next read */ - io_read->readx.in.offset += io_read->readx.out.nread; - io_read->readx.in.mincnt = MIN(32768, io->out.size - io_read->readx.in.offset); - io_read->readx.out.data = io->out.data + io_read->readx.in.offset; + state->io_read->readx.in.offset += state->io_read->readx.out.nread; + state->io_read->readx.in.mincnt = MIN(32768, io->out.size - state->io_read->readx.in.offset); + state->io_read->readx.out.data = io->out.data + state->io_read->readx.in.offset; - req = smb_raw_read_send(tree, io_read); + req = smb_raw_read_send(tree, state->io_read); NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the read is done */ @@ -185,21 +187,21 @@ static NTSTATUS loadfile_close(struct smbcli_composite *c, static void loadfile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; - struct smb_composite_loadfile *io = c->composite_parms; + struct loadfile_state *state = c->private; /* when this handler is called, the stage indicates what call has just finished */ switch (c->stage) { case LOADFILE_OPEN: - c->status = loadfile_open(c, io); + c->status = loadfile_open(c, state->io); break; case LOADFILE_READ: - c->status = loadfile_read(c, io); + c->status = loadfile_read(c, state->io); break; case LOADFILE_CLOSE: - c->status = loadfile_close(c, io); + c->status = loadfile_close(c, state->io); break; } @@ -219,37 +221,41 @@ struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, struct smb_composite_loadfile *io) { struct smbcli_composite *c; - union smb_open *io_open; struct smbcli_request *req; + struct loadfile_state *state; c = talloc_zero(tree, struct smbcli_composite); if (c == NULL) goto failed; + state = talloc(c, struct loadfile_state); + if (state == NULL) goto failed; + + state->io = io; + + c->private = state; c->state = SMBCLI_REQUEST_SEND; - c->composite_parms = io; c->event_ctx = tree->session->transport->socket->event.ctx; /* setup for the open */ - io_open = talloc_zero(c, union smb_open); - if (io_open == NULL) goto failed; + state->io_open = talloc_zero(c, union smb_open); + if (state->io_open == NULL) goto failed; - io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; - io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; - io_open->ntcreatex.in.access_mask = SEC_FILE_READ_DATA; - io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; - io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; - io_open->ntcreatex.in.fname = io->in.fname; + state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + state->io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + state->io_open->ntcreatex.in.access_mask = SEC_FILE_READ_DATA; + state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + state->io_open->ntcreatex.in.fname = io->in.fname; /* send the open on its way */ - req = smb_raw_open_send(tree, io_open); + req = smb_raw_open_send(tree, state->io_open); if (req == NULL) goto failed; /* setup the callback handler */ req->async.fn = loadfile_handler; req->async.private = c; - c->req_parms = io_open; c->req = req; c->stage = LOADFILE_OPEN; @@ -271,8 +277,8 @@ NTSTATUS smb_composite_loadfile_recv(struct smbcli_composite *c, TALLOC_CTX *mem status = smb_composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct smb_composite_loadfile *io = c->composite_parms; - talloc_steal(mem_ctx, io->out.data); + struct loadfile_state *state = c->private; + talloc_steal(mem_ctx, state->io->out.data); } talloc_free(c); diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index af9d81b16b..9abe5f5329 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -34,6 +34,9 @@ static void savefile_handler(struct smbcli_request *req); struct savefile_state { off_t total_written; + struct smb_composite_savefile *io; + union smb_open *io_open; + union smb_write *io_write; }; @@ -61,7 +64,6 @@ static NTSTATUS setup_close(struct smbcli_composite *c, c->stage = SAVEFILE_CLOSE; req->async.fn = savefile_handler; req->async.private = c; - c->req_parms = io_close; c->req = req; return NT_STATUS_OK; @@ -74,18 +76,18 @@ static NTSTATUS setup_close(struct smbcli_composite *c, static NTSTATUS savefile_open(struct smbcli_composite *c, struct smb_composite_savefile *io) { - union smb_open *io_open = c->req_parms; + struct savefile_state *state = c->private; + union smb_write *io_write; struct smbcli_request *req = c->req; struct smbcli_tree *tree = req->tree; - union smb_write *io_write; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - status = smb_raw_open_recv(c->req, c, io_open); + status = smb_raw_open_recv(c->req, c, state->io_open); NT_STATUS_NOT_OK_RETURN(status); if (io->in.size == 0) { - return setup_close(c, tree, io_open->ntcreatex.out.fnum); + return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); } /* setup for the first write */ @@ -93,12 +95,13 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, NT_STATUS_HAVE_NO_MEMORY(io_write); io_write->writex.level = RAW_WRITE_WRITEX; - io_write->writex.in.fnum = io_open->ntcreatex.out.fnum; + io_write->writex.in.fnum = state->io_open->ntcreatex.out.fnum; io_write->writex.in.offset = 0; io_write->writex.in.wmode = 0; io_write->writex.in.remaining = 0; io_write->writex.in.count = MIN(max_xmit - 100, io->in.size); io_write->writex.in.data = io->in.data; + state->io_write = io_write; req = smb_raw_write_send(tree, io_write); NT_STATUS_HAVE_NO_MEMORY(req); @@ -107,9 +110,8 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, c->stage = SAVEFILE_WRITE; req->async.fn = savefile_handler; req->async.private = c; - c->req_parms = io_write; c->req = req; - talloc_free(io_open); + talloc_free(state->io_open); return NT_STATUS_OK; } @@ -122,30 +124,30 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, static NTSTATUS savefile_write(struct smbcli_composite *c, struct smb_composite_savefile *io) { - union smb_write *io_write = c->req_parms; + struct savefile_state *state = c->private; struct smbcli_request *req = c->req; struct smbcli_tree *tree = req->tree; - struct savefile_state *state = c->private; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - status = smb_raw_write_recv(c->req, io_write); + status = smb_raw_write_recv(c->req, state->io_write); NT_STATUS_NOT_OK_RETURN(status); - state->total_written += io_write->writex.out.nwritten; + state->total_written += state->io_write->writex.out.nwritten; /* we might be done */ - if (io_write->writex.out.nwritten != io_write->writex.in.count || + if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count || state->total_written == io->in.size) { - return setup_close(c, tree, io_write->writex.in.fnum); + return setup_close(c, tree, state->io_write->writex.in.fnum); } /* setup for the next write */ - io_write->writex.in.offset = state->total_written; - io_write->writex.in.count = MIN(max_xmit - 100, io->in.size - state->total_written); - io_write->writex.in.data = io->in.data + state->total_written; + state->io_write->writex.in.offset = state->total_written; + state->io_write->writex.in.count = MIN(max_xmit - 100, + io->in.size - state->total_written); + state->io_write->writex.in.data = io->in.data + state->total_written; - req = smb_raw_write_send(tree, io_write); + req = smb_raw_write_send(tree, state->io_write); NT_STATUS_HAVE_NO_MEMORY(req); /* call the handler again when the write is done */ @@ -162,8 +164,8 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, static NTSTATUS savefile_close(struct smbcli_composite *c, struct smb_composite_savefile *io) { - NTSTATUS status; struct savefile_state *state = c->private; + NTSTATUS status; status = smbcli_request_simple_recv(c->req); NT_STATUS_NOT_OK_RETURN(status); @@ -187,21 +189,21 @@ static NTSTATUS savefile_close(struct smbcli_composite *c, static void savefile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; - struct smb_composite_savefile *io = c->composite_parms; + struct savefile_state *state = c->private; /* when this handler is called, the stage indicates what call has just finished */ switch (c->stage) { case SAVEFILE_OPEN: - c->status = savefile_open(c, io); + c->status = savefile_open(c, state->io); break; case SAVEFILE_WRITE: - c->status = savefile_write(c, io); + c->status = savefile_write(c, state->io); break; case SAVEFILE_CLOSE: - c->status = savefile_close(c, io); + c->status = savefile_close(c, state->io); break; } @@ -221,22 +223,22 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, struct smb_composite_savefile *io) { struct smbcli_composite *c; - union smb_open *io_open; struct savefile_state *state; struct smbcli_request *req; + union smb_open *io_open; c = talloc_zero(tree, struct smbcli_composite); if (c == NULL) goto failed; c->state = SMBCLI_REQUEST_SEND; c->stage = SAVEFILE_OPEN; - c->composite_parms = io; c->event_ctx = tree->session->transport->socket->event.ctx; state = talloc(c, struct savefile_state); if (state == NULL) goto failed; state->total_written = 0; + state->io = io; /* setup for the open */ io_open = talloc_zero(c, union smb_open); @@ -250,6 +252,7 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io_open->ntcreatex.in.fname = io->in.fname; + state->io_open = io_open; /* send the open on its way */ req = smb_raw_open_send(tree, io_open); @@ -258,7 +261,6 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, /* setup the callback handler */ req->async.fn = savefile_handler; req->async.private = c; - c->req_parms = io_open; c->private = state; c->req = req; diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 597c8d7923..7053c9f9e5 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -30,6 +30,7 @@ struct sesssetup_state { union smb_sesssetup setup; NTSTATUS session_key_err; + struct smb_composite_sesssetup *io; }; @@ -93,7 +94,6 @@ static void request_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; struct sesssetup_state *state = c->private; - struct smb_composite_sesssetup *io = c->composite_parms; struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); @@ -102,15 +102,15 @@ static void request_handler(struct smbcli_request *req) switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: - io->out.vuid = state->setup.old.out.vuid; + state->io->out.vuid = state->setup.old.out.vuid; break; case RAW_SESSSETUP_NT1: - io->out.vuid = state->setup.nt1.out.vuid; + state->io->out.vuid = state->setup.nt1.out.vuid; break; case RAW_SESSSETUP_SPNEGO: - session->vuid = io->out.vuid = state->setup.spnego.out.vuid; + session->vuid = state->io->out.vuid = state->setup.spnego.out.vuid; if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(c->status)) { break; @@ -142,7 +142,7 @@ static void request_handler(struct smbcli_request *req) } /* enforce the local signing required flag */ - if (NT_STATUS_IS_OK(c->status) && io->in.user && io->in.user[0]) { + if (NT_STATUS_IS_OK(c->status) && state->io->in.user && state->io->in.user[0]) { if (!session->transport->negotiate.sign_info.doing_signing && session->transport->negotiate.sign_info.mandatory_signing) { DEBUG(0, ("SMB signing required, but server does not support it\n")); @@ -346,11 +346,11 @@ struct smbcli_composite *smb_composite_sesssetup_send(struct smbcli_session *ses state = talloc(c, struct sesssetup_state); if (state == NULL) goto failed; + state->io = io; + c->state = SMBCLI_REQUEST_SEND; - c->req_parms = io; c->private = state; c->event_ctx = session->transport->socket->event.ctx; - c->composite_parms = io; /* no session setup at all in earliest protocol varients */ if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { -- cgit From a38df2d251cc0e5489b7ea56401f40910798edd5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 22:22:13 +0000 Subject: r4783: got rid of another void* in the composite code. This brings us down to the minimal level I think (one private pointer for the composite function, and one private pointer for the caller) (This used to be commit 0240bf928163e32e7c69be88fe3ed4987dd18778) --- source4/libcli/composite/composite.h | 6 ++-- source4/libcli/composite/connect.c | 68 +++++++++++++++--------------------- source4/libcli/composite/loadfile.c | 54 +++++++++++++--------------- source4/libcli/composite/savefile.c | 52 ++++++++++++--------------- source4/libcli/composite/sesssetup.c | 22 ++++++------ 5 files changed, 88 insertions(+), 114 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 2e50d0b1ed..fba458795c 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -36,10 +36,8 @@ struct smbcli_composite { /* the internal stage */ uint16_t stage; - /* the currently running sub-request */ - void *req; - - /* a private pointer for use by the composite code */ + /* a private pointer for use by the composite function + implementation */ void *private; /* status code when finished */ diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index aa5afae9e9..bc39cc99fc 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -39,6 +39,8 @@ struct connect_state { struct smb_composite_connect *io; union smb_tcon *io_tcon; struct smb_composite_sesssetup *io_setup; + struct smbcli_request *req; + struct smbcli_composite *creq; }; @@ -52,15 +54,13 @@ static NTSTATUS connect_send_negprot(struct smbcli_composite *c, struct smb_composite_connect *io) { struct connect_state *state = c->private; - struct smbcli_request *req; - req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); + NT_STATUS_HAVE_NO_MEMORY(state->req); - req->async.fn = request_handler; - req->async.private = c; + state->req->async.fn = request_handler; + state->req->async.private = c; c->stage = CONNECT_NEGPROT; - c->req = req; return NT_STATUS_OK; } @@ -73,10 +73,9 @@ static NTSTATUS connect_tcon(struct smbcli_composite *c, struct smb_composite_connect *io) { struct connect_state *state = c->private; - struct smbcli_request *req = c->req; NTSTATUS status; - status = smb_tree_connect_recv(req, c, state->io_tcon); + status = smb_tree_connect_recv(state->req, c, state->io_tcon); NT_STATUS_NOT_OK_RETURN(status); io->out.tree->tid = state->io_tcon->tconx.out.tid; @@ -106,11 +105,9 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, struct smb_composite_connect *io) { struct connect_state *state = c->private; - struct smbcli_composite *req = c->req; - struct smbcli_request *req2; NTSTATUS status; - status = smb_composite_sesssetup_recv(req); + status = smb_composite_sesssetup_recv(state->creq); NT_STATUS_NOT_OK_RETURN(status); state->session->vuid = state->io_setup->out.vuid; @@ -138,12 +135,11 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, state->io_tcon->tconx.in.device = io->in.service_type; } - req2 = smb_tree_connect_send(io->out.tree, state->io_tcon); - NT_STATUS_HAVE_NO_MEMORY(req2); + state->req = smb_tree_connect_send(io->out.tree, state->io_tcon); + NT_STATUS_HAVE_NO_MEMORY(state->req); - req2->async.fn = request_handler; - req2->async.private = c; - c->req = req2; + state->req->async.fn = request_handler; + state->req->async.private = c; c->stage = CONNECT_TCON; return NT_STATUS_OK; @@ -156,11 +152,9 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, struct smb_composite_connect *io) { struct connect_state *state = c->private; - struct smbcli_request *req = c->req; - struct smbcli_composite *req2; NTSTATUS status; - status = smb_raw_negotiate_recv(req); + status = smb_raw_negotiate_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); /* next step is a session setup */ @@ -180,12 +174,11 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, state->io_setup->in.user = io->in.user; state->io_setup->in.password = io->in.password; - req2 = smb_composite_sesssetup_send(state->session, state->io_setup); - NT_STATUS_HAVE_NO_MEMORY(req2); + state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); + NT_STATUS_HAVE_NO_MEMORY(state->creq); - req2->async.fn = composite_handler; - req2->async.private = c; - c->req = req2; + state->creq->async.fn = composite_handler; + state->creq->async.private = c; c->stage = CONNECT_SESSION_SETUP; return NT_STATUS_OK; @@ -198,10 +191,10 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, static NTSTATUS connect_session_request(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct smbcli_request *req = c->req; + struct connect_state *state = c->private; NTSTATUS status; - status = smbcli_transport_connect_recv(req); + status = smbcli_transport_connect_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); /* next step is a negprot */ @@ -216,10 +209,9 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, { struct connect_state *state = c->private; NTSTATUS status; - struct smbcli_request *req; struct nmb_name calling, called; - status = smbcli_sock_connect_recv(c->req); + status = smbcli_sock_connect_recv(state->creq); NT_STATUS_NOT_OK_RETURN(status); /* the socket is up - we can initialise the smbcli transport layer */ @@ -236,13 +228,12 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, make_nmb_name(&calling, io->in.calling_name, 0x0); choose_called_name(&called, io->in.called_name, 0x20); - req = smbcli_transport_connect_send(state->transport, &calling, &called); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smbcli_transport_connect_send(state->transport, &calling, &called); + NT_STATUS_HAVE_NO_MEMORY(state->req); - req->async.fn = request_handler; - req->async.private = c; + state->req->async.fn = request_handler; + state->req->async.private = c; c->stage = CONNECT_SESSION_REQUEST; - c->req = req; return NT_STATUS_OK; } @@ -306,7 +297,7 @@ static void composite_handler(struct smbcli_composite *req) */ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect *io) { - struct smbcli_composite *c, *req; + struct smbcli_composite *c; struct connect_state *state; c = talloc_zero(NULL, struct smbcli_composite); @@ -325,12 +316,11 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect c->event_ctx = state->sock->event.ctx; c->private = state; - req = smbcli_sock_connect_send(state->sock, io->in.dest_host, io->in.port); - if (req == NULL) goto failed; + state->creq = smbcli_sock_connect_send(state->sock, io->in.dest_host, io->in.port); + if (state->creq == NULL) goto failed; - req->async.private = c; - req->async.fn = composite_handler; - c->req = req; + state->creq->async.private = c; + state->creq->async.fn = composite_handler; return c; failed: diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index e219707bc0..2d38096c88 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -34,6 +34,7 @@ static void loadfile_handler(struct smbcli_request *req); struct loadfile_state { struct smb_composite_loadfile *io; + struct smbcli_request *req; union smb_open *io_open; union smb_read *io_read; }; @@ -44,7 +45,7 @@ struct loadfile_state { static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { - struct smbcli_request *req; + struct loadfile_state *state = c->private; union smb_close *io_close; /* nothing to read, setup the close */ @@ -55,13 +56,12 @@ static NTSTATUS setup_close(struct smbcli_composite *c, io_close->close.in.fnum = fnum; io_close->close.in.write_time = 0; - req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the close is done */ - req->async.fn = loadfile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = loadfile_handler; + state->req->async.private = c; c->stage = LOADFILE_CLOSE; return NT_STATUS_OK; @@ -75,11 +75,10 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, struct smb_composite_loadfile *io) { struct loadfile_state *state = c->private; - struct smbcli_request *req = c->req; - struct smbcli_tree *tree = req->tree; + struct smbcli_tree *tree = state->req->tree; NTSTATUS status; - status = smb_raw_open_recv(req, c, state->io_open); + status = smb_raw_open_recv(state->req, c, state->io_open); NT_STATUS_NOT_OK_RETURN(status); /* don't allow stupidly large loads */ @@ -108,13 +107,12 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, state->io_read->readx.in.remaining = 0; state->io_read->readx.out.data = io->out.data; - req = smb_raw_read_send(tree, state->io_read); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_read_send(tree, state->io_read); + NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the first read is done */ - req->async.fn = loadfile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = loadfile_handler; + state->req->async.private = c; c->stage = LOADFILE_READ; talloc_free(state->io_open); @@ -131,11 +129,10 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, struct smb_composite_loadfile *io) { struct loadfile_state *state = c->private; - struct smbcli_request *req = c->req; - struct smbcli_tree *tree = req->tree; + struct smbcli_tree *tree = state->req->tree; NTSTATUS status; - status = smb_raw_read_recv(req, state->io_read); + status = smb_raw_read_recv(state->req, state->io_read); NT_STATUS_NOT_OK_RETURN(status); /* we might be done */ @@ -149,13 +146,12 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, state->io_read->readx.in.mincnt = MIN(32768, io->out.size - state->io_read->readx.in.offset); state->io_read->readx.out.data = io->out.data + state->io_read->readx.in.offset; - req = smb_raw_read_send(tree, state->io_read); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_read_send(tree, state->io_read); + NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the read is done */ - req->async.fn = loadfile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = loadfile_handler; + state->req->async.private = c; return NT_STATUS_OK; } @@ -166,10 +162,10 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, static NTSTATUS loadfile_close(struct smbcli_composite *c, struct smb_composite_loadfile *io) { + struct loadfile_state *state = c->private; NTSTATUS status; - struct smbcli_request *req = c->req; - status = smbcli_request_simple_recv(req); + status = smbcli_request_simple_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); c->state = SMBCLI_REQUEST_DONE; @@ -221,7 +217,6 @@ struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, struct smb_composite_loadfile *io) { struct smbcli_composite *c; - struct smbcli_request *req; struct loadfile_state *state; c = talloc_zero(tree, struct smbcli_composite); @@ -250,13 +245,12 @@ struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, state->io_open->ntcreatex.in.fname = io->in.fname; /* send the open on its way */ - req = smb_raw_open_send(tree, state->io_open); - if (req == NULL) goto failed; + state->req = smb_raw_open_send(tree, state->io_open); + if (state->req == NULL) goto failed; /* setup the callback handler */ - req->async.fn = loadfile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = loadfile_handler; + state->req->async.private = c; c->stage = LOADFILE_OPEN; return c; diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index 9abe5f5329..f516939c2b 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -37,6 +37,7 @@ struct savefile_state { struct smb_composite_savefile *io; union smb_open *io_open; union smb_write *io_write; + struct smbcli_request *req; }; @@ -46,8 +47,8 @@ struct savefile_state { static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { + struct savefile_state *state = c->private; union smb_close *io_close; - struct smbcli_request *req = c->req; /* nothing to write, setup the close */ io_close = talloc(c, union smb_close); @@ -57,14 +58,13 @@ static NTSTATUS setup_close(struct smbcli_composite *c, io_close->close.in.fnum = fnum; io_close->close.in.write_time = 0; - req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the close is done */ c->stage = SAVEFILE_CLOSE; - req->async.fn = savefile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = savefile_handler; + state->req->async.private = c; return NT_STATUS_OK; } @@ -78,12 +78,11 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, { struct savefile_state *state = c->private; union smb_write *io_write; - struct smbcli_request *req = c->req; - struct smbcli_tree *tree = req->tree; + struct smbcli_tree *tree = state->req->tree; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - status = smb_raw_open_recv(c->req, c, state->io_open); + status = smb_raw_open_recv(state->req, c, state->io_open); NT_STATUS_NOT_OK_RETURN(status); if (io->in.size == 0) { @@ -103,14 +102,13 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, io_write->writex.in.data = io->in.data; state->io_write = io_write; - req = smb_raw_write_send(tree, io_write); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_write_send(tree, io_write); + NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the first write is done */ c->stage = SAVEFILE_WRITE; - req->async.fn = savefile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = savefile_handler; + state->req->async.private = c; talloc_free(state->io_open); return NT_STATUS_OK; @@ -125,12 +123,11 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, struct smb_composite_savefile *io) { struct savefile_state *state = c->private; - struct smbcli_request *req = c->req; - struct smbcli_tree *tree = req->tree; + struct smbcli_tree *tree = state->req->tree; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - status = smb_raw_write_recv(c->req, state->io_write); + status = smb_raw_write_recv(state->req, state->io_write); NT_STATUS_NOT_OK_RETURN(status); state->total_written += state->io_write->writex.out.nwritten; @@ -147,13 +144,12 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, io->in.size - state->total_written); state->io_write->writex.in.data = io->in.data + state->total_written; - req = smb_raw_write_send(tree, state->io_write); - NT_STATUS_HAVE_NO_MEMORY(req); + state->req = smb_raw_write_send(tree, state->io_write); + NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the write is done */ - req->async.fn = savefile_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = savefile_handler; + state->req->async.private = c; return NT_STATUS_OK; } @@ -167,7 +163,7 @@ static NTSTATUS savefile_close(struct smbcli_composite *c, struct savefile_state *state = c->private; NTSTATUS status; - status = smbcli_request_simple_recv(c->req); + status = smbcli_request_simple_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); if (state->total_written != io->in.size) { @@ -224,7 +220,6 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, { struct smbcli_composite *c; struct savefile_state *state; - struct smbcli_request *req; union smb_open *io_open; c = talloc_zero(tree, struct smbcli_composite); @@ -255,14 +250,13 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, state->io_open = io_open; /* send the open on its way */ - req = smb_raw_open_send(tree, io_open); - if (req == NULL) goto failed; + state->req = smb_raw_open_send(tree, io_open); + if (state->req == NULL) goto failed; /* setup the callback handler */ - req->async.fn = savefile_handler; - req->async.private = c; + state->req->async.fn = savefile_handler; + state->req->async.private = c; c->private = state; - c->req = req; return c; diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 7053c9f9e5..fdc638837c 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -31,6 +31,7 @@ struct sesssetup_state { union smb_sesssetup setup; NTSTATUS session_key_err; struct smb_composite_sesssetup *io; + struct smbcli_request *req; }; @@ -134,10 +135,9 @@ static void request_handler(struct smbcli_request *req) smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } - req = smb_raw_session_setup_send(session, &state->setup); - req->async.fn = request_handler; - req->async.private = c; - c->req = req; + state->req = smb_raw_session_setup_send(session, &state->setup); + state->req->async.fn = request_handler; + state->req->async.private = c; return; } @@ -338,7 +338,6 @@ struct smbcli_composite *smb_composite_sesssetup_send(struct smbcli_session *ses { struct smbcli_composite *c; struct sesssetup_state *state; - struct smbcli_request *req = NULL; c = talloc_zero(session, struct smbcli_composite); if (c == NULL) goto failed; @@ -361,19 +360,18 @@ struct smbcli_composite *smb_composite_sesssetup_send(struct smbcli_session *ses /* see what session setup interface we will use */ if (session->transport->negotiate.protocol < PROTOCOL_NT1) { - req = session_setup_old(c, session, io); + state->req = session_setup_old(c, session, io); } else if (!session->transport->options.use_spnego || !(io->in.capabilities & CAP_EXTENDED_SECURITY)) { - req = session_setup_nt1(c, session, io); + state->req = session_setup_nt1(c, session, io); } else { - req = session_setup_spnego(c, session, io); + state->req = session_setup_spnego(c, session, io); } - if (req == NULL) goto failed; + if (state->req == NULL) goto failed; - req->async.fn = request_handler; - req->async.private = c; - c->req = req; + state->req->async.fn = request_handler; + state->req->async.private = c; return c; -- cgit From 4a03172e66694b51a24f7b5566f361c1f1767e29 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2005 23:23:45 +0000 Subject: r4791: used the new talloc type safety macros to make the "void *private" pointers in the composite code type safe. This is a bit of an experiement, I'd be interested in comments on whether we should use this more widely. (This used to be commit 0e1da827b380998355f75f4ef4f424802059c278) --- source4/libcli/composite/connect.c | 16 ++++++++-------- source4/libcli/composite/loadfile.c | 12 ++++++------ source4/libcli/composite/savefile.c | 10 +++++----- source4/libcli/composite/sesssetup.c | 8 ++++---- source4/libcli/raw/clisocket.c | 4 ++-- 5 files changed, 25 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index bc39cc99fc..bdb1b4d263 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -53,7 +53,7 @@ static void composite_handler(struct smbcli_composite *); static NTSTATUS connect_send_negprot(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); state->req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); NT_STATUS_HAVE_NO_MEMORY(state->req); @@ -72,7 +72,7 @@ static NTSTATUS connect_send_negprot(struct smbcli_composite *c, static NTSTATUS connect_tcon(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; status = smb_tree_connect_recv(state->req, c, state->io_tcon); @@ -104,7 +104,7 @@ static NTSTATUS connect_tcon(struct smbcli_composite *c, static NTSTATUS connect_session_setup(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; status = smb_composite_sesssetup_recv(state->creq); @@ -151,7 +151,7 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, static NTSTATUS connect_negprot(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; status = smb_raw_negotiate_recv(state->req); @@ -191,7 +191,7 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, static NTSTATUS connect_session_request(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; status = smbcli_transport_connect_recv(state->req); @@ -207,7 +207,7 @@ static NTSTATUS connect_session_request(struct smbcli_composite *c, static NTSTATUS connect_socket(struct smbcli_composite *c, struct smb_composite_connect *io) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; struct nmb_name calling, called; @@ -245,7 +245,7 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, */ static void state_handler(struct smbcli_composite *c) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); switch (c->stage) { case CONNECT_SOCKET: @@ -338,7 +338,7 @@ NTSTATUS smb_composite_connect_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ status = smb_composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct connect_state *state = c->private; + struct connect_state *state = talloc_get_type(c->private, struct connect_state); talloc_steal(mem_ctx, state->io->out.tree); } diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index 2d38096c88..8290876224 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -45,7 +45,7 @@ struct loadfile_state { static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { - struct loadfile_state *state = c->private; + struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); union smb_close *io_close; /* nothing to read, setup the close */ @@ -74,7 +74,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, static NTSTATUS loadfile_open(struct smbcli_composite *c, struct smb_composite_loadfile *io) { - struct loadfile_state *state = c->private; + struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); struct smbcli_tree *tree = state->req->tree; NTSTATUS status; @@ -128,7 +128,7 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, static NTSTATUS loadfile_read(struct smbcli_composite *c, struct smb_composite_loadfile *io) { - struct loadfile_state *state = c->private; + struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); struct smbcli_tree *tree = state->req->tree; NTSTATUS status; @@ -162,7 +162,7 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, static NTSTATUS loadfile_close(struct smbcli_composite *c, struct smb_composite_loadfile *io) { - struct loadfile_state *state = c->private; + struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); NTSTATUS status; status = smbcli_request_simple_recv(state->req); @@ -183,7 +183,7 @@ static NTSTATUS loadfile_close(struct smbcli_composite *c, static void loadfile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; - struct loadfile_state *state = c->private; + struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); /* when this handler is called, the stage indicates what call has just finished */ @@ -271,7 +271,7 @@ NTSTATUS smb_composite_loadfile_recv(struct smbcli_composite *c, TALLOC_CTX *mem status = smb_composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct loadfile_state *state = c->private; + struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); talloc_steal(mem_ctx, state->io->out.data); } diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index f516939c2b..06eb13bb01 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -47,7 +47,7 @@ struct savefile_state { static NTSTATUS setup_close(struct smbcli_composite *c, struct smbcli_tree *tree, uint16_t fnum) { - struct savefile_state *state = c->private; + struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); union smb_close *io_close; /* nothing to write, setup the close */ @@ -76,7 +76,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, static NTSTATUS savefile_open(struct smbcli_composite *c, struct smb_composite_savefile *io) { - struct savefile_state *state = c->private; + struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); union smb_write *io_write; struct smbcli_tree *tree = state->req->tree; NTSTATUS status; @@ -122,7 +122,7 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, static NTSTATUS savefile_write(struct smbcli_composite *c, struct smb_composite_savefile *io) { - struct savefile_state *state = c->private; + struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); struct smbcli_tree *tree = state->req->tree; NTSTATUS status; uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; @@ -160,7 +160,7 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, static NTSTATUS savefile_close(struct smbcli_composite *c, struct smb_composite_savefile *io) { - struct savefile_state *state = c->private; + struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); NTSTATUS status; status = smbcli_request_simple_recv(state->req); @@ -185,7 +185,7 @@ static NTSTATUS savefile_close(struct smbcli_composite *c, static void savefile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; - struct savefile_state *state = c->private; + struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); /* when this handler is called, the stage indicates what call has just finished */ diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index fdc638837c..771f85e541 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -94,7 +94,7 @@ static void use_nt1_session_keys(struct smbcli_session *session, static void request_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; - struct sesssetup_state *state = c->private; + struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); @@ -168,7 +168,7 @@ static struct smbcli_request *session_setup_nt1(struct smbcli_composite *c, struct smbcli_session *session, struct smb_composite_sesssetup *io) { - struct sesssetup_state *state = c->private; + struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); state->setup.nt1.level = RAW_SESSSETUP_NT1; state->setup.nt1.in.bufsize = session->transport->options.max_xmit; @@ -207,7 +207,7 @@ static struct smbcli_request *session_setup_old(struct smbcli_composite *c, struct smbcli_session *session, struct smb_composite_sesssetup *io) { - struct sesssetup_state *state = c->private; + struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); state->setup.old.level = RAW_SESSSETUP_OLD; state->setup.old.in.bufsize = session->transport->options.max_xmit; @@ -241,7 +241,7 @@ static struct smbcli_request *session_setup_spnego(struct smbcli_composite *c, struct smbcli_session *session, struct smb_composite_sesssetup *io) { - struct sesssetup_state *state = c->private; + struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); NTSTATUS status; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index ad1c6a13b8..66555695d3 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -66,8 +66,8 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, struct timeval t, uint16_t flags) { - struct smbcli_composite *c = fde->private; - struct clisocket_connect *conn = c->private; + struct smbcli_composite *c = talloc_get_type(fde->private, struct smbcli_composite); + struct clisocket_connect *conn = talloc_get_type(c->private, struct clisocket_connect); int i; c->status = socket_connect_complete(conn->sock->sock, 0); -- cgit From 6e135908736431b3c9f90dabf5193aa47c2d0714 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Jan 2005 04:08:24 +0000 Subject: r4795: stronget type checking in composite connect function (This used to be commit e16f67c931ba93011d52fdf14312d12a9b09c49a) --- source4/libcli/composite/connect.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index bdb1b4d263..891d16b4e6 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -279,7 +279,8 @@ static void state_handler(struct smbcli_composite *c) */ static void request_handler(struct smbcli_request *req) { - struct smbcli_composite *c = req->async.private; + struct smbcli_composite *c = talloc_get_type(req->async.private, + struct smbcli_composite); return state_handler(c); } @@ -288,7 +289,8 @@ static void request_handler(struct smbcli_request *req) */ static void composite_handler(struct smbcli_composite *req) { - struct smbcli_composite *c = req->async.private; + struct smbcli_composite *c = talloc_get_type(req->async.private, + struct smbcli_composite); return state_handler(c); } -- cgit From c06493912b9a8bb39a3d3459b9597daaa5d1c065 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Jan 2005 22:53:00 +0000 Subject: r4810: fixed anonymous connections with smbclient. Thanks to jbm for pointing this out. (This used to be commit 7da0af98a0e0bc743d3c64be30b37cbc45e00737) --- source4/libcli/raw/clitree.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index c6b3fa5ad9..06963d5bc4 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -173,9 +173,13 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.calling_name = my_name; io.in.service = service; io.in.service_type = service_type; - io.in.user = user; io.in.domain = domain; - io.in.password = password; + io.in.user = user; + if (user && user[0]) { + io.in.password = password; + } else { + io.in.password = NULL; + } status = smb_composite_connect(&io, parent_ctx); if (NT_STATUS_IS_OK(status)) { -- cgit From 196a5ec240c0386aff4f4442c9c44ac7cdd0a494 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Jan 2005 22:53:37 +0000 Subject: r4811: now that the event context is at the socket level, the event cleanup should be there too (This used to be commit 058ae5527e3daeb50eeea9e0ecee858c84e7e17d) --- source4/libcli/raw/clisocket.c | 13 +++++++++++++ source4/libcli/raw/clitransport.c | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 66555695d3..0edb95e1a1 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -35,6 +35,17 @@ struct clisocket_connect { const char *dest_host; }; + +static int smbcli_sock_destructor(void *ptr) +{ + struct smbcli_socket *sock = talloc_get_type(ptr, struct smbcli_socket); + + if (sock->event.fde && sock->event.ctx) { + event_remove_fd(sock->event.ctx, sock->event.fde); + } + return 0; +} + /* create a smbcli_socket context */ @@ -53,6 +64,8 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) return NULL; } + talloc_set_destructor(sock, smbcli_sock_destructor); + return sock; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 55a7e25f72..eb9d2dde78 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -54,7 +54,6 @@ static int transport_destructor(void *ptr) struct smbcli_transport *transport = ptr; smbcli_transport_dead(transport); - event_remove_fd(transport->socket->event.ctx, transport->socket->event.fde); event_remove_timed(transport->socket->event.ctx, transport->socket->event.te); return 0; } -- cgit From ea923fb4a26f88664a1db36e1a93a2c96239a7a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 06:54:10 +0000 Subject: r4885: added a new NBT client library. Features include: - structures defined using IDL in nbt.idl - build around our events structure, and talloc - fully async - supports all NBT packet fields as per rfc1002 - easy interfaces for name query and status For the moment there are just a couple of test functions in namequery.c, test_name_query() and test_name_status(). These will be removed when we hook the new library into libcli/ fully The new library will also be a fairly good basis for a nbt server. Although it can't be a server as-is, I wrote it with the needs of a server in mind (for example, extremely scalable idtree based packet handling) (This used to be commit ae7e625bfa4b4a3ee32c64566064b6a4c84ee4b9) --- source4/libcli/config.mk | 10 +- source4/libcli/nbt/libnbt.h | 118 ++++++++++++++ source4/libcli/nbt/namequery.c | 277 ++++++++++++++++++++++++++++++++ source4/libcli/nbt/nbtname.c | 285 +++++++++++++++++++++++++++++++++ source4/libcli/nbt/nbtsocket.c | 347 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1036 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/nbt/libnbt.h create mode 100644 source4/libcli/nbt/namequery.c create mode 100644 source4/libcli/nbt/nbtname.c create mode 100644 source4/libcli/nbt/nbtsocket.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0c4ba5cef0..87866db66d 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -26,5 +26,13 @@ ADD_OBJ_FILES = \ libcli/composite/connect.o \ libcli/composite/sesssetup.o +[SUBSYSTEM::LIBCLI_NBT] +ADD_OBJ_FILES = \ + libcli/nbt/nbtname.o \ + libcli/nbt/nbtsocket.o \ + libcli/nbt/namequery.o +REQUIRED_SUBSYSTEMS = NDR_NBT + [SUBSYSTEM::LIBCLI] -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB LIBCLI_COMPOSITE +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB \ + LIBCLI_COMPOSITE LIBCLI_NBT diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h new file mode 100644 index 0000000000..3658f1dd77 --- /dev/null +++ b/source4/libcli/nbt/libnbt.h @@ -0,0 +1,118 @@ +/* + Unix SMB/CIFS implementation. + + a raw async NBT library + + Copyright (C) Andrew Tridgell 2005 + + 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 "librpc/gen_ndr/ndr_nbt.h" + +/* + possible states for pending requests +*/ +enum nbt_request_state {NBT_REQUEST_SEND, + NBT_REQUEST_WAIT, + NBT_REQUEST_DONE, + NBT_REQUEST_TIMEOUT, + NBT_REQUEST_ERROR}; + +/* + a nbt name request +*/ +struct nbt_name_request { + struct nbt_name_request *next, *prev; + + enum nbt_request_state state; + + NTSTATUS status; + + /* the socket this was on */ + struct nbt_name_socket *nbtsock; + + /* where to send the request */ + const char *dest_addr; + int dest_port; + + /* the timeout event */ + struct timed_event *te; + + struct nbt_name_packet *request; + + /* shall we allow multiple replies? */ + BOOL allow_multiple_replies; + + uint_t num_replies; + struct nbt_name_reply { + struct nbt_name_packet *packet; + const char *reply_addr; + int reply_port; + } *replies; +}; + + + +/* + context structure for operations on name queries +*/ +struct nbt_name_socket { + struct socket_context *sock; + struct event_context *event_ctx; + + /* a queue of requests pending to be sent */ + struct nbt_name_request *send_queue; + + /* the fd event */ + struct fd_event *fde; + + /* mapping from name_trn_id to pending event */ + struct idr_context *idr; + + /* how many requests are waiting for a reply */ + uint16_t num_pending; +}; + + +/* a simple name query */ +struct nbt_name_query { + struct { + struct nbt_name name; + const char *dest_addr; + BOOL broadcast; + BOOL wins_lookup; + int timeout; /* in seconds */ + } in; + struct { + const char *reply_from; + struct nbt_name name; + const char *reply_addr; + } out; +}; + +/* a simple name status query */ +struct nbt_name_status { + struct { + struct nbt_name name; + const char *dest_addr; + int timeout; /* in seconds */ + } in; + struct { + const char *reply_from; + struct nbt_name name; + struct nbt_rdata_status status; + } out; +}; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c new file mode 100644 index 0000000000..23a63ede11 --- /dev/null +++ b/source4/libcli/nbt/namequery.c @@ -0,0 +1,277 @@ +/* + Unix SMB/CIFS implementation. + + make nbt name query requests + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/nbt/libnbt.h" +#include "system/network.h" + +/* + send a nbt name query +*/ +struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, + struct nbt_name_query *io) +{ + struct nbt_name_request *req; + struct nbt_name_packet *packet; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return NULL; + + packet->qdcount = 1; + packet->operation = NBT_OPCODE_QUERY; + if (io->in.broadcast) { + packet->operation |= NBT_FLAG_BROADCAST; + } + if (io->in.wins_lookup) { + packet->operation |= NBT_FLAG_RECURSION_DESIRED; + } + + packet->questions = talloc_array(packet, struct nbt_name_question, 1); + if (packet->questions == NULL) goto failed; + + packet->questions[0].name = io->in.name; + packet->questions[0].question_type = NBT_QTYPE_NETBIOS; + packet->questions[0].question_class = NBT_QCLASS_IP; + + req = nbt_name_request_send(nbtsock, io->in.dest_addr, NBT_NAME_SERVICE_PORT, packet, + timeval_current_ofs(io->in.timeout, 0), False); + if (req == NULL) goto failed; + + talloc_steal(req, packet); + + return req; + +failed: + talloc_free(packet); + return NULL; +} + +/* + wait for a name query replu +*/ +NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io) +{ + NTSTATUS status; + struct nbt_name_packet *packet; + const char *addr; + struct in_addr in; + + status = nbt_name_request_recv(req); + if (!NT_STATUS_IS_OK(status) || + req->num_replies == 0) { + talloc_free(req); + return status; + } + + packet = req->replies[0].packet; + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + + if (packet->ancount != 1 || + packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || + packet->answers[0].rr_class != NBT_QCLASS_IP) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + io->out.name = packet->answers[0].name; + in.s_addr = htonl(packet->answers[0].rdata.netbios.ipaddr); + addr = inet_ntoa(in); + if (addr == NULL) { + talloc_free(req); + return NT_STATUS_NO_MEMORY; + } + io->out.reply_addr = talloc_strdup(mem_ctx, addr); + talloc_steal(mem_ctx, io->out.name.name); + talloc_steal(mem_ctx, io->out.name.scope); + + talloc_free(req); + + return NT_STATUS_OK; +} + +/* + wait for a name query replu +*/ +NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io) +{ + struct nbt_name_request *req = nbt_name_query_send(nbtsock, io); + return nbt_name_query_recv(req, mem_ctx, io); +} + + +/* + send a nbt name status +*/ +struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, + struct nbt_name_status *io) +{ + struct nbt_name_request *req; + struct nbt_name_packet *packet; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return NULL; + + packet->qdcount = 1; + packet->operation = NBT_OPCODE_QUERY; + + packet->questions = talloc_array(packet, struct nbt_name_question, 1); + if (packet->questions == NULL) goto failed; + + packet->questions[0].name = io->in.name; + packet->questions[0].question_type = NBT_QTYPE_STATUS; + packet->questions[0].question_class = NBT_QCLASS_IP; + + req = nbt_name_request_send(nbtsock, io->in.dest_addr, NBT_NAME_SERVICE_PORT, packet, + timeval_current_ofs(io->in.timeout, 0), False); + if (req == NULL) goto failed; + + talloc_steal(req, packet); + + return req; + +failed: + talloc_free(packet); + return NULL; +} + +/* + wait for a name status replu +*/ +NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_status *io) +{ + NTSTATUS status; + struct nbt_name_packet *packet; + int i; + + status = nbt_name_request_recv(req); + if (!NT_STATUS_IS_OK(status) || + req->num_replies == 0) { + talloc_free(req); + return status; + } + + packet = req->replies[0].packet; + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + + if (packet->ancount != 1 || + packet->answers[0].rr_type != NBT_QTYPE_STATUS || + packet->answers[0].rr_class != NBT_QCLASS_IP) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + io->out.name = packet->answers[0].name; + talloc_steal(mem_ctx, io->out.name.name); + talloc_steal(mem_ctx, io->out.name.scope); + + io->out.status = packet->answers[0].rdata.status; + talloc_steal(mem_ctx, io->out.status.names); + for (i=0;iout.status.num_names;i++) { + talloc_steal(io->out.status.names, io->out.status.names[i].name); + } + + + talloc_free(req); + + return NT_STATUS_OK; +} + +/* + wait for a name status replu +*/ +NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_status *io) +{ + struct nbt_name_request *req = nbt_name_status_send(nbtsock, io); + return nbt_name_status_recv(req, mem_ctx, io); +} + + +/* + some test functions - will be removed when nbt is hooked in everywhere +*/ +void test_name_status(const char *name, const char *addr) +{ + struct nbt_name_status io; + NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + struct nbt_name_socket *nbtsock; + int i; + + nbtsock = nbt_name_socket_init(tmp_ctx, NULL); + + io.in.name.name = name; + io.in.name.scope = NULL; + io.in.name.type = NBT_NAME_CLIENT; + io.in.dest_addr = addr; + io.in.timeout = 5; + + status = nbt_name_status(nbtsock, tmp_ctx, &io); + if (!NT_STATUS_IS_OK(status)) { + printf("status failed for %s - %s\n", name, nt_errstr(status)); + talloc_free(tmp_ctx); + exit(1); + return; + } + + printf("Received %d names for %s\n", io.out.status.num_names, io.out.name.name); + for (i=0;i= ndr->data_size) { + return NT_STATUS_BAD_NETWORK_NAME; + } + len = ndr->data[*offset]; + if (len == 0) { + *offset += 1; + *max_offset = MAX(*max_offset, *offset); + *component = NULL; + return NT_STATUS_OK; + } + if ((len & 0xC0) == 0xC0) { + /* its a label pointer */ + if (1 + *offset >= ndr->data_size) { + return NT_STATUS_BAD_NETWORK_NAME; + } + *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset]; + *max_offset = MAX(*max_offset, *offset + 1); + loops++; + continue; + } + if ((len & 0xC0) != 0) { + /* its a reserved length field */ + return NT_STATUS_BAD_NETWORK_NAME; + } + if (*offset + len + 2 >= ndr->data_size) { + return NT_STATUS_BAD_NETWORK_NAME; + } + *component = (uint8_t*)talloc_strndup(ndr, &ndr->data[1 + *offset], len); + NT_STATUS_HAVE_NO_MEMORY(*component); + *offset += len + 1; + *max_offset = MAX(*max_offset, *offset); + return NT_STATUS_OK; + } + + /* too many pointers */ + return NT_STATUS_BAD_NETWORK_NAME; +} + +/* + decompress a 'compressed' name component + */ +static NTSTATUS decompress_name(char *name, enum nbt_name_type *type) +{ + int i; + for (i=0;name[2*i];i++) { + uint8_t c1 = name[2*i]; + uint8_t c2 = name[1+(2*i)]; + if (c1 < 'A' || c1 > 'P' || + c2 < 'A' || c2 > 'P') { + return NT_STATUS_BAD_NETWORK_NAME; + } + name[i] = ((c1-'A')<<4) | (c2-'A'); + } + name[i] = 0; + if (i == 16) { + *type = (enum nbt_name_type)(name[15]); + name[15] = 0; + i--; + } else { + *type = NBT_NAME_CLIENT; + } + + /* trim trailing spaces */ + for (;i>0 && name[i-1]==' ';i--) { + name[i-1] = 0; + } + + return NT_STATUS_OK; +} + + +/* + compress a name component + */ +static uint8_t *compress_name(TALLOC_CTX *mem_ctx, + uint8_t *name, enum nbt_name_type type) +{ + uint8_t *cname; + int i; + uint8_t pad_char; + + if (strlen(name) > 15) { + return NULL; + } + + cname = talloc_array(mem_ctx, uint8_t, 33); + if (cname == NULL) return NULL; + + for (i=0;name[i];i++) { + cname[2*i] = 'A' + (name[i]>>4); + cname[1+2*i] = 'A' + (name[i]&0xF); + } + if (name[0] == '*') { + pad_char = 0; + } else { + pad_char = ' '; + } + for (;i<15;i++) { + cname[2*i] = 'A' + (pad_char>>4); + cname[1+2*i] = 'A' + (pad_char&0xF); + } + + pad_char = type; + cname[2*i] = 'A' + (pad_char>>4); + cname[1+2*i] = 'A' + (pad_char&0xF); + + cname[32] = 0; + return cname; +} + +/* + pull a nbt name from the wire +*/ +NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) +{ + NTSTATUS status; + uint_t num_components; + uint32_t offset = ndr->offset; + uint32_t max_offset = offset; + uint8_t *components[MAX_COMPONENTS]; + int i; + ssize_t ret; + void *p; + uint8_t *scope; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + /* break up name into a list of components */ + for (num_components=0;num_componentsoffset = max_offset; + + /* the first component is limited to 16 bytes in the DOS charset, + which is 32 in the 'compressed' form */ + if (strlen(components[0]) > 32) { + return NT_STATUS_BAD_NETWORK_NAME; + } + + /* decompress the first component */ + status = decompress_name(components[0], &r->type); + NT_STATUS_NOT_OK_RETURN(status); + + ret = convert_string_talloc(ndr, CH_DOS, CH_UNIX, components[0], + strlen(components[0])+1, &p); + if (ret <= 0) { + return NT_STATUS_BAD_NETWORK_NAME; + } + r->name = p; + + /* combine the remaining components into the scope */ + scope = components[1]; + for (i=2;iscope)+1, &p); + if (ret <= 0) { + return NT_STATUS_BAD_NETWORK_NAME; + } + r->scope = p; + } else { + r->scope = NULL; + } + + return NT_STATUS_OK; +} + +/* + push a nbt name to the wire +*/ +NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name *r) +{ + uint_t num_components; + uint8_t *components[MAX_COMPONENTS]; + void *ptr; + char *dname, *dscope=NULL, *p; + uint8_t *cname; + ssize_t ret; + int i; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + /* convert to DOS format */ + ret = convert_string_talloc(ndr, CH_UNIX, CH_DOS, r->name, + strlen(r->name)+1, &ptr); + if (ret <= 0) { + return NT_STATUS_BAD_NETWORK_NAME; + } + dname = strupper_talloc(ndr, ptr); + NT_STATUS_HAVE_NO_MEMORY(dname); + if (r->scope) { + ret = convert_string_talloc(ndr, CH_UNIX, CH_DOS, r->scope, + strlen(r->scope)+1, &ptr); + if (ret <= 0) { + return NT_STATUS_BAD_NETWORK_NAME; + } + dscope = strupper_talloc(ndr, ptr); + NT_STATUS_HAVE_NO_MEMORY(dscope); + } + + cname = compress_name(ndr, dname, r->type); + NT_STATUS_HAVE_NO_MEMORY(cname); + + /* form the base components */ + components[0] = cname; + num_components = 1; + + while (dscope && (p=strchr(dscope, '.')) && + num_components < MAX_COMPONENTS) { + *p = 0; + components[num_components] = dscope; + NT_STATUS_HAVE_NO_MEMORY(components[num_components]); + dscope = p+1; + num_components++; + } + if (num_components == MAX_COMPONENTS) { + return NT_STATUS_BAD_NETWORK_NAME; + } + + /* push the components */ + for (i=0;istate == NBT_REQUEST_SEND) { + DLIST_REMOVE(req->nbtsock->send_queue, req); + } + if (req->state == NBT_REQUEST_WAIT) { + req->nbtsock->num_pending--; + } + if (req->request->name_trn_id != 0) { + idr_remove(req->nbtsock->idr, req->request->name_trn_id); + req->request->name_trn_id = 0; + } + if (req->te) { + event_remove_timed(req->nbtsock->event_ctx, req->te); + req->te = NULL; + } + if (req->nbtsock->send_queue == NULL) { + req->nbtsock->fde->flags &= ~EVENT_FD_WRITE; + } + if (req->nbtsock->num_pending == 0) { + req->nbtsock->fde->flags &= ~EVENT_FD_READ; + } + return 0; +} + + +/* + handle send events on a nbt name socket +*/ +static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) +{ + struct nbt_name_request *req = nbtsock->send_queue; + TALLOC_CTX *tmp_ctx = talloc_new(req); + NTSTATUS status; + + while ((req = nbtsock->send_queue)) { + DATA_BLOB blob; + size_t len; + + if (DEBUGLVL(10)) { + DEBUG(10,("Sending nbt packet:\n")); + NDR_PRINT_DEBUG(nbt_name_packet, req->request); + } + + status = ndr_push_struct_blob(&blob, tmp_ctx, req->request, + (ndr_push_flags_fn_t) + ndr_push_nbt_name_packet); + if (!NT_STATUS_IS_OK(status)) goto failed; + + if (req->request->operation & NBT_FLAG_BROADCAST) { + socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); + } + + len = blob.length; + status = socket_sendto(nbtsock->sock, &blob, &len, 0, + req->dest_addr, req->dest_port); + if (NT_STATUS_IS_ERR(status)) goto failed; + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + DLIST_REMOVE(nbtsock->send_queue, req); + req->state = NBT_REQUEST_WAIT; + nbtsock->fde->flags |= EVENT_FD_READ; + nbtsock->num_pending++; + } + + nbtsock->fde->flags &= ~EVENT_FD_WRITE; + talloc_free(tmp_ctx); + return; + +failed: + DLIST_REMOVE(nbtsock->send_queue, req); + nbt_name_request_destructor(req); + req->status = status; + req->state = NBT_REQUEST_ERROR; + talloc_free(tmp_ctx); + return; +} + + +/* + handle recv events on a nbt name socket +*/ +static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) +{ + TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); + NTSTATUS status; + const char *src_addr; + int src_port; + DATA_BLOB blob; + size_t nread; + struct nbt_name_packet *packet; + struct nbt_name_request *req; + + blob = data_blob_talloc(tmp_ctx, NULL, NBT_MAX_PACKET_SIZE); + if (blob.data == NULL) { + talloc_free(tmp_ctx); + return; + } + + status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, + &src_addr, &src_port); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + talloc_steal(tmp_ctx, src_addr); + + packet = talloc(tmp_ctx, struct nbt_name_packet); + if (packet == NULL) { + talloc_free(tmp_ctx); + return; + } + + status = ndr_pull_struct_blob(&blob, packet, packet, + (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Failed to parse incoming NBT name packet - %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return; + } + + if (DEBUGLVL(10)) { + DEBUG(10,("Received nbt packet:\n")); + NDR_PRINT_DEBUG(nbt_name_packet, packet); + } + + if (!(packet->operation & NBT_FLAG_REPLY)) { + talloc_free(tmp_ctx); + return; + } + + /* find the matching request */ + req = idr_find(nbtsock->idr, packet->name_trn_id); + if (req == NULL) { + DEBUG(2,("Failed to match request for incoming name packet id 0x%04x\n", + packet->name_trn_id)); + talloc_free(tmp_ctx); + return; + } + + req->replies = talloc_realloc(req, req->replies, struct nbt_name_reply, req->num_replies+1); + if (req->replies == NULL) { + nbt_name_request_destructor(req); + req->state = NBT_REQUEST_DONE; + req->status = NT_STATUS_NO_MEMORY; + talloc_free(tmp_ctx); + return; + } + + req->replies[req->num_replies].reply_addr = talloc_steal(req, src_addr); + req->replies[req->num_replies].reply_port = src_port; + req->replies[req->num_replies].packet = talloc_steal(req, packet); + req->num_replies++; + + /* if we don't want multiple replies then we are done */ + if (!req->allow_multiple_replies || + req->num_replies == NBT_MAX_REPLIES) { + nbt_name_request_destructor(req); + req->state = NBT_REQUEST_DONE; + req->status = NT_STATUS_OK; + } + + talloc_free(tmp_ctx); +} + +/* + handle fd events on a nbt_name_socket +*/ +static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde, + struct timeval t, uint16_t flags) +{ + struct nbt_name_socket *nbtsock = talloc_get_type(fde->private, + struct nbt_name_socket); + if (flags & EVENT_FD_WRITE) { + nbt_name_socket_send(nbtsock); + } else if (flags & EVENT_FD_READ) { + nbt_name_socket_recv(nbtsock); + } +} + + +/* + initialise a nbt_name_socket. The event_ctx is optional, if provided + then operations will use that event context +*/ +struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) +{ + struct nbt_name_socket *nbtsock; + NTSTATUS status; + struct fd_event fde; + + nbtsock = talloc(mem_ctx, struct nbt_name_socket); + if (nbtsock == NULL) goto failed; + + if (event_ctx == NULL) { + nbtsock->event_ctx = event_context_init(nbtsock); + } else { + nbtsock->event_ctx = talloc_reference(nbtsock, event_ctx); + } + if (nbtsock->event_ctx == NULL) goto failed; + + status = socket_create("ip", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0); + if (!NT_STATUS_IS_OK(status)) goto failed; + + talloc_steal(nbtsock, nbtsock->sock); + + nbtsock->idr = idr_init(nbtsock); + if (nbtsock->idr == NULL) goto failed; + + nbtsock->send_queue = NULL; + nbtsock->num_pending = 0; + + fde.fd = socket_get_fd(nbtsock->sock); + fde.flags = 0; + fde.handler = nbt_name_socket_handler; + fde.private = nbtsock; + nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde); + + return nbtsock; + +failed: + talloc_free(nbtsock); + return NULL; +} + +/* + handle a request timeout +*/ +static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te, + struct timeval t) +{ + struct nbt_name_request *req = talloc_get_type(te->private, + struct nbt_name_request); + nbt_name_request_destructor(req); + req->state = NBT_REQUEST_TIMEOUT; + req->status = NT_STATUS_IO_TIMEOUT; +} + +/* + send off a nbt name request +*/ +struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, + const char *dest_addr, int dest_port, + struct nbt_name_packet *request, + struct timeval timeout, + BOOL allow_multiple_replies) +{ + struct nbt_name_request *req; + struct timed_event te; + int id; + + req = talloc_zero(nbtsock, struct nbt_name_request); + if (req == NULL) goto failed; + + req->nbtsock = nbtsock; + req->dest_addr = dest_addr; + req->dest_port = dest_port; + req->request = talloc_reference(req, request); + req->allow_multiple_replies = allow_multiple_replies; + req->state = NBT_REQUEST_SEND; + + if (req->request->name_trn_id == 0) { + req->request->name_trn_id = random() % UINT16_MAX; + } + + id = idr_get_new_above(req->nbtsock->idr, req, + req->request->name_trn_id, UINT16_MAX); + if (id == -1) { + id = idr_get_new_above(req->nbtsock->idr, req, 1+(random()%10000), + UINT16_MAX); + } + if (id == -1) goto failed; + + te.next_event = timeout; + te.handler = nbt_name_socket_timeout; + te.private = req; + req->te = event_add_timed(nbtsock->event_ctx, &te); + + talloc_set_destructor(req, nbt_name_request_destructor); + + DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); + + nbtsock->fde->flags |= EVENT_FD_WRITE; + + return req; + +failed: + talloc_free(req); + return NULL; +} + +/* + wait for a nbt request to complete +*/ +NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) +{ + if (!req) return NT_STATUS_NO_MEMORY; + + while (req->state < NBT_REQUEST_DONE) { + if (event_loop_once(req->nbtsock->event_ctx) != 0) { + req->state = NBT_REQUEST_ERROR; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + } + return req->status; +} -- cgit From ad1c91250e3430a3262de405fbaf9da56e6e2610 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 06:55:33 +0000 Subject: r4886: fixed two places where we process the send side of a socket after the recv side in the same event. That's a bad idea, as the first callback could decide to destroy the socket. (This used to be commit bf74ea34fc0e3c31e220c8f5a9217c95f3ca1d52) --- source4/libcli/raw/clitransport.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index eb9d2dde78..e6d40639c6 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -40,6 +40,7 @@ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_e if (flags & EVENT_FD_READ) { smbcli_transport_process_recv(transport); + return; } if (flags & EVENT_FD_WRITE) { smbcli_transport_process_send(transport); -- cgit From f1aaef3015864f9323711127a4964a8eceff6a52 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Jan 2005 11:10:03 +0000 Subject: r4890: Try to cope with mechanism mismatch in the client speaks first version of the SPNEGO state-machine. (Such as on LDAP and HTTP) Andrew Bartlett (This used to be commit c1cae6b3b1efe109a09e449ed2e09983431eac7e) --- source4/libcli/auth/spnego.c | 105 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index f7221b7458..1e92a7d16e 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -287,11 +287,63 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec } -static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_security, - struct spnego_state *spnego_state, - TALLOC_CTX *out_mem_ctx, - const char **mechType, - const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) +/* + Parse the netTokenInit from the client, to the server. + + +*/ + +static NTSTATUS gensec_spnego_server_parse_negTokenInit(struct gensec_security *gensec_security, + struct spnego_state *spnego_state, + TALLOC_CTX *out_mem_ctx, + const char **mechType, + const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) +{ + NTSTATUS nt_status; + + if (!mechType || !mechType[0]) { + DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_subcontext_start(spnego_state, + gensec_security, + &spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + /* select the sub context */ + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechType[0]); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; + return nt_status; + } + + if (!unwrapped_in.length) { + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + unwrapped_in, + unwrapped_out); + + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { + DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; + } + return nt_status; +} + +static NTSTATUS gensec_spnego_client_parse_negTokenInit(struct gensec_security *gensec_security, + struct spnego_state *spnego_state, + TALLOC_CTX *out_mem_ctx, + const char **mechType, + const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) { int i; NTSTATUS nt_status; @@ -440,6 +492,40 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec } spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; spnego_state->state_position = SPNEGO_DONE; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) { + if (spnego_state->sub_sec_security) { + /* we have a mech, but we just didn't get the input parameter */ + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; + } else { + const char **mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); + if (!mechTypes) { + DEBUG(1, ("no GENSEC OID backends available\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_subcontext_start(spnego_state, + gensec_security, + &spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + /* select our preferred mech */ + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechTypes[0]); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(spnego_state->sub_sec_security); + spnego_state->sub_sec_security = NULL; + return nt_status; + } + + /* we should be sending the whole list here */ + spnego_out.negTokenTarg.supportedMech = mechTypes[0]; + } + + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego_state->state_position = SPNEGO_SERVER_TARG; + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; } else { spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); @@ -500,7 +586,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } - nt_status = gensec_spnego_parse_negTokenInit(gensec_security, + nt_status = gensec_spnego_server_parse_negTokenInit(gensec_security, spnego_state, out_mem_ctx, spnego.negTokenInit.mechTypes, @@ -580,7 +666,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } } - nt_status = gensec_spnego_parse_negTokenInit(gensec_security, + nt_status = gensec_spnego_client_parse_negTokenInit(gensec_security, spnego_state, out_mem_ctx, spnego.negTokenInit.mechTypes, @@ -640,6 +726,11 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + if (!spnego_state->sub_sec_security) { + DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = gensec_update(spnego_state->sub_sec_security, out_mem_ctx, spnego.negTokenTarg.responseToken, -- cgit From 2383787f199c51cdc202a3cef5822a9fe6b8774c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 11:18:56 +0000 Subject: r4891: - added a generic resolve_name() async interface in libcli/resolve/, which will eventually try all resolution methods setup in smb.conf - only resolution backend at the moment is bcast, which does a parallel broadcast to all configured network interfaces, and takes the first reply that comes in (this nicely demonstrates how to do parallel requests using the async APIs) - converted all the existing code to use the new resolve_name() api - removed all the old nmb code (yay!) (This used to be commit 239c310f255e43dd2d1c2433f666c9faaacbdce3) --- source4/libcli/cliconnect.c | 8 +- source4/libcli/composite/connect.c | 47 +- source4/libcli/config.mk | 18 +- source4/libcli/namequery.c | 1104 ------------------------------ source4/libcli/namequery_dc.c | 27 - source4/libcli/nbt/libnbt.h | 6 + source4/libcli/nbt/namequery.c | 66 -- source4/libcli/nbt/nbtname.c | 54 ++ source4/libcli/nbt/nbtsocket.c | 48 +- source4/libcli/nmblib.c | 1316 ------------------------------------ source4/libcli/raw/clisocket.c | 16 +- source4/libcli/raw/clitransport.c | 47 +- source4/libcli/raw/libcliraw.h | 3 +- source4/libcli/resolve/bcast.c | 163 +++++ source4/libcli/resolve/resolve.c | 51 ++ source4/libcli/unexpected.c | 170 ----- 16 files changed, 414 insertions(+), 2730 deletions(-) delete mode 100644 source4/libcli/namequery.c delete mode 100644 source4/libcli/namequery_dc.c delete mode 100644 source4/libcli/nmblib.c create mode 100644 source4/libcli/resolve/bcast.c create mode 100644 source4/libcli/resolve/resolve.c delete mode 100644 source4/libcli/unexpected.c (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 0f916d1eb1..aaed36eb05 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. + client connect/disconnect routines - Copyright (C) Andrew Tridgell 2003 + + Copyright (C) Andrew Tridgell 2003-2005 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 @@ -49,8 +51,8 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) /* wrapper around smbcli_transport_connect() */ BOOL smbcli_transport_establish(struct smbcli_state *cli, - struct nmb_name *calling, - struct nmb_name *called) + struct nbt_name *calling, + struct nbt_name *called) { return smbcli_transport_connect(cli->transport, calling, called); } diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 891d16b4e6..7e08aab0d5 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -26,7 +26,8 @@ #include "libcli/composite/composite.h" /* the stages of this call */ -enum connect_stage {CONNECT_SOCKET, +enum connect_stage {CONNECT_RESOLVE, + CONNECT_SOCKET, CONNECT_SESSION_REQUEST, CONNECT_NEGPROT, CONNECT_SESSION_SETUP, @@ -209,7 +210,7 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, { struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; - struct nmb_name calling, called; + struct nbt_name calling, called; status = smbcli_sock_connect_recv(state->creq); NT_STATUS_NOT_OK_RETURN(status); @@ -225,8 +226,11 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, return connect_send_negprot(c, io); } - make_nmb_name(&calling, io->in.calling_name, 0x0); - choose_called_name(&called, io->in.called_name, 0x20); + calling.name = io->in.calling_name; + calling.type = NBT_NAME_CLIENT; + calling.scope = NULL; + + nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); state->req = smbcli_transport_connect_send(state->transport, &calling, &called); NT_STATUS_HAVE_NO_MEMORY(state->req); @@ -239,6 +243,29 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, } +/* + called when name resolution is finished +*/ +static NTSTATUS connect_resolve(struct smbcli_composite *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private, struct connect_state); + NTSTATUS status; + const char *address; + + status = resolve_name_recv(state->creq, state, &address); + NT_STATUS_NOT_OK_RETURN(status); + + state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port); + NT_STATUS_HAVE_NO_MEMORY(state->creq); + + c->stage = CONNECT_SOCKET; + state->creq->async.private = c; + state->creq->async.fn = composite_handler; + + return NT_STATUS_OK; +} + /* handle and dispatch state transitions @@ -248,6 +275,9 @@ static void state_handler(struct smbcli_composite *c) struct connect_state *state = talloc_get_type(c->private, struct connect_state); switch (c->stage) { + case CONNECT_RESOLVE: + c->status = connect_resolve(c, state->io); + break; case CONNECT_SOCKET: c->status = connect_socket(c, state->io); break; @@ -301,6 +331,7 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect { struct smbcli_composite *c; struct connect_state *state; + struct nbt_name name; c = talloc_zero(NULL, struct smbcli_composite); if (c == NULL) goto failed; @@ -314,11 +345,15 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect state->io = io; c->state = SMBCLI_REQUEST_SEND; - c->stage = CONNECT_SOCKET; + c->stage = CONNECT_RESOLVE; c->event_ctx = state->sock->event.ctx; c->private = state; - state->creq = smbcli_sock_connect_send(state->sock, io->in.dest_host, io->in.port); + name.name = io->in.dest_host; + name.type = NBT_NAME_SERVER; + name.scope = NULL; + + state->creq = resolve_name_send(&name, c->event_ctx); if (state->creq == NULL) goto failed; state->creq->async.private = c; diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 87866db66d..21cfed8987 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -8,15 +8,9 @@ ADD_OBJ_FILES = libcli/util/asn1.o \ libcli/util/smbdes.o \ libcli/util/smbencrypt.o -[SUBSYSTEM::LIBCLI_NMB] -ADD_OBJ_FILES = libcli/unexpected.o \ - libcli/namecache.o \ - libcli/nmblib.o \ - libcli/namequery.o -REQUIRED_SUBSYSTEMS = RPC_NDR_LSA - [SUBSYSTEM::LIBCLI_LSA] ADD_OBJ_FILES = libcli/util/clilsa.o +REQUIRED_SUBSYSTEMS = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_COMPOSITE] ADD_OBJ_FILES = \ @@ -33,6 +27,12 @@ ADD_OBJ_FILES = \ libcli/nbt/namequery.o REQUIRED_SUBSYSTEMS = NDR_NBT +[SUBSYSTEM::LIBCLI_RESOLVE] +ADD_OBJ_FILES = \ + libcli/resolve/resolve.o \ + libcli/resolve/bcast.o +REQUIRED_SUBSYSTEMS = LIBCLI_NBT + [SUBSYSTEM::LIBCLI] -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB \ - LIBCLI_COMPOSITE LIBCLI_NBT +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ + LIBCLI_COMPOSITE LIBCLI_NBT LIBCLI_RESOLVE diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c deleted file mode 100644 index c440a604c7..0000000000 --- a/source4/libcli/namequery.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* - Unix SMB/CIFS implementation. - name query routines - Copyright (C) Andrew Tridgell 1994-1998 - - 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 "system/network.h" -#include "system/time.h" - -/* A netbios node status array element. */ -struct node_status { - char name[16]; - uint8_t type; - uint8_t flags; -}; - - -/* nmbd.c sets this to True. */ -BOOL global_in_nmbd = False; - -/**************************************************************************** -generate a random trn_id -****************************************************************************/ -static int generate_trn_id(void) -{ - static int trn_id; - - if (trn_id == 0) { - sys_srandom(getpid()); - } - - trn_id = sys_random(); - - return trn_id % (uint_t)0x7FFF; -} - - -/**************************************************************************** - parse a node status response into an array of structures -****************************************************************************/ -static struct node_status *parse_node_status(char *p, int *num_names) -{ - struct node_status *ret; - int i; - - *num_names = CVAL(p,0); - - if (*num_names == 0) return NULL; - - ret = malloc_array_p(struct node_status, *num_names); - if (!ret) return NULL; - - p++; - for (i=0;i< *num_names;i++) { - StrnCpy(ret[i].name,p,15); - trim_string(ret[i].name,NULL," "); - ret[i].type = CVAL(p,15); - ret[i].flags = p[16]; - p += 18; - DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, - ret[i].type, ret[i].flags)); - } - return ret; -} - - -/**************************************************************************** -do a NBT node status query on an open socket and return an array of -structures holding the returned names or NULL if the query failed -**************************************************************************/ -struct node_status *node_status_query(int fd,struct nmb_name *name, - struct ipv4_addr to_ip, int *num_names) -{ - BOOL found=False; - int retries = 2; - int retry_time = 2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct node_status *ret; - - ZERO_STRUCT(p); - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = False; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - nmb->question.question_name = *name; - nmb->question.question_type = 0x21; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return NULL; - - retries--; - - while (1) { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount || - nmb2->answers->rr_type != 0x21) { - /* XXXX what do we do with this? could be a - redirect, but we'll discard it for the - moment */ - free_packet(p2); - continue; - } - - ret = parse_node_status(&nmb2->answers->rdata[0], num_names); - free_packet(p2); - return ret; - } - } - - return NULL; -} - - -/**************************************************************************** -find the first type XX name in a node status reply - used for finding -a servers name given its IP -return the matched name in *name -**************************************************************************/ - -BOOL name_status_find(const char *q_name, int q_type, int type, struct ipv4_addr to_ip, char *name) -{ - struct node_status *status = NULL; - struct nmb_name nname; - int count, i; - int sock; - BOOL result = False; - - if (lp_disable_netbios()) { - DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); - return False; - } - - DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, - q_type, sys_inet_ntoa(to_ip))); - - sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); - if (sock == -1) - goto done; - - /* W2K PDC's seem not to respond to '*'#0. JRA */ - make_nmb_name(&nname, q_name, q_type); - status = node_status_query(sock, &nname, to_ip, &count); - close(sock); - if (!status) - goto done; - - for (i=0;iaddr, (uint8_t *)&ip.addr); - bits2 = matching_quad_bits((uint8_t *)&ip2->addr, (uint8_t *)&ip.addr); - max_bits1 = MAX(bits1, max_bits1); - max_bits2 = MAX(bits2, max_bits2); - } - - /* bias towards directly reachable IPs */ - if (iface_local(*ip1)) { - max_bits1 += 32; - } - if (iface_local(*ip2)) { - max_bits2 += 32; - } - - return max_bits2 - max_bits1; -} - -/* - sort an IP list so that names that are close to one of our interfaces - are at the top. This prevents the problem where a WINS server returns an IP that - is not reachable from our subnet as the first match -*/ -static void sort_ip_list(struct ipv4_addr *iplist, int count) -{ - if (count <= 1) { - return; - } - - qsort(iplist, count, sizeof(struct ipv4_addr), QSORT_CAST ip_compare); -} - - -/**************************************************************************** - Do a netbios name query to find someones IP. - Returns an array of IP addresses or NULL if none. - *count will be set to the number of addresses returned. - *timed_out is set if we failed by timing out -****************************************************************************/ -struct ipv4_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, - struct ipv4_addr to_ip, int *count, int *flags, - BOOL *timed_out) -{ - BOOL found=False; - int i, retries = 3; - int retry_time = bcast?250:2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct ipv4_addr *ip_list = NULL; - - if (lp_disable_netbios()) { - DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type)); - return NULL; - } - - if (timed_out) { - *timed_out = False; - } - - memset((char *)&p,'\0',sizeof(p)); - (*count) = 0; - (*flags) = 0; - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return NULL; - - retries--; - - while (1) { - struct timeval tval2; - struct ipv4_addr *tmp_ip_list; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - /* If we get a Negative Name Query Response from a WINS - * server, we should report it and give up. - */ - if( 0 == nmb2->header.opcode /* A query response */ - && !(bcast) /* from a WINS server */ - && nmb2->header.rcode /* Error returned */ - ) { - - if (DEBUGLVL(3)) { - /* Only executed if DEBUGLEVEL >= 3 */ - DEBUG(3,("Negative name query response, rcode 0x%02x: ", nmb2->header.rcode )); - switch( nmb2->header.rcode ) { - case 0x01: - DEBUG(3,("Request was invalidly formatted.\n" )); - break; - case 0x02: - DEBUG(3,("Problem with NBNS, cannot process name.\n")); - break; - case 0x03: - DEBUG(3,("The name requested does not exist.\n" )); - break; - case 0x04: - DEBUG(3,("Unsupported request error.\n" )); - break; - case 0x05: - DEBUG(3,("Query refused error.\n" )); - break; - default: - DEBUG(3,("Unrecognized error code.\n" )); - break; - } - } - free_packet(p2); - return( NULL ); - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) { - /* - * XXXX what do we do with this? Could be a - * redirect, but we'll discard it for the - * moment. - */ - free_packet(p2); - continue; - } - - tmp_ip_list = realloc_p(ip_list, - struct ipv4_addr, - (*count) + nmb2->answers->rdlength/6); - - if (!tmp_ip_list) { - DEBUG(0,("name_query: realloc_p failed.\n")); - SAFE_FREE(ip_list); - } - - ip_list = tmp_ip_list; - - if (ip_list) { - DEBUG(2,("Got a positive name query response from %s ( ", sys_inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUGADD(2,("%s ",sys_inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUGADD(2,(")\n")); - } - - found=True; - retries=0; - /* We add the flags back ... */ - if (nmb2->header.response) - (*flags) |= NM_FLAGS_RS; - if (nmb2->header.nm_flags.authoritative) - (*flags) |= NM_FLAGS_AA; - if (nmb2->header.nm_flags.trunc) - (*flags) |= NM_FLAGS_TC; - if (nmb2->header.nm_flags.recursion_desired) - (*flags) |= NM_FLAGS_RD; - if (nmb2->header.nm_flags.recursion_available) - (*flags) |= NM_FLAGS_RA; - if (nmb2->header.nm_flags.bcast) - (*flags) |= NM_FLAGS_B; - free_packet(p2); - /* - * If we're doing a unicast lookup we only - * expect one reply. Don't wait the full 2 - * seconds if we got one. JRA. - */ - if(!bcast && found) - break; - } - } - - if (timed_out) { - *timed_out = True; - } - - /* sort the ip list so we choose close servers first if possible */ - sort_ip_list(ip_list, *count); - - return ip_list; -} - -/******************************************************** - Resolve via "bcast" method. -*********************************************************/ - -BOOL name_resolve_bcast(const char *name, int name_type, - struct ipv4_addr **return_ip_list, int *return_count) -{ - int sock, i; - int num_interfaces = iface_count(); - - if (lp_disable_netbios()) { - DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type)); - return False; - } - - *return_ip_list = NULL; - *return_count = 0; - - /* - * "bcast" means do a broadcast lookup on all the local interfaces. - */ - - DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), True ); - - if (sock == -1) return False; - - set_socket_options(sock,"SO_BROADCAST"); - /* - * Lookup the name on all the interfaces, return on - * the first successful match. - */ - for( i = num_interfaces-1; i >= 0; i--) { - struct ipv4_addr sendto_ip; - int flags; - /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_n_bcast(i); - *return_ip_list = name_query(sock, name, name_type, True, - True, sendto_ip, return_count, &flags, NULL); - if(*return_ip_list != NULL) { - close(sock); - return True; - } - } - - close(sock); - return False; -} - -/******************************************************** - Resolve via "wins" method. -*********************************************************/ -BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, - struct ipv4_addr **return_iplist, int *return_count) -{ - int sock, t, i; - char **wins_tags; - struct ipv4_addr src_ip; - - if (lp_disable_netbios()) { - DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); - return False; - } - - *return_iplist = NULL; - *return_count = 0; - - DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - - if (wins_srv_count() < 1) { - DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); - return False; - } - - /* we try a lookup on each of the WINS tags in turn */ - wins_tags = wins_srv_tags(); - - if (!wins_tags) { - /* huh? no tags?? give up in disgust */ - return False; - } - - /* the address we will be sending from */ - src_ip = interpret_addr2(lp_socket_address()); - - /* in the worst case we will try every wins server with every - tag! */ - for (t=0; wins_tags && wins_tags[t]; t++) { - int srv_count = wins_srv_count_tag(wins_tags[t]); - for (i=0; i\n", name)); - - if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - struct ipv4_addr return_ip; - putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = malloc_p(struct ipv4_addr); - if(*return_iplist == NULL) { - DEBUG(3,("resolve_hosts: malloc fail !\n")); - return False; - } - **return_iplist = return_ip; - *return_count = 1; - return True; - } - return False; -} - -/******************************************************** - Internal interface to resolve a name into an IP address. - Use this function if the string is either an IP address, DNS - or host name or NetBIOS name. This uses the name switch in the - smb.conf to determine the order of name resolution. -*********************************************************/ - -static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int name_type, - struct ipv4_addr **return_iplist, int *return_count) -{ - char *name_resolve_list; - fstring tok; - const char *ptr; - BOOL allones = (strcmp(name,"255.255.255.255") == 0); - BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); - BOOL is_address = is_ipaddress(name); - BOOL result = False; - struct ipv4_addr *nodupes_iplist; - int i; - - *return_iplist = NULL; - *return_count = 0; - - DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); - - if (allzeros || allones || is_address) { - *return_iplist = malloc_p(struct ipv4_addr); - if(*return_iplist == NULL) { - DEBUG(3,("internal_resolve_name: malloc fail !\n")); - return False; - } - if(is_address) { - /* if it's in the form of an IP address then get the lib to interpret it */ - if (((*return_iplist)->addr = inet_addr(name)) == 0xFFFFFFFF ){ - DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); - return False; - } - } else { - (*return_iplist)->addr = allones ? 0xFFFFFFFF : 0; - *return_count = 1; - } - return True; - } - - /* Check netbios name cache */ - - if (namecache_fetch(mem_ctx, name, name_type, return_iplist, return_count)) { - - /* This could be a negative response */ - - return (*return_count > 0); - } - - name_resolve_list = talloc_strdup(mem_ctx, lp_name_resolve_order()); - ptr = name_resolve_list; - if (!ptr || !*ptr) - ptr = "host"; - - while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { - if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20) { - if (resolve_hosts(name, return_iplist, return_count)) { - result = True; - goto done; - } - } - } else if(strequal( tok, "lmhosts")) { - /* REWRITE: add back in? */ - DEBUG(2,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok)); - } else if(strequal( tok, "wins")) { - /* don't resolve 1D via WINS */ - if (name_type != 0x1D && - resolve_wins(mem_ctx, name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "bcast")) { - if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); - } - } - - /* All of the resolve_* functions above have returned false. */ - - SAFE_FREE(*return_iplist); - *return_count = 0; - - return False; - - done: - - /* Remove duplicate entries. Some queries, notably #1c (domain - controllers) return the PDC in iplist[0] and then all domain - controllers including the PDC in iplist[1..n]. Iterating over - the iplist when the PDC is down will cause two sets of timeouts. */ - - if (*return_count && (nodupes_iplist = malloc_array_p(struct ipv4_addr, *return_count))) { - int nodupes_count = 0; - - /* Iterate over return_iplist looking for duplicates */ - - for (i = 0; i < *return_count; i++) { - BOOL is_dupe = False; - int j; - - for (j = i + 1; j < *return_count; j++) { - if (ipv4_equal((*return_iplist)[i], - (*return_iplist)[j])) { - is_dupe = True; - break; - } - } - - if (!is_dupe) { - - /* This one not a duplicate */ - - nodupes_iplist[nodupes_count] = (*return_iplist)[i]; - nodupes_count++; - } - } - - /* Switcheroo with original list */ - - free(*return_iplist); - - *return_iplist = nodupes_iplist; - *return_count = nodupes_count; - } - - /* Save in name cache */ - for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) - DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, - name_type, sys_inet_ntoa((*return_iplist)[i]))); - - namecache_store(mem_ctx, name, name_type, *return_count, *return_iplist); - - /* Display some debugging info */ - - DEBUG(10, ("internal_resolve_name: returning %d addresses: ", - *return_count)); - - for (i = 0; i < *return_count; i++) - DEBUGADD(10, ("%s ", sys_inet_ntoa((*return_iplist)[i]))); - - DEBUG(10, ("\n")); - - return result; -} - -/******************************************************** - Internal interface to resolve a name into one IP address. - Use this function if the string is either an IP address, DNS - or host name or NetBIOS name. This uses the name switch in the - smb.conf to determine the order of name resolution. -*********************************************************/ -BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct ipv4_addr *return_ip, int name_type) -{ - struct ipv4_addr *ip_list = NULL; - int count = 0; - - if (is_ipaddress(name)) { - *return_ip = interpret_addr2(name); - return True; - } - - if (internal_resolve_name(mem_ctx, name, name_type, &ip_list, &count)) { - int i; - /* only return valid addresses for TCP connections */ - for (i=0; iheader.msg_type = 0x10; - dgram->header.flags.node_type = M_NODE; - dgram->header.flags.first = True; - dgram->header.flags.more = False; - dgram->header.dgm_id = dgm_id; - dgram->header.source_ip = *iface_ip(*pdc_ip); - dgram->header.source_port = ntohs(sock_name.sin_port); - dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ - dgram->header.packet_offset = 0; - - make_nmb_name(&dgram->source_name,srcname,0); - make_nmb_name(&dgram->dest_name,domain,0x1C); - - ptr = &dgram->data[0]; - - /* Setup the smb part. */ - ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ - memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); - memcpy(ptr,tmp,4); - - CVAL(ptr,smb_com) = SMBtrans; - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - pstrcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buffer,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ - - p.ip = *pdc_ip; - p.port = DGRAM_PORT; - p.fd = sock; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - - retries--; - - while (1) { - struct timeval tval2; - struct packet_struct *p_ret; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - GetTimeOfDay(&tval); - retries--; - } - - if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) { - struct dgram_packet *dgram2 = &p_ret->packet.dgram; - char *buf; - char *buf2; - - buf = &dgram2->data[0]; - buf -= 4; - - if (CVAL(buf,smb_com) != SMBtrans) { - DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (uint_t) - CVAL(buf,smb_com), (uint_t)SMBtrans )); - free_packet(p_ret); - continue; - } - - len = SVAL(buf,smb_vwv11); - buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); - - if (len <= 0) { - DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); - free_packet(p_ret); - continue; - } - - DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", - nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), - sys_inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); - - if(SVAL(buf2,0) != QUERYFORPDC_R) { - DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", - (uint_t)SVAL(buf,0), (uint_t)QUERYFORPDC_R )); - free_packet(p_ret); - continue; - } - - buf2 += 2; - /* Note this is safe as it is a bounded strcpy. */ - fstrcpy(ret_name, buf2); - ret_name[sizeof(fstring)-1] = '\0'; - close(sock); - free_packet(p_ret); - return True; - } - } - - close(sock); - return False; -#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ -} - -/******************************************************** - Get the IP address list of the primary domain controller - for a domain. -*********************************************************/ - -BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr *ip) -{ - struct ipv4_addr *ip_list; - int count; - int i = 0; - - /* Look up #1B name */ - - if (!internal_resolve_name(mem_ctx, domain, 0x1b, &ip_list, &count)) - return False; - - /* if we get more than 1 IP back we have to assume it is a - multi-homed PDC and not a mess up */ - - if ( count > 1 ) { - DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); - - /* look for a local net */ - for ( i=0; iname = talloc_strdup(mem_ctx, newname->name); + NT_STATUS_HAVE_NO_MEMORY(newname->name); + newname->scope = talloc_strdup(mem_ctx, newname->scope); + if (name->scope) { + NT_STATUS_HAVE_NO_MEMORY(newname->scope); + } + return NT_STATUS_OK; +} + +/* + push a nbt name into a blob +*/ +NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name) +{ + return ndr_push_struct_blob(blob, mem_ctx, name, + (ndr_push_flags_fn_t)ndr_push_nbt_name); +} + +/* + choose a name to use when calling a server in a NBT session request. + we use heuristics to see if the name we have been given is a IP + address, or a too-long name. If it is then use *SMBSERVER, or a + truncated name +*/ +void nbt_choose_called_name(TALLOC_CTX *mem_ctx, + struct nbt_name *n, const char *name, int type) +{ + n->scope = NULL; + n->type = type; + + if (is_ipaddress(name)) { + n->name = "*SMBSERVER"; + return; + } + if (strlen(name) > 15) { + const char *p = strchr(name, '.'); + if (p - name > 15) { + n->name = "*SMBSERVER"; + return; + } + n->name = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); + return; + } + + n->name = talloc_strdup(mem_ctx, name); +} diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 896ed68e98..6d5b450a31 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -28,6 +28,16 @@ #define NBT_MAX_PACKET_SIZE 2048 #define NBT_MAX_REPLIES 1000 +/* + destroy a nbt socket +*/ +static int nbtsock_destructor(void *ptr) +{ + struct nbt_name_socket *nbtsock = talloc_get_type(ptr, struct nbt_name_socket); + event_remove_fd(nbtsock->event_ctx, nbtsock->fde); + return 0; +} + /* destroy a pending request */ @@ -111,6 +121,9 @@ failed: nbt_name_request_destructor(req); req->status = status; req->state = NBT_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } talloc_free(tmp_ctx); return; } @@ -184,6 +197,9 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req->state = NBT_REQUEST_DONE; req->status = NT_STATUS_NO_MEMORY; talloc_free(tmp_ctx); + if (req->async.fn) { + req->async.fn(req); + } return; } @@ -192,15 +208,18 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req->replies[req->num_replies].packet = talloc_steal(req, packet); req->num_replies++; + talloc_free(tmp_ctx); + /* if we don't want multiple replies then we are done */ if (!req->allow_multiple_replies || req->num_replies == NBT_MAX_REPLIES) { nbt_name_request_destructor(req); req->state = NBT_REQUEST_DONE; req->status = NT_STATUS_OK; + if (req->async.fn) { + req->async.fn(req); + } } - - talloc_free(tmp_ctx); } /* @@ -257,6 +276,8 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, fde.private = nbtsock; nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde); + talloc_set_destructor(nbtsock, nbtsock_destructor); + return nbtsock; failed: @@ -273,8 +294,16 @@ static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event struct nbt_name_request *req = talloc_get_type(te->private, struct nbt_name_request); nbt_name_request_destructor(req); - req->state = NBT_REQUEST_TIMEOUT; - req->status = NT_STATUS_IO_TIMEOUT; + if (req->num_replies == 0) { + req->state = NBT_REQUEST_TIMEOUT; + req->status = NT_STATUS_IO_TIMEOUT; + } else { + req->state = NBT_REQUEST_DONE; + req->status = NT_STATUS_OK; + } + if (req->async.fn) { + req->async.fn(req); + } } /* @@ -300,14 +329,20 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, req->allow_multiple_replies = allow_multiple_replies; req->state = NBT_REQUEST_SEND; + /* we select a random transaction id unless the user supplied one */ if (req->request->name_trn_id == 0) { req->request->name_trn_id = random() % UINT16_MAX; } + /* choose the next available transaction id >= the one asked for. + The strange 2nd call is to try to make the ids less guessable + and less likely to collide. It's not possible to make NBT secure + to ID guessing, but this at least makes accidential collisions + less likely */ id = idr_get_new_above(req->nbtsock->idr, req, req->request->name_trn_id, UINT16_MAX); if (id == -1) { - id = idr_get_new_above(req->nbtsock->idr, req, 1+(random()%10000), + id = idr_get_new_above(req->nbtsock->idr, req, 1+(random()%(UINT16_MAX/2)), UINT16_MAX); } if (id == -1) goto failed; @@ -341,6 +376,9 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) if (event_loop_once(req->nbtsock->event_ctx) != 0) { req->state = NBT_REQUEST_ERROR; req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } } } return req->status; diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c deleted file mode 100644 index 0a3f72ba74..0000000000 --- a/source4/libcli/nmblib.c +++ /dev/null @@ -1,1316 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NBT netbios library routines - Copyright (C) Andrew Tridgell 1994-1998 - - 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 "system/network.h" -#include "system/time.h" -#include "system/iconv.h" - -static const struct opcode_names { - const char *nmb_opcode_name; - int opcode; -} nmb_header_opcode_names[] = { - {"Query", 0 }, - {"Registration", 5 }, - {"Release", 6 }, - {"WACK", 7 }, - {"Refresh", 8 }, - {"Refresh(altcode)", 9 }, - {"Multi-homed Registration", 15 }, - {0, -1 } -}; - -/**************************************************************************** - * Lookup a nmb opcode name. - ****************************************************************************/ -static const char *lookup_opcode_name( int opcode ) -{ - const struct opcode_names *op_namep; - int i; - - for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { - op_namep = &nmb_header_opcode_names[i]; - if(opcode == op_namep->opcode) - return op_namep->nmb_opcode_name; - } - return ""; -} - -/**************************************************************************** - print out a res_rec structure - ****************************************************************************/ -static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) -{ - int i, j; - - DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - nmb_namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl ) ); - - if( res->rdlength == 0 || res->rdata == NULL ) - return; - - for (i = 0; i < res->rdlength; i+= 16) - { - DEBUGADD(4, (" %s %3x char ", hdr, i)); - - for (j = 0; j < 16; j++) - { - uint8_t x = res->rdata[i+j]; - if (x < 32 || x > 127) x = '.'; - - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%c", x)); - } - - DEBUGADD(4, (" hex ")); - - for (j = 0; j < 16; j++) - { - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (uint8_t)res->rdata[i+j])); - } - - DEBUGADD(4, ("\n")); - } -} - -/**************************************************************************** - process a nmb packet - ****************************************************************************/ -void debug_nmb_packet(struct packet_struct *p) -{ - struct nmb_packet *nmb = &p->packet.nmb; - - if (DEBUGLVL(4)) { - DEBUG(4, ("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - sys_inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode, - BOOLSTR(nmb->header.response))); - DEBUG(4, (" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative))); - DEBUG(4, (" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount)); - } - - if (nmb->header.qdcount) - { - DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - nmb_namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class) ); - } - - if (nmb->answers && nmb->header.ancount) - { - debug_nmb_res_rec(nmb->answers,"answers"); - } - if (nmb->nsrecs && nmb->header.nscount) - { - debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); - } - if (nmb->additional && nmb->header.arcount) - { - debug_nmb_res_rec(nmb->additional,"additional"); - } -} - -/******************************************************************* - handle "compressed" name pointers - ******************************************************************/ -static BOOL handle_name_ptrs(uint8_t *ubuf,int *offset,int length, - BOOL *got_pointer,int *ret) -{ - int loop_count=0; - - while ((ubuf[*offset] & 0xC0) == 0xC0) { - if (!*got_pointer) (*ret) += 2; - (*got_pointer)=True; - (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); - } - } - return(True); -} - -/******************************************************************* - parse a nmb name from "compressed" format to something readable - return the space taken by the name, or 0 if the name is invalid - ******************************************************************/ -static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) -{ - int m,n=0; - uint8_t *ubuf = (uint8_t *)inbuf; - int ret = 0; - BOOL got_pointer=False; - int loop_count=0; - int offset = ofs; - - if (length - offset < 2) - return(0); - - /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - - if (!m) - return(0); - if ((m & 0xC0) || offset+m+2 > length) - return(0); - - memset((char *)name,'\0',sizeof(*name)); - - /* the "compressed" part */ - if (!got_pointer) - ret += m + 2; - offset++; - while (m > 0) { - uint8_t c1,c2; - c1 = ubuf[offset++]-'A'; - c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) - return(0); - name->name[n++] = (c1<<4) | c2; - m -= 2; - } - name->name[n] = 0; - - if (n==16) { - /* parse out the name type, - its always in the 16th byte of the name */ - name->name_type = ((uint8_t)name->name[15]) & 0xff; - - /* remove trailing spaces */ - name->name[15] = 0; - n = 14; - while (n && name->name[n]==' ') - name->name[n--] = 0; - } - - /* now the domain parts (if any) */ - n = 0; - while (ubuf[offset]) { - /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - /* - * Don't allow null domain parts. - */ - if (!m) - return(0); - if (!got_pointer) - ret += m+1; - if (n) - name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) - return(0); - offset++; - while (m--) - name->scope[n++] = (char)ubuf[offset++]; - - /* - * Watch for malicious loops. - */ - if (loop_count++ == 10) - return 0; - } - name->scope[n++] = 0; - - return(ret); -} - - -/******************************************************************* - put a compressed nmb name into a buffer. return the length of the - compressed name - - compressed names are really weird. The "compression" doubles the - size. The idea is that it also means that compressed names conform - to the doman name system. See RFC1002. - ******************************************************************/ -static int put_nmb_name(char *buf,int offset,struct nmb_name *name) -{ - int ret,m; - fstring buf1; - char *p; - - if (strcmp(name->name,"*") == 0) { - /* special case for wildcard name */ - memset(buf1,'\0',20); - buf1[0] = '*'; - buf1[15] = name->name_type; - } else { - slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); - } - - buf[offset] = 0x20; - - ret = 34; - - for (m=0;m<16;m++) { - buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); - } - offset += 33; - - buf[offset] = 0; - - if (name->scope[0]) { - /* XXXX this scope handling needs testing */ - ret += strlen(name->scope) + 1; - pstrcpy(&buf[offset+1],name->scope); - - p = &buf[offset+1]; - while ((p = strchr_m(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); - p = &buf[offset+1]; - } - buf[offset] = strlen(&buf[offset+1]); - } - - return(ret); -} - -/******************************************************************* - useful for debugging messages - ******************************************************************/ -char *nmb_namestr(struct nmb_name *n) -{ - static int i=0; - static fstring ret[4]; - char *p = ret[i]; - - if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); - - i = (i+1)%4; - return(p); -} - -/******************************************************************* - allocate and parse some resource records - ******************************************************************/ -static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, - struct res_rec **recs, int count) -{ - int i; - *recs = malloc_array_p(struct res_rec, count); - if (!*recs) return(False); - - memset((char *)*recs,'\0',sizeof(**recs)*count); - - for (i=0;i length) { - SAFE_FREE(*recs); - return(False); - } - (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); - (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); - (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); - (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); - (*offset) += 10; - if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || - (*offset)+(*recs)[i].rdlength > length) { - SAFE_FREE(*recs); - return(False); - } - memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; - } - return(True); -} - -/******************************************************************* - put a resource record into a packet - ******************************************************************/ -static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) -{ - int ret=0; - int i; - - for (i=0;i> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); - offset += 2; - ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); - offset += 10+rec->rdlength; - ret += 10+rec->rdlength; - - return(ret); -} - -/******************************************************************* - parse a dgram packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - - this is documented in section 4.4.1 of RFC1002 - ******************************************************************/ -static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) -{ - int offset; - int flags; - - memset((char *)dgram,'\0',sizeof(*dgram)); - - if (length < 14) return(False); - - dgram->header.msg_type = CVAL(inbuf,0); - flags = CVAL(inbuf,1); - dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); - if (flags & 1) dgram->header.flags.more = True; - if (flags & 2) dgram->header.flags.first = True; - dgram->header.dgm_id = RSVAL(inbuf,2); - putip((char *)&dgram->header.source_ip,inbuf+4); - dgram->header.source_port = RSVAL(inbuf,8); - dgram->header.dgm_length = RSVAL(inbuf,10); - dgram->header.packet_offset = RSVAL(inbuf,12); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); - } - - if (offset >= length || (length-offset > sizeof(dgram->data))) - return(False); - - dgram->datasize = length-offset; - memcpy(dgram->data,inbuf+offset,dgram->datasize); - - return(True); -} - - -/******************************************************************* - parse a nmb packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - ******************************************************************/ -static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) -{ - int nm_flags,offset; - - memset((char *)nmb,'\0',sizeof(*nmb)); - - if (length < 12) return(False); - - /* parse the header */ - nmb->header.name_trn_id = RSVAL(inbuf,0); - - DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); - - nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; - nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; - nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); - nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; - nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; - nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; - nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; - nmb->header.rcode = CVAL(inbuf,3) & 0xF; - nmb->header.qdcount = RSVAL(inbuf,4); - nmb->header.ancount = RSVAL(inbuf,6); - nmb->header.nscount = RSVAL(inbuf,8); - nmb->header.arcount = RSVAL(inbuf,10); - - if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); - if (!offset) return(False); - - if (length - (12+offset) < 4) return(False); - nmb->question.question_type = RSVAL(inbuf,12+offset); - nmb->question.question_class = RSVAL(inbuf,12+offset+2); - - offset += 12+4; - } else { - offset = 12; - } - - /* and any resource records */ - if (nmb->header.ancount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, - nmb->header.ancount)) - return(False); - - if (nmb->header.nscount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, - nmb->header.nscount)) - return(False); - - if (nmb->header.arcount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) - return(False); - - return(True); -} - -/******************************************************************* - 'Copy constructor' for an nmb packet - ******************************************************************/ -static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) -{ - struct nmb_packet *nmb; - struct nmb_packet *copy_nmb; - struct packet_struct *pkt_copy; - - if(( pkt_copy = malloc_p(struct packet_struct)) == NULL) - { - DEBUG(0,("copy_nmb_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* Ensure this copy has no resource records. */ - nmb = &packet->packet.nmb; - copy_nmb = &pkt_copy->packet.nmb; - - copy_nmb->answers = NULL; - copy_nmb->nsrecs = NULL; - copy_nmb->additional = NULL; - - /* Now copy any resource records. */ - - if (nmb->answers) - { - if((copy_nmb->answers = malloc_array_p(struct res_rec, nmb->header.ancount)) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, - nmb->header.ancount * sizeof(struct res_rec)); - } - if (nmb->nsrecs) - { - if((copy_nmb->nsrecs = malloc_array_p(struct res_rec, nmb->header.nscount)) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, - nmb->header.nscount * sizeof(struct res_rec)); - } - if (nmb->additional) - { - if((copy_nmb->additional = malloc_array_p(struct res_rec, nmb->header.arcount)) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, - nmb->header.arcount * sizeof(struct res_rec)); - } - - return pkt_copy; - -free_and_exit: - - SAFE_FREE(copy_nmb->answers); - SAFE_FREE(copy_nmb->nsrecs); - SAFE_FREE(copy_nmb->additional); - SAFE_FREE(pkt_copy); - - DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); - return NULL; -} - -/******************************************************************* - 'Copy constructor' for a dgram packet - ******************************************************************/ -static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) -{ - struct packet_struct *pkt_copy; - - if(( pkt_copy = malloc_p(struct packet_struct)) == NULL) - { - DEBUG(0,("copy_dgram_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* There are no additional pointers in a dgram packet, - we are finished. */ - return pkt_copy; -} - -/******************************************************************* - 'Copy constructor' for a generic packet - ******************************************************************/ -struct packet_struct *copy_packet(struct packet_struct *packet) -{ - if(packet->packet_type == NMB_PACKET) - return copy_nmb_packet(packet); - else if (packet->packet_type == DGRAM_PACKET) - return copy_dgram_packet(packet); - return NULL; -} - -/******************************************************************* - free up any resources associated with an nmb packet - ******************************************************************/ -static void free_nmb_packet(struct nmb_packet *nmb) -{ - SAFE_FREE(nmb->answers); - SAFE_FREE(nmb->nsrecs); - SAFE_FREE(nmb->additional); -} - -/******************************************************************* - free up any resources associated with a dgram packet - ******************************************************************/ -static void free_dgram_packet(struct dgram_packet *nmb) -{ - /* We have nothing to do for a dgram packet. */ -} - -/******************************************************************* - free up any resources associated with a packet - ******************************************************************/ -void free_packet(struct packet_struct *packet) -{ - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - else if (packet->packet_type == DGRAM_PACKET) - free_dgram_packet(&packet->packet.dgram); - ZERO_STRUCTPN(packet); - SAFE_FREE(packet); -} - -/******************************************************************* -parse a packet buffer into a packet structure - ******************************************************************/ -struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type) -{ - struct packet_struct *p; - BOOL ok=False; - - p = malloc_p(struct packet_struct); - if (!p) return(NULL); - - p->next = NULL; - p->prev = NULL; - p->locked = False; - p->timestamp = time(NULL); - p->packet_type = packet_type; - - switch (packet_type) { - case NMB_PACKET: - ok = parse_nmb(buf,length,&p->packet.nmb); - break; - - case DGRAM_PACKET: - ok = parse_dgram(buf,length,&p->packet.dgram); - break; - } - - if (!ok) { - free_packet(p); - return NULL; - } - - return p; -} - -/******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket - ******************************************************************/ -struct packet_struct *read_packet(int fd,enum packet_type packet_type) -{ - struct packet_struct *packet; - char buf[MAX_DGRAM_SIZE]; - int length; - struct ipv4_addr addr; - int port; - - length = read_udp_socket(fd, buf, sizeof(buf), &addr, &port); - if (length < MIN_DGRAM_SIZE) return(NULL); - - packet = parse_packet(buf, length, packet_type); - if (!packet) return NULL; - - packet->fd = fd; - packet->ip = addr; - packet->port = port; - - DEBUG(5,("Received a packet of len %d from (%s) port %d\n", - length, sys_inet_ntoa(packet->ip), packet->port)); - - return packet; -} - - -/******************************************************************* - send a udp packet on a already open socket - ******************************************************************/ -static BOOL send_udp(int fd,char *buf,int len,struct ipv4_addr ip,int port) -{ - BOOL ret = False; - int i; - struct sockaddr_in sock_out; - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; - - DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", - len, sys_inet_ntoa(ip), port ) ); - - /* - * Patch to fix asynch error notifications from Linux kernel. - */ - - for (i = 0; i < 5; i++) { - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); - if (ret || errno != ECONNREFUSED) - break; - } - - if (!ret) - DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", - sys_inet_ntoa(ip),port,strerror(errno))); - - return(ret); -} - -/******************************************************************* - build a dgram packet ready for sending - - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. - - [...but it isn't clear that we would ever need to send a - a fragmented NBT Datagram. The IP layer does its own - fragmentation to ensure that messages can fit into the path - MTU. It *is* important to be able to receive and rebuild - fragmented NBT datagrams, just in case someone out there - really has implemented this 'feature'. crh -)------ ] - - ******************************************************************/ -static int build_dgram(char *buf,struct packet_struct *p) -{ - struct dgram_packet *dgram = &p->packet.dgram; - uint8_t *ubuf = (uint8_t *)buf; - int offset=0; - - /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) ubuf[1] |= 1; - if (dgram->header.flags.first) ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); - offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); - } - - memcpy(ubuf+offset,dgram->data,dgram->datasize); - offset += dgram->datasize; - - /* automatically set the dgm_length - * NOTE: RFC1002 says the dgm_length does *not* - * include the fourteen-byte header. crh - */ - dgram->header.dgm_length = (offset - 14); - RSSVAL(ubuf,10,dgram->header.dgm_length); - - return(offset); -} - -/******************************************************************* - Build a nmb name -*******************************************************************/ - -void make_nmb_name( struct nmb_name *n, const char *name, int type) -{ - memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); - n->name_type = (uint_t)type & 0xFF; - StrnCpy( n->scope, lp_netbios_scope(), 63 ); - strupper( n->scope ); -} - -/******************************************************************* - Compare two nmb names - ******************************************************************/ - -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) -{ - return ((n1->name_type == n2->name_type) && - strequal(n1->name ,n2->name ) && - strequal(n1->scope,n2->scope)); -} - -/******************************************************************* - build a nmb packet ready for sending - - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) - ******************************************************************/ -static int build_nmb(char *buf,struct packet_struct *p) -{ - struct nmb_packet *nmb = &p->packet.nmb; - uint8_t *ubuf = (uint8_t *)buf; - int offset=0; - - /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); - - offset += 12; - if (nmb->header.qdcount) { - /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); - offset += 4; - } - - if (nmb->header.ancount) - offset += put_res_rec((char *)ubuf,offset,nmb->answers, - nmb->header.ancount); - - if (nmb->header.nscount) - offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, - nmb->header.nscount); - - /* - * The spec says we must put compressed name pointers - * in the following outgoing packets : - * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, - * NAME_RELEASE_REQUEST. - */ - - if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - - } else if (nmb->header.arcount) { - offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); - } - return(offset); -} - - -/******************************************************************* -linearise a packet - ******************************************************************/ -int build_packet(char *buf, struct packet_struct *p) -{ - int len = 0; - - switch (p->packet_type) { - case NMB_PACKET: - len = build_nmb(buf,p); - break; - - case DGRAM_PACKET: - len = build_dgram(buf,p); - break; - } - - return len; -} - -/******************************************************************* - send a packet_struct - ******************************************************************/ -BOOL send_packet(struct packet_struct *p) -{ - char buf[1024]; - int len=0; - - memset(buf,'\0',sizeof(buf)); - - len = build_packet(buf, p); - - if (!len) return(False); - - return(send_udp(p->fd,buf,len,p->ip,p->port)); -} - -/**************************************************************************** - receive a packet with timeout on a open UDP filedescriptor - The timeout is in milliseconds - ***************************************************************************/ -struct packet_struct *receive_packet(int fd,enum packet_type type,int t) -{ - fd_set fds; - struct timeval timeout; - int ret; - - FD_ZERO(&fds); - FD_SET(fd,&fds); - timeout.tv_sec = t/1000; - timeout.tv_usec = 1000*(t%1000); - - if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) { - /* errno should be EBADF or EINVAL. */ - DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); - return NULL; - } - - if (ret == 0) /* timeout */ - return NULL; - - if (FD_ISSET(fd,&fds)) - return(read_packet(fd,type)); - - return(NULL); -} - - -/**************************************************************************** - receive a UDP/137 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified trn_id - The timeout is in milliseconds - ***************************************************************************/ -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) -{ - struct packet_struct *p; - - p = receive_packet(fd, NMB_PACKET, t); - - if (p && p->packet.nmb.header.response && - p->packet.nmb.header.name_trn_id == trn_id) { - return p; - } - if (p) free_packet(p); - - /* try the unexpected packet queue */ - return receive_unexpected(NMB_PACKET, trn_id, NULL); -} - -/**************************************************************************** - receive a UDP/138 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified mailslot name - The timeout is in milliseconds - ***************************************************************************/ -struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) -{ - struct packet_struct *p; - - p = receive_packet(fd, DGRAM_PACKET, t); - - if (p && match_mailslot_name(p, mailslot_name)) { - return p; - } - if (p) free_packet(p); - - /* try the unexpected packet queue */ - return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); -} - - -/**************************************************************************** - see if a datagram has the right mailslot name -***************************************************************************/ -BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) -{ - struct dgram_packet *dgram = &p->packet.dgram; - char *buf; - - buf = &dgram->data[0]; - buf -= 4; - - buf = smb_buf(buf); - - if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) { - return True; - } - - return False; -} - - -/**************************************************************************** -return the number of bits that match between two 4 character buffers - ***************************************************************************/ -int matching_quad_bits(uint8_t *p1, uint8_t *p2) -{ - int i, j, ret = 0; - for (i=0; i<4; i++) { - if (p1[i] != p2[i]) break; - ret += 8; - } - - if (i==4) return ret; - - for (j=0; j<8; j++) { - if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; - ret++; - } - - return ret; -} - - -static uint8_t sort_ip[4]; - -/**************************************************************************** -compare two query reply records - ***************************************************************************/ -static int name_query_comp(uint8_t *p1, uint8_t *p2) -{ - return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); -} - -/**************************************************************************** -sort a set of 6 byte name query response records so that the IPs that -have the most leading bits in common with the specified address come first - ***************************************************************************/ -void sort_query_replies(char *data, int n, struct ipv4_addr ip) -{ - if (n <= 1) return; - - putip(sort_ip, (char *)&ip); - - qsort(data, n, 6, QSORT_CAST name_query_comp); -} - - -#define TRUNCATE_NETBIOS_NAME 1 - -/******************************************************************* - convert, possibly using a stupid microsoft-ism which has destroyed - the transport independence of netbios (for CIFS vendors that usually - use the Win95-type methods, not for NT to NT communication, which uses - DCE/RPC and therefore full-length unicode strings...) a dns name into - a netbios name. - - the netbios name (NOT necessarily null-terminated) is truncated to 15 - characters. - - ******************************************************************/ -char *dns_to_netbios_name(char *dns_name) -{ - static char netbios_name[16]; - int i; - StrnCpy(netbios_name, dns_name, 15); - netbios_name[15] = 0; - -#ifdef TRUNCATE_NETBIOS_NAME - /* ok. this is because of a stupid microsoft-ism. if the called host - name contains a '.', microsoft clients expect you to truncate the - netbios name up to and including the '.' this even applies, by - mistake, to workgroup (domain) names, which is _really_ daft. - */ - for (i = 15; i >= 0; i--) - { - if (netbios_name[i] == '.') - { - netbios_name[i] = 0; - break; - } - } -#endif /* TRUNCATE_NETBIOS_NAME */ - - return netbios_name; -} - - -/**************************************************************************** -interpret the weird netbios "name". Return the name type -****************************************************************************/ -static int name_interpret(char *in,char *out) -{ - int ret; - int len = (*in++) / 2; - - *out=0; - - if (len > 30 || len<1) return(0); - - while (len--) - { - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { - *out = 0; - return(0); - } - *out = ((in[0]-'A')<<4) + (in[1]-'A'); - in += 2; - out++; - } - *out = 0; - ret = out[-1]; - -#ifdef NETBIOS_SCOPE - /* Handle any scope names */ - while(*in) - { - *out++ = '.'; /* Scope names are separated by periods */ - len = *(uint8_t *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; - } -#endif - return(ret); -} - - -/**************************************************************************** -return the number of bytes that would be occupied by the result of -name_mangle() -****************************************************************************/ -uint_t nbt_mangled_name_len(void) -{ - const char *scope = lp_netbios_scope(); - uint_t ret = 34; - if (scope && *scope) { - ret += strlen(scope) + 1; - } - return ret; -} - -/**************************************************************************** -mangle a name into netbios format - - Note: must be nbt_mangled_name_len() in length -****************************************************************************/ -int name_mangle(char *In, char *Out, char name_type) -{ - int i; - int c; - int len; - char buf[20]; - char *p = Out; - const char *scope = lp_netbios_scope(); - - /* Safely copy the input string, In, into buf[]. */ - memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) { - buf[0] = '*'; - } else { - slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type); - } - - /* Place the length of the first field into the output buffer. */ - p[0] = 32; - p++; - - /* Now convert the name to the rfc1001/1002 format. */ - for ( i = 0; i < 16; i++ ) { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0xF ) + 'A'; - p[(i*2)+1] = (c & 0xF) + 'A'; - } - p += 32; - p[0] = '\0'; - - if (!scope || !*scope) { - return name_len(Out); - } - - /* Add the scope string. */ - for (i = 0, len = 0; scope[i]; i++, len++) { - switch(scope[i]) { - case '.': - p[0] = len; - p += (len + 1); - len = -1; - break; - default: - p[len+1] = scope[i]; - break; - } - } - - p[0] = len; - if (len > 0) { - p[len+1] = 0; - } - - return name_len(Out); -} - -/**************************************************************************** -find a pointer to a netbios name -****************************************************************************/ -static char *name_ptr(char *buf,int ofs) -{ - uint8_t c = *(uint8_t *)(buf+ofs); - - if ((c & 0xC0) == 0xC0) - { - uint16_t l = RSVAL(buf, ofs) & 0x3FFF; - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); - } - else - return(buf+ofs); -} - -/**************************************************************************** -extract a netbios name from a buf -****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) -{ - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - pstrcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); -} - -/**************************************************************************** -return the total storage length of a mangled name -****************************************************************************/ -int name_len(char *s1) -{ - /* NOTE: this argument _must_ be unsigned */ - uint8_t *s = (uint8_t *)s1; - int len; - - /* If the two high bits of the byte are set, return 2. */ - if (0xC0 == (*s & 0xC0)) - return(2); - - /* Add up the length bytes. */ - for (len = 1; (*s); s += (*s) + 1) { - len += *s + 1; - SMB_ASSERT(len < 80); - } - - return(len); -} /* name_len */ - - -/* - choose a name to use when calling a server in a NBT session request. - we use heuristics to see if the name we have been given is a IP - address, or a too-long name. If it is then use *SMBSERVER, or a - truncated name -*/ -void choose_called_name(struct nmb_name *n, const char *name, int type) -{ - if (is_ipaddress(name)) { - make_nmb_name(n, "*SMBSERVER", type); - return; - } - if (strlen(name) > 16) { - const char *p = strchr(name, '.'); - char name2[17]; - if (p - name > 16) { - make_nmb_name(n, "*SMBSERVER", type); - return; - } - strlcpy(name2, name, 1+(p-name)); - make_nmb_name(n, name2, type); - return; - } - - /* looks OK */ - make_nmb_name(n, name, type); -} diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 0edb95e1a1..e981049535 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -326,10 +326,11 @@ resolve a hostname and connect ****************************************************************************/ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, int port) { - int name_type = 0x20; - struct ipv4_addr ip; - char *name, *p; + int name_type = NBT_NAME_SERVER; + const char *address; NTSTATUS status; + struct nbt_name nbt_name; + char *name, *p; name = talloc_strdup(sock, host); @@ -339,13 +340,18 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in *p = 0; } - if (!resolve_name(name, name, &ip, name_type)) { + nbt_name.name = name; + nbt_name.type = name_type; + nbt_name.scope = NULL; + + status = resolve_name(&nbt_name, sock, &address); + if (!NT_STATUS_IS_OK(status)) { return False; } sock->hostname = name; - status = smbcli_sock_connect(sock, sys_inet_ntoa(ip), port); + status = smbcli_sock_connect(sock, address, port); return NT_STATUS_IS_OK(status); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index e6d40639c6..918f18fa40 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -145,41 +145,52 @@ static void smbcli_transport_write_disable(struct smbcli_transport *transport) send a session request */ struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport, - struct nmb_name *calling, - struct nmb_name *called) + struct nbt_name *calling, + struct nbt_name *called) { uint8_t *p; - int len = NBT_HDR_SIZE; struct smbcli_request *req; + DATA_BLOB calling_blob, called_blob; + TALLOC_CTX *tmp_ctx = talloc_new(transport); + NTSTATUS status; - if (called) { - transport->called = *called; - } + status = nbt_name_dup(transport, called, &transport->called); + if (!NT_STATUS_IS_OK(status)) goto failed; + + status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling); + if (!NT_STATUS_IS_OK(status)) goto failed; + + status = nbt_name_to_blob(tmp_ctx, &called_blob, called); + if (!NT_STATUS_IS_OK(status)) goto failed; /* allocate output buffer */ req = smbcli_request_setup_nonsmb(transport, - NBT_HDR_SIZE + 2*nbt_mangled_name_len()); - if (req == NULL) return NULL; + NBT_HDR_SIZE + + calling_blob.length + called_blob.length); + if (req == NULL) goto failed; /* put in the destination name */ p = req->out.buffer + NBT_HDR_SIZE; - name_mangle(called->name, (char *)p, called->name_type); - len += name_len((char *)p); + memcpy(p, called_blob.data, called_blob.length); + p += called_blob.length; - /* and my name */ - p = req->out.buffer+len; - name_mangle(calling->name, (char *)p, calling->name_type); - len += name_len((char *)p); + memcpy(p, calling_blob.data, calling_blob.length); + p += calling_blob.length; - _smb_setlen(req->out.buffer,len-4); + _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer)-4); SCVAL(req->out.buffer,0,0x81); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); - return NULL; + goto failed; } + talloc_free(tmp_ctx); return req; + +failed: + talloc_free(tmp_ctx); + return NULL; } /* @@ -237,8 +248,8 @@ NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req) send a session request (if needed) */ BOOL smbcli_transport_connect(struct smbcli_transport *transport, - struct nmb_name *calling, - struct nmb_name *called) + struct nbt_name *calling, + struct nbt_name *called) { struct smbcli_request *req; NTSTATUS status; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 4047a5d369..d7414a237e 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -21,6 +21,7 @@ */ #include "request.h" +#include "librpc/gen_ndr/ndr_nbt.h" struct smbcli_tree; /* forward declare */ struct smbcli_request; /* forward declare */ @@ -151,7 +152,7 @@ struct smbcli_transport { /* remember the called name - some sub-protocols require us to know the server name */ - struct nmb_name called; + struct nbt_name called; /* a buffer for partially received SMB packets. */ struct { diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c new file mode 100644 index 0000000000..b2d37fbfbb --- /dev/null +++ b/source4/libcli/resolve/bcast.c @@ -0,0 +1,163 @@ +/* + Unix SMB/CIFS implementation. + + broadcast name resolution module + + Copyright (C) Andrew Tridgell 2005 + + 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 "system/network.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/composite/composite.h" + +struct bcast_state { + struct nbt_name name; + struct nbt_name_socket *nbtsock; + int num_queries; + struct nbt_name_request **queries; + struct nbt_name_query *io_queries; + const char *reply_addr; +}; + +/* + handle events during broadcast name resolution +*/ +static void bcast_handler(struct nbt_name_request *req) +{ + struct smbcli_composite *c = talloc_get_type(req->async.private, + struct smbcli_composite); + struct bcast_state *state = talloc_get_type(c->private, struct bcast_state); + int i; + + for (i=0;inum_queries;i++) { + if (req == state->queries[i]) break; + } + if (i == state->num_queries) { + /* not for us?! */ + c->status = NT_STATUS_INTERNAL_ERROR; + c->state = SMBCLI_REQUEST_ERROR; + goto done; + } + + c->status = nbt_name_query_recv(req, state, &state->io_queries[i]); + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + } else { + c->state = SMBCLI_REQUEST_DONE; + state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr); + } + +done: + talloc_free(state->nbtsock); + if (c->async.fn) { + c->async.fn(c); + } +} + +/* + broadcast name resolution method - async send + */ +struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, + struct event_context *event_ctx) +{ + struct smbcli_composite *c; + struct bcast_state *state; + int i; + NTSTATUS status; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct bcast_state); + if (state == NULL) goto failed; + + status = nbt_name_dup(state, name, &state->name); + if (!NT_STATUS_IS_OK(status)) goto failed; + + state->nbtsock = nbt_name_socket_init(state, event_ctx); + if (state->nbtsock == NULL) goto failed; + + state->num_queries = iface_count(); + + state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries); + if (!state->io_queries) goto failed; + + state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries); + if (!state->queries) goto failed; + + for (i=0;inum_queries;i++) { + struct ipv4_addr *ip = iface_n_bcast(i); + const char *addr = sys_inet_ntoa(*ip); + if (!addr) goto failed; + + state->io_queries[i].in.name = state->name; + state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, addr); + if (!state->io_queries[i].in.dest_addr) goto failed; + state->io_queries[i].in.broadcast = True; + state->io_queries[i].in.wins_lookup = False; + state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "bcastTimeout", 5); + + state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); + if (!state->queries[i]) goto failed; + + state->queries[i]->async.fn = bcast_handler; + state->queries[i]->async.private = c; + } + + c->state = SMBCLI_REQUEST_SEND; + c->private = state; + c->event_ctx = state->nbtsock->event_ctx; + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + broadcast name resolution method - recv side + */ +NTSTATUS resolve_name_bcast_recv(struct smbcli_composite *c, + TALLOC_CTX *mem_ctx, const char **reply_addr) +{ + NTSTATUS status; + + status = smb_composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct bcast_state *state = talloc_get_type(c->private, struct bcast_state); + *reply_addr = talloc_steal(mem_ctx, state->reply_addr); + } + + talloc_free(c); + return status; +} + +/* + broadcast name resolution method - sync call + */ +NTSTATUS resolve_name_bcast(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + const char **reply_addr) +{ + struct smbcli_composite *c = resolve_name_bcast_send(name, NULL); + return resolve_name_bcast_recv(c, mem_ctx, reply_addr); +} + diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c new file mode 100644 index 0000000000..e83b11c95e --- /dev/null +++ b/source4/libcli/resolve/resolve.c @@ -0,0 +1,51 @@ +/* + Unix SMB/CIFS implementation. + + general name resolution interface + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" + +/* + general name resolution - async send + */ +struct smbcli_composite *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx) +{ + return resolve_name_bcast_send(name, event_ctx); +} + +/* + general name resolution method - recv side + */ +NTSTATUS resolve_name_recv(struct smbcli_composite *c, + TALLOC_CTX *mem_ctx, const char **reply_addr) +{ + return resolve_name_bcast_recv(c, mem_ctx, reply_addr); +} + +/* + general name resolution - sync call + */ +NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) +{ + struct smbcli_composite *c = resolve_name_send(name, NULL); + return resolve_name_recv(c, mem_ctx, reply_addr); +} diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c deleted file mode 100644 index 264b9d7b33..0000000000 --- a/source4/libcli/unexpected.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - Unix SMB/CIFS implementation. - handle unexpected packets - Copyright (C) Andrew Tridgell 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" - -static struct tdb_wrap *tdbd = NULL; - -/* the key type used in the unexpeceted packet database */ -struct unexpected_key { - enum packet_type packet_type; - time_t timestamp; - int count; -}; - - - -/**************************************************************************** - all unexpected packets are passed in here, to be stored in a unexpected - packet database. This allows nmblookup and other tools to receive packets - erroneoously sent to the wrong port by broken MS systems - **************************************************************************/ -void unexpected_packet(struct packet_struct *p) -{ - static int count; - TDB_DATA kbuf, dbuf; - struct unexpected_key key; - char buf[1024]; - int len=0; - - if (!tdbd) { - char *path = smbd_tmp_path(NULL, "unexpected.tdb"); - tdbd = tdb_wrap_open(NULL, path, 0, - TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); - talloc_free(path); - if (!tdbd) { - return; - } - } - - memset(buf,'\0',sizeof(buf)); - - len = build_packet(buf, p); - - key.packet_type = p->packet_type; - key.timestamp = p->timestamp; - key.count = count++; - - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); - dbuf.dptr = buf; - dbuf.dsize = len; - - tdb_store(tdbd->tdb, kbuf, dbuf, TDB_REPLACE); -} - - -static time_t lastt; - -/**************************************************************************** -delete the record if it is too old - **************************************************************************/ -static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) -{ - struct unexpected_key key; - - memcpy(&key, kbuf.dptr, sizeof(key)); - - if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) { - tdb_delete(ttdb, kbuf); - } - - return 0; -} - - -/**************************************************************************** -delete all old unexpected packets - **************************************************************************/ -void clear_unexpected(time_t t) -{ - if (!tdbd) return; - - if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT)) - return; - - lastt = t; - - tdb_traverse(tdbd->tdb, traverse_fn, NULL); -} - - -static struct packet_struct *matched_packet; -static int match_id; -static enum packet_type match_type; -static const char *match_name; - -/**************************************************************************** -tdb traversal fn to find a matching 137 packet - **************************************************************************/ -static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) -{ - struct unexpected_key key; - struct packet_struct *p; - - memcpy(&key, kbuf.dptr, sizeof(key)); - - if (key.packet_type != match_type) return 0; - - p = parse_packet(dbuf.dptr, dbuf.dsize, match_type); - - if ((match_type == NMB_PACKET && - p->packet.nmb.header.name_trn_id == match_id) || - (match_type == DGRAM_PACKET && - match_mailslot_name(p, match_name))) { - matched_packet = p; - return -1; - } - - free_packet(p); - - return 0; -} - - -/**************************************************************************** -check for a particular packet in the unexpected packet queue - **************************************************************************/ -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - const char *mailslot_name) -{ - struct tdb_wrap *tdb2; - char *path; - - path = smbd_tmp_path(NULL, "unexpected.tdb"); - tdb2 = tdb_wrap_open(NULL, path, 0, 0, O_RDONLY, 0); - talloc_free(path); - if (!tdb2) { - return NULL; - } - - matched_packet = NULL; - match_id = id; - match_type = packet_type; - match_name = mailslot_name; - - tdb_traverse(tdb2->tdb, traverse_match, NULL); - - talloc_free(tdb2); - - return matched_packet; -} -- cgit From 4962fd4f288eb58b491a42f5496a4e6185d42df8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Jan 2005 11:23:11 +0000 Subject: r4893: Move to using secrets.ldb for the Kerberos verify, instead of secrets.tdb from Samba3. Andrew Bartlett (This used to be commit 21bfda2a0d1c8373f8800269ed9b982e1b9a19e5) --- source4/libcli/auth/kerberos_verify.c | 45 +++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 92980f1122..b089d633ed 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -26,6 +26,8 @@ #include "system/kerberos.h" #include "libcli/auth/kerberos.h" #include "asn_1.h" +#include "lib/ldb/include/ldb.h" +#include "secrets.h" #ifdef HAVE_KRB5 @@ -179,26 +181,46 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte krb5_keyblock *keyblock) { krb5_error_code ret = 0; - char *password_s = NULL; krb5_data password; krb5_enctype *enctypes = NULL; int i; - + const struct ldb_val *password_v; + struct ldb_wrap *ldb; + int ldb_ret; + struct ldb_message **msgs; + const char *base_dn = SECRETS_PRIMARY_DOMAIN_DN; + const char *attrs[] = { + "secret", + NULL + }; + ZERO_STRUCTP(keyblock); - if (!secrets_init()) { - DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); - return KRB5_KT_END; + /* Local secrets are stored in secrets.ldb */ + ldb = secrets_db_connect(mem_ctx); + if (!ldb) { + return ENOENT; } - password_s = secrets_fetch_machine_password(lp_workgroup()); - if (!password_s) { - DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n")); - return KRB5_KT_END; + /* search for the secret record */ + ldb_ret = samdb_search(ldb, + mem_ctx, base_dn, &msgs, attrs, + "(&(realm=%s)(objectclass=primaryDomain))", + lp_realm()); + if (ldb_ret == 0) { + DEBUG(1, ("Could not find domain join record for %s\n", + lp_realm())); + return ENOENT; + } else if (ldb_ret != 1) { + DEBUG(1, ("Found %d records matching cn=%s under DN %s\n", ldb_ret, + lp_realm(), base_dn)); + return ENOENT; } - password.data = password_s; - password.length = strlen(password_s); + password_v = ldb_msg_find_ldb_val(msgs[0], "secret"); + + password.data = password_v->data; + password.length = password_v->length; /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ @@ -247,7 +269,6 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte out: free_kerberos_etypes(context, enctypes); - SAFE_FREE(password_s); return ret; } -- cgit From a721be4519d0090c27935afcec1c3bb75115eb87 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 11:25:33 +0000 Subject: r4894: namecache.c is not used any more either (This used to be commit 24927e69d824a1f3c01b2f63876afdfc6064d5ac) --- source4/libcli/namecache.c | 247 --------------------------------------------- 1 file changed, 247 deletions(-) delete mode 100644 source4/libcli/namecache.c (limited to 'source4/libcli') diff --git a/source4/libcli/namecache.c b/source4/libcli/namecache.c deleted file mode 100644 index 34df4a3c5f..0000000000 --- a/source4/libcli/namecache.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - NetBIOS name cache module on top of gencache mechanism. - - Copyright (C) Tim Potter 2002 - Copyright (C) Rafal Szczesniak 2002 - - 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 "system/time.h" - -#define NBTKEY_FMT "NBT/%s#%02X" - - -/** - * Initialise namecache system. Function calls gencache - * initialisation function to perform necessary actions - * - * @return true upon successful initialisation of the cache or - * false on failure - **/ - -BOOL namecache_enableTODO(void) -{ - /* - * Check if name caching disabled by setting the name cache - * timeout to zero. - */ - - if (lp_name_cache_timeout() == 0) { - DEBUG(5, ("namecache_enable: disabling netbios name cache\n")); - return False; - } - - /* Init namecache by calling gencache initialisation */ - - if (!gencache_init()) { - DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n")); - return False; - } - - /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */ - DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " - "seconds\n", lp_name_cache_timeout())); - - return True; -} - - -/** - * Shutdown namecache. Routine calls gencache close function - * to safely close gencache file. - * - * @return true upon successful shutdown of the cache or - * false on failure - **/ - -BOOL namecache_shutdownTODO(void) -{ - if (!gencache_shutdown()) { - DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n")); - return False; - } - - DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n")); - return True; -} - - -/** - * Generates a key for netbios name lookups on basis of - * netbios name and type. - * The caller must free returned key string when finished. - * - * @param name netbios name string (case insensitive) - * @param name_type netbios type of the name being looked up - * - * @return string consisted of uppercased name and appended - * type number - */ - -static char* namecache_key(TALLOC_CTX *mem_ctx, const char *name, int name_type) -{ - char *keystr; - asprintf(&keystr, NBTKEY_FMT, strupper_talloc(mem_ctx, name), name_type); - - return keystr; -} - - -/** - * Store a name(s) in the name cache - * - * @param name netbios names array - * @param name_type integer netbios name type - * @param num_names number of names being stored - * @param ip_list array of in_addr structures containing - * ip addresses being stored - **/ - -BOOL namecache_store(TALLOC_CTX *mem_ctx, const char *name, int name_type, - int num_names, struct ipv4_addr *ip_list) -{ - time_t expiry; - char *key, *value_string; - int i; - - /* - * we use gecache call to avoid annoying debug messages about - * initialised namecache again and again... - */ - if (!gencache_init()) return False; - - DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", - num_names, num_names == 1 ? "": "es", name, name_type)); - - for (i = 0; i < num_names; i++) - DEBUGADD(5, ("%s%s", sys_inet_ntoa(ip_list[i]), - i == (num_names - 1) ? "" : ", ")); - - DEBUGADD(5, ("\n")); - - key = namecache_key(mem_ctx, name, name_type); - - /* - * Cache pdc location or dc lists for only a little while - * otherwise if we lock on to a bad DC we can potentially be - * out of action for the entire cache timeout time! - */ - - if (name_type == 0x1b || name_type == 0x1c) - expiry = time(NULL) + 10; - else - expiry = time(NULL) + lp_name_cache_timeout(); - - /* - * Generate string representation of ip addresses list - * First, store the number of ip addresses and then - * place each single ip - */ - ipstr_list_make(&value_string, ip_list, num_names); - - /* set the entry */ - return (gencache_set(key, value_string, expiry)); -} - - -/** - * Look up a name in the cache. - * - * @param name netbios name to look up for - * @param name_type netbios name type of @param name - * @param ip_list mallocated list of IP addresses if found in the cache, - * NULL otherwise - * @param num_names number of entries found - * - * @return true upon successful fetch or - * false if name isn't found in the cache or has expired - **/ - -BOOL namecache_fetch(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct ipv4_addr **ip_list, - int *num_names) -{ - char *key, *value; - time_t timeout; - - *num_names = 0; - - /* exit now if null pointers were passed as they're required further */ - if (!ip_list || !num_names) return False; - - if (!gencache_init()) - return False; - - /* - * Use gencache interface - lookup the key - */ - key = namecache_key(mem_ctx, name, name_type); - - if (!gencache_get(key, &value, &timeout)) { - DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); - SAFE_FREE(key); - return False; - } else { - DEBUG(5, ("name %s#%02X found.\n", name, name_type)); - } - - /* - * Split up the stored value into the list of IP adresses - */ - *num_names = ipstr_list_parse(value, ip_list); - - SAFE_FREE(key); - SAFE_FREE(value); - return *num_names > 0; /* true only if some ip has been fetched */ -} - - -/** - * Delete single namecache entry. Look at the - * gencache_iterate definition. - * - **/ - -static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr) -{ - gencache_del(key); - DEBUG(5, ("Deleting entry %s\n", key)); -} - - -/** - * Flush all names from the name cache. - * It's done by gencache_iterate() - * - * @return True upon successful deletion or - * False in case of an error - **/ - -void namecache_flush(void) -{ - if (!gencache_init()) - return; - - /* - * iterate through each NBT cache's entry and flush it - * by flush_netbios_name function - */ - gencache_iterate(flush_netbios_name, NULL, "NBT/*"); - DEBUG(5, ("Namecache flushed\n")); -} - -- cgit From c0e21a4d3eaac92387c497f75b5957d0b8a4dc8a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 11:41:48 +0000 Subject: r4896: make sure the event context doesn't go away while waiting for event completion (This used to be commit c1063919c069b0b36dd3da6dc6853236629804e3) --- source4/libcli/resolve/bcast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index b2d37fbfbb..d424b5303a 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -122,7 +122,7 @@ struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, c->state = SMBCLI_REQUEST_SEND; c->private = state; - c->event_ctx = state->nbtsock->event_ctx; + c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx); return c; -- cgit From 6f0aef31cdfa9b486d1f2e0f097e071830f5600d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 13:13:24 +0000 Subject: r4898: - removed the unused wins_srv_*() code - expanded the generic async name resolver to try multiple methods - added wins resolutions to the list of methods tried - fixed up the random trn id generation to use the good random generator (This used to be commit 266fd2751c01808e5a18d4094032af50554ceb7a) --- source4/libcli/config.mk | 4 +- source4/libcli/nbt/nbtsocket.c | 4 +- source4/libcli/resolve/bcast.c | 116 ++++---------------------- source4/libcli/resolve/nbtlist.c | 170 +++++++++++++++++++++++++++++++++++++++ source4/libcli/resolve/resolve.c | 113 +++++++++++++++++++++++++- source4/libcli/resolve/wins.c | 58 +++++++++++++ 6 files changed, 359 insertions(+), 106 deletions(-) create mode 100644 source4/libcli/resolve/nbtlist.c create mode 100644 source4/libcli/resolve/wins.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 21cfed8987..904a07dc0f 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -30,7 +30,9 @@ REQUIRED_SUBSYSTEMS = NDR_NBT [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ libcli/resolve/resolve.o \ - libcli/resolve/bcast.o + libcli/resolve/nbtlist.o \ + libcli/resolve/bcast.o \ + libcli/resolve/wins.o REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI] diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 6d5b450a31..865c542ca8 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -331,7 +331,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, /* we select a random transaction id unless the user supplied one */ if (req->request->name_trn_id == 0) { - req->request->name_trn_id = random() % UINT16_MAX; + req->request->name_trn_id = generate_random() % UINT16_MAX; } /* choose the next available transaction id >= the one asked for. @@ -342,7 +342,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, id = idr_get_new_above(req->nbtsock->idr, req, req->request->name_trn_id, UINT16_MAX); if (id == -1) { - id = idr_get_new_above(req->nbtsock->idr, req, 1+(random()%(UINT16_MAX/2)), + id = idr_get_new_above(req->nbtsock->idr, req, 1+(generate_random()%(UINT16_MAX/2)), UINT16_MAX); } if (id == -1) goto failed; diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index d424b5303a..9aefa32fae 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -23,112 +23,36 @@ #include "includes.h" #include "system/network.h" #include "libcli/raw/libcliraw.h" -#include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" -struct bcast_state { - struct nbt_name name; - struct nbt_name_socket *nbtsock; - int num_queries; - struct nbt_name_request **queries; - struct nbt_name_query *io_queries; - const char *reply_addr; -}; - -/* - handle events during broadcast name resolution -*/ -static void bcast_handler(struct nbt_name_request *req) -{ - struct smbcli_composite *c = talloc_get_type(req->async.private, - struct smbcli_composite); - struct bcast_state *state = talloc_get_type(c->private, struct bcast_state); - int i; - - for (i=0;inum_queries;i++) { - if (req == state->queries[i]) break; - } - if (i == state->num_queries) { - /* not for us?! */ - c->status = NT_STATUS_INTERNAL_ERROR; - c->state = SMBCLI_REQUEST_ERROR; - goto done; - } - - c->status = nbt_name_query_recv(req, state, &state->io_queries[i]); - if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; - } else { - c->state = SMBCLI_REQUEST_DONE; - state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr); - } - -done: - talloc_free(state->nbtsock); - if (c->async.fn) { - c->async.fn(c); - } -} - /* broadcast name resolution method - async send */ struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, struct event_context *event_ctx) { + int num_interfaces = iface_count(); + const char **address_list; struct smbcli_composite *c; - struct bcast_state *state; int i; - NTSTATUS status; - - c = talloc_zero(NULL, struct smbcli_composite); - if (c == NULL) goto failed; - state = talloc(c, struct bcast_state); - if (state == NULL) goto failed; + address_list = talloc_array(NULL, const char *, num_interfaces+1); + if (address_list == NULL) return NULL; - status = nbt_name_dup(state, name, &state->name); - if (!NT_STATUS_IS_OK(status)) goto failed; - - state->nbtsock = nbt_name_socket_init(state, event_ctx); - if (state->nbtsock == NULL) goto failed; - - state->num_queries = iface_count(); - - state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries); - if (!state->io_queries) goto failed; - - state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries); - if (!state->queries) goto failed; - - for (i=0;inum_queries;i++) { + for (i=0;iio_queries[i].in.name = state->name; - state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, addr); - if (!state->io_queries[i].in.dest_addr) goto failed; - state->io_queries[i].in.broadcast = True; - state->io_queries[i].in.wins_lookup = False; - state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "bcastTimeout", 5); - - state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); - if (!state->queries[i]) goto failed; - - state->queries[i]->async.fn = bcast_handler; - state->queries[i]->async.private = c; + address_list[i] = talloc_strdup(address_list, sys_inet_ntoa(*ip)); + if (address_list[i] == NULL) { + talloc_free(address_list); + return NULL; + } } + address_list[i] = NULL; - c->state = SMBCLI_REQUEST_SEND; - c->private = state; - c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx); - - return c; + c = resolve_name_nbtlist_send(name, event_ctx, address_list, True, False); + talloc_free(address_list); -failed: - talloc_free(c); - return NULL; + return c; } /* @@ -137,17 +61,7 @@ failed: NTSTATUS resolve_name_bcast_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { - NTSTATUS status; - - status = smb_composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct bcast_state *state = talloc_get_type(c->private, struct bcast_state); - *reply_addr = talloc_steal(mem_ctx, state->reply_addr); - } - - talloc_free(c); - return status; + return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } /* diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c new file mode 100644 index 0000000000..036e983fd2 --- /dev/null +++ b/source4/libcli/resolve/nbtlist.c @@ -0,0 +1,170 @@ +/* + Unix SMB/CIFS implementation. + + nbt list of addresses name resolution module + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +/* + TODO: we should lower the timeout, and add retries for each name +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/composite/composite.h" + +struct nbtlist_state { + struct nbt_name name; + struct nbt_name_socket *nbtsock; + int num_queries; + struct nbt_name_request **queries; + struct nbt_name_query *io_queries; + const char *reply_addr; +}; + +/* + handle events during nbtlist name resolution +*/ +static void nbtlist_handler(struct nbt_name_request *req) +{ + struct smbcli_composite *c = talloc_get_type(req->async.private, + struct smbcli_composite); + struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); + int i; + + for (i=0;inum_queries;i++) { + if (req == state->queries[i]) break; + } + if (i == state->num_queries) { + /* not for us?! */ + c->status = NT_STATUS_INTERNAL_ERROR; + c->state = SMBCLI_REQUEST_ERROR; + goto done; + } + + c->status = nbt_name_query_recv(req, state, &state->io_queries[i]); + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + } else { + c->state = SMBCLI_REQUEST_DONE; + state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr); + } + +done: + talloc_free(state->nbtsock); + if (c->async.fn) { + c->async.fn(c); + } +} + +/* + nbtlist name resolution method - async send + */ +struct smbcli_composite *resolve_name_nbtlist_send(struct nbt_name *name, + struct event_context *event_ctx, + const char **address_list, + BOOL broadcast, + BOOL wins_lookup) +{ + struct smbcli_composite *c; + struct nbtlist_state *state; + int i; + NTSTATUS status; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct nbtlist_state); + if (state == NULL) goto failed; + + status = nbt_name_dup(state, name, &state->name); + if (!NT_STATUS_IS_OK(status)) goto failed; + + state->nbtsock = nbt_name_socket_init(state, event_ctx); + if (state->nbtsock == NULL) goto failed; + + /* count the address_list size */ + for (i=0;address_list[i];i++) /* noop */ ; + + state->num_queries = i; + state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries); + if (!state->io_queries) goto failed; + + state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries); + if (!state->queries) goto failed; + + for (i=0;inum_queries;i++) { + state->io_queries[i].in.name = state->name; + state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); + if (!state->io_queries[i].in.dest_addr) goto failed; + state->io_queries[i].in.broadcast = broadcast; + state->io_queries[i].in.wins_lookup = wins_lookup; + state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 3); + + state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); + if (!state->queries[i]) goto failed; + + state->queries[i]->async.fn = nbtlist_handler; + state->queries[i]->async.private = c; + } + + c->state = SMBCLI_REQUEST_SEND; + c->private = state; + c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx); + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + nbt list of addresses name resolution method - recv side + */ +NTSTATUS resolve_name_nbtlist_recv(struct smbcli_composite *c, + TALLOC_CTX *mem_ctx, const char **reply_addr) +{ + NTSTATUS status; + + status = smb_composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); + *reply_addr = talloc_steal(mem_ctx, state->reply_addr); + } + + talloc_free(c); + return status; +} + +/* + nbt list of addresses name resolution method - sync call + */ +NTSTATUS resolve_name_nbtlist(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + const char **address_list, + BOOL broadcast, BOOL wins_lookup, + const char **reply_addr) +{ + struct smbcli_composite *c = resolve_name_nbtlist_send(name, NULL, address_list, + broadcast, wins_lookup); + return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); +} + diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index e83b11c95e..b36d6e8ee6 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -24,12 +24,111 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +struct resolve_state { + struct nbt_name name; + const char **methods; + struct smbcli_composite *req; + const char *reply_addr; +}; + +static struct smbcli_composite *setup_next_method(struct smbcli_composite *c); + +/* + handle completion of one name resolve method +*/ +static void resolve_handler(struct smbcli_composite *req) +{ + struct smbcli_composite *c = req->async.private; + struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); + const char *method = state->methods[0]; + + if (strcasecmp(method, "bcast")) { + c->status = resolve_name_bcast_recv(req, state, &state->reply_addr); + } else if (strcasecmp(method, "wins")) { + c->status = resolve_name_wins_recv(req, state, &state->reply_addr); + } else { + c->status = NT_STATUS_INTERNAL_ERROR; + } + + if (!NT_STATUS_IS_OK(c->status)) { + state->methods++; + state->req = setup_next_method(c); + if (state->req != NULL) { + return; + } + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + } else { + c->state = SMBCLI_REQUEST_DONE; + } + if (c->async.fn) { + c->async.fn(c); + } +} + + +static struct smbcli_composite *setup_next_method(struct smbcli_composite *c) +{ + struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); + const char *method; + struct smbcli_composite *req = NULL; + + do { + method = state->methods[0]; + if (method == NULL) break; + if (strcasecmp(method, "bcast")) { + req = resolve_name_bcast_send(&state->name, c->event_ctx); + } else if (strcasecmp(method, "wins")) { + req = resolve_name_wins_send(&state->name, c->event_ctx); + } + if (req == NULL) state->methods++; + } while (!req && state->methods[0]); + + if (req) { + req->async.fn = resolve_handler; + req->async.private = c; + } + + return req; +} + /* general name resolution - async send */ struct smbcli_composite *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx) { - return resolve_name_bcast_send(name, event_ctx); + struct smbcli_composite *c; + struct resolve_state *state; + NTSTATUS status; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct resolve_state); + if (state == NULL) goto failed; + + status = nbt_name_dup(state, name, &state->name); + if (!NT_STATUS_IS_OK(status)) goto failed; + + state->methods = lp_name_resolve_order(); + if (state->methods == NULL) { + return NULL; + } + + c->state = SMBCLI_REQUEST_SEND; + c->private = state; + c->event_ctx = talloc_reference(c, event_ctx); + + state->req = setup_next_method(c); + if (state->req == NULL) goto failed; + + return c; + +failed: + talloc_free(c); + return NULL; } /* @@ -38,7 +137,17 @@ struct smbcli_composite *resolve_name_send(struct nbt_name *name, struct event_c NTSTATUS resolve_name_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { - return resolve_name_bcast_recv(c, mem_ctx, reply_addr); + NTSTATUS status; + + status = smb_composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); + *reply_addr = talloc_steal(mem_ctx, state->reply_addr); + } + + talloc_free(c); + return status; } /* diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c new file mode 100644 index 0000000000..5a0e067832 --- /dev/null +++ b/source4/libcli/resolve/wins.c @@ -0,0 +1,58 @@ +/* + Unix SMB/CIFS implementation. + + wins name resolution module + + Copyright (C) Andrew Tridgell 2005 + + 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 "system/network.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" + +/* + wins name resolution method - async send + */ +struct smbcli_composite *resolve_name_wins_send(struct nbt_name *name, + struct event_context *event_ctx) +{ + const char **address_list = lp_wins_server_list(); + if (address_list == NULL) return NULL; + return resolve_name_nbtlist_send(name, event_ctx, address_list, False, True); +} + +/* + wins name resolution method - recv side + */ +NTSTATUS resolve_name_wins_recv(struct smbcli_composite *c, + TALLOC_CTX *mem_ctx, const char **reply_addr) +{ + return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); +} + +/* + wins name resolution method - sync call + */ +NTSTATUS resolve_name_wins(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + const char **reply_addr) +{ + struct smbcli_composite *c = resolve_name_wins_send(name, NULL); + return resolve_name_wins_recv(c, mem_ctx, reply_addr); +} + -- cgit From 6b5f8665b0de1ebf6d51e81e3d9687dceb93c015 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 13:39:33 +0000 Subject: r4901: a bit more info on nbt packets under high debug level (This used to be commit 9a34af29388d8ca837c670d054a76d1f75098cbd) --- source4/libcli/nbt/nbtsocket.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 865c542ca8..8b212fb555 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -83,7 +83,8 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) size_t len; if (DEBUGLVL(10)) { - DEBUG(10,("Sending nbt packet:\n")); + DEBUG(10,("Sending nbt packet to %s:%d\n", + req->dest_addr, req->dest_port)); NDR_PRINT_DEBUG(nbt_name_packet, req->request); } @@ -156,6 +157,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) return; } talloc_steal(tmp_ctx, src_addr); + blob.length = nread; packet = talloc(tmp_ctx, struct nbt_name_packet); if (packet == NULL) { @@ -173,7 +175,8 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } if (DEBUGLVL(10)) { - DEBUG(10,("Received nbt packet:\n")); + DEBUG(10,("Received nbt packet of length %d from %s:%d\n", + blob.length, src_addr, src_port)); NDR_PRINT_DEBUG(nbt_name_packet, packet); } -- cgit From a09f8c305256b94b078f7d293fe1fc9b56d28810 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 20:38:33 +0000 Subject: r4909: fixed name_trn_id generation (thanks to metze for spotting the bug!) (This used to be commit 9d2d16ce5fd57cad01ddaf1112beed916cc2088d) --- source4/libcli/nbt/nbtsocket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 8b212fb555..b0248b6de0 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -345,10 +345,12 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, id = idr_get_new_above(req->nbtsock->idr, req, req->request->name_trn_id, UINT16_MAX); if (id == -1) { - id = idr_get_new_above(req->nbtsock->idr, req, 1+(generate_random()%(UINT16_MAX/2)), + id = idr_get_new_above(req->nbtsock->idr, req, + 1+(generate_random()%(UINT16_MAX/2)), UINT16_MAX); } if (id == -1) goto failed; + req->request->name_trn_id = id; te.next_event = timeout; te.handler = nbt_name_socket_timeout; -- cgit From 8485a8d935484cebc7754bbe21ec7ebb9ecd03c3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 22:01:57 +0000 Subject: r4911: make sure we fill in the transport called name on port 445 as well (thanks to abartlet for spotting this bug) (This used to be commit 8b653f12f21e7a8eee8e60cefb193505c2df7f8f) --- source4/libcli/composite/connect.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 7e08aab0d5..4f6df154a7 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -219,19 +219,22 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, state->transport = smbcli_transport_init(state->sock); NT_STATUS_HAVE_NO_MEMORY(state->transport); + calling.name = io->in.calling_name; + calling.type = NBT_NAME_CLIENT; + calling.scope = NULL; + + nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); + /* we have a connected socket - next step is a session request, if needed. Port 445 doesn't need it, so it goes straight to the negprot */ if (state->sock->port == 445) { + status = nbt_name_dup(state->transport, &called, + &state->transport->called); + NT_STATUS_NOT_OK_RETURN(status); return connect_send_negprot(c, io); } - calling.name = io->in.calling_name; - calling.type = NBT_NAME_CLIENT; - calling.scope = NULL; - - nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); - state->req = smbcli_transport_connect_send(state->transport, &calling, &called); NT_STATUS_HAVE_NO_MEMORY(state->req); -- cgit From 79ef4f216bbf26db69560acffa8d075ac704d654 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 23:53:10 +0000 Subject: r4915: free temp context _before_ the async callback, as the async callback might destroy our top level context leaving the tmp context freed (so a double free) (This used to be commit b20c0561b8ec3ec7010f846be7a39165783e15c2) --- source4/libcli/nbt/nbtsocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index b0248b6de0..664e6fdce0 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -122,10 +122,10 @@ failed: nbt_name_request_destructor(req); req->status = status; req->state = NBT_REQUEST_ERROR; + talloc_free(tmp_ctx); if (req->async.fn) { req->async.fn(req); } - talloc_free(tmp_ctx); return; } -- cgit From b9a1e9a6677613865474c3c66b443b1c9e54c408 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 22 Jan 2005 00:52:54 +0000 Subject: r4916: added "host" name resolution using fork() per gethostbyname() comments welcome, but please think about the alternatives first :-) (This used to be commit 3d40b479907226be349137117e0d2bd718efa1a8) --- source4/libcli/config.mk | 3 +- source4/libcli/resolve/host.c | 233 +++++++++++++++++++++++++++++++++++++++ source4/libcli/resolve/resolve.c | 51 ++++++--- 3 files changed, 270 insertions(+), 17 deletions(-) create mode 100644 source4/libcli/resolve/host.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 904a07dc0f..a43644f197 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -32,7 +32,8 @@ ADD_OBJ_FILES = \ libcli/resolve/resolve.o \ libcli/resolve/nbtlist.o \ libcli/resolve/bcast.o \ - libcli/resolve/wins.o + libcli/resolve/wins.o \ + libcli/resolve/host.o REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI] diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c new file mode 100644 index 0000000000..2cc0c1705f --- /dev/null +++ b/source4/libcli/resolve/host.c @@ -0,0 +1,233 @@ +/* + Unix SMB/CIFS implementation. + + async gethostbyname() name resolution module + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +/* + this module uses a fork() per gethostbyname() call. At first that + might seem crazy, but it is actually very fast, and solves many of + the tricky problems of keeping a child hanging around in a library + (like what happens when the parent forks). We use a talloc + destructor to ensure that the child is cleaned up when we have + finished with this name resolution. +*/ + +#include "includes.h" +#include "events.h" +#include "system/network.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" + +struct host_state { + struct nbt_name name; + const char *reply_addr; + pid_t child; + int child_fd; + struct fd_event *fde; + struct event_context *event_ctx; +}; + + +/* + kill off a wayward child if needed. This allows us to stop an async + name resolution without leaving a potentially blocking call running + in a child +*/ +static int host_destructor(void *ptr) +{ + struct host_state *state = talloc_get_type(ptr, struct host_state); + close(state->child_fd); + if (state->child != (pid_t)-1) { + kill(state->child, SIGTERM); + } + if (state->fde) { + event_remove_fd(state->event_ctx, state->fde); + } + return 0; +} + +/* + the blocking child +*/ +static void run_child(struct smbcli_composite *c, int fd) +{ + struct host_state *state = talloc_get_type(c->private, struct host_state); + struct ipv4_addr ip; + const char *address; + + /* this is the blocking call we are going to lots of trouble + to avoid in the parent */ + ip = interpret_addr2(state->name.name); + + address = sys_inet_ntoa(ip); + if (address != NULL) { + write(fd, address, strlen(address)+1); + } +} + +/* + handle a read event on the pipe +*/ +static void pipe_handler(struct event_context *ev, struct fd_event *fde, + struct timeval t, uint16_t flags) +{ + struct smbcli_composite *c = talloc_get_type(fde->private, struct smbcli_composite); + struct host_state *state = talloc_get_type(c->private, struct host_state); + char address[128]; + int ret; + + /* if we get any event from the child then we know that we + won't need to kill it off */ + state->child = (pid_t)-1; + + /* yes, we don't care about EAGAIN or other niceities + here. They just can't happen with this parent/child + relationship, and even if they did then giving an error is + the right thing to do */ + ret = read(state->child_fd, address, sizeof(address)-1); + if (ret <= 0) goto failed; + + /* enusre the address looks good */ + address[ret] = 0; + if (strcmp(address, "0.0.0.0") == 0 || + sys_inet_addr(address) == INADDR_NONE) { + goto failed; + } + + state->reply_addr = talloc_strdup(state, address); + if (state->reply_addr == NULL) goto failed; + + c->status = NT_STATUS_OK; + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); + } + return; + +failed: + c->status = NT_STATUS_BAD_NETWORK_NAME; + c->state = SMBCLI_REQUEST_ERROR; + if (c->async.fn) { + c->async.fn(c); + } +} + +/* + gethostbyname name resolution method - async send + */ +struct smbcli_composite *resolve_name_host_send(struct nbt_name *name, + struct event_context *event_ctx) +{ + struct smbcli_composite *c; + struct host_state *state; + NTSTATUS status; + int fd[2] = { -1, -1 }; + struct fd_event fde; + int ret; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct host_state); + if (state == NULL) goto failed; + + status = nbt_name_dup(state, name, &state->name); + if (!NT_STATUS_IS_OK(status)) goto failed; + + c->state = SMBCLI_REQUEST_SEND; + c->private = state; + c->event_ctx = talloc_reference(c, event_ctx); + + /* setup a pipe to chat to our child */ + ret = pipe(fd); + if (ret == -1) goto failed; + + state->child_fd = fd[0]; + state->event_ctx = c->event_ctx; + + /* we need to put the child in our event context so + we know when the gethostbyname() has finished */ + fde.fd = state->child_fd; + fde.flags = EVENT_FD_READ; + fde.handler = pipe_handler; + fde.private = c; + state->fde = event_add_fd(c->event_ctx, &fde); + if (state->fde == NULL) { + close(fd[0]); + close(fd[1]); + goto failed; + } + + /* signal handling in posix really sucks - doing this in a library + affects the whole app, but what else to do?? */ + signal(SIGCHLD, SIG_IGN); + + state->child = fork(); + if (state->child == (pid_t)-1) { + goto failed; + } + + if (state->child == 0) { + close(fd[0]); + run_child(c, fd[1]); + _exit(0); + } + close(fd[1]); + + /* cleanup wayward children */ + talloc_set_destructor(state, host_destructor); + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + gethostbyname name resolution method - recv side +*/ +NTSTATUS resolve_name_host_recv(struct smbcli_composite *c, + TALLOC_CTX *mem_ctx, const char **reply_addr) +{ + NTSTATUS status; + + status = smb_composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct host_state *state = talloc_get_type(c->private, struct host_state); + *reply_addr = talloc_steal(mem_ctx, state->reply_addr); + } + + talloc_free(c); + return status; +} + +/* + gethostbyname name resolution method - sync call + */ +NTSTATUS resolve_name_host(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + const char **reply_addr) +{ + struct smbcli_composite *c = resolve_name_host_send(name, NULL); + return resolve_name_host_recv(c, mem_ctx, reply_addr); +} + diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index b36d6e8ee6..013403fd9c 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -33,6 +33,33 @@ struct resolve_state { static struct smbcli_composite *setup_next_method(struct smbcli_composite *c); +/* pointers to the resolver backends */ +static const struct resolve_method { + const char *name; + struct smbcli_composite *(*send_fn)(struct nbt_name *, struct event_context *); + NTSTATUS (*recv_fn)(struct smbcli_composite *, TALLOC_CTX *, const char **); +} methods[] = { + { "bcast", resolve_name_bcast_send, resolve_name_bcast_recv }, + { "wins", resolve_name_wins_send, resolve_name_wins_recv }, + { "host", resolve_name_host_send, resolve_name_host_recv } +}; + + +/* + find a matching backend +*/ +static const struct resolve_method *find_method(const char *name) +{ + int i; + if (name == NULL) return NULL; + for (i=0;iasync.private; struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); - const char *method = state->methods[0]; + const struct resolve_method *method = find_method(state->methods[0]); - if (strcasecmp(method, "bcast")) { - c->status = resolve_name_bcast_recv(req, state, &state->reply_addr); - } else if (strcasecmp(method, "wins")) { - c->status = resolve_name_wins_recv(req, state, &state->reply_addr); - } else { - c->status = NT_STATUS_INTERNAL_ERROR; - } + c->status = method->recv_fn(req, state, &state->reply_addr); if (!NT_STATUS_IS_OK(c->status)) { state->methods++; @@ -72,18 +93,16 @@ static void resolve_handler(struct smbcli_composite *req) static struct smbcli_composite *setup_next_method(struct smbcli_composite *c) { struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); - const char *method; struct smbcli_composite *req = NULL; do { - method = state->methods[0]; - if (method == NULL) break; - if (strcasecmp(method, "bcast")) { - req = resolve_name_bcast_send(&state->name, c->event_ctx); - } else if (strcasecmp(method, "wins")) { - req = resolve_name_wins_send(&state->name, c->event_ctx); + const struct resolve_method *method = find_method(state->methods[0]); + if (method) { + req = method->send_fn(&state->name, c->event_ctx); + if (req == NULL) { + state->methods++; + } } - if (req == NULL) state->methods++; } while (!req && state->methods[0]); if (req) { -- cgit From d069c368fbd900f9c6e22d7dccdd84c5202997a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 22 Jan 2005 01:37:48 +0000 Subject: r4919: if a caller doesn't provide an event context to the resolver library, then create one. This fixes a crash in the RAW-NEGNOWAIT test for 'host' resolution. (This used to be commit 3268d523cc381b9b3077f794bb53daf0865d139c) --- source4/libcli/resolve/resolve.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 013403fd9c..ef906d4ed0 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -138,7 +138,12 @@ struct smbcli_composite *resolve_name_send(struct nbt_name *name, struct event_c c->state = SMBCLI_REQUEST_SEND; c->private = state; - c->event_ctx = talloc_reference(c, event_ctx); + if (event_ctx == NULL) { + c->event_ctx = event_context_init(c); + if (c->event_ctx == NULL) goto failed; + } else { + c->event_ctx = talloc_reference(c, event_ctx); + } state->req = setup_next_method(c); if (state->req == NULL) goto failed; -- cgit From 5ffedbac3d06ef852508dde3924841a86b802295 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 22 Jan 2005 02:08:30 +0000 Subject: r4922: fixed an infinite loop in the name resolve code when handling a method in smb.conf that isn't implemented in the library (This used to be commit dd5b43ed37b37feec4708f8f13033b42eb6a838c) --- source4/libcli/resolve/resolve.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index ef906d4ed0..054f10d529 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -99,10 +99,8 @@ static struct smbcli_composite *setup_next_method(struct smbcli_composite *c) const struct resolve_method *method = find_method(state->methods[0]); if (method) { req = method->send_fn(&state->name, c->event_ctx); - if (req == NULL) { - state->methods++; - } } + if (req == NULL) state->methods++; } while (!req && state->methods[0]); if (req) { -- cgit From aefaa18554a55da5b5d9fdb9815eb246b539c8a2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 22 Jan 2005 02:51:39 +0000 Subject: r4924: continue the effort to simplify and generalise the composite interface. This patch removes the "stage" variable, which is really better suited to the backend state structures (This used to be commit 39da684ea8bc72d7a4a12c00eaad56b4f32890a9) --- source4/libcli/composite/composite.h | 3 --- source4/libcli/composite/connect.c | 15 ++++++++------- source4/libcli/composite/loadfile.c | 9 +++++---- source4/libcli/composite/savefile.c | 10 +++++----- source4/libcli/raw/clisocket.c | 7 ++++--- 5 files changed, 22 insertions(+), 22 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index fba458795c..35d6d94878 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -33,9 +33,6 @@ struct smbcli_composite { /* the external state - will be queried by the caller */ enum smbcli_request_state state; - /* the internal stage */ - uint16_t stage; - /* a private pointer for use by the composite function implementation */ void *private; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 4f6df154a7..2663c789e4 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -34,6 +34,7 @@ enum connect_stage {CONNECT_RESOLVE, CONNECT_TCON}; struct connect_state { + enum connect_stage stage; struct smbcli_socket *sock; struct smbcli_transport *transport; struct smbcli_session *session; @@ -61,7 +62,7 @@ static NTSTATUS connect_send_negprot(struct smbcli_composite *c, state->req->async.fn = request_handler; state->req->async.private = c; - c->stage = CONNECT_NEGPROT; + state->stage = CONNECT_NEGPROT; return NT_STATUS_OK; } @@ -141,7 +142,7 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, state->req->async.fn = request_handler; state->req->async.private = c; - c->stage = CONNECT_TCON; + state->stage = CONNECT_TCON; return NT_STATUS_OK; } @@ -180,7 +181,7 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, state->creq->async.fn = composite_handler; state->creq->async.private = c; - c->stage = CONNECT_SESSION_SETUP; + state->stage = CONNECT_SESSION_SETUP; return NT_STATUS_OK; } @@ -240,7 +241,7 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, state->req->async.fn = request_handler; state->req->async.private = c; - c->stage = CONNECT_SESSION_REQUEST; + state->stage = CONNECT_SESSION_REQUEST; return NT_STATUS_OK; } @@ -262,7 +263,7 @@ static NTSTATUS connect_resolve(struct smbcli_composite *c, state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port); NT_STATUS_HAVE_NO_MEMORY(state->creq); - c->stage = CONNECT_SOCKET; + state->stage = CONNECT_SOCKET; state->creq->async.private = c; state->creq->async.fn = composite_handler; @@ -277,7 +278,7 @@ static void state_handler(struct smbcli_composite *c) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); - switch (c->stage) { + switch (state->stage) { case CONNECT_RESOLVE: c->status = connect_resolve(c, state->io); break; @@ -346,9 +347,9 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect if (state->sock == NULL) goto failed; state->io = io; + state->stage = CONNECT_RESOLVE; c->state = SMBCLI_REQUEST_SEND; - c->stage = CONNECT_RESOLVE; c->event_ctx = state->sock->event.ctx; c->private = state; diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index 8290876224..b95f43149e 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -33,6 +33,7 @@ enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE}; static void loadfile_handler(struct smbcli_request *req); struct loadfile_state { + enum loadfile_stage stage; struct smb_composite_loadfile *io; struct smbcli_request *req; union smb_open *io_open; @@ -62,7 +63,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, /* call the handler again when the close is done */ state->req->async.fn = loadfile_handler; state->req->async.private = c; - c->stage = LOADFILE_CLOSE; + state->stage = LOADFILE_CLOSE; return NT_STATUS_OK; } @@ -113,7 +114,7 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, /* call the handler again when the first read is done */ state->req->async.fn = loadfile_handler; state->req->async.private = c; - c->stage = LOADFILE_READ; + state->stage = LOADFILE_READ; talloc_free(state->io_open); @@ -187,7 +188,7 @@ static void loadfile_handler(struct smbcli_request *req) /* when this handler is called, the stage indicates what call has just finished */ - switch (c->stage) { + switch (state->stage) { case LOADFILE_OPEN: c->status = loadfile_open(c, state->io); break; @@ -251,7 +252,7 @@ struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, /* setup the callback handler */ state->req->async.fn = loadfile_handler; state->req->async.private = c; - c->stage = LOADFILE_OPEN; + state->stage = LOADFILE_OPEN; return c; diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index 06eb13bb01..29d26c7eba 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -29,10 +29,10 @@ /* the stages of this call */ enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE}; - static void savefile_handler(struct smbcli_request *req); struct savefile_state { + enum savefile_stage stage; off_t total_written; struct smb_composite_savefile *io; union smb_open *io_open; @@ -62,7 +62,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the close is done */ - c->stage = SAVEFILE_CLOSE; + state->stage = SAVEFILE_CLOSE; state->req->async.fn = savefile_handler; state->req->async.private = c; @@ -106,7 +106,7 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, NT_STATUS_HAVE_NO_MEMORY(state->req); /* call the handler again when the first write is done */ - c->stage = SAVEFILE_WRITE; + state->stage = SAVEFILE_WRITE; state->req->async.fn = savefile_handler; state->req->async.private = c; talloc_free(state->io_open); @@ -189,7 +189,7 @@ static void savefile_handler(struct smbcli_request *req) /* when this handler is called, the stage indicates what call has just finished */ - switch (c->stage) { + switch (state->stage) { case SAVEFILE_OPEN: c->status = savefile_open(c, state->io); break; @@ -226,12 +226,12 @@ struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, if (c == NULL) goto failed; c->state = SMBCLI_REQUEST_SEND; - c->stage = SAVEFILE_OPEN; c->event_ctx = tree->session->transport->socket->event.ctx; state = talloc(c, struct savefile_state); if (state == NULL) goto failed; + state->stage = SAVEFILE_OPEN; state->total_written = 0; state->io = io; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index e981049535..cbbd6490bd 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -30,6 +30,7 @@ this private structure is used during async connection handling */ struct clisocket_connect { + int port_num; int *iports; struct smbcli_socket *sock; const char *dest_host; @@ -95,8 +96,8 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even } /* that port failed - try the next port */ - for (i=c->stage+1;conn->iports[i];i++) { - c->stage = i; + for (i=conn->port_num+1;conn->iports[i];i++) { + conn->port_num = i; c->status = smbcli_sock_connect_one(conn->sock, conn->dest_host, conn->iports[i]); @@ -204,7 +205,7 @@ struct smbcli_composite *smbcli_sock_connect_send(struct smbcli_socket *sock, /* startup the connect process for each port in turn until one succeeds or tells us that it is pending */ for (i=0;conn->iports[i];i++) { - c->stage = i; + conn->port_num = i; conn->sock->port = conn->iports[i]; c->status = smbcli_sock_connect_one(sock, conn->dest_host, -- cgit From 3b9431ddb963db68101e35b54f044ba0938b2fa7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 22 Jan 2005 05:36:32 +0000 Subject: r4927: parse the NBT session request in the smb server. This gets rid of that annoying "not parsing session request" message on each SMB connection (This used to be commit b06b8dd2f4f4fea750b05fd29d68372828159f16) --- source4/libcli/nbt/nbtname.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 8c46379f0b..0584f55fb1 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -63,7 +63,7 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, /* its a reserved length field */ return NT_STATUS_BAD_NETWORK_NAME; } - if (*offset + len + 2 >= ndr->data_size) { + if (*offset + len + 2 > ndr->data_size) { return NT_STATUS_BAD_NETWORK_NAME; } *component = (uint8_t*)talloc_strndup(ndr, &ndr->data[1 + *offset], len); @@ -309,6 +309,17 @@ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name (ndr_push_flags_fn_t)ndr_push_nbt_name); } + +/* + pull a nbt name from a blob +*/ +NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) +{ + return ndr_pull_struct_blob(blob, mem_ctx, name, + (ndr_pull_flags_fn_t)ndr_pull_nbt_name); +} + + /* choose a name to use when calling a server in a NBT session request. we use heuristics to see if the name we have been given is a IP -- cgit From 8eb0963c95bde4a8226f5d02ee0d8b478cf2dcc4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 00:51:20 +0000 Subject: r4935: fixed a bug where "c->status = xxx_handler(x);" could write to c after it is freed. The problem is that the handler might complete the request, and called the c->async.fn() async handler. That handler might free the request handle. (This used to be commit c4faceadc74e0849f6197ccbec9952f6c94f6176) --- source4/libcli/composite/connect.c | 16 +++++++++------- source4/libcli/composite/loadfile.c | 11 +++++++---- source4/libcli/composite/savefile.c | 10 ++++++---- 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 2663c789e4..67123a3af5 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -277,29 +277,31 @@ static NTSTATUS connect_resolve(struct smbcli_composite *c, static void state_handler(struct smbcli_composite *c) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); + NTSTATUS status; switch (state->stage) { case CONNECT_RESOLVE: - c->status = connect_resolve(c, state->io); + status = connect_resolve(c, state->io); break; case CONNECT_SOCKET: - c->status = connect_socket(c, state->io); + status = connect_socket(c, state->io); break; case CONNECT_SESSION_REQUEST: - c->status = connect_session_request(c, state->io); + status = connect_session_request(c, state->io); break; case CONNECT_NEGPROT: - c->status = connect_negprot(c, state->io); + status = connect_negprot(c, state->io); break; case CONNECT_SESSION_SETUP: - c->status = connect_session_setup(c, state->io); + status = connect_session_setup(c, state->io); break; case CONNECT_TCON: - c->status = connect_tcon(c, state->io); + status = connect_tcon(c, state->io); break; } - if (!NT_STATUS_IS_OK(c->status)) { + if (!NT_STATUS_IS_OK(status)) { + c->status = status; c->state = SMBCLI_REQUEST_ERROR; if (c->async.fn) { c->async.fn(c); diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index b95f43149e..37327ca62e 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -185,24 +185,26 @@ static void loadfile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); + NTSTATUS status; /* when this handler is called, the stage indicates what call has just finished */ switch (state->stage) { case LOADFILE_OPEN: - c->status = loadfile_open(c, state->io); + status = loadfile_open(c, state->io); break; case LOADFILE_READ: - c->status = loadfile_read(c, state->io); + status = loadfile_read(c, state->io); break; case LOADFILE_CLOSE: - c->status = loadfile_close(c, state->io); + status = loadfile_close(c, state->io); break; } - if (!NT_STATUS_IS_OK(c->status)) { + if (!NT_STATUS_IS_OK(status)) { + c->status = status; c->state = SMBCLI_REQUEST_ERROR; if (c->async.fn) { c->async.fn(c); @@ -291,3 +293,4 @@ NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree, struct smbcli_composite *c = smb_composite_loadfile_send(tree, io); return smb_composite_loadfile_recv(c, mem_ctx); } + diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index 29d26c7eba..c87ea178f9 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -186,24 +186,26 @@ static void savefile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); + NTSTATUS status; /* when this handler is called, the stage indicates what call has just finished */ switch (state->stage) { case SAVEFILE_OPEN: - c->status = savefile_open(c, state->io); + status = savefile_open(c, state->io); break; case SAVEFILE_WRITE: - c->status = savefile_write(c, state->io); + status = savefile_write(c, state->io); break; case SAVEFILE_CLOSE: - c->status = savefile_close(c, state->io); + status = savefile_close(c, state->io); break; } - if (!NT_STATUS_IS_OK(c->status)) { + if (!NT_STATUS_IS_OK(status)) { + c->status = status; c->state = SMBCLI_REQUEST_ERROR; if (c->async.fn) { c->async.fn(c); -- cgit From 0db8b5a949dd84966c21828bc91cd9d54b082b71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 08:16:16 +0000 Subject: r4936: moved to a convention where the completion function is only called in one place. This makes the code more robust, and simpler (it would have prevented the error that volker found). (This used to be commit 420b53091ee784d7891fb62d48e2f5a225b4dbf8) --- source4/libcli/composite/loadfile.c | 21 +++++++++------------ source4/libcli/composite/savefile.c | 21 +++++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index 37327ca62e..37f3608a4b 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -170,9 +170,6 @@ static NTSTATUS loadfile_close(struct smbcli_composite *c, NT_STATUS_NOT_OK_RETURN(status); c->state = SMBCLI_REQUEST_DONE; - if (c->async.fn) { - c->async.fn(c); - } return NT_STATUS_OK; } @@ -185,30 +182,30 @@ static void loadfile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - NTSTATUS status; /* when this handler is called, the stage indicates what call has just finished */ switch (state->stage) { case LOADFILE_OPEN: - status = loadfile_open(c, state->io); + c->status = loadfile_open(c, state->io); break; case LOADFILE_READ: - status = loadfile_read(c, state->io); + c->status = loadfile_read(c, state->io); break; case LOADFILE_CLOSE: - status = loadfile_close(c, state->io); + c->status = loadfile_close(c, state->io); break; } - if (!NT_STATUS_IS_OK(status)) { - c->status = status; + if (!NT_STATUS_IS_OK(c->status)) { c->state = SMBCLI_REQUEST_ERROR; - if (c->async.fn) { - c->async.fn(c); - } + } + + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); } } diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index c87ea178f9..5da5660127 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -171,9 +171,6 @@ static NTSTATUS savefile_close(struct smbcli_composite *c, } c->state = SMBCLI_REQUEST_DONE; - if (c->async.fn) { - c->async.fn(c); - } return NT_STATUS_OK; } @@ -186,30 +183,30 @@ static void savefile_handler(struct smbcli_request *req) { struct smbcli_composite *c = req->async.private; struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - NTSTATUS status; /* when this handler is called, the stage indicates what call has just finished */ switch (state->stage) { case SAVEFILE_OPEN: - status = savefile_open(c, state->io); + c->status = savefile_open(c, state->io); break; case SAVEFILE_WRITE: - status = savefile_write(c, state->io); + c->status = savefile_write(c, state->io); break; case SAVEFILE_CLOSE: - status = savefile_close(c, state->io); + c->status = savefile_close(c, state->io); break; } - if (!NT_STATUS_IS_OK(status)) { - c->status = status; + if (!NT_STATUS_IS_OK(c->status)) { c->state = SMBCLI_REQUEST_ERROR; - if (c->async.fn) { - c->async.fn(c); - } + } + + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); } } -- cgit From 0e9c55e70f7720d1c424867bd8054859847e84fa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 08:19:38 +0000 Subject: r4937: simplify the connect code in the same way (This used to be commit 347dfa47249d55c61e1e7c82d10444a71aca8a85) --- source4/libcli/composite/connect.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 67123a3af5..83f1dc4fa6 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -92,9 +92,6 @@ static NTSTATUS connect_tcon(struct smbcli_composite *c, /* all done! */ c->state = SMBCLI_REQUEST_DONE; - if (c->async.fn) { - c->async.fn(c); - } return NT_STATUS_OK; } @@ -277,35 +274,35 @@ static NTSTATUS connect_resolve(struct smbcli_composite *c, static void state_handler(struct smbcli_composite *c) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; switch (state->stage) { case CONNECT_RESOLVE: - status = connect_resolve(c, state->io); + c->status = connect_resolve(c, state->io); break; case CONNECT_SOCKET: - status = connect_socket(c, state->io); + c->status = connect_socket(c, state->io); break; case CONNECT_SESSION_REQUEST: - status = connect_session_request(c, state->io); + c->status = connect_session_request(c, state->io); break; case CONNECT_NEGPROT: - status = connect_negprot(c, state->io); + c->status = connect_negprot(c, state->io); break; case CONNECT_SESSION_SETUP: - status = connect_session_setup(c, state->io); + c->status = connect_session_setup(c, state->io); break; case CONNECT_TCON: - status = connect_tcon(c, state->io); + c->status = connect_tcon(c, state->io); break; } - if (!NT_STATUS_IS_OK(status)) { - c->status = status; + if (!NT_STATUS_IS_OK(c->status)) { c->state = SMBCLI_REQUEST_ERROR; - if (c->async.fn) { - c->async.fn(c); - } + } + + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); } } -- cgit From 9d6e923aab2036d6ce72e31aa4633d55b5991558 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 09:01:46 +0000 Subject: r4938: allow the caller to supply an existing event_context if they want to in smb_composite_connect_send(). This makes doing parallel calls much easier. (This used to be commit 442308970c123b9fb25615673049e1c1c234a0b9) --- source4/libcli/cliconnect.c | 2 +- source4/libcli/composite/connect.c | 9 +++++---- source4/libcli/raw/clisocket.c | 10 ++++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index aaed36eb05..4d9fb5ba1f 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -32,7 +32,7 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) { struct smbcli_socket *sock; - sock = smbcli_sock_init(cli); + sock = smbcli_sock_init(cli, NULL); if (!sock) return False; if (!smbcli_sock_connect_byname(sock, server, 0)) { diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 83f1dc4fa6..69b394310e 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -330,7 +330,8 @@ static void composite_handler(struct smbcli_composite *req) /* a function to establish a smbcli_tree from scratch */ -struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect *io) +struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect *io, + struct event_context *event_ctx) { struct smbcli_composite *c; struct connect_state *state; @@ -342,14 +343,14 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect state = talloc(c, struct connect_state); if (state == NULL) goto failed; - state->sock = smbcli_sock_init(state); + state->sock = smbcli_sock_init(state, event_ctx); if (state->sock == NULL) goto failed; state->io = io; state->stage = CONNECT_RESOLVE; c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = state->sock->event.ctx; + c->event_ctx = talloc_reference(c, state->sock->event.ctx); c->private = state; name.name = io->in.dest_host; @@ -391,6 +392,6 @@ NTSTATUS smb_composite_connect_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ */ NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx) { - struct smbcli_composite *c = smb_composite_connect_send(io); + struct smbcli_composite *c = smb_composite_connect_send(io, NULL); return smb_composite_connect_recv(c, mem_ctx); } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index cbbd6490bd..9249f453e8 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -49,8 +49,10 @@ static int smbcli_sock_destructor(void *ptr) /* create a smbcli_socket context + The event_ctx is optional - if not supplied one will be created */ -struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) +struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) { struct smbcli_socket *sock; @@ -59,7 +61,11 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx) return NULL; } - sock->event.ctx = event_context_init(sock); + if (event_ctx) { + sock->event.ctx = talloc_reference(sock, event_ctx); + } else { + sock->event.ctx = event_context_init(sock); + } if (sock->event.ctx == NULL) { talloc_free(sock); return NULL; -- cgit From fd62df64188c0f992876c72fdda8a6da5dba3090 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 11:49:15 +0000 Subject: r4943: Smplified the events handling code a lot. The first source of complexity was that events didn't automatically cleanup themselves. This was because the events code was written before we had talloc destructors, so you needed to call event_remove_XX() to clean the event out of the event lists from every piece of code that used events. I have now added automatic event destructors, which in turn allowed me to simplify a lot of the calling code. The 2nd source of complexity was caused by the ref_count, which was needed to cope with event handlers destroying events while handling them, which meant the linked lists became invalid, so the ref_count ws used to mark events for later destruction. The new system is much simpler. I now have a ev->destruction_count, which is incremented in all event destructors. The event dispatch code checks for changes to this and handles it. (This used to be commit a3c7417cfeab429ffb22d5546b205818f531a7b4) --- source4/libcli/nbt/nbtsocket.c | 14 ++------------ source4/libcli/raw/clisocket.c | 20 +++----------------- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/resolve/host.c | 4 +--- 4 files changed, 7 insertions(+), 33 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 664e6fdce0..d970f8e4e0 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -28,16 +28,6 @@ #define NBT_MAX_PACKET_SIZE 2048 #define NBT_MAX_REPLIES 1000 -/* - destroy a nbt socket -*/ -static int nbtsock_destructor(void *ptr) -{ - struct nbt_name_socket *nbtsock = talloc_get_type(ptr, struct nbt_name_socket); - event_remove_fd(nbtsock->event_ctx, nbtsock->fde); - return 0; -} - /* destroy a pending request */ @@ -56,7 +46,6 @@ static int nbt_name_request_destructor(void *ptr) req->request->name_trn_id = 0; } if (req->te) { - event_remove_timed(req->nbtsock->event_ctx, req->te); req->te = NULL; } if (req->nbtsock->send_queue == NULL) { @@ -279,7 +268,7 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, fde.private = nbtsock; nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde); - talloc_set_destructor(nbtsock, nbtsock_destructor); + talloc_steal(nbtsock, nbtsock->fde); return nbtsock; @@ -356,6 +345,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, te.handler = nbt_name_socket_timeout; te.private = req; req->te = event_add_timed(nbtsock->event_ctx, &te); + talloc_steal(req, req->te); talloc_set_destructor(req, nbt_name_request_destructor); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 9249f453e8..847f5c1b0a 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -37,16 +37,6 @@ struct clisocket_connect { }; -static int smbcli_sock_destructor(void *ptr) -{ - struct smbcli_socket *sock = talloc_get_type(ptr, struct smbcli_socket); - - if (sock->event.fde && sock->event.ctx) { - event_remove_fd(sock->event.ctx, sock->event.fde); - } - return 0; -} - /* create a smbcli_socket context The event_ctx is optional - if not supplied one will be created @@ -71,8 +61,6 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx, return NULL; } - talloc_set_destructor(sock, smbcli_sock_destructor); - return sock; } @@ -134,11 +122,7 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, talloc_free(sock->sock); sock->sock = NULL; } - - if (sock->event.fde) { - event_remove_fd(sock->event.ctx, sock->event.fde); - sock->event.fde = NULL; - } + talloc_free(sock->event.fde); status = socket_create("ip", SOCKET_TYPE_STREAM, &sock->sock, 0); if (!NT_STATUS_IS_OK(status)) { @@ -155,6 +139,8 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, fde.private = sock; sock->event.fde = event_add_fd(sock->event.ctx, &fde); + talloc_steal(sock, sock->event.fde); + sock->port = port; set_blocking(fde.fd, False); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 918f18fa40..b053b362ca 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -55,7 +55,6 @@ static int transport_destructor(void *ptr) struct smbcli_transport *transport = ptr; smbcli_transport_dead(transport); - event_remove_timed(transport->socket->event.ctx, transport->socket->event.te); return 0; } @@ -323,6 +322,7 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, te.handler = idle_handler; te.private = transport; transport->socket->event.te = event_add_timed(transport->socket->event.ctx, &te); + talloc_steal(transport, transport->socket->event.te); } /* diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 2cc0c1705f..b9aa1aa272 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -57,9 +57,6 @@ static int host_destructor(void *ptr) if (state->child != (pid_t)-1) { kill(state->child, SIGTERM); } - if (state->fde) { - event_remove_fd(state->event_ctx, state->fde); - } return 0; } @@ -174,6 +171,7 @@ struct smbcli_composite *resolve_name_host_send(struct nbt_name *name, close(fd[1]); goto failed; } + talloc_steal(state, state->fde); /* signal handling in posix really sucks - doing this in a library affects the whole app, but what else to do?? */ -- cgit From 6c14b0133dede38294a812be7f5f5bd5ec3d498b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 12:17:45 +0000 Subject: r4944: every event_add_*() caller was having to call talloc_steal() to take control of the event, so instead build that into the function. If you pass NULL as mem_ctx then it leaves it as a child of the events structure. (This used to be commit 7f981b9ed96f39027cbfd500f41e0c2be64cbb50) --- source4/libcli/nbt/nbtsocket.c | 7 ++----- source4/libcli/raw/clisocket.c | 3 +-- source4/libcli/raw/clitransport.c | 4 ++-- source4/libcli/resolve/host.c | 3 +-- 4 files changed, 6 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index d970f8e4e0..1eea77d356 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -266,9 +266,7 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, fde.flags = 0; fde.handler = nbt_name_socket_handler; fde.private = nbtsock; - nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde); - - talloc_steal(nbtsock, nbtsock->fde); + nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde, nbtsock); return nbtsock; @@ -344,8 +342,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, te.next_event = timeout; te.handler = nbt_name_socket_timeout; te.private = req; - req->te = event_add_timed(nbtsock->event_ctx, &te); - talloc_steal(req, req->te); + req->te = event_add_timed(nbtsock->event_ctx, &te, req); talloc_set_destructor(req, nbt_name_request_destructor); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 847f5c1b0a..c9934fa16d 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -138,8 +138,7 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, fde.handler = smbcli_sock_connect_handler; fde.private = sock; - sock->event.fde = event_add_fd(sock->event.ctx, &fde); - talloc_steal(sock, sock->event.fde); + sock->event.fde = event_add_fd(sock->event.ctx, &fde, sock); sock->port = port; set_blocking(fde.fd, False); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index b053b362ca..e3a8281f3f 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -321,8 +321,8 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, te.next_event = timeval_current_ofs(0, period); te.handler = idle_handler; te.private = transport; - transport->socket->event.te = event_add_timed(transport->socket->event.ctx, &te); - talloc_steal(transport, transport->socket->event.te); + transport->socket->event.te = event_add_timed(transport->socket->event.ctx, + &te, transport); } /* diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index b9aa1aa272..5b28a850fc 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -165,13 +165,12 @@ struct smbcli_composite *resolve_name_host_send(struct nbt_name *name, fde.flags = EVENT_FD_READ; fde.handler = pipe_handler; fde.private = c; - state->fde = event_add_fd(c->event_ctx, &fde); + state->fde = event_add_fd(c->event_ctx, &fde, state); if (state->fde == NULL) { close(fd[0]); close(fd[1]); goto failed; } - talloc_steal(state, state->fde); /* signal handling in posix really sucks - doing this in a library affects the whole app, but what else to do?? */ -- cgit From 63ba8383e196bc41d18c7b9a8a80578eb9430188 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Jan 2005 23:23:26 +0000 Subject: r4949: First version of a fetchfile composite function which connects to a server and loads a file. Needs a smb url parsing wrapper. Volker (This used to be commit fa435bf7c878d4a5beb6afb2ed6e2990abc11e82) --- source4/libcli/composite/composite.h | 19 ++++ source4/libcli/composite/fetchfile.c | 187 +++++++++++++++++++++++++++++++++++ source4/libcli/config.mk | 3 +- 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/composite/fetchfile.c (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 35d6d94878..cb8cee779c 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -65,6 +65,25 @@ struct smb_composite_loadfile { } out; }; +struct smb_composite_fetchfile { + struct { + const char *dest_host; + int port; + const char *called_name; + const char *calling_name; + const char *service; + const char *service_type; + const char *user; + const char *domain; + const char *password; + const char *filename; + } in; + struct { + uint8_t *data; + uint32_t size; + } out; +}; + /* a composite open/write(s)/close request that saves a whole file from memory. Used as a demo of the composite system. diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c new file mode 100644 index 0000000000..f18657c452 --- /dev/null +++ b/source4/libcli/composite/fetchfile.c @@ -0,0 +1,187 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Volker Lendecke 2005 + + 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. +*/ +/* + a composite API for loading a whole file into memory +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +enum fetchfile_stage {FETCHFILE_CONNECT, + FETCHFILE_READ}; + +struct fetchfile_state { + enum fetchfile_stage stage; + struct smb_composite_fetchfile *io; + struct smbcli_composite *req; + struct smb_composite_connect *connect; + struct smb_composite_loadfile *loadfile; +}; + +static void fetchfile_composite_handler(struct smbcli_composite *req); + +static NTSTATUS fetchfile_connect(struct smbcli_composite *c, + struct smb_composite_fetchfile *io) +{ + NTSTATUS status; + struct fetchfile_state *state; + state = talloc_get_type(c->private, struct fetchfile_state); + + status = smb_composite_connect_recv(state->req, c); + NT_STATUS_NOT_OK_RETURN(status); + + printf("connect done\n"); + + state->loadfile = talloc(state, struct smb_composite_loadfile); + NT_STATUS_NOT_OK_RETURN(status); + + state->loadfile->in.fname = io->in.filename; + + state->req = smb_composite_loadfile_send(state->connect->out.tree, + state->loadfile); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + state->req->async.private = c; + state->req->async.fn = fetchfile_composite_handler; + + state->stage = FETCHFILE_READ; + c->event_ctx = talloc_reference(c, state->req->event_ctx); + + printf("load started\n"); + + return NT_STATUS_OK; +} + +static NTSTATUS fetchfile_read(struct smbcli_composite *c, + struct smb_composite_fetchfile *io) +{ + NTSTATUS status; + struct fetchfile_state *state; + state = talloc_get_type(c->private, struct fetchfile_state); + + printf("read event\n"); + + status = smb_composite_loadfile_recv(state->req, NULL); + NT_STATUS_NOT_OK_RETURN(status); + + printf("read done\n"); + + io->out.data = state->loadfile->out.data; + io->out.size = state->loadfile->out.size; + + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) + c->async.fn(c); + + return NT_STATUS_OK; +} + +static void fetchfile_state_handler(struct smbcli_composite *c) +{ + struct fetchfile_state *state; + NTSTATUS status; + + state = talloc_get_type(c->private, struct fetchfile_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case FETCHFILE_CONNECT: + status = fetchfile_connect(c, state->io); + break; + case FETCHFILE_READ: + status = fetchfile_read(c, state->io); + break; + } + + if (!NT_STATUS_IS_OK(status)) { + c->status = status; + c->state = SMBCLI_REQUEST_ERROR; + if (c->async.fn) { + c->async.fn(c); + } + } +} + +static void fetchfile_composite_handler(struct smbcli_composite *req) +{ + struct smbcli_composite *c = talloc_get_type(req->async.private, + struct smbcli_composite); + return fetchfile_state_handler(c); +} + +struct smbcli_composite *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, + struct event_context *event_ctx) +{ + struct smbcli_composite *c; + struct fetchfile_state *state; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct fetchfile_state); + if (state == NULL) goto failed; + + state->connect = talloc(state, struct smb_composite_connect); + if (state->connect == NULL) goto failed; + + state->io = io; + + state->connect->in.dest_host = io->in.dest_host; + state->connect->in.port = io->in.port; + state->connect->in.called_name = io->in.called_name; + state->connect->in.calling_name = io->in.calling_name; + state->connect->in.service = io->in.service; + state->connect->in.service_type = io->in.service_type; + state->connect->in.user = io->in.user; + state->connect->in.domain = io->in.domain; + state->connect->in.password = io->in.password; + + state->req = smb_composite_connect_send(state->connect, event_ctx); + if (state->req == NULL) goto failed; + + state->req->async.private = c; + state->req->async.fn = fetchfile_composite_handler; + + c->state = SMBCLI_REQUEST_SEND; + state->stage = FETCHFILE_CONNECT; + c->event_ctx = talloc_reference(c, state->req->event_ctx); + c->private = state; + + return c; + failed: + talloc_free(c); + return NULL; +} + +NTSTATUS smb_composite_fetchfile_recv(struct smbcli_composite *c, + TALLOC_CTX *mem_ctx) +{ + return smb_composite_wait(c); +} + +NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io, + TALLOC_CTX *mem_ctx) +{ + struct smbcli_composite *c = smb_composite_fetchfile_send(io, NULL); + return smb_composite_fetchfile_recv(c, mem_ctx); +} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index a43644f197..806ef775dc 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -18,7 +18,8 @@ ADD_OBJ_FILES = \ libcli/composite/loadfile.o \ libcli/composite/savefile.o \ libcli/composite/connect.o \ - libcli/composite/sesssetup.o + libcli/composite/sesssetup.o \ + libcli/composite/fetchfile.o [SUBSYSTEM::LIBCLI_NBT] ADD_OBJ_FILES = \ -- cgit From 46b5a3d7542b5e0960e6ef3ac9cbd7fcf142ac3f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Jan 2005 00:51:06 +0000 Subject: r4950: removed some excessive debugging messages (This used to be commit 4a351901aa49090700d89274559d6dda76f06b7d) --- source4/libcli/composite/fetchfile.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index f18657c452..24f4808f64 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -49,8 +49,6 @@ static NTSTATUS fetchfile_connect(struct smbcli_composite *c, status = smb_composite_connect_recv(state->req, c); NT_STATUS_NOT_OK_RETURN(status); - printf("connect done\n"); - state->loadfile = talloc(state, struct smb_composite_loadfile); NT_STATUS_NOT_OK_RETURN(status); @@ -66,8 +64,6 @@ static NTSTATUS fetchfile_connect(struct smbcli_composite *c, state->stage = FETCHFILE_READ; c->event_ctx = talloc_reference(c, state->req->event_ctx); - printf("load started\n"); - return NT_STATUS_OK; } @@ -78,13 +74,9 @@ static NTSTATUS fetchfile_read(struct smbcli_composite *c, struct fetchfile_state *state; state = talloc_get_type(c->private, struct fetchfile_state); - printf("read event\n"); - status = smb_composite_loadfile_recv(state->req, NULL); NT_STATUS_NOT_OK_RETURN(status); - printf("read done\n"); - io->out.data = state->loadfile->out.data; io->out.size = state->loadfile->out.size; -- cgit From 3e44c4a3ba6acd7d9bc997c012d1863377e9d873 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Jan 2005 00:57:14 +0000 Subject: r4951: some of the code dealing with libcli was getting too complex trying to handle the inverted memory hierarchy that a normal session establishment gave. The inverted hierarchy came from that fact that you first establish a socket, then a transport, then a session and finally a tree. That leads to the socket being at the top of the memory hierarchy and the tree at the bottom, which makes no sense from the users point of view, as they want to be able to free the tree and have everything disappear. The core problem was that the libcli interface didn't distinguish between establishing a primary context and a secondary context. If you establish a 2nd session on a transport then you want the transport to be referenced by the session, whereas if you establish a primary session then you want the transport to be a child of the session. To fix this I have added "parent_ctx" and "primary" arguments to the libcli intialisation functions. This makes using the library much easier, and gives us a memory hierarchy that makes much more sense. I was prompted to do this by a bug in the cifs backend, which was caused by the socket not being properly torn down on a disconnect due to the inverted memory hierarchy. (This used to be commit 5e8fd5f70178992e249805c2e1ddafaf6840739b) --- source4/libcli/cliconnect.c | 9 +++------ source4/libcli/composite/connect.c | 9 +++------ source4/libcli/raw/clisession.c | 11 ++++++++--- source4/libcli/raw/clitransport.c | 13 ++++++++----- source4/libcli/raw/clitree.c | 12 +++++++++--- source4/libcli/util/clilsa.c | 2 +- 6 files changed, 32 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 4d9fb5ba1f..5aabb55f5d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -40,8 +40,7 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) return False; } - cli->transport = smbcli_transport_init(sock); - talloc_free(sock); + cli->transport = smbcli_transport_init(sock, cli, True); if (!cli->transport) { return False; } @@ -73,9 +72,8 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, NTSTATUS status; TALLOC_CTX *mem_ctx; - cli->session = smbcli_session_init(cli->transport); + cli->session = smbcli_session_init(cli->transport, cli, True); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; - talloc_free(cli->transport); mem_ctx = talloc_init("smbcli_session_setup"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; @@ -114,8 +112,7 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, TALLOC_CTX *mem_ctx; NTSTATUS status; - cli->tree = smbcli_tree_init(cli->session); - talloc_free(cli->session); + cli->tree = smbcli_tree_init(cli->session, cli, True); if (!cli->tree) return NT_STATUS_UNSUCCESSFUL; mem_ctx = talloc_init("tcon"); diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 69b394310e..8dd7fe39ab 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -112,7 +112,7 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, state->session->vuid = state->io_setup->out.vuid; /* setup for a tconx */ - io->out.tree = smbcli_tree_init(state->session); + io->out.tree = smbcli_tree_init(state->session, state, True); NT_STATUS_HAVE_NO_MEMORY(io->out.tree); state->io_tcon = talloc(c, union smb_tcon); @@ -157,12 +157,9 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, NT_STATUS_NOT_OK_RETURN(status); /* next step is a session setup */ - state->session = smbcli_session_init(state->transport); + state->session = smbcli_session_init(state->transport, state, True); NT_STATUS_HAVE_NO_MEMORY(state->session); - /* get rid of the extra reference to the transport */ - talloc_free(state->transport); - state->io_setup = talloc(c, struct smb_composite_sesssetup); NT_STATUS_HAVE_NO_MEMORY(state->io_setup); @@ -214,7 +211,7 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, NT_STATUS_NOT_OK_RETURN(status); /* the socket is up - we can initialise the smbcli transport layer */ - state->transport = smbcli_transport_init(state->sock); + state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); calling.name = io->in.calling_name; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index ed50601c25..30382e0837 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -33,18 +33,23 @@ /**************************************************************************** Initialize the session context ****************************************************************************/ -struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport) +struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, + TALLOC_CTX *parent_ctx, BOOL primary) { struct smbcli_session *session; uint16_t flags2; uint32_t capabilities; - session = talloc_zero(transport, struct smbcli_session); + session = talloc_zero(parent_ctx, struct smbcli_session); if (!session) { return NULL; } - session->transport = talloc_reference(session, transport); + if (primary) { + session->transport = talloc_steal(session, transport); + } else { + session->transport = talloc_reference(session, transport); + } session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index e3a8281f3f..c993fd7e60 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -61,16 +61,19 @@ static int transport_destructor(void *ptr) /* create a transport structure based on an established socket */ -struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock) +struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, + TALLOC_CTX *parent_ctx, BOOL primary) { struct smbcli_transport *transport; - transport = talloc_p(sock, struct smbcli_transport); + transport = talloc_zero(parent_ctx, struct smbcli_transport); if (!transport) return NULL; - ZERO_STRUCTP(transport); - - transport->socket = talloc_reference(transport, sock); + if (primary) { + transport->socket = talloc_steal(transport, sock); + } else { + transport->socket = talloc_reference(transport, sock); + } transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(); transport->options.max_xmit = lp_max_xmit(); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 06963d5bc4..ce4dafca9f 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -33,16 +33,22 @@ /**************************************************************************** Initialize the tree context ****************************************************************************/ -struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session) +struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session, + TALLOC_CTX *parent_ctx, BOOL primary) { struct smbcli_tree *tree; - tree = talloc_zero(session, struct smbcli_tree); + tree = talloc_zero(parent_ctx, struct smbcli_tree); if (!tree) { return NULL; } - tree->session = talloc_reference(tree, session); + if (primary) { + tree->session = talloc_steal(tree, session); + } else { + tree->session = talloc_reference(tree, session); + } + return tree; } diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index eac6984254..40991a8855 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -58,7 +58,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) return NT_STATUS_NO_MEMORY; } - lsa->ipc_tree = smbcli_tree_init(cli->session); + lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, False); if (lsa->ipc_tree == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From 52ad7774b5f9ff701a5b03d801a54aa7e7005640 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Jan 2005 01:04:15 +0000 Subject: r4952: removed a bogus talloc_steal() that was trying to cope with the inverted memory hierarchy. Now the memory hierarchy is logical its not needed (and can cause a double free in RPC-SCHANNEL) (This used to be commit f8a950b57d7137c6fd0a77d063d946b4f9b3f014) --- source4/libcli/cliconnect.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 5aabb55f5d..354840b84c 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -188,7 +188,6 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, (*ret_cli)->tree = tree; (*ret_cli)->session = tree->session; (*ret_cli)->transport = tree->session->transport; - talloc_steal(*ret_cli, tree->session->transport->socket); done: talloc_free(mem_ctx); -- cgit From af4ce4805ce1504fc8869ead032eabb72fca77a0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Jan 2005 01:51:45 +0000 Subject: r4954: we don't need the separate event_remove_*() calls any more, as you now remove an event by calling talloc_free(). (This used to be commit 8f19b6886cc58a56d52aecfc83a175197061e533) --- source4/libcli/raw/clitransport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index c993fd7e60..1904618be9 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -318,7 +318,7 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, transport->idle.period = period; if (transport->socket->event.te != NULL) { - event_remove_timed(transport->socket->event.ctx, transport->socket->event.te); + talloc_free(transport->socket->event.te); } te.next_event = timeval_current_ofs(0, period); -- cgit From 657583b9b9da6076fe0f2b850f0536249d314dea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Jan 2005 03:43:48 +0000 Subject: r4957: the fetchfile _recv() function was neglecting to steal the data and free the connection context. This left a whole lot of state hanging around and didn't give the memory to the caller properly (This used to be commit 3e13e1d526563d91cb2342ae68455e54eb49a9bd) --- source4/libcli/composite/fetchfile.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index 24f4808f64..8178090398 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -168,7 +168,17 @@ struct smbcli_composite *smb_composite_fetchfile_send(struct smb_composite_fetch NTSTATUS smb_composite_fetchfile_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx) { - return smb_composite_wait(c); + NTSTATUS status; + + status = smb_composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct fetchfile_state *state = talloc_get_type(c->private, struct fetchfile_state); + talloc_steal(mem_ctx, state->io->out.data); + } + + talloc_free(c); + return status; } NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io, -- cgit From 52a6067fcb65514ad6ebf44569ce234ba05132df Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 24 Jan 2005 14:30:22 +0000 Subject: r4958: fix compiler warnings metze (This used to be commit 522af7ecc0020b7c56182ca628f6d1623abe303e) --- source4/libcli/auth/gensec_gssapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index 0b5bd01194..80a17c1b6b 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -35,7 +35,7 @@ struct gensec_gssapi_state { struct gss_channel_bindings_struct *input_chan_bindings; gss_name_t server_name; gss_name_t client_name; - int want_flags, got_flags; + OM_uint32 want_flags, got_flags; const gss_OID_desc *gss_oid; }; static int gensec_gssapi_destory(void *ptr) @@ -205,7 +205,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, case GENSEC_SERVER: { maj_stat = gss_accept_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, + &gensec_gssapi_state->gssapi_context, GSS_C_NO_CREDENTIAL, &input_token, gensec_gssapi_state->input_chan_bindings, -- cgit From 3dd17f128831e09c230a8d56e34495d3b31dbacb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 06:16:59 +0000 Subject: r5034: - added a type mapping function in pidl, so the type names in our IDL files don't need to match the type names in the generated headers - with this type mapping we no longer need definitions for the deprecated "int32", "uint8" etc form of types. We can now force everyone to use the standard types int32_t, uint8_t etc. - fixed all the code that used the deprecated types - converted the IDL types "int64" and "uint64" to "dlong" and "udlong". These are the 4 byte aligned 64 bit integers that Microsoft internally define as two 32 bit integers in a structure. After discussions with Ronnie Sahlberg we decided that calling these "int64" was confusing, as it implied a true 8 byte aligned type - fixed all the cases where we incorrectly used things like "NTTIME_hyper" in our C code. The generated API now uses a NTTIME for those. The fact that it is hyper-aligned on the wire is not relevant to the API, and should remain just a IDL property (This used to be commit f86521677d7ff16bdc4815f9524e5286026f10f3) --- source4/libcli/ldap/ldap.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 65962bf5b5..8947562b77 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -146,8 +146,8 @@ struct ldap_SearchRequest { const char *basedn; enum ldap_scope scope; enum ldap_deref deref; - uint32 timelimit; - uint32 sizelimit; + uint32_t timelimit; + uint32_t sizelimit; BOOL attributesonly; char *filter; int num_attributes; @@ -206,7 +206,7 @@ struct ldap_CompareRequest { }; struct ldap_AbandonRequest { - uint32 messageid; + uint32_t messageid; }; struct ldap_ExtendedRequest { @@ -251,8 +251,8 @@ struct ldap_Control { struct ldap_message { TALLOC_CTX *mem_ctx; - uint32 messageid; - uint8 type; + uint32_t messageid; + uint8_t type; union ldap_Request r; int num_controls; struct ldap_Control *controls; @@ -269,7 +269,7 @@ struct ldap_connection { int sock; int next_msgid; char *host; - uint16 port; + uint16_t port; BOOL ldaps; const char *auth_dn; -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/libcli/auth/clikrb5.c | 2 +- source4/libcli/auth/gensec.c | 6 +++--- source4/libcli/auth/gensec_gssapi.c | 2 +- source4/libcli/auth/gensec_krb5.c | 2 +- source4/libcli/auth/gensec_ntlmssp.c | 2 +- source4/libcli/auth/ntlmssp.c | 4 ++-- source4/libcli/auth/ntlmssp_parse.c | 4 ++-- source4/libcli/auth/schannel.c | 2 +- source4/libcli/auth/spnego.c | 4 ++-- source4/libcli/auth/spnego_parse.c | 2 +- source4/libcli/cliconnect.c | 2 +- source4/libcli/clifile.c | 8 ++++---- source4/libcli/clilist.c | 10 +++++----- source4/libcli/clitrans2.c | 14 +++++++------- source4/libcli/ldap/ldap.c | 14 +++++++------- source4/libcli/ldap/ldap_client.c | 6 +++--- source4/libcli/ldap/ldap_ldif.c | 8 ++++---- source4/libcli/raw/rawacl.c | 2 +- source4/libcli/raw/raweas.c | 6 +++--- source4/libcli/raw/rawfile.c | 4 ++-- source4/libcli/raw/rawfileinfo.c | 10 +++++----- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/raw/rawsetfileinfo.c | 8 ++++---- source4/libcli/security/dom_sid.c | 12 ++++++------ source4/libcli/security/security_descriptor.c | 8 ++++---- source4/libcli/security/security_token.c | 6 +++--- source4/libcli/util/asn1.c | 4 ++-- source4/libcli/util/clilsa.c | 4 ++-- source4/libcli/util/smbencrypt.c | 2 +- 29 files changed, 80 insertions(+), 80 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 122f9510e7..051798c9f1 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -321,7 +321,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_cc_default_name(context), http_timestring(mem_ctx, credsp->times.endtime))); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); /* we will probably need new tickets if the current ones will expire within 10 seconds. diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index fb638a9000..e9dea6be33 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -94,7 +94,7 @@ const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) if (!ops) { return NULL; } - oid_list = talloc_array_p(mem_ctx, const char *, num_backends + 1); + oid_list = talloc_array(mem_ctx, const char *, num_backends + 1); if (!oid_list) { return NULL; } @@ -123,7 +123,7 @@ const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) */ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) { - (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); + (*gensec_security) = talloc(mem_ctx, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; } @@ -155,7 +155,7 @@ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, struct gensec_security *parent, struct gensec_security **gensec_security) { - (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); + (*gensec_security) = talloc(mem_ctx, struct gensec_security); if (!(*gensec_security)) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index 80a17c1b6b..43113412f7 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -62,7 +62,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; - gensec_gssapi_state = talloc_p(gensec_security, struct gensec_gssapi_state); + gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state); if (!gensec_gssapi_state) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index aaf892e1e6..e5bfd3865a 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -258,7 +258,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) struct gensec_krb5_state *gensec_krb5_state; krb5_error_code ret = 0; - gensec_krb5_state = talloc_p(gensec_security, struct gensec_krb5_state); + gensec_krb5_state = talloc(gensec_security, struct gensec_krb5_state); if (!gensec_krb5_state) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index ae97803ef7..59bab6ced2 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -143,7 +143,7 @@ static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) { struct gensec_ntlmssp_state *gensec_ntlmssp_state; - gensec_ntlmssp_state = talloc_p(gensec_security, struct gensec_ntlmssp_state); + gensec_ntlmssp_state = talloc(gensec_security, struct gensec_ntlmssp_state); if (!gensec_ntlmssp_state) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index a9fb66d41e..d5ddcfbfb6 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -909,7 +909,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) { - *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state); + *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); return NT_STATUS_NO_MEMORY; @@ -1269,7 +1269,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) { - *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state); + *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index a713b9896d..543f3d9b61 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -54,8 +54,8 @@ BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, DATA_BLOB *pointers; - pointers = talloc_array_p(mem_ctx, DATA_BLOB, strlen(format)); - intargs = talloc_array_p(pointers, int, strlen(format)); + pointers = talloc_array(mem_ctx, DATA_BLOB, strlen(format)); + intargs = talloc_array(pointers, int, strlen(format)); /* first scan the format to work out the header and body size */ va_start(ap, format); diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 51b8690c97..92442234bd 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -289,7 +289,7 @@ NTSTATUS schannel_start(struct schannel_state **state, const uint8_t session_key[16], BOOL initiator) { - (*state) = talloc_p(NULL, struct schannel_state); + (*state) = talloc(NULL, struct schannel_state); if (!(*state)) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 1e92a7d16e..a61680c9d4 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -50,7 +50,7 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi { struct spnego_state *spnego_state; - spnego_state = talloc_p(gensec_security, struct spnego_state); + spnego_state = talloc(gensec_security, struct spnego_state); if (!spnego_state) { return NT_STATUS_NO_MEMORY; } @@ -68,7 +68,7 @@ static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_securi { struct spnego_state *spnego_state; - spnego_state = talloc_p(gensec_security, struct spnego_state); + spnego_state = talloc(gensec_security, struct spnego_state); if (!spnego_state) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index 78a94a6a44..e48c32f0da 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -49,7 +49,7 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = talloc_p(NULL, const char *); + token->mechTypes = talloc(NULL, const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = talloc_realloc(NULL, diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 354840b84c..263527ffc0 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -211,7 +211,7 @@ struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) { struct smbcli_state *cli; - cli = talloc_zero_p(mem_ctx, struct smbcli_state); + cli = talloc_zero(mem_ctx, struct smbcli_state); if (cli) { ZERO_STRUCTP(cli); } diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 992d2c225d..0b9cac4c07 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -252,7 +252,7 @@ int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname, open_parms.ntcreatex.in.fname = fname; status = smb_raw_open(tree, mem_ctx, &open_parms); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { return open_parms.ntcreatex.out.fnum; @@ -319,7 +319,7 @@ int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, open_parms.openx.in.fname = fname; status = smb_raw_open(tree, mem_ctx, &open_parms); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { return open_parms.openx.out.fnum; @@ -633,7 +633,7 @@ NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, int *bsize, int *total, int *a *avail = fsinfo_parms.dskattr.out.units_free; } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -660,7 +660,7 @@ int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path) if (tmp_path) { *tmp_path = strdup(open_parms.ctemp.out.name); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { return open_parms.ctemp.out.fnum; } diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 77fd760837..0d69a386eb 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -147,7 +147,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.mem_ctx, &first_parms, (void*)&state, smbcli_list_new_callback); if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(state.mem_ctx); + talloc_free(state.mem_ctx); return -1; } @@ -192,7 +192,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu fn(&state.dirlist[i], Mask, caller_state); } - talloc_destroy(state.mem_ctx); + talloc_free(state.mem_ctx); return state.total_received; } @@ -283,7 +283,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu smbcli_list_old_callback); if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(state.mem_ctx); + talloc_free(state.mem_ctx); return -1; } @@ -307,7 +307,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu break; } if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(state.mem_ctx); + talloc_free(state.mem_ctx); return -1; } received = next_parms.search_next.out.count; @@ -321,7 +321,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu fn(&state.dirlist[i], Mask, caller_state); } - talloc_destroy(state.mem_ctx); + talloc_free(state.mem_ctx); return state.total_received; } diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index eb2c671a95..6be92fa17d 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -38,7 +38,7 @@ NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname, parms.standard.in.fname = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(status)) return status; @@ -80,7 +80,7 @@ NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname, parms.all_info.in.fname = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(status)) return status; @@ -124,14 +124,14 @@ NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name) status = smb_raw_fileinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); *name = NULL; return status; } *name = strdup(parms.name_info.out.fname.s); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -157,7 +157,7 @@ NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum, parms.all_info.in.fnum = fnum; status = smb_raw_fileinfo(tree, mem_ctx, &parms); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -206,7 +206,7 @@ NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname, status = smb_raw_pathinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); *alt_name = NULL; return smbcli_nt_error(tree); } @@ -217,7 +217,7 @@ NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname, *alt_name = strdup(parms.alt_name_info.out.fname.s); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NT_STATUS_OK; } diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b2a6bd957a..eab94bb194 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -130,7 +130,7 @@ static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, if (val && strchr("()&|", *val)) return NULL; - ret = talloc_p(mem_ctx, struct ldap_parse_tree); + ret = talloc(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -157,7 +157,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, { struct ldap_parse_tree *ret, *next; - ret = talloc_p(mem_ctx, struct ldap_parse_tree); + ret = talloc(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -165,7 +165,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, ret->operation = op; ret->u.list.num_elements = 1; - ret->u.list.elements = talloc_p(mem_ctx, struct ldap_parse_tree *); + ret->u.list.elements = talloc(mem_ctx, struct ldap_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; return NULL; @@ -180,7 +180,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { struct ldap_parse_tree **e; - e = talloc_realloc_p(ret, + e = talloc_realloc(ret, ret->u.list.elements, struct ldap_parse_tree *, ret->u.list.num_elements+1); @@ -205,7 +205,7 @@ static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s { struct ldap_parse_tree *ret; - ret = talloc_p(mem_ctx, struct ldap_parse_tree); + ret = talloc(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -448,7 +448,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ldap_push_filter(&data, tree); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); } asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -1186,7 +1186,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { asn1_start_tag(data, ASN1_SEQUENCE(0)); - ctrl = talloc_realloc_p(msg->mem_ctx, ctrl, struct ldap_Control, i+1); + ctrl = talloc_realloc(msg->mem_ctx, ctrl, struct ldap_Control, i+1); if (!ctrl) { return False; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 84fd0f1d64..c9e81ac28f 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -100,7 +100,7 @@ static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) { struct ldap_connection *result; - result = talloc_p(mem_ctx, struct ldap_connection); + result = talloc(mem_ctx, struct ldap_connection); if (!result) { return NULL; @@ -158,7 +158,7 @@ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { struct ldap_message *result; - result = talloc_p(mem_ctx, struct ldap_message); + result = talloc(mem_ctx, struct ldap_message); if (!result) { return NULL; @@ -472,7 +472,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha done: if (mem_ctx) - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return result; } diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 809c75cf96..a0249a4ba0 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -159,7 +159,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, struct ldap_attribute *attrib) { - attrib->values = talloc_realloc_p(mem_ctx, + attrib->values = talloc_realloc(mem_ctx, attrib->values, DATA_BLOB, attrib->num_values+1); @@ -177,7 +177,7 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_attribute **attribs, int *num_attribs) { - *attribs = talloc_realloc_p(mem_ctx, + *attribs = talloc_realloc(mem_ctx, *attribs, struct ldap_attribute, *num_attribs+1); @@ -211,7 +211,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc_p(msg->mem_ctx, + r->attributes = talloc_realloc(msg->mem_ctx, r->attributes, struct ldap_attribute, r->num_attributes+1); @@ -236,7 +236,7 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod **mods, int *num_mods) { - *mods = talloc_realloc_p(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); if (*mods == NULL) return False; diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 97e0212137..b2dac09f81 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -81,7 +81,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, return NT_STATUS_INVALID_PARAMETER; } - io->query_secdesc.out.sd = talloc_p(mem_ctx, struct security_descriptor); + io->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor); if (!io->query_secdesc.out.sd) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index ec8bacdf64..49be9a43e6 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -187,7 +187,7 @@ NTSTATUS ea_pull_list(const DATA_BLOB *blob, blob2.data = blob->data + ofs; blob2.length = ea_size - ofs; - *eas = talloc_realloc_p(mem_ctx, *eas, struct ea_struct, n+1); + *eas = talloc_realloc(mem_ctx, *eas, struct ea_struct, n+1); if (! *eas) return NT_STATUS_NO_MEMORY; len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); @@ -232,7 +232,7 @@ NTSTATUS ea_pull_list_chained(const DATA_BLOB *blob, blob2.data = blob->data + ofs + 4; blob2.length = blob->length - (ofs + 4); - *eas = talloc_realloc_p(mem_ctx, *eas, struct ea_struct, n+1); + *eas = talloc_realloc(mem_ctx, *eas, struct ea_struct, n+1); if (! *eas) return NT_STATUS_NO_MEMORY; len = ea_pull_struct(&blob2, mem_ctx, &(*eas)[n]); @@ -312,7 +312,7 @@ NTSTATUS ea_pull_name_list(const DATA_BLOB *blob, blob2.data = blob->data + ofs; blob2.length = ea_size - ofs; - *ea_names = talloc_realloc_p(mem_ctx, *ea_names, struct ea_name, n+1); + *ea_names = talloc_realloc(mem_ctx, *ea_names, struct ea_name, n+1); if (! *ea_names) return NT_STATUS_NO_MEMORY; len = ea_pull_name(&blob2, mem_ctx, &(*ea_names)[n]); diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index e0b54cacc3..c6652125c2 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -140,7 +140,7 @@ static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, req = smb_raw_trans2_send(tree, &t2); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return req; } @@ -383,7 +383,7 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, req = smb_raw_trans2_send(tree, &t2); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return req; } diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 3befb8ee4d..88c2f0d0fc 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -182,7 +182,7 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, while (blob->length - ofs >= 24) { uint_t n = parms->stream_info.out.num_streams; parms->stream_info.out.streams = - talloc_realloc_p(mem_ctx, + talloc_realloc(mem_ctx, parms->stream_info.out.streams, struct stream_struct, n+1); @@ -306,7 +306,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); if (!tp.in.params.data) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NULL; } @@ -315,7 +315,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre req = smb_raw_trans2_send(tree, &tp); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return req; } @@ -360,7 +360,7 @@ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tre tp.in.params = data_blob_talloc(mem_ctx, NULL, 6); if (!tp.in.params.data) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NULL; } @@ -371,7 +371,7 @@ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tre req = smb_raw_trans2_send(tree, &tp); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return req; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 7fb12dcf80..7dbe6b3468 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -67,7 +67,7 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran { struct smbcli_request *req; - req = talloc_p(transport, struct smbcli_request); + req = talloc(transport, struct smbcli_request); if (!req) { return NULL; } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 9576bdf356..7934171ab0 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -274,7 +274,7 @@ struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree, if (!mem_ctx) return NULL; if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NULL; } @@ -285,7 +285,7 @@ struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree, parms->generic.level, &blob); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return req; } @@ -321,7 +321,7 @@ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, if (!mem_ctx) return NULL; if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NULL; } @@ -332,7 +332,7 @@ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, parms->generic.level, &blob); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return req; } diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index d76f9fa239..493ecab183 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -149,12 +149,12 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) if (sidstr[i] == '-') num_sub_auths++; } - ret = talloc_p(mem_ctx, struct dom_sid); + ret = talloc(mem_ctx, struct dom_sid); if (!ret) { return NULL; } - ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, num_sub_auths); + ret->sub_auths = talloc_array(mem_ctx, uint32_t, num_sub_auths); if (!ret->sub_auths) { return NULL; } @@ -190,12 +190,12 @@ struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid) { struct dom_sid *ret; int i; - ret = talloc_p(mem_ctx, struct dom_sid); + ret = talloc(mem_ctx, struct dom_sid); if (!ret) { return NULL; } - ret->sub_auths = talloc_array_p(ret, uint32_t, dom_sid->num_auths); + ret->sub_auths = talloc_array(ret, uint32_t, dom_sid->num_auths); if (!ret->sub_auths) { return NULL; } @@ -226,12 +226,12 @@ struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, { struct dom_sid *sid; - sid = talloc_p(mem_ctx, struct dom_sid); + sid = talloc(mem_ctx, struct dom_sid); if (!sid) return NULL; *sid = *domain_sid; - sid->sub_auths = talloc_array_p(sid, uint32_t, sid->num_auths+1); + sid->sub_auths = talloc_array(sid, uint32_t, sid->num_auths+1); if (!sid->sub_auths) { return NULL; } diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 509ec1f343..bbfee31fbe 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -30,7 +30,7 @@ struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx) { struct security_descriptor *sd; - sd = talloc_p(mem_ctx, struct security_descriptor); + sd = talloc(mem_ctx, struct security_descriptor); if (!sd) { return NULL; } @@ -72,7 +72,7 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, const struct security_ace *ace) { if (sd->dacl == NULL) { - sd->dacl = talloc_p(sd, struct security_acl); + sd->dacl = talloc(sd, struct security_acl); if (sd->dacl == NULL) { return NT_STATUS_NO_MEMORY; } @@ -82,7 +82,7 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, sd->dacl->aces = NULL; } - sd->dacl->aces = talloc_realloc_p(sd->dacl, sd->dacl->aces, + sd->dacl->aces = talloc_realloc(sd->dacl, sd->dacl->aces, struct security_ace, sd->dacl->num_aces+1); if (sd->dacl->aces == NULL) { return NT_STATUS_NO_MEMORY; @@ -257,7 +257,7 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, va_start(ap, group_sid); while ((sidstr = va_arg(ap, const char *))) { struct dom_sid *sid; - struct security_ace *ace = talloc_p(sd, struct security_ace); + struct security_ace *ace = talloc(sd, struct security_ace); NTSTATUS status; if (ace == NULL) { diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index b9baf796df..663c4f28bc 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -31,7 +31,7 @@ struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx) { struct security_token *st; - st = talloc_p(mem_ctx, struct security_token); + st = talloc(mem_ctx, struct security_token); if (!st) { return NULL; } @@ -63,7 +63,7 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, ptoken = security_token_initialise(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(ptoken); - ptoken->sids = talloc_array_p(ptoken, struct dom_sid *, n_groupSIDs + 5); + ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5); NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); ptoken->user_sid = talloc_reference(ptoken, user_sid); @@ -163,5 +163,5 @@ void security_token_debug(int dbg_lev, const struct security_token *token) } } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index de14eb0e57..550450fea7 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -59,7 +59,7 @@ BOOL asn1_push_tag(struct asn1_data *data, uint8_t tag) struct nesting *nesting; asn1_write_uint8(data, tag); - nesting = talloc_p(NULL, struct nesting); + nesting = talloc(NULL, struct nesting); if (!nesting) { data->has_error = True; return False; @@ -349,7 +349,7 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) data->has_error = True; return False; } - nesting = talloc_p(NULL, struct nesting); + nesting = talloc(NULL, struct nesting); if (!nesting) { data->has_error = True; return False; diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 40991a8855..0c0c64c0b4 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -53,7 +53,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) return NT_STATUS_OK; } - lsa = talloc_p(cli, struct smblsa_state); + lsa = talloc(cli, struct smblsa_state); if (lsa == NULL) { return NT_STATUS_NO_MEMORY; } @@ -217,7 +217,7 @@ NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli, names.names = NULL; sids.num_sids = 1; - sids.sids = talloc_p(mem_ctx2, struct lsa_SidPtr); + sids.sids = talloc(mem_ctx2, struct lsa_SidPtr); sids.sids[0].sid = sid; r.in.handle = &cli->lsa->handle; diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c index bd2aae3db1..7e2890272c 100644 --- a/source4/libcli/util/smbencrypt.c +++ b/source4/libcli/util/smbencrypt.c @@ -344,7 +344,7 @@ static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], memcpy(final_response.data+sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return final_response; } -- cgit From 99ecf2d95325e7b6143596760dbc2780ba246dc6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jan 2005 11:25:01 +0000 Subject: r5053: - fix up the library dependencies so that tools that need nbt don't need to pull in the whole dcerpc subsystem - moved smbencrypt.c code into libcli/auth/ (This used to be commit 3351c636af23ad88649e84f4cb88fc1167d5c654) --- source4/libcli/auth/config.mk | 3 +- source4/libcli/auth/smbencrypt.c | 504 +++++++++++++++++++++++++++++++++++++++ source4/libcli/config.mk | 7 +- source4/libcli/util/smbencrypt.c | 504 --------------------------------------- 4 files changed, 509 insertions(+), 509 deletions(-) create mode 100644 source4/libcli/auth/smbencrypt.c delete mode 100644 source4/libcli/util/smbencrypt.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index a3bb3f1c78..c40a1346db 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -3,7 +3,8 @@ [SUBSYSTEM::LIBCLI_AUTH] ADD_OBJ_FILES = libcli/auth/schannel.o \ libcli/auth/credentials.o \ - libcli/auth/session.o + libcli/auth/session.o \ + libcli/auth/smbencrypt.o REQUIRED_SUBSYSTEMS = \ AUTH SCHANNELDB GENSEC # End SUBSYSTEM LIBCLI_AUTH diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c new file mode 100644 index 0000000000..7e2890272c --- /dev/null +++ b/source4/libcli/auth/smbencrypt.c @@ -0,0 +1,504 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-1998 + Modified by Jeremy Allison 1995. + Copyright (C) Jeremy Allison 1995-2000. + Copyright (C) Luke Kennethc Casson Leighton 1996-2000. + Copyright (C) Andrew Bartlett 2002-2003 + + 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 "system/time.h" +#include "auth/auth.h" +#include "lib/crypto/crypto.h" + +/* + This implements the X/Open SMB password encryption + It takes a password ('unix' string), a 8 byte "crypt key" + and puts 24 bytes of encrypted password into p24 + + Returns False if password must have been truncated to create LM hash +*/ +BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) +{ + BOOL ret; + uint8_t p21[21]; + + memset(p21,'\0',21); + ret = E_deshash(passwd, p21); + + SMBOWFencrypt(p21, c8, p24); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); +#endif + + return ret; +} + +/** + * Creates the MD4 Hash of the users password in NT UNICODE. + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with md4, caller allocated 16 byte buffer + */ + +void E_md4hash(const char *passwd, uint8_t p16[16]) +{ + int len; + void *wpwd; + + len = push_ucs2_talloc(NULL, &wpwd, passwd); + SMB_ASSERT(len >= 2); + + len -= 2; + mdfour(p16, wpwd, len); + + talloc_free(wpwd); +} + +/** + * Creates the DES forward-only Hash of the users password in DOS ASCII charset + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with DES, caller allocated 16 byte buffer + * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True + * @note p16 is filled in regardless + */ + +BOOL E_deshash(const char *passwd, uint8_t p16[16]) +{ + BOOL ret = True; + fstring dospwd; + ZERO_STRUCT(dospwd); + + /* Password must be converted to DOS charset - null terminated, uppercase. */ + push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + E_P16((const uint8_t *)dospwd, p16); + + if (strlen(dospwd) > 14) { + ret = False; + } + + ZERO_STRUCT(dospwd); + + return ret; +} + +/* Does both the NTLMv2 owfs of a user's password */ +BOOL ntv2_owf_gen(const uint8_t owf[16], + const char *user_in, const char *domain_in, + BOOL upper_case_domain, /* Transform the domain into UPPER case */ + uint8_t kr_buf[16]) +{ + void *user; + void *domain; + size_t user_byte_len; + size_t domain_byte_len; + + HMACMD5Context ctx; + TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); + if (!mem_ctx) { + return False; + } + + user_in = strupper_talloc(mem_ctx, user_in); + if (user_in == NULL) { + talloc_free(mem_ctx); + return False; + } + + if (upper_case_domain) { + domain_in = strupper_talloc(mem_ctx, domain_in); + if (domain_in == NULL) { + talloc_free(mem_ctx); + return False; + } + } + + user_byte_len = push_ucs2_talloc(mem_ctx, &user, user_in); + if (user_byte_len == (ssize_t)-1) { + DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); + talloc_free(mem_ctx); + return False; + } + + domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in); + if (domain_byte_len == (ssize_t)-1) { + DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); + talloc_free(mem_ctx); + return False; + } + + SMB_ASSERT(user_byte_len >= 2); + SMB_ASSERT(domain_byte_len >= 2); + + /* We don't want null termination */ + user_byte_len = user_byte_len - 2; + domain_byte_len = domain_byte_len - 2; + + hmac_md5_init_limK_to_64(owf, 16, &ctx); + hmac_md5_update(user, user_byte_len, &ctx); + hmac_md5_update(domain, domain_byte_len, &ctx); + hmac_md5_final(kr_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); + dump_data(100, user, user_byte_len); + dump_data(100, domain, domain_byte_len); + dump_data(100, owf, 16); + dump_data(100, kr_buf, 16); +#endif + + talloc_free(mem_ctx); + return True; +} + +/* Does the des encryption from the NT or LM MD4 hash. */ +void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) +{ + uint8_t p21[21]; + + ZERO_STRUCT(p21); + + memcpy(p21, passwd, 16); + E_P24(p21, c8, p24); +} + +/* Does the NT MD4 hash then des encryption. */ + +void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) +{ + uint8_t p21[21]; + + memset(p21,'\0',21); + + E_md4hash(passwd, p21); + SMBOWFencrypt(p21, c8, p24); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); +#endif +} + +/* Does the md5 encryption from the Key Response for NTLMv2. */ +void SMBOWFencrypt_ntv2(const uint8_t kr[16], + const DATA_BLOB *srv_chal, + const DATA_BLOB *smbcli_chal, + uint8_t resp_buf[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); + hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx); + hmac_md5_final(resp_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n")); + dump_data(100, srv_chal->data, srv_chal->length); + dump_data(100, smbcli_chal->data, smbcli_chal->length); + dump_data(100, resp_buf, 16); +#endif +} + +void SMBsesskeygen_ntv2(const uint8_t kr[16], + const uint8_t * nt_resp, uint8_t sess_key[16]) +{ + /* a very nice, 128 bit, variable session key */ + + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(nt_resp, 16, &ctx); + hmac_md5_final((uint8_t *)sess_key, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv2:\n")); + dump_data(100, sess_key, 16); +#endif +} + +void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) +{ + /* yes, this session key does not change - yes, this + is a problem - but it is 128 bits */ + + mdfour((uint8_t *)sess_key, kr, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv1:\n")); + dump_data(100, sess_key, 16); +#endif +} + +void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], + const uint8_t lm_resp[24], /* only uses 8 */ + uint8_t sess_key[16]) +{ + /* Calculate the LM session key (effective length 40 bits, + but changes with each session) */ + uint8_t p24[24]; + uint8_t p21[21]; + + memset(p21,'\0',21); + memcpy(p21, lm_hash, 8); + memset(p21 + 8, 0xbd, 8); + + E_P24(p21, lm_resp, p24); + + memcpy(sess_key, p24, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n")); + dump_data(100, sess_key, 16); +#endif +} + +DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, + const char *hostname, + const char *domain) +{ + DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); + + msrpc_gen(mem_ctx, &names_blob, "aaa", + NTLMSSP_NAME_TYPE_DOMAIN, domain, + NTLMSSP_NAME_TYPE_SERVER, hostname, + 0, ""); + return names_blob; +} + +static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) +{ + uint8_t client_chal[8]; + DATA_BLOB response = data_blob(NULL, 0); + uint8_t long_date[8]; + NTTIME nttime; + + unix_to_nt_time(&nttime, time(NULL)); + + generate_random_buffer(client_chal, sizeof(client_chal)); + + push_nttime(long_date, 0, nttime); + + /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ + + msrpc_gen(mem_ctx, &response, "ddbbdb", + 0x00000101, /* Header */ + 0, /* 'Reserved' */ + long_date, 8, /* Timestamp */ + client_chal, 8, /* client challenge */ + 0, /* Unknown */ + names_blob->data, names_blob->length); /* End of name list */ + + return response; +} + +static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob) +{ + uint8_t ntlmv2_response[16]; + DATA_BLOB ntlmv2_client_data; + DATA_BLOB final_response; + + TALLOC_CTX *mem_ctx = talloc_init("NTLMv2_generate_response internal context"); + + if (!mem_ctx) { + return data_blob(NULL, 0); + } + + /* NTLMv2 */ + /* generate some data to pass into the response function - including + the hostname and domain name of the server */ + ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); + + final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); + + memcpy(final_response.data+sizeof(ntlmv2_response), + ntlmv2_client_data.data, ntlmv2_client_data.length); + + talloc_free(mem_ctx); + + return final_response; +} + +static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], + const DATA_BLOB *server_chal) +{ + uint8_t lmv2_response[16]; + DATA_BLOB lmv2_client_data = data_blob(NULL, 8); + DATA_BLOB final_response = data_blob(NULL, 24); + + /* LMv2 */ + /* client-supplied random data */ + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); + memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); + + /* after the first 16 bytes is the random data we generated above, + so the server can verify us with it */ + memcpy(final_response.data+sizeof(lmv2_response), + lmv2_client_data.data, lmv2_client_data.length); + + data_blob_free(&lmv2_client_data); + + return final_response; +} + +BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t nt_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) +{ + uint8_t ntlm_v2_hash[16]; + + /* We don't use the NT# directly. Instead we use it mashed up with + the username and domain. + This prevents username swapping during the auth exchange + */ + if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { + return False; + } + + if (nt_response) { + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, + names_blob); + if (user_session_key) { + *user_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); + } + } + + /* LMv2 */ + + if (lm_response) { + *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); + if (lm_session_key) { + *lm_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of lm_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); + } + } + + return True; +} + +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) +{ + uint8_t nt_hash[16]; + E_md4hash(password, nt_hash); + + return SMBNTLMv2encrypt_hash(user, domain, nt_hash, server_chal, names_blob, + lm_response, nt_response, lm_session_key, user_session_key); +} + +/*********************************************************** + encode a password buffer with a unicode password. The buffer + is filled with random data to make it harder to attack. +************************************************************/ +BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) +{ + uint8_t new_pw[512]; + size_t new_pw_len; + + new_pw_len = push_string(new_pw, + password, + sizeof(new_pw), string_flags); + + memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); + + generate_random_buffer(buffer, 512 - new_pw_len); + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + SIVAL(buffer, 512, new_pw_len); + ZERO_STRUCT(new_pw); + return True; +} + + +/*********************************************************** + decode a password buffer + *new_pw_len is the length in bytes of the possibly mulitbyte + returned password including termination. +************************************************************/ +BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, + int new_pwrd_size, uint32_t *new_pw_len, + int string_flags) +{ + int byte_len=0; + + /* + Warning !!! : This function is called from some rpc call. + The password IN the buffer may be a UNICODE string. + The password IN new_pwrd is an ASCII string + If you reuse that code somewhere else check first. + */ + + /* The length of the new password is in the last 4 bytes of the data buffer. */ + + byte_len = IVAL(in_buffer, 512); + +#ifdef DEBUG_PASSWORD + dump_data(100, in_buffer, 516); +#endif + + /* Password cannot be longer than the size of the password buffer */ + if ( (byte_len < 0) || (byte_len > 512)) { + return False; + } + + /* decode into the return buffer. Buffer length supplied */ + *new_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + byte_len, string_flags); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("decode_pw_buffer: new_pwrd: ")); + dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len); + DEBUG(100,("multibyte len:%d\n", *new_pw_len)); + DEBUG(100,("original char len:%d\n", byte_len/2)); +#endif + + return True; +} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 806ef775dc..06b46c6f18 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -5,8 +5,7 @@ ADD_OBJ_FILES = libcli/util/asn1.o \ libcli/util/errormap.o \ libcli/util/clierror.o \ libcli/util/nterr.o \ - libcli/util/smbdes.o \ - libcli/util/smbencrypt.o + libcli/util/smbdes.o [SUBSYSTEM::LIBCLI_LSA] ADD_OBJ_FILES = libcli/util/clilsa.o @@ -26,7 +25,7 @@ ADD_OBJ_FILES = \ libcli/nbt/nbtname.o \ libcli/nbt/nbtsocket.o \ libcli/nbt/namequery.o -REQUIRED_SUBSYSTEMS = NDR_NBT +REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ @@ -39,4 +38,4 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ - LIBCLI_COMPOSITE LIBCLI_NBT LIBCLI_RESOLVE + LIBCLI_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c deleted file mode 100644 index 7e2890272c..0000000000 --- a/source4/libcli/util/smbencrypt.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1998 - Modified by Jeremy Allison 1995. - Copyright (C) Jeremy Allison 1995-2000. - Copyright (C) Luke Kennethc Casson Leighton 1996-2000. - Copyright (C) Andrew Bartlett 2002-2003 - - 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 "system/time.h" -#include "auth/auth.h" -#include "lib/crypto/crypto.h" - -/* - This implements the X/Open SMB password encryption - It takes a password ('unix' string), a 8 byte "crypt key" - and puts 24 bytes of encrypted password into p24 - - Returns False if password must have been truncated to create LM hash -*/ -BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) -{ - BOOL ret; - uint8_t p21[21]; - - memset(p21,'\0',21); - ret = E_deshash(passwd, p21); - - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif - - return ret; -} - -/** - * Creates the MD4 Hash of the users password in NT UNICODE. - * @param passwd password in 'unix' charset. - * @param p16 return password hashed with md4, caller allocated 16 byte buffer - */ - -void E_md4hash(const char *passwd, uint8_t p16[16]) -{ - int len; - void *wpwd; - - len = push_ucs2_talloc(NULL, &wpwd, passwd); - SMB_ASSERT(len >= 2); - - len -= 2; - mdfour(p16, wpwd, len); - - talloc_free(wpwd); -} - -/** - * Creates the DES forward-only Hash of the users password in DOS ASCII charset - * @param passwd password in 'unix' charset. - * @param p16 return password hashed with DES, caller allocated 16 byte buffer - * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True - * @note p16 is filled in regardless - */ - -BOOL E_deshash(const char *passwd, uint8_t p16[16]) -{ - BOOL ret = True; - fstring dospwd; - ZERO_STRUCT(dospwd); - - /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - - /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - E_P16((const uint8_t *)dospwd, p16); - - if (strlen(dospwd) > 14) { - ret = False; - } - - ZERO_STRUCT(dospwd); - - return ret; -} - -/* Does both the NTLMv2 owfs of a user's password */ -BOOL ntv2_owf_gen(const uint8_t owf[16], - const char *user_in, const char *domain_in, - BOOL upper_case_domain, /* Transform the domain into UPPER case */ - uint8_t kr_buf[16]) -{ - void *user; - void *domain; - size_t user_byte_len; - size_t domain_byte_len; - - HMACMD5Context ctx; - TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); - if (!mem_ctx) { - return False; - } - - user_in = strupper_talloc(mem_ctx, user_in); - if (user_in == NULL) { - talloc_free(mem_ctx); - return False; - } - - if (upper_case_domain) { - domain_in = strupper_talloc(mem_ctx, domain_in); - if (domain_in == NULL) { - talloc_free(mem_ctx); - return False; - } - } - - user_byte_len = push_ucs2_talloc(mem_ctx, &user, user_in); - if (user_byte_len == (ssize_t)-1) { - DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); - talloc_free(mem_ctx); - return False; - } - - domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in); - if (domain_byte_len == (ssize_t)-1) { - DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); - talloc_free(mem_ctx); - return False; - } - - SMB_ASSERT(user_byte_len >= 2); - SMB_ASSERT(domain_byte_len >= 2); - - /* We don't want null termination */ - user_byte_len = user_byte_len - 2; - domain_byte_len = domain_byte_len - 2; - - hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update(user, user_byte_len, &ctx); - hmac_md5_update(domain, domain_byte_len, &ctx); - hmac_md5_final(kr_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, user, user_byte_len); - dump_data(100, domain, domain_byte_len); - dump_data(100, owf, 16); - dump_data(100, kr_buf, 16); -#endif - - talloc_free(mem_ctx); - return True; -} - -/* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) -{ - uint8_t p21[21]; - - ZERO_STRUCT(p21); - - memcpy(p21, passwd, 16); - E_P24(p21, c8, p24); -} - -/* Does the NT MD4 hash then des encryption. */ - -void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) -{ - uint8_t p21[21]; - - memset(p21,'\0',21); - - E_md4hash(passwd, p21); - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif -} - -/* Does the md5 encryption from the Key Response for NTLMv2. */ -void SMBOWFencrypt_ntv2(const uint8_t kr[16], - const DATA_BLOB *srv_chal, - const DATA_BLOB *smbcli_chal, - uint8_t resp_buf[16]) -{ - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); - hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx); - hmac_md5_final(resp_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n")); - dump_data(100, srv_chal->data, srv_chal->length); - dump_data(100, smbcli_chal->data, smbcli_chal->length); - dump_data(100, resp_buf, 16); -#endif -} - -void SMBsesskeygen_ntv2(const uint8_t kr[16], - const uint8_t * nt_resp, uint8_t sess_key[16]) -{ - /* a very nice, 128 bit, variable session key */ - - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(nt_resp, 16, &ctx); - hmac_md5_final((uint8_t *)sess_key, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_ntv2:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) -{ - /* yes, this session key does not change - yes, this - is a problem - but it is 128 bits */ - - mdfour((uint8_t *)sess_key, kr, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_ntv1:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], - const uint8_t lm_resp[24], /* only uses 8 */ - uint8_t sess_key[16]) -{ - /* Calculate the LM session key (effective length 40 bits, - but changes with each session) */ - uint8_t p24[24]; - uint8_t p21[21]; - - memset(p21,'\0',21); - memcpy(p21, lm_hash, 8); - memset(p21 + 8, 0xbd, 8); - - E_P24(p21, lm_resp, p24); - - memcpy(sess_key, p24, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n")); - dump_data(100, sess_key, 16); -#endif -} - -DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, - const char *hostname, - const char *domain) -{ - DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - - msrpc_gen(mem_ctx, &names_blob, "aaa", - NTLMSSP_NAME_TYPE_DOMAIN, domain, - NTLMSSP_NAME_TYPE_SERVER, hostname, - 0, ""); - return names_blob; -} - -static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) -{ - uint8_t client_chal[8]; - DATA_BLOB response = data_blob(NULL, 0); - uint8_t long_date[8]; - NTTIME nttime; - - unix_to_nt_time(&nttime, time(NULL)); - - generate_random_buffer(client_chal, sizeof(client_chal)); - - push_nttime(long_date, 0, nttime); - - /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - - msrpc_gen(mem_ctx, &response, "ddbbdb", - 0x00000101, /* Header */ - 0, /* 'Reserved' */ - long_date, 8, /* Timestamp */ - client_chal, 8, /* client challenge */ - 0, /* Unknown */ - names_blob->data, names_blob->length); /* End of name list */ - - return response; -} - -static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob) -{ - uint8_t ntlmv2_response[16]; - DATA_BLOB ntlmv2_client_data; - DATA_BLOB final_response; - - TALLOC_CTX *mem_ctx = talloc_init("NTLMv2_generate_response internal context"); - - if (!mem_ctx) { - return data_blob(NULL, 0); - } - - /* NTLMv2 */ - /* generate some data to pass into the response function - including - the hostname and domain name of the server */ - ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - - final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); - - memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - - memcpy(final_response.data+sizeof(ntlmv2_response), - ntlmv2_client_data.data, ntlmv2_client_data.length); - - talloc_free(mem_ctx); - - return final_response; -} - -static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], - const DATA_BLOB *server_chal) -{ - uint8_t lmv2_response[16]; - DATA_BLOB lmv2_client_data = data_blob(NULL, 8); - DATA_BLOB final_response = data_blob(NULL, 24); - - /* LMv2 */ - /* client-supplied random data */ - generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); - memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); - - /* after the first 16 bytes is the random data we generated above, - so the server can verify us with it */ - memcpy(final_response.data+sizeof(lmv2_response), - lmv2_client_data.data, lmv2_client_data.length); - - data_blob_free(&lmv2_client_data); - - return final_response; -} - -BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t nt_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) -{ - uint8_t ntlm_v2_hash[16]; - - /* We don't use the NT# directly. Instead we use it mashed up with - the username and domain. - This prevents username swapping during the auth exchange - */ - if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { - return False; - } - - if (nt_response) { - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, - names_blob); - if (user_session_key) { - *user_session_key = data_blob(NULL, 16); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); - } - } - - /* LMv2 */ - - if (lm_response) { - *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); - if (lm_session_key) { - *lm_session_key = data_blob(NULL, 16); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of lm_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); - } - } - - return True; -} - -BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) -{ - uint8_t nt_hash[16]; - E_md4hash(password, nt_hash); - - return SMBNTLMv2encrypt_hash(user, domain, nt_hash, server_chal, names_blob, - lm_response, nt_response, lm_session_key, user_session_key); -} - -/*********************************************************** - encode a password buffer with a unicode password. The buffer - is filled with random data to make it harder to attack. -************************************************************/ -BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) -{ - uint8_t new_pw[512]; - size_t new_pw_len; - - new_pw_len = push_string(new_pw, - password, - sizeof(new_pw), string_flags); - - memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - - generate_random_buffer(buffer, 512 - new_pw_len); - - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ - SIVAL(buffer, 512, new_pw_len); - ZERO_STRUCT(new_pw); - return True; -} - - -/*********************************************************** - decode a password buffer - *new_pw_len is the length in bytes of the possibly mulitbyte - returned password including termination. -************************************************************/ -BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32_t *new_pw_len, - int string_flags) -{ - int byte_len=0; - - /* - Warning !!! : This function is called from some rpc call. - The password IN the buffer may be a UNICODE string. - The password IN new_pwrd is an ASCII string - If you reuse that code somewhere else check first. - */ - - /* The length of the new password is in the last 4 bytes of the data buffer. */ - - byte_len = IVAL(in_buffer, 512); - -#ifdef DEBUG_PASSWORD - dump_data(100, in_buffer, 516); -#endif - - /* Password cannot be longer than the size of the password buffer */ - if ( (byte_len < 0) || (byte_len > 512)) { - return False; - } - - /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, - byte_len, string_flags); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len); - DEBUG(100,("multibyte len:%d\n", *new_pw_len)); - DEBUG(100,("original char len:%d\n", byte_len/2)); -#endif - - return True; -} -- cgit From ea2209e3db4dc1a6d455e01d5339b0b981c361b1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Jan 2005 04:04:38 +0000 Subject: r5092: Add a bit more const - moving it further into the LDB layer. Andrew Bartlett (This used to be commit ffad9b22be595279b247fa72d51145830fecbb06) --- source4/libcli/auth/credentials.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index ffefcc0305..7c3c4379d1 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -30,8 +30,8 @@ struct creds_CredentialState { struct netr_Credential client; struct netr_Credential server; uint16_t secure_channel_type; - char *computer_name; - char *account_name; + const char *computer_name; + const char *account_name; }; /* for the timebeing, use the same neg flags as Samba3. */ -- cgit From a0ab1f7afda62964d480af9dc26e60a38d1350e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 07:22:16 +0000 Subject: r5107: moved the horrible ldap socket code, and the even worse asn1-tied-to-blocking-sockets code into the ldap client and torture suite, and out of the generic libs, so nobody else is tempted to use it for any new code. (This used to be commit 39d1ced21baeca40d1fca62ba65243ca8f15757e) --- source4/libcli/ldap/ldap_client.c | 240 ++++++++++++++++++++++++++++++++++++++ source4/libcli/util/asn1.c | 61 ---------- 2 files changed, 240 insertions(+), 61 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c9e81ac28f..73099ec1be 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -29,6 +29,246 @@ #include "asn_1.h" #include "dlinklist.h" + + +/**************************************************************************** + Check the timeout. +****************************************************************************/ +static BOOL timeout_until(struct timeval *timeout, + const struct timeval *endtime) +{ + struct timeval now; + + GetTimeOfDay(&now); + + if ((now.tv_sec > endtime->tv_sec) || + ((now.tv_sec == endtime->tv_sec) && + (now.tv_usec > endtime->tv_usec))) + return False; + + timeout->tv_sec = endtime->tv_sec - now.tv_sec; + timeout->tv_usec = endtime->tv_usec - now.tv_usec; + return True; +} + + +/**************************************************************************** + Read data from the client, reading exactly N bytes, with timeout. +****************************************************************************/ +static ssize_t read_data_until(int fd,char *buffer,size_t N, + const struct timeval *endtime) +{ + ssize_t ret; + size_t total=0; + + while (total < N) { + + if (endtime != NULL) { + fd_set r_fds; + struct timeval timeout; + int res; + + FD_ZERO(&r_fds); + FD_SET(fd, &r_fds); + + if (!timeout_until(&timeout, endtime)) + return -1; + + res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout); + if (res <= 0) + return -1; + } + + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + return 0; + } + + if (ret == -1) { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + return -1; + } + total += ret; + } + return (ssize_t)total; +} + + +/**************************************************************************** + Write data to a fd with timeout. +****************************************************************************/ +static ssize_t write_data_until(int fd,char *buffer,size_t N, + const struct timeval *endtime) +{ + size_t total=0; + ssize_t ret; + + while (total < N) { + + if (endtime != NULL) { + fd_set w_fds; + struct timeval timeout; + int res; + + FD_ZERO(&w_fds); + FD_SET(fd, &w_fds); + + if (!timeout_until(&timeout, endtime)) + return -1; + + res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout); + if (res <= 0) + return -1; + } + + ret = sys_write(fd,buffer + total,N - total); + + if (ret == -1) { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t)total; +} + + + +static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data, + const struct timeval *endtime) +{ + if (read_data_until(sock, result, 1, endtime) != 1) + return False; + + return asn1_write(data, result, 1); +} + +/* Read a complete ASN sequence (ie LDAP result) from a socket */ +static BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, + const struct timeval *endtime) +{ + uint8_t b; + size_t len; + char *buf; + + ZERO_STRUCTP(data); + + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + + if (b != 0x30) { + data->has_error = True; + return False; + } + + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + + if (b & 0x80) { + int n = b & 0x7f; + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + len = b; + while (n > 1) { + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + len = (len<<8) | b; + n--; + } + } else { + len = b; + } + + buf = talloc_size(NULL, len); + if (buf == NULL) + return False; + + if (read_data_until(sock, buf, len, endtime) != len) + return False; + + if (!asn1_write(data, buf, len)) + return False; + + talloc_free(buf); + + data->ofs = 0; + + return True; +} + + + +/**************************************************************************** + create an outgoing socket. timeout is in milliseconds. + **************************************************************************/ +static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeout) +{ + struct sockaddr_in sock_out; + int res,ret; + int connect_loop = 250; /* 250 milliseconds */ + int loops = (timeout) / connect_loop; + + /* create a socket to write to */ + res = socket(PF_INET, type, 0); + if (res == -1) + { DEBUG(0,("socket error\n")); return -1; } + + if (type != SOCK_STREAM) return(res); + + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); + + sock_out.sin_port = htons( port ); + sock_out.sin_family = PF_INET; + + /* set it non-blocking */ + set_blocking(res,False); + + DEBUG(3,("Connecting to %s at port %d\n", sys_inet_ntoa(*addr),port)); + + /* and connect it to the destination */ +connect_again: + ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN) && loops--) { + msleep(connect_loop); + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN)) { + DEBUG(1,("timeout connecting to %s:%d\n", sys_inet_ntoa(*addr),port)); + close(res); + return -1; + } + +#ifdef EISCONN + if (ret < 0 && errno == EISCONN) { + errno = 0; + ret = 0; + } +#endif + + if (ret < 0) { + DEBUG(2,("error connecting to %s:%d (%s)\n", + sys_inet_ntoa(*addr),port,strerror(errno))); + close(res); + return -1; + } + + /* set it blocking again */ + set_blocking(res,True); + + return res; +} + #if 0 static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn, const char *base, diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 550450fea7..1124cc1701 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -379,67 +379,6 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) return !data->has_error; } -static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data, - const struct timeval *endtime) -{ - if (read_data_until(sock, result, 1, endtime) != 1) - return False; - - return asn1_write(data, result, 1); -} - -/* Read a complete ASN sequence (ie LDAP result) from a socket */ -BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, - const struct timeval *endtime) -{ - uint8_t b; - size_t len; - char *buf; - - ZERO_STRUCTP(data); - - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - - if (b != 0x30) { - data->has_error = True; - return False; - } - - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - - if (b & 0x80) { - int n = b & 0x7f; - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - len = b; - while (n > 1) { - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - len = (len<<8) | b; - n--; - } - } else { - len = b; - } - - buf = talloc_size(NULL, len); - if (buf == NULL) - return False; - - if (read_data_until(sock, buf, len, endtime) != len) - return False; - - if (!asn1_write(data, buf, len)) - return False; - - talloc_free(buf); - - data->ofs = 0; - - return True; -} /* Get the length to be expected in buf */ BOOL asn1_object_length(uint8_t *buf, size_t buf_length, -- cgit From c7ded5ab0accc54a28df4d43cb923e6c808ff347 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 10:24:36 +0000 Subject: r5108: the beginnings of a nbtd server for Samba4. Currently just displays the packets it receives, but it at least shows how the server structure will work. To implement it I extended the libcli/nbt/ library to allow for an incoming packet handler to be registered. That allows the nbt client library to be used for low level processing of the nbtd server packets. Other changes: - made the socket library always set SO_REUSEADDR when binding to an interface, to ensure that restarts of a server don't have to wait for a couple of minutes. - made the nbt port configurable. Defaults to 137, but other ports will be useful for testing. (This used to be commit 2fedca6adfd4df9e85cc86896dfa79630777a917) --- source4/libcli/nbt/libnbt.h | 8 ++++++++ source4/libcli/nbt/namequery.c | 4 ++-- source4/libcli/nbt/nbtsocket.c | 23 ++++++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index a7788f791b..82069f0390 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -90,6 +90,14 @@ struct nbt_name_socket { /* how many requests are waiting for a reply */ uint16_t num_pending; + + /* what to do with incoming request packets */ + struct { + void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, + const char *, int ); + void *private; + } incoming; + }; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 05d5e55491..6f549e6241 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -52,7 +52,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_NETBIOS; packet->questions[0].question_class = NBT_QCLASS_IP; - req = nbt_name_request_send(nbtsock, io->in.dest_addr, NBT_NAME_SERVICE_PORT, packet, + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; @@ -142,7 +142,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_STATUS; packet->questions[0].question_class = NBT_QCLASS_IP; - req = nbt_name_request_send(nbtsock, io->in.dest_addr, NBT_NAME_SERVICE_PORT, packet, + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1eea77d356..f1964b7158 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -51,7 +51,8 @@ static int nbt_name_request_destructor(void *ptr) if (req->nbtsock->send_queue == NULL) { req->nbtsock->fde->flags &= ~EVENT_FD_WRITE; } - if (req->nbtsock->num_pending == 0) { + if (req->nbtsock->num_pending == 0 && + req->nbtsock->incoming.handler == NULL) { req->nbtsock->fde->flags &= ~EVENT_FD_READ; } return 0; @@ -170,6 +171,9 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } if (!(packet->operation & NBT_FLAG_REPLY)) { + if (nbtsock->incoming.handler) { + nbtsock->incoming.handler(nbtsock, packet, src_addr, src_port); + } talloc_free(tmp_ctx); return; } @@ -375,3 +379,20 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) } return req->status; } + + +/* + setup a handler for incoming requests +*/ +NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, + void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, + const char *, int ), + void *private) +{ + nbtsock->incoming.handler = handler; + nbtsock->incoming.private = private; + nbtsock->fde->flags |= EVENT_FD_READ; + socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); + return NT_STATUS_OK; +} + -- cgit From 414f6c80b22b128c25d947d62f6b5d1ec13091b6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 01:57:58 +0000 Subject: r5114: the nbtd task can now act as a basic B-node server. It registers its names on the network and answers name queries. Lots of details are still missing, but at least this now means you don't need a Samba3 nmbd to use Samba4. missing pieces include: - name registrations should be "shout 3 times, then demand" - no WINS server yet - no master browser code (This used to be commit d7d31fdc6670f026f96b50e51a4de19f0b920e5b) --- source4/libcli/config.mk | 3 +- source4/libcli/nbt/libnbt.h | 23 ++++++- source4/libcli/nbt/namequery.c | 27 +++++--- source4/libcli/nbt/nameregister.c | 140 ++++++++++++++++++++++++++++++++++++++ source4/libcli/nbt/nbtsocket.c | 52 ++++++++++++-- 5 files changed, 228 insertions(+), 17 deletions(-) create mode 100644 source4/libcli/nbt/nameregister.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 06b46c6f18..c801524c2f 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -24,7 +24,8 @@ ADD_OBJ_FILES = \ ADD_OBJ_FILES = \ libcli/nbt/nbtname.o \ libcli/nbt/nbtsocket.o \ - libcli/nbt/namequery.o + libcli/nbt/namequery.o \ + libcli/nbt/nameregister.o REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET [SUBSYSTEM::LIBCLI_RESOLVE] diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 82069f0390..3bfffa25d0 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -113,7 +113,8 @@ struct nbt_name_query { struct { const char *reply_from; struct nbt_name name; - const char *reply_addr; + int16_t num_addrs; + const char **reply_addrs; } out; }; @@ -130,3 +131,23 @@ struct nbt_name_status { struct nbt_rdata_status status; } out; }; + +/* a name registration request */ +struct nbt_name_register { + struct { + struct nbt_name name; + const char *dest_addr; + const char *address; + uint16_t nb_flags; + BOOL register_demand; + BOOL broadcast; + uint32_t ttl; + int timeout; /* in seconds */ + } in; + struct { + const char *reply_from; + struct nbt_name name; + const char *reply_addr; + uint8_t rcode; + } out; +}; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 6f549e6241..f6744e9f14 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -66,7 +66,7 @@ failed: } /* - wait for a name query replu + wait for a name query reply */ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_query *io) @@ -75,6 +75,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, struct nbt_name_packet *packet; const char *addr; struct in_addr in; + int i; status = nbt_name_request_recv(req); if (!NT_STATUS_IS_OK(status) || @@ -94,13 +95,23 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } io->out.name = packet->answers[0].name; - in.s_addr = htonl(packet->answers[0].rdata.netbios.ipaddr); - addr = inet_ntoa(in); - if (addr == NULL) { + io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6; + io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs); + if (io->out.reply_addrs == NULL) { talloc_free(req); return NT_STATUS_NO_MEMORY; } - io->out.reply_addr = talloc_strdup(mem_ctx, addr); + + for (i=0;iout.num_addrs;i++) { + in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[i].ipaddr); + addr = inet_ntoa(in); + if (addr == NULL) { + talloc_free(req); + return NT_STATUS_NO_MEMORY; + } + io->out.reply_addrs[i] = talloc_strdup(mem_ctx, addr); + } + talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); @@ -110,7 +121,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } /* - wait for a name query replu + wait for a name query reply */ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_query *io) @@ -156,7 +167,7 @@ failed: } /* - wait for a name status replu + wait for a name status reply */ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_status *io) @@ -199,7 +210,7 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, } /* - wait for a name status replu + wait for a name status reply */ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_status *io) diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c new file mode 100644 index 0000000000..2d1e964977 --- /dev/null +++ b/source4/libcli/nbt/nameregister.c @@ -0,0 +1,140 @@ +/* + Unix SMB/CIFS implementation. + + send out a name registration request + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/nbt/libnbt.h" +#include "system/network.h" + +/* + send a nbt name registration request +*/ +struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, + struct nbt_name_register *io) +{ + struct nbt_name_request *req; + struct nbt_name_packet *packet; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return NULL; + + packet->qdcount = 1; + packet->arcount = 1; + packet->operation = NBT_OPCODE_REGISTER; + if (io->in.broadcast) { + packet->operation |= NBT_FLAG_BROADCAST; + } + if (io->in.register_demand) { + packet->operation |= NBT_FLAG_RECURSION_DESIRED; + } + + packet->questions = talloc_array(packet, struct nbt_name_question, 1); + if (packet->questions == NULL) goto failed; + + packet->questions[0].name = io->in.name; + packet->questions[0].question_type = NBT_QTYPE_NETBIOS; + packet->questions[0].question_class = NBT_QCLASS_IP; + + packet->additional = talloc_array(packet, struct nbt_res_rec, 1); + if (packet->additional == NULL) goto failed; + + packet->additional[0].name = io->in.name; + packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; + packet->additional[0].rr_class = NBT_QCLASS_IP; + packet->additional[0].ttl = io->in.ttl; + packet->additional[0].rdata.netbios.length = 6; + packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, + struct nbt_rdata_address, 1); + if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; + packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; + packet->additional[0].rdata.netbios.addresses[0].ipaddr = htonl(inet_addr(io->in.address)); + + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + timeval_current_ofs(io->in.timeout, 0), False); + if (req == NULL) goto failed; + + talloc_steal(req, packet); + + return req; + +failed: + talloc_free(packet); + return NULL; +} + +/* + wait for a registration reply +*/ +NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_register *io) +{ + NTSTATUS status; + struct nbt_name_packet *packet; + const char *addr; + struct in_addr in; + + status = nbt_name_request_recv(req); + if (!NT_STATUS_IS_OK(status) || + req->num_replies == 0) { + talloc_free(req); + return status; + } + + packet = req->replies[0].packet; + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + + if (packet->ancount != 1 || + packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || + packet->answers[0].rr_class != NBT_QCLASS_IP) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + io->out.rcode = packet->operation & NBT_RCODE; + io->out.name = packet->answers[0].name; + if (packet->answers[0].rdata.netbios.length < 6) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr); + addr = inet_ntoa(in); + if (addr == NULL) { + talloc_free(req); + return NT_STATUS_NO_MEMORY; + } + io->out.reply_addr = talloc_strdup(mem_ctx, addr); + talloc_steal(mem_ctx, io->out.name.name); + talloc_steal(mem_ctx, io->out.name.scope); + + talloc_free(req); + + return NT_STATUS_OK; +} + +/* + synchronous name registration request +*/ +NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_register *io) +{ + struct nbt_name_request *req = nbt_name_register_send(nbtsock, io); + return nbt_name_register_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index f1964b7158..90b4f6e029 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -41,7 +41,8 @@ static int nbt_name_request_destructor(void *ptr) if (req->state == NBT_REQUEST_WAIT) { req->nbtsock->num_pending--; } - if (req->request->name_trn_id != 0) { + if (req->request->name_trn_id != 0 && + !(req->request->operation & NBT_FLAG_REPLY)) { idr_remove(req->nbtsock->idr, req->request->name_trn_id); req->request->name_trn_id = 0; } @@ -65,7 +66,7 @@ static int nbt_name_request_destructor(void *ptr) static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) { struct nbt_name_request *req = nbtsock->send_queue; - TALLOC_CTX *tmp_ctx = talloc_new(req); + TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); NTSTATUS status; while ((req = nbtsock->send_queue)) { @@ -98,9 +99,13 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) } DLIST_REMOVE(nbtsock->send_queue, req); - req->state = NBT_REQUEST_WAIT; - nbtsock->fde->flags |= EVENT_FD_READ; - nbtsock->num_pending++; + if (req->request->operation & NBT_FLAG_REPLY) { + talloc_free(req); + } else { + req->state = NBT_REQUEST_WAIT; + nbtsock->fde->flags |= EVENT_FD_READ; + nbtsock->num_pending++; + } } nbtsock->fde->flags &= ~EVENT_FD_WRITE; @@ -317,7 +322,8 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, if (req == NULL) goto failed; req->nbtsock = nbtsock; - req->dest_addr = dest_addr; + req->dest_addr = talloc_strdup(req, dest_addr); + if (req->dest_addr == NULL) goto failed; req->dest_port = dest_port; req->request = talloc_reference(req, request); req->allow_multiple_replies = allow_multiple_replies; @@ -361,6 +367,39 @@ failed: return NULL; } + +/* + send off a nbt name reply +*/ +NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, + const char *dest_addr, int dest_port, + struct nbt_name_packet *request) +{ + struct nbt_name_request *req; + + req = talloc_zero(nbtsock, struct nbt_name_request); + NT_STATUS_HAVE_NO_MEMORY(req); + + req->nbtsock = nbtsock; + req->dest_addr = talloc_strdup(req, dest_addr); + if (req->dest_addr == NULL) goto failed; + req->dest_port = dest_port; + req->request = talloc_reference(req, request); + req->state = NBT_REQUEST_SEND; + + talloc_set_destructor(req, nbt_name_request_destructor); + + DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); + + nbtsock->fde->flags |= EVENT_FD_WRITE; + + return NT_STATUS_OK; + +failed: + talloc_free(req); + return NT_STATUS_NO_MEMORY; +} + /* wait for a nbt request to complete */ @@ -392,7 +431,6 @@ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, nbtsock->incoming.handler = handler; nbtsock->incoming.private = private; nbtsock->fde->flags |= EVENT_FD_READ; - socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); return NT_STATUS_OK; } -- cgit From 5269fb13a92850b5f22bf9f7640568d5946a43d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 02:50:49 +0000 Subject: r5116: fixed build of the nbtlist code (This used to be commit 506e1e823cd3f652a793db9f4c43147d298b9b8b) --- source4/libcli/resolve/nbtlist.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 036e983fd2..08dc90c39d 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -62,8 +62,13 @@ static void nbtlist_handler(struct nbt_name_request *req) if (!NT_STATUS_IS_OK(c->status)) { c->state = SMBCLI_REQUEST_ERROR; } else { - c->state = SMBCLI_REQUEST_DONE; - state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr); + if (state->io_queries[i].out.num_addrs < 1) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } else { + c->state = SMBCLI_REQUEST_DONE; + state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addrs[0]); + } } done: -- cgit From 5e6082b4b0e8d47d8634cf1b0c5bb460d0b6dbd1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 03:14:15 +0000 Subject: r5117: used a composite function to add 4 stage name registration. We send 3 broadcast name registration demands per name per interface at 1 second intervals, then send a name overwrite request and demand. Any name conflict replies are reported. (This used to be commit d656fba6f1a2e9d8c03893741327e5fb59c5271e) --- source4/libcli/config.mk | 8 ++- source4/libcli/nbt/libnbt.h | 11 ++++ source4/libcli/nbt/nameregister.c | 134 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c801524c2f..d3aa4ff5ab 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -11,14 +11,18 @@ ADD_OBJ_FILES = libcli/util/asn1.o \ ADD_OBJ_FILES = libcli/util/clilsa.o REQUIRED_SUBSYSTEMS = RPC_NDR_LSA +[SUBSYSTEM::LIBCLI_COMPOSITE_BASE] +ADD_OBJ_FILES = \ + libcli/composite/composite.o + [SUBSYSTEM::LIBCLI_COMPOSITE] ADD_OBJ_FILES = \ - libcli/composite/composite.o \ libcli/composite/loadfile.o \ libcli/composite/savefile.o \ libcli/composite/connect.o \ libcli/composite/sesssetup.o \ libcli/composite/fetchfile.o +REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE_BASE [SUBSYSTEM::LIBCLI_NBT] ADD_OBJ_FILES = \ @@ -26,7 +30,7 @@ ADD_OBJ_FILES = \ libcli/nbt/nbtsocket.o \ libcli/nbt/namequery.o \ libcli/nbt/nameregister.o -REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET +REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 3bfffa25d0..a3630e2a12 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -151,3 +151,14 @@ struct nbt_name_register { uint8_t rcode; } out; }; + +/* a send 3 times then demand name broadcast name registration */ +struct nbt_name_register_bcast { + struct { + struct nbt_name name; + const char *dest_addr; + const char *address; + uint16_t nb_flags; + uint32_t ttl; + } in; +}; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 2d1e964977..6d4938cd19 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -22,6 +22,8 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" #include "system/network.h" /* @@ -138,3 +140,135 @@ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, struct nbt_name_request *req = nbt_name_register_send(nbtsock, io); return nbt_name_register_recv(req, mem_ctx, io); } + + +/* + a 4 step broadcast registration. 3 lots of name registration requests, followed by + a name registration demand +*/ +struct register_bcast_state { + struct nbt_name_socket *nbtsock; + struct nbt_name_register *io; + int num_sends; + struct nbt_name_request *req; +}; + + +/* + state handler for 4 stage name registration +*/ +static void name_register_handler(struct nbt_name_request *req) +{ + struct smbcli_composite *c = talloc_get_type(req->async.private, struct smbcli_composite); + struct register_bcast_state *state = talloc_get_type(c->private, struct register_bcast_state); + NTSTATUS status; + + status = nbt_name_register_recv(state->req, state, state->io); + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + /* the registration timed out - good, send the next one */ + state->num_sends++; + if (state->num_sends == 4) { + /* all done */ + c->state = SMBCLI_REQUEST_DONE; + c->status = NT_STATUS_OK; + goto done; + } + if (state->num_sends == 3) { + state->io->in.register_demand = True; + } + state->req = nbt_name_register_send(state->nbtsock, state->io); + if (state->req == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } else { + state->req->async.fn = name_register_handler; + state->req->async.private = c; + } + } else if (!NT_STATUS_IS_OK(status)) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = status; + } else { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_CONFLICTING_ADDRESSES; + DEBUG(3,("Name registration conflict from %s for %s<%02x> with ip %s - rcode %d\n", + state->io->out.reply_from, + state->io->out.name.name, + state->io->out.name.type, + state->io->out.reply_addr, + state->io->out.rcode)); + } + +done: + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); + } +} + +/* + the async send call for a 4 stage name registration +*/ +struct smbcli_composite *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, + struct nbt_name_register_bcast *io) +{ + struct smbcli_composite *c; + struct register_bcast_state *state; + + c = talloc_zero(nbtsock, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct register_bcast_state); + if (state == NULL) goto failed; + + state->io = talloc(state, struct nbt_name_register); + if (state->io == NULL) goto failed; + + state->io->in.name = io->in.name; + state->io->in.dest_addr = io->in.dest_addr; + state->io->in.address = io->in.address; + state->io->in.nb_flags = io->in.nb_flags; + state->io->in.register_demand = False; + state->io->in.broadcast = True; + state->io->in.ttl = io->in.ttl; + state->io->in.timeout = 1; + + state->num_sends = 0; + state->nbtsock = nbtsock; + + state->req = nbt_name_register_send(nbtsock, state->io); + if (state->req == NULL) goto failed; + + state->req->async.fn = name_register_handler; + state->req->async.private = c; + + c->private = state; + c->state = SMBCLI_REQUEST_SEND; + c->event_ctx = nbtsock->event_ctx; + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + broadcast 4 part name register - recv +*/ +NTSTATUS nbt_name_register_bcast_recv(struct smbcli_composite *c) +{ + NTSTATUS status; + status = smb_composite_wait(c); + talloc_free(c); + return status; +} + +/* + broadcast 4 part name register - sync interface +*/ +NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock, + struct nbt_name_register_bcast *io) +{ + struct smbcli_composite *c = nbt_name_register_bcast_send(nbtsock, io); + return nbt_name_register_bcast_recv(c); +} -- cgit From 0700676da69a68066e0a2f7541ffa0d3bf956616 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 04:53:53 +0000 Subject: r5120: encode outgoing nbt packets when queueing them rather than in the send event code, as elements of the callers packet structure could go away while the queue is pending (if for example a name was de-registered while a packet referencing that name is queued) (This used to be commit 6726f15cf44388e5787eec223a8c9778110a508f) --- source4/libcli/nbt/libnbt.h | 9 +++++- source4/libcli/nbt/nbtsocket.c | 66 +++++++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 30 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index a3630e2a12..35eff9961c 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -51,7 +51,14 @@ struct nbt_name_request { /* the timeout event */ struct timed_event *te; - struct nbt_name_packet *request; + /* the name transaction id */ + uint16_t name_trn_id; + + /* is it a reply? */ + BOOL is_reply; + + /* the encoded request */ + DATA_BLOB encoded; /* shall we allow multiple replies? */ BOOL allow_multiple_replies; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 90b4f6e029..3f16bf6921 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -41,10 +41,9 @@ static int nbt_name_request_destructor(void *ptr) if (req->state == NBT_REQUEST_WAIT) { req->nbtsock->num_pending--; } - if (req->request->name_trn_id != 0 && - !(req->request->operation & NBT_FLAG_REPLY)) { - idr_remove(req->nbtsock->idr, req->request->name_trn_id); - req->request->name_trn_id = 0; + if (req->name_trn_id != 0 && !req->is_reply) { + idr_remove(req->nbtsock->idr, req->name_trn_id); + req->name_trn_id = 0; } if (req->te) { req->te = NULL; @@ -70,26 +69,10 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) NTSTATUS status; while ((req = nbtsock->send_queue)) { - DATA_BLOB blob; size_t len; - if (DEBUGLVL(10)) { - DEBUG(10,("Sending nbt packet to %s:%d\n", - req->dest_addr, req->dest_port)); - NDR_PRINT_DEBUG(nbt_name_packet, req->request); - } - - status = ndr_push_struct_blob(&blob, tmp_ctx, req->request, - (ndr_push_flags_fn_t) - ndr_push_nbt_name_packet); - if (!NT_STATUS_IS_OK(status)) goto failed; - - if (req->request->operation & NBT_FLAG_BROADCAST) { - socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); - } - - len = blob.length; - status = socket_sendto(nbtsock->sock, &blob, &len, 0, + len = req->encoded.length; + status = socket_sendto(nbtsock->sock, &req->encoded, &len, 0, req->dest_addr, req->dest_port); if (NT_STATUS_IS_ERR(status)) goto failed; @@ -99,7 +82,7 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) } DLIST_REMOVE(nbtsock->send_queue, req); - if (req->request->operation & NBT_FLAG_REPLY) { + if (req->is_reply) { talloc_free(req); } else { req->state = NBT_REQUEST_WAIT; @@ -270,6 +253,7 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, nbtsock->send_queue = NULL; nbtsock->num_pending = 0; + nbtsock->incoming.handler = NULL; fde.fd = socket_get_fd(nbtsock->sock); fde.flags = 0; @@ -317,6 +301,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, struct nbt_name_request *req; struct timed_event te; int id; + NTSTATUS status; req = talloc_zero(nbtsock, struct nbt_name_request); if (req == NULL) goto failed; @@ -325,13 +310,13 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, req->dest_addr = talloc_strdup(req, dest_addr); if (req->dest_addr == NULL) goto failed; req->dest_port = dest_port; - req->request = talloc_reference(req, request); req->allow_multiple_replies = allow_multiple_replies; req->state = NBT_REQUEST_SEND; + req->is_reply = False; /* we select a random transaction id unless the user supplied one */ - if (req->request->name_trn_id == 0) { - req->request->name_trn_id = generate_random() % UINT16_MAX; + if (request->name_trn_id == 0) { + request->name_trn_id = generate_random() % UINT16_MAX; } /* choose the next available transaction id >= the one asked for. @@ -340,14 +325,15 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, to ID guessing, but this at least makes accidential collisions less likely */ id = idr_get_new_above(req->nbtsock->idr, req, - req->request->name_trn_id, UINT16_MAX); + request->name_trn_id, UINT16_MAX); if (id == -1) { id = idr_get_new_above(req->nbtsock->idr, req, 1+(generate_random()%(UINT16_MAX/2)), UINT16_MAX); } if (id == -1) goto failed; - req->request->name_trn_id = id; + request->name_trn_id = id; + req->name_trn_id = id; te.next_event = timeout; te.handler = nbt_name_socket_timeout; @@ -356,8 +342,22 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, talloc_set_destructor(req, nbt_name_request_destructor); + status = ndr_push_struct_blob(&req->encoded, req, request, + (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); + if (!NT_STATUS_IS_OK(status)) goto failed; + DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); + if (request->operation & NBT_FLAG_BROADCAST) { + socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); + } + + if (DEBUGLVL(10)) { + DEBUG(10,("Queueing nbt packet to %s:%d\n", + req->dest_addr, req->dest_port)); + NDR_PRINT_DEBUG(nbt_name_packet, request); + } + nbtsock->fde->flags |= EVENT_FD_WRITE; return req; @@ -376,6 +376,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request) { struct nbt_name_request *req; + NTSTATUS status; req = talloc_zero(nbtsock, struct nbt_name_request); NT_STATUS_HAVE_NO_MEMORY(req); @@ -384,11 +385,18 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, req->dest_addr = talloc_strdup(req, dest_addr); if (req->dest_addr == NULL) goto failed; req->dest_port = dest_port; - req->request = talloc_reference(req, request); req->state = NBT_REQUEST_SEND; + req->is_reply = True; talloc_set_destructor(req, nbt_name_request_destructor); + status = ndr_push_struct_blob(&req->encoded, req, request, + (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return status; + } + DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); nbtsock->fde->flags |= EVENT_FD_WRITE; -- cgit From 2e953b967ae181be10fcdff2595daf36d903c3b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 06:55:25 +0000 Subject: r5121: added periodic name refresh requests for all our registered names, reporting any name conflicts (This used to be commit 69e6a1cd4bac665debb10601d1a3ddc0ae86e779) --- source4/libcli/config.mk | 3 +- source4/libcli/nbt/libnbt.h | 20 ++++++ source4/libcli/nbt/namequery.c | 6 +- source4/libcli/nbt/namerefresh.c | 138 ++++++++++++++++++++++++++++++++++++++ source4/libcli/nbt/nameregister.c | 3 +- 5 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 source4/libcli/nbt/namerefresh.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index d3aa4ff5ab..8458eb780d 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -29,7 +29,8 @@ ADD_OBJ_FILES = \ libcli/nbt/nbtname.o \ libcli/nbt/nbtsocket.o \ libcli/nbt/namequery.o \ - libcli/nbt/nameregister.o + libcli/nbt/nameregister.o \ + libcli/nbt/namerefresh.o REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE [SUBSYSTEM::LIBCLI_RESOLVE] diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 35eff9961c..114d6d3b92 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -169,3 +169,23 @@ struct nbt_name_register_bcast { uint32_t ttl; } in; }; + + +/* a name refresh request */ +struct nbt_name_refresh { + struct { + struct nbt_name name; + const char *dest_addr; + const char *address; + uint16_t nb_flags; + BOOL broadcast; + uint32_t ttl; + int timeout; /* in seconds */ + } in; + struct { + const char *reply_from; + struct nbt_name name; + const char *reply_addr; + uint8_t rcode; + } out; +}; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index f6744e9f14..36fbfc8dd0 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -56,8 +56,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; - talloc_steal(req, packet); - + talloc_free(packet); return req; failed: @@ -157,8 +156,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; - talloc_steal(req, packet); - + talloc_free(packet); return req; failed: diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c new file mode 100644 index 0000000000..47fcae4f7c --- /dev/null +++ b/source4/libcli/nbt/namerefresh.c @@ -0,0 +1,138 @@ +/* + Unix SMB/CIFS implementation. + + send out a name refresh request + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/nbt/libnbt.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "system/network.h" + +/* + send a nbt name refresh request +*/ +struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, + struct nbt_name_refresh *io) +{ + struct nbt_name_request *req; + struct nbt_name_packet *packet; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return NULL; + + packet->qdcount = 1; + packet->arcount = 1; + packet->operation = NBT_OPCODE_REFRESH; + if (io->in.broadcast) { + packet->operation |= NBT_FLAG_BROADCAST; + } + + packet->questions = talloc_array(packet, struct nbt_name_question, 1); + if (packet->questions == NULL) goto failed; + + packet->questions[0].name = io->in.name; + packet->questions[0].question_type = NBT_QTYPE_NETBIOS; + packet->questions[0].question_class = NBT_QCLASS_IP; + + packet->additional = talloc_array(packet, struct nbt_res_rec, 1); + if (packet->additional == NULL) goto failed; + + packet->additional[0].name = io->in.name; + packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; + packet->additional[0].rr_class = NBT_QCLASS_IP; + packet->additional[0].ttl = io->in.ttl; + packet->additional[0].rdata.netbios.length = 6; + packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, + struct nbt_rdata_address, 1); + if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; + packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; + packet->additional[0].rdata.netbios.addresses[0].ipaddr = htonl(inet_addr(io->in.address)); + + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + timeval_current_ofs(io->in.timeout, 0), False); + if (req == NULL) goto failed; + + talloc_free(packet); + return req; + +failed: + talloc_free(packet); + return NULL; +} + +/* + wait for a refresh reply +*/ +NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) +{ + NTSTATUS status; + struct nbt_name_packet *packet; + const char *addr; + struct in_addr in; + + status = nbt_name_request_recv(req); + if (!NT_STATUS_IS_OK(status) || + req->num_replies == 0) { + talloc_free(req); + return status; + } + + packet = req->replies[0].packet; + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + + if (packet->ancount != 1 || + packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || + packet->answers[0].rr_class != NBT_QCLASS_IP) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + io->out.rcode = packet->operation & NBT_RCODE; + io->out.name = packet->answers[0].name; + if (packet->answers[0].rdata.netbios.length < 6) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr); + addr = inet_ntoa(in); + if (addr == NULL) { + talloc_free(req); + return NT_STATUS_NO_MEMORY; + } + io->out.reply_addr = talloc_strdup(mem_ctx, addr); + talloc_steal(mem_ctx, io->out.name.name); + talloc_steal(mem_ctx, io->out.name.scope); + + talloc_free(req); + + return NT_STATUS_OK; +} + +/* + synchronous name refresh request +*/ +NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) +{ + struct nbt_name_request *req = nbt_name_refresh_send(nbtsock, io); + return nbt_name_refresh_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 6d4938cd19..703210cb48 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -73,8 +73,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; - talloc_steal(req, packet); - + talloc_free(packet); return req; failed: -- cgit From 9a70f446fc4abc2bd1278772810c0e8132f4bea4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 08:30:44 +0000 Subject: r5126: the composite code is no longer client specific or smb specific, so rename the core structure to composite_context and the wait routine to composite_wait() (suggestion from metze) (This used to be commit cf11d05e35179c2c3e51c5ab370cd0a3fb15f24a) --- source4/libcli/composite/composite.c | 2 +- source4/libcli/composite/composite.h | 4 ++-- source4/libcli/composite/connect.c | 42 ++++++++++++++++++------------------ source4/libcli/composite/fetchfile.c | 28 ++++++++++++------------ source4/libcli/composite/loadfile.c | 22 +++++++++---------- source4/libcli/composite/savefile.c | 22 +++++++++---------- source4/libcli/composite/sesssetup.c | 20 ++++++++--------- source4/libcli/nbt/nameregister.c | 14 ++++++------ source4/libcli/raw/clisocket.c | 14 ++++++------ source4/libcli/resolve/bcast.c | 8 +++---- source4/libcli/resolve/host.c | 16 +++++++------- source4/libcli/resolve/nbtlist.c | 16 +++++++------- source4/libcli/resolve/resolve.c | 28 ++++++++++++------------ source4/libcli/resolve/wins.c | 6 +++--- 14 files changed, 121 insertions(+), 121 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index d4eb5a9323..998631204d 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -29,7 +29,7 @@ /* block until a composite function has completed, then return the status */ -NTSTATUS smb_composite_wait(struct smbcli_composite *c) +NTSTATUS composite_wait(struct composite_context *c) { if (c == NULL) return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index cb8cee779c..bf0fb9ed48 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -29,7 +29,7 @@ */ -struct smbcli_composite { +struct composite_context { /* the external state - will be queried by the caller */ enum smbcli_request_state state; @@ -45,7 +45,7 @@ struct smbcli_composite { /* information on what to do on completion */ struct { - void (*fn)(struct smbcli_composite *); + void (*fn)(struct composite_context *); void *private; } async; }; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 8dd7fe39ab..5f5275f7e6 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -42,17 +42,17 @@ struct connect_state { union smb_tcon *io_tcon; struct smb_composite_sesssetup *io_setup; struct smbcli_request *req; - struct smbcli_composite *creq; + struct composite_context *creq; }; static void request_handler(struct smbcli_request *); -static void composite_handler(struct smbcli_composite *); +static void composite_handler(struct composite_context *); /* setup a negprot send */ -static NTSTATUS connect_send_negprot(struct smbcli_composite *c, +static NTSTATUS connect_send_negprot(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -71,7 +71,7 @@ static NTSTATUS connect_send_negprot(struct smbcli_composite *c, /* a tree connect request has competed */ -static NTSTATUS connect_tcon(struct smbcli_composite *c, +static NTSTATUS connect_tcon(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -100,7 +100,7 @@ static NTSTATUS connect_tcon(struct smbcli_composite *c, /* a session setup request has competed */ -static NTSTATUS connect_session_setup(struct smbcli_composite *c, +static NTSTATUS connect_session_setup(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -147,7 +147,7 @@ static NTSTATUS connect_session_setup(struct smbcli_composite *c, /* a negprot request has competed */ -static NTSTATUS connect_negprot(struct smbcli_composite *c, +static NTSTATUS connect_negprot(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -184,7 +184,7 @@ static NTSTATUS connect_negprot(struct smbcli_composite *c, /* a session request operation has competed */ -static NTSTATUS connect_session_request(struct smbcli_composite *c, +static NTSTATUS connect_session_request(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -200,7 +200,7 @@ static NTSTATUS connect_session_request(struct smbcli_composite *c, /* a socket connection operation has competed */ -static NTSTATUS connect_socket(struct smbcli_composite *c, +static NTSTATUS connect_socket(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -244,7 +244,7 @@ static NTSTATUS connect_socket(struct smbcli_composite *c, /* called when name resolution is finished */ -static NTSTATUS connect_resolve(struct smbcli_composite *c, +static NTSTATUS connect_resolve(struct composite_context *c, struct smb_composite_connect *io) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -268,7 +268,7 @@ static NTSTATUS connect_resolve(struct smbcli_composite *c, /* handle and dispatch state transitions */ -static void state_handler(struct smbcli_composite *c) +static void state_handler(struct composite_context *c) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -309,32 +309,32 @@ static void state_handler(struct smbcli_composite *c) */ static void request_handler(struct smbcli_request *req) { - struct smbcli_composite *c = talloc_get_type(req->async.private, - struct smbcli_composite); + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); return state_handler(c); } /* handler for completion of a smbcli_composite sub-request */ -static void composite_handler(struct smbcli_composite *req) +static void composite_handler(struct composite_context *req) { - struct smbcli_composite *c = talloc_get_type(req->async.private, - struct smbcli_composite); + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); return state_handler(c); } /* a function to establish a smbcli_tree from scratch */ -struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect *io, +struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io, struct event_context *event_ctx) { - struct smbcli_composite *c; + struct composite_context *c; struct connect_state *state; struct nbt_name name; - c = talloc_zero(NULL, struct smbcli_composite); + c = talloc_zero(NULL, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct connect_state); @@ -369,11 +369,11 @@ failed: /* recv half of async composite connect code */ -NTSTATUS smb_composite_connect_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx) +NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct connect_state *state = talloc_get_type(c->private, struct connect_state); @@ -389,6 +389,6 @@ NTSTATUS smb_composite_connect_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ */ NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx) { - struct smbcli_composite *c = smb_composite_connect_send(io, NULL); + struct composite_context *c = smb_composite_connect_send(io, NULL); return smb_composite_connect_recv(c, mem_ctx); } diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index 8178090398..4f63f6328f 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -32,14 +32,14 @@ enum fetchfile_stage {FETCHFILE_CONNECT, struct fetchfile_state { enum fetchfile_stage stage; struct smb_composite_fetchfile *io; - struct smbcli_composite *req; + struct composite_context *req; struct smb_composite_connect *connect; struct smb_composite_loadfile *loadfile; }; -static void fetchfile_composite_handler(struct smbcli_composite *req); +static void fetchfile_composite_handler(struct composite_context *req); -static NTSTATUS fetchfile_connect(struct smbcli_composite *c, +static NTSTATUS fetchfile_connect(struct composite_context *c, struct smb_composite_fetchfile *io) { NTSTATUS status; @@ -67,7 +67,7 @@ static NTSTATUS fetchfile_connect(struct smbcli_composite *c, return NT_STATUS_OK; } -static NTSTATUS fetchfile_read(struct smbcli_composite *c, +static NTSTATUS fetchfile_read(struct composite_context *c, struct smb_composite_fetchfile *io) { NTSTATUS status; @@ -87,7 +87,7 @@ static NTSTATUS fetchfile_read(struct smbcli_composite *c, return NT_STATUS_OK; } -static void fetchfile_state_handler(struct smbcli_composite *c) +static void fetchfile_state_handler(struct composite_context *c) { struct fetchfile_state *state; NTSTATUS status; @@ -114,20 +114,20 @@ static void fetchfile_state_handler(struct smbcli_composite *c) } } -static void fetchfile_composite_handler(struct smbcli_composite *req) +static void fetchfile_composite_handler(struct composite_context *req) { - struct smbcli_composite *c = talloc_get_type(req->async.private, - struct smbcli_composite); + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); return fetchfile_state_handler(c); } -struct smbcli_composite *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, +struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, struct event_context *event_ctx) { - struct smbcli_composite *c; + struct composite_context *c; struct fetchfile_state *state; - c = talloc_zero(NULL, struct smbcli_composite); + c = talloc_zero(NULL, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct fetchfile_state); @@ -165,12 +165,12 @@ struct smbcli_composite *smb_composite_fetchfile_send(struct smb_composite_fetch return NULL; } -NTSTATUS smb_composite_fetchfile_recv(struct smbcli_composite *c, +NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct fetchfile_state *state = talloc_get_type(c->private, struct fetchfile_state); @@ -184,6 +184,6 @@ NTSTATUS smb_composite_fetchfile_recv(struct smbcli_composite *c, NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io, TALLOC_CTX *mem_ctx) { - struct smbcli_composite *c = smb_composite_fetchfile_send(io, NULL); + struct composite_context *c = smb_composite_fetchfile_send(io, NULL); return smb_composite_fetchfile_recv(c, mem_ctx); } diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c index 37f3608a4b..69a8219dba 100644 --- a/source4/libcli/composite/loadfile.c +++ b/source4/libcli/composite/loadfile.c @@ -43,7 +43,7 @@ struct loadfile_state { /* setup for the close */ -static NTSTATUS setup_close(struct smbcli_composite *c, +static NTSTATUS setup_close(struct composite_context *c, struct smbcli_tree *tree, uint16_t fnum) { struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); @@ -72,7 +72,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, called when the open is done - pull the results and setup for the first readx, or close if the file is zero size */ -static NTSTATUS loadfile_open(struct smbcli_composite *c, +static NTSTATUS loadfile_open(struct composite_context *c, struct smb_composite_loadfile *io) { struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); @@ -126,7 +126,7 @@ static NTSTATUS loadfile_open(struct smbcli_composite *c, called when a read is done - pull the results and setup for the next read, or close if the file is all done */ -static NTSTATUS loadfile_read(struct smbcli_composite *c, +static NTSTATUS loadfile_read(struct composite_context *c, struct smb_composite_loadfile *io) { struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); @@ -160,7 +160,7 @@ static NTSTATUS loadfile_read(struct smbcli_composite *c, /* called when the close is done, check the status and cleanup */ -static NTSTATUS loadfile_close(struct smbcli_composite *c, +static NTSTATUS loadfile_close(struct composite_context *c, struct smb_composite_loadfile *io) { struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); @@ -180,7 +180,7 @@ static NTSTATUS loadfile_close(struct smbcli_composite *c, */ static void loadfile_handler(struct smbcli_request *req) { - struct smbcli_composite *c = req->async.private; + struct composite_context *c = req->async.private; struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); /* when this handler is called, the stage indicates what @@ -213,13 +213,13 @@ static void loadfile_handler(struct smbcli_request *req) composite loadfile call - does an openx followed by a number of readx calls, followed by a close */ -struct smbcli_composite *smb_composite_loadfile_send(struct smbcli_tree *tree, +struct composite_context *smb_composite_loadfile_send(struct smbcli_tree *tree, struct smb_composite_loadfile *io) { - struct smbcli_composite *c; + struct composite_context *c; struct loadfile_state *state; - c = talloc_zero(tree, struct smbcli_composite); + c = talloc_zero(tree, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct loadfile_state); @@ -264,11 +264,11 @@ failed: /* composite loadfile call - recv side */ -NTSTATUS smb_composite_loadfile_recv(struct smbcli_composite *c, TALLOC_CTX *mem_ctx) +NTSTATUS smb_composite_loadfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); @@ -287,7 +287,7 @@ NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_composite_loadfile *io) { - struct smbcli_composite *c = smb_composite_loadfile_send(tree, io); + struct composite_context *c = smb_composite_loadfile_send(tree, io); return smb_composite_loadfile_recv(c, mem_ctx); } diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c index 5da5660127..0b08963966 100644 --- a/source4/libcli/composite/savefile.c +++ b/source4/libcli/composite/savefile.c @@ -44,7 +44,7 @@ struct savefile_state { /* setup for the close */ -static NTSTATUS setup_close(struct smbcli_composite *c, +static NTSTATUS setup_close(struct composite_context *c, struct smbcli_tree *tree, uint16_t fnum) { struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); @@ -73,7 +73,7 @@ static NTSTATUS setup_close(struct smbcli_composite *c, called when the open is done - pull the results and setup for the first writex, or close if the file is zero size */ -static NTSTATUS savefile_open(struct smbcli_composite *c, +static NTSTATUS savefile_open(struct composite_context *c, struct smb_composite_savefile *io) { struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); @@ -119,7 +119,7 @@ static NTSTATUS savefile_open(struct smbcli_composite *c, called when a write is done - pull the results and setup for the next write, or close if the file is all done */ -static NTSTATUS savefile_write(struct smbcli_composite *c, +static NTSTATUS savefile_write(struct composite_context *c, struct smb_composite_savefile *io) { struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); @@ -157,7 +157,7 @@ static NTSTATUS savefile_write(struct smbcli_composite *c, /* called when the close is done, check the status and cleanup */ -static NTSTATUS savefile_close(struct smbcli_composite *c, +static NTSTATUS savefile_close(struct composite_context *c, struct smb_composite_savefile *io) { struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); @@ -181,7 +181,7 @@ static NTSTATUS savefile_close(struct smbcli_composite *c, */ static void savefile_handler(struct smbcli_request *req) { - struct smbcli_composite *c = req->async.private; + struct composite_context *c = req->async.private; struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); /* when this handler is called, the stage indicates what @@ -214,14 +214,14 @@ static void savefile_handler(struct smbcli_request *req) composite savefile call - does an openx followed by a number of writex calls, followed by a close */ -struct smbcli_composite *smb_composite_savefile_send(struct smbcli_tree *tree, +struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree, struct smb_composite_savefile *io) { - struct smbcli_composite *c; + struct composite_context *c; struct savefile_state *state; union smb_open *io_open; - c = talloc_zero(tree, struct smbcli_composite); + c = talloc_zero(tree, struct composite_context); if (c == NULL) goto failed; c->state = SMBCLI_REQUEST_SEND; @@ -268,10 +268,10 @@ failed: /* composite savefile call - recv side */ -NTSTATUS smb_composite_savefile_recv(struct smbcli_composite *c) +NTSTATUS smb_composite_savefile_recv(struct composite_context *c) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); talloc_free(c); return status; } @@ -283,6 +283,6 @@ NTSTATUS smb_composite_savefile_recv(struct smbcli_composite *c) NTSTATUS smb_composite_savefile(struct smbcli_tree *tree, struct smb_composite_savefile *io) { - struct smbcli_composite *c = smb_composite_savefile_send(tree, io); + struct composite_context *c = smb_composite_savefile_send(tree, io); return smb_composite_savefile_recv(c); } diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 771f85e541..07c718b05b 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -93,7 +93,7 @@ static void use_nt1_session_keys(struct smbcli_session *session, */ static void request_handler(struct smbcli_request *req) { - struct smbcli_composite *c = req->async.private; + struct composite_context *c = req->async.private; struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); @@ -164,7 +164,7 @@ static void request_handler(struct smbcli_request *req) /* send a nt1 style session setup */ -static struct smbcli_request *session_setup_nt1(struct smbcli_composite *c, +static struct smbcli_request *session_setup_nt1(struct composite_context *c, struct smbcli_session *session, struct smb_composite_sesssetup *io) { @@ -203,7 +203,7 @@ static struct smbcli_request *session_setup_nt1(struct smbcli_composite *c, /* old style session setup (pre NT1 protocol level) */ -static struct smbcli_request *session_setup_old(struct smbcli_composite *c, +static struct smbcli_request *session_setup_old(struct composite_context *c, struct smbcli_session *session, struct smb_composite_sesssetup *io) { @@ -237,7 +237,7 @@ static struct smbcli_request *session_setup_old(struct smbcli_composite *c, /* old style session setup (pre NT1 protocol level) */ -static struct smbcli_request *session_setup_spnego(struct smbcli_composite *c, +static struct smbcli_request *session_setup_spnego(struct composite_context *c, struct smbcli_session *session, struct smb_composite_sesssetup *io) { @@ -333,13 +333,13 @@ static struct smbcli_request *session_setup_spnego(struct smbcli_composite *c, different session setup varients, including the multi-pass nature of the spnego varient */ -struct smbcli_composite *smb_composite_sesssetup_send(struct smbcli_session *session, +struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session, struct smb_composite_sesssetup *io) { - struct smbcli_composite *c; + struct composite_context *c; struct sesssetup_state *state; - c = talloc_zero(session, struct smbcli_composite); + c = talloc_zero(session, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct sesssetup_state); @@ -384,10 +384,10 @@ failed: /* receive a composite session setup reply */ -NTSTATUS smb_composite_sesssetup_recv(struct smbcli_composite *c) +NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); talloc_free(c); return status; } @@ -397,6 +397,6 @@ NTSTATUS smb_composite_sesssetup_recv(struct smbcli_composite *c) */ NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io) { - struct smbcli_composite *c = smb_composite_sesssetup_send(session, io); + struct composite_context *c = smb_composite_sesssetup_send(session, io); return smb_composite_sesssetup_recv(c); } diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 703210cb48..7e0134c283 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -158,7 +158,7 @@ struct register_bcast_state { */ static void name_register_handler(struct nbt_name_request *req) { - struct smbcli_composite *c = talloc_get_type(req->async.private, struct smbcli_composite); + struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); struct register_bcast_state *state = talloc_get_type(c->private, struct register_bcast_state); NTSTATUS status; @@ -207,13 +207,13 @@ done: /* the async send call for a 4 stage name registration */ -struct smbcli_composite *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, +struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, struct nbt_name_register_bcast *io) { - struct smbcli_composite *c; + struct composite_context *c; struct register_bcast_state *state; - c = talloc_zero(nbtsock, struct smbcli_composite); + c = talloc_zero(nbtsock, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct register_bcast_state); @@ -254,10 +254,10 @@ failed: /* broadcast 4 part name register - recv */ -NTSTATUS nbt_name_register_bcast_recv(struct smbcli_composite *c) +NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); talloc_free(c); return status; } @@ -268,6 +268,6 @@ NTSTATUS nbt_name_register_bcast_recv(struct smbcli_composite *c) NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock, struct nbt_name_register_bcast *io) { - struct smbcli_composite *c = nbt_name_register_bcast_send(nbtsock, io); + struct composite_context *c = nbt_name_register_bcast_send(nbtsock, io); return nbt_name_register_bcast_recv(c); } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index c9934fa16d..78a096fb8f 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -74,7 +74,7 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, struct timeval t, uint16_t flags) { - struct smbcli_composite *c = talloc_get_type(fde->private, struct smbcli_composite); + struct composite_context *c = talloc_get_type(fde->private, struct composite_context); struct clisocket_connect *conn = talloc_get_type(c->private, struct clisocket_connect); int i; @@ -153,14 +153,14 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, this is the async send side of the interface */ -struct smbcli_composite *smbcli_sock_connect_send(struct smbcli_socket *sock, +struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, const char *host_addr, int port) { - struct smbcli_composite *c; + struct composite_context *c; struct clisocket_connect *conn; int i; - c = talloc_zero(sock, struct smbcli_composite); + c = talloc_zero(sock, struct composite_context); if (c == NULL) return NULL; c->event_ctx = sock->event.ctx; @@ -219,10 +219,10 @@ failed: /* finish a smbcli_sock_connect_send() operation */ -NTSTATUS smbcli_sock_connect_recv(struct smbcli_composite *c) +NTSTATUS smbcli_sock_connect_recv(struct composite_context *c) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); talloc_free(c); return status; } @@ -235,7 +235,7 @@ NTSTATUS smbcli_sock_connect_recv(struct smbcli_composite *c) */ NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port) { - struct smbcli_composite *c; + struct composite_context *c; c = smbcli_sock_connect_send(sock, host_addr, port); if (c == NULL) { diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 9aefa32fae..5fb6e6dd5c 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -28,12 +28,12 @@ /* broadcast name resolution method - async send */ -struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, +struct composite_context *resolve_name_bcast_send(struct nbt_name *name, struct event_context *event_ctx) { int num_interfaces = iface_count(); const char **address_list; - struct smbcli_composite *c; + struct composite_context *c; int i; address_list = talloc_array(NULL, const char *, num_interfaces+1); @@ -58,7 +58,7 @@ struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, /* broadcast name resolution method - recv side */ -NTSTATUS resolve_name_bcast_recv(struct smbcli_composite *c, +NTSTATUS resolve_name_bcast_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); @@ -71,7 +71,7 @@ NTSTATUS resolve_name_bcast(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct smbcli_composite *c = resolve_name_bcast_send(name, NULL); + struct composite_context *c = resolve_name_bcast_send(name, NULL); return resolve_name_bcast_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 5b28a850fc..9bf278154d 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -63,7 +63,7 @@ static int host_destructor(void *ptr) /* the blocking child */ -static void run_child(struct smbcli_composite *c, int fd) +static void run_child(struct composite_context *c, int fd) { struct host_state *state = talloc_get_type(c->private, struct host_state); struct ipv4_addr ip; @@ -85,7 +85,7 @@ static void run_child(struct smbcli_composite *c, int fd) static void pipe_handler(struct event_context *ev, struct fd_event *fde, struct timeval t, uint16_t flags) { - struct smbcli_composite *c = talloc_get_type(fde->private, struct smbcli_composite); + struct composite_context *c = talloc_get_type(fde->private, struct composite_context); struct host_state *state = talloc_get_type(c->private, struct host_state); char address[128]; int ret; @@ -129,17 +129,17 @@ failed: /* gethostbyname name resolution method - async send */ -struct smbcli_composite *resolve_name_host_send(struct nbt_name *name, +struct composite_context *resolve_name_host_send(struct nbt_name *name, struct event_context *event_ctx) { - struct smbcli_composite *c; + struct composite_context *c; struct host_state *state; NTSTATUS status; int fd[2] = { -1, -1 }; struct fd_event fde; int ret; - c = talloc_zero(NULL, struct smbcli_composite); + c = talloc_zero(NULL, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct host_state); @@ -201,12 +201,12 @@ failed: /* gethostbyname name resolution method - recv side */ -NTSTATUS resolve_name_host_recv(struct smbcli_composite *c, +NTSTATUS resolve_name_host_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct host_state *state = talloc_get_type(c->private, struct host_state); @@ -224,7 +224,7 @@ NTSTATUS resolve_name_host(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct smbcli_composite *c = resolve_name_host_send(name, NULL); + struct composite_context *c = resolve_name_host_send(name, NULL); return resolve_name_host_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 08dc90c39d..5a9e31e09d 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -43,8 +43,8 @@ struct nbtlist_state { */ static void nbtlist_handler(struct nbt_name_request *req) { - struct smbcli_composite *c = talloc_get_type(req->async.private, - struct smbcli_composite); + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); int i; @@ -81,18 +81,18 @@ done: /* nbtlist name resolution method - async send */ -struct smbcli_composite *resolve_name_nbtlist_send(struct nbt_name *name, +struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, struct event_context *event_ctx, const char **address_list, BOOL broadcast, BOOL wins_lookup) { - struct smbcli_composite *c; + struct composite_context *c; struct nbtlist_state *state; int i; NTSTATUS status; - c = talloc_zero(NULL, struct smbcli_composite); + c = talloc_zero(NULL, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct nbtlist_state); @@ -143,12 +143,12 @@ failed: /* nbt list of addresses name resolution method - recv side */ -NTSTATUS resolve_name_nbtlist_recv(struct smbcli_composite *c, +NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); @@ -168,7 +168,7 @@ NTSTATUS resolve_name_nbtlist(struct nbt_name *name, BOOL broadcast, BOOL wins_lookup, const char **reply_addr) { - struct smbcli_composite *c = resolve_name_nbtlist_send(name, NULL, address_list, + struct composite_context *c = resolve_name_nbtlist_send(name, NULL, address_list, broadcast, wins_lookup); return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 054f10d529..eb35a7cb99 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -27,17 +27,17 @@ struct resolve_state { struct nbt_name name; const char **methods; - struct smbcli_composite *req; + struct composite_context *req; const char *reply_addr; }; -static struct smbcli_composite *setup_next_method(struct smbcli_composite *c); +static struct composite_context *setup_next_method(struct composite_context *c); /* pointers to the resolver backends */ static const struct resolve_method { const char *name; - struct smbcli_composite *(*send_fn)(struct nbt_name *, struct event_context *); - NTSTATUS (*recv_fn)(struct smbcli_composite *, TALLOC_CTX *, const char **); + struct composite_context *(*send_fn)(struct nbt_name *, struct event_context *); + NTSTATUS (*recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); } methods[] = { { "bcast", resolve_name_bcast_send, resolve_name_bcast_recv }, { "wins", resolve_name_wins_send, resolve_name_wins_recv }, @@ -63,9 +63,9 @@ static const struct resolve_method *find_method(const char *name) /* handle completion of one name resolve method */ -static void resolve_handler(struct smbcli_composite *req) +static void resolve_handler(struct composite_context *req) { - struct smbcli_composite *c = req->async.private; + struct composite_context *c = req->async.private; struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); const struct resolve_method *method = find_method(state->methods[0]); @@ -90,10 +90,10 @@ static void resolve_handler(struct smbcli_composite *req) } -static struct smbcli_composite *setup_next_method(struct smbcli_composite *c) +static struct composite_context *setup_next_method(struct composite_context *c) { struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); - struct smbcli_composite *req = NULL; + struct composite_context *req = NULL; do { const struct resolve_method *method = find_method(state->methods[0]); @@ -114,13 +114,13 @@ static struct smbcli_composite *setup_next_method(struct smbcli_composite *c) /* general name resolution - async send */ -struct smbcli_composite *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx) +struct composite_context *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx) { - struct smbcli_composite *c; + struct composite_context *c; struct resolve_state *state; NTSTATUS status; - c = talloc_zero(NULL, struct smbcli_composite); + c = talloc_zero(NULL, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct resolve_state); @@ -156,12 +156,12 @@ failed: /* general name resolution method - recv side */ -NTSTATUS resolve_name_recv(struct smbcli_composite *c, +NTSTATUS resolve_name_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { NTSTATUS status; - status = smb_composite_wait(c); + status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); @@ -177,6 +177,6 @@ NTSTATUS resolve_name_recv(struct smbcli_composite *c, */ NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct smbcli_composite *c = resolve_name_send(name, NULL); + struct composite_context *c = resolve_name_send(name, NULL); return resolve_name_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 5a0e067832..aa4ec0cea4 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -28,7 +28,7 @@ /* wins name resolution method - async send */ -struct smbcli_composite *resolve_name_wins_send(struct nbt_name *name, +struct composite_context *resolve_name_wins_send(struct nbt_name *name, struct event_context *event_ctx) { const char **address_list = lp_wins_server_list(); @@ -39,7 +39,7 @@ struct smbcli_composite *resolve_name_wins_send(struct nbt_name *name, /* wins name resolution method - recv side */ -NTSTATUS resolve_name_wins_recv(struct smbcli_composite *c, +NTSTATUS resolve_name_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); @@ -52,7 +52,7 @@ NTSTATUS resolve_name_wins(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct smbcli_composite *c = resolve_name_wins_send(name, NULL); + struct composite_context *c = resolve_name_wins_send(name, NULL); return resolve_name_wins_recv(c, mem_ctx, reply_addr); } -- cgit From f0d97d27aefa746f7c925296a2e4fa4d57b3219d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 16:02:58 +0000 Subject: r5136: fix types metze (This used to be commit 344367cc4cdb232c394ce45ab64cc357cce4259f) --- source4/libcli/auth/gensec.c | 4 ++-- source4/libcli/auth/gensec.h | 6 +++--- source4/libcli/auth/gssapi_parse.c | 4 ++-- source4/libcli/auth/spnego.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index e9dea6be33..e0fa27359a 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -487,7 +487,7 @@ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_ */ void gensec_want_feature(struct gensec_security *gensec_security, - uint32 feature) + uint32_t feature) { gensec_security->want_features |= feature; } @@ -498,7 +498,7 @@ void gensec_want_feature(struct gensec_security *gensec_security, */ BOOL gensec_have_feature(struct gensec_security *gensec_security, - uint32 feature) + uint32_t feature) { if (!gensec_security->ops->have_feature) { return False; diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 434f3fdb4d..a555584840 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -58,7 +58,7 @@ struct auth_session_info; struct gensec_security_ops { const char *name; const char *sasl_name; - uint8 auth_type; /* 0 if not offered on DCE-RPC */ + uint8_t auth_type; /* 0 if not offered on DCE-RPC */ const char *oid; /* NULL if not offered by SPENGO */ NTSTATUS (*client_start)(struct gensec_security *gensec_security); NTSTATUS (*server_start)(struct gensec_security *gensec_security); @@ -93,7 +93,7 @@ struct gensec_security_ops { NTSTATUS (*session_info)(struct gensec_security *gensec_security, struct auth_session_info **session_info); BOOL (*have_feature)(struct gensec_security *gensec_security, - uint32 feature); + uint32_t feature); BOOL enabled; }; @@ -109,7 +109,7 @@ struct gensec_security { struct gensec_target target; enum gensec_role gensec_role; BOOL subcontext; - uint32 want_features; + uint32_t want_features; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c index e1fb2e9cf5..f984f6303f 100644 --- a/source4/libcli/auth/gssapi_parse.c +++ b/source4/libcli/auth/gssapi_parse.c @@ -31,7 +31,7 @@ /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8 tok_id[2]) +DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2]) { struct asn1_data data; DATA_BLOB ret = data_blob(NULL,0); @@ -63,7 +63,7 @@ DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *tick /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8 tok_id[2]) +BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2]) { BOOL ret; struct asn1_data data; diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index 3b9d148c67..1064370146 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -49,7 +49,7 @@ struct spnego_negTokenInit { }; struct spnego_negTokenTarg { - uint8 negResult; + uint8_t negResult; const char *supportedMech; DATA_BLOB responseToken; DATA_BLOB mechListMIC; -- cgit From d8d3a5ffe3fb73d64869c133fe398efeb4e79d77 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 16:06:21 +0000 Subject: r5137: fix types metze (This used to be commit add1c579375d08040f722946da31ee3862f9e7ac) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/security/security_descriptor.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index eab94bb194..655838b64f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1220,7 +1220,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16 *port, BOOL *ldaps) + char **host, uint16_t *port, BOOL *ldaps) { int tmp_port = 0; char protocol[11]; diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index bbfee31fbe..77d296235a 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -194,7 +194,7 @@ BOOL security_descriptor_equal(const struct security_descriptor *sd1, */ BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, const struct security_descriptor *sd2, - uint32 mask) + uint32_t mask) { if (sd1 == sd2) return True; if (!sd1 || !sd2) return False; -- cgit From ca3f70256ac0430e2db846d0293a7750a6d3ef6b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 17:16:45 +0000 Subject: r5145: define struct ipv4_addr in misc.idl, so we can use it in nbt.idl and get a nicer debug output metze (This used to be commit abacbc9192646f6f3c720758ab65889b82b9ae7b) --- source4/libcli/nbt/namequery.c | 2 +- source4/libcli/nbt/namerefresh.c | 4 ++-- source4/libcli/nbt/nameregister.c | 4 ++-- source4/libcli/nbt/nbtsocket.c | 4 ++++ 4 files changed, 9 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 36fbfc8dd0..d77482fc2b 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -102,7 +102,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } for (i=0;iout.num_addrs;i++) { - in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[i].ipaddr); + in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[i].ipaddr.addr); addr = inet_ntoa(in); if (addr == NULL) { talloc_free(req); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 47fcae4f7c..c121d9c920 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -64,7 +64,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, struct nbt_rdata_address, 1); if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = htonl(inet_addr(io->in.address)); + packet->additional[0].rdata.netbios.addresses[0].ipaddr.addr = htonl(inet_addr(io->in.address)); req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); @@ -112,7 +112,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, talloc_free(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; } - in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr); + in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr.addr); addr = inet_ntoa(in); if (addr == NULL) { talloc_free(req); diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 7e0134c283..7bed37cf78 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -67,7 +67,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, struct nbt_rdata_address, 1); if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = htonl(inet_addr(io->in.address)); + packet->additional[0].rdata.netbios.addresses[0].ipaddr.addr = htonl(inet_addr(io->in.address)); req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); @@ -115,7 +115,7 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, talloc_free(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; } - in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr); + in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr.addr); addr = inet_ntoa(in); if (addr == NULL) { talloc_free(req); diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 3f16bf6921..3d1397e019 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -390,6 +390,10 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, talloc_set_destructor(req, nbt_name_request_destructor); + if (DEBUGLVL(10)) { + NDR_PRINT_DEBUG(nbt_name_packet, request); + } + status = ndr_push_struct_blob(&req->encoded, req, request, (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); if (!NT_STATUS_IS_OK(status)) { -- cgit From 9b9c23b19be5a90821e1075a76f8b94fdb2424e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 1 Feb 2005 04:12:44 +0000 Subject: r5155: define ipv4address as a based IDL type, mapped to a "const char *" in the header, and defined on the wire as a 4 byte network byte order IP. This means the calling code doesn't have to worry about network byte order conversions. (This used to be commit 72048e37179dd5b9ada0c5280d2f0d8c23d1a17d) --- source4/libcli/nbt/namequery.c | 11 ++--------- source4/libcli/nbt/namerefresh.c | 14 ++++---------- source4/libcli/nbt/nameregister.c | 15 +++++---------- 3 files changed, 11 insertions(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index d77482fc2b..072b1e459a 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -72,8 +72,6 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, { NTSTATUS status; struct nbt_name_packet *packet; - const char *addr; - struct in_addr in; int i; status = nbt_name_request_recv(req); @@ -102,13 +100,8 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } for (i=0;iout.num_addrs;i++) { - in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[i].ipaddr.addr); - addr = inet_ntoa(in); - if (addr == NULL) { - talloc_free(req); - return NT_STATUS_NO_MEMORY; - } - io->out.reply_addrs[i] = talloc_strdup(mem_ctx, addr); + io->out.reply_addrs[i] = talloc_steal(mem_ctx, + packet->answers[0].rdata.netbios.addresses[i].ipaddr); } talloc_steal(mem_ctx, io->out.name.name); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index c121d9c920..0d0576d764 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -64,7 +64,8 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, struct nbt_rdata_address, 1); if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr.addr = htonl(inet_addr(io->in.address)); + packet->additional[0].rdata.netbios.addresses[0].ipaddr = + talloc_strdup(packet->additional, io->in.address); req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); @@ -86,8 +87,6 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, { NTSTATUS status; struct nbt_name_packet *packet; - const char *addr; - struct in_addr in; status = nbt_name_request_recv(req); if (!NT_STATUS_IS_OK(status) || @@ -112,13 +111,8 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, talloc_free(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; } - in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr.addr); - addr = inet_ntoa(in); - if (addr == NULL) { - talloc_free(req); - return NT_STATUS_NO_MEMORY; - } - io->out.reply_addr = talloc_strdup(mem_ctx, addr); + io->out.reply_addr = talloc_steal(mem_ctx, + packet->answers[0].rdata.netbios.addresses[0].ipaddr); talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 7bed37cf78..4701d0c1bc 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -67,7 +67,9 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, struct nbt_rdata_address, 1); if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr.addr = htonl(inet_addr(io->in.address)); + packet->additional[0].rdata.netbios.addresses[0].ipaddr = + talloc_strdup(packet->additional, io->in.address); + if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); @@ -89,8 +91,6 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, { NTSTATUS status; struct nbt_name_packet *packet; - const char *addr; - struct in_addr in; status = nbt_name_request_recv(req); if (!NT_STATUS_IS_OK(status) || @@ -115,13 +115,8 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, talloc_free(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; } - in.s_addr = htonl(packet->answers[0].rdata.netbios.addresses[0].ipaddr.addr); - addr = inet_ntoa(in); - if (addr == NULL) { - talloc_free(req); - return NT_STATUS_NO_MEMORY; - } - io->out.reply_addr = talloc_strdup(mem_ctx, addr); + io->out.reply_addr = talloc_steal(mem_ctx, + packet->answers[0].rdata.netbios.addresses[0].ipaddr); talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); -- cgit From 66170ef8b36b499aa5b44ef10c1bd362a50f2636 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 02:35:52 +0000 Subject: r5185: make all the events data structures private to events.c. This will make it possible to add optimisations to the events code such as keeping the next timed event in a sorted list, and using epoll for file descriptor events. I also removed the loop events code, as it wasn't being used anywhere, and changed timed events to always be one-shot (as adding a new timed event in the event handler is so easy to do if needed) (This used to be commit d7b4b6de51342a65bf46fce772d313f92f8d73d3) --- source4/libcli/composite/composite.c | 1 + source4/libcli/config.mk | 3 ++- source4/libcli/nbt/nbtsocket.c | 38 +++++++++++++----------------- source4/libcli/raw/clisocket.c | 27 +++++++++------------- source4/libcli/raw/clitransport.c | 45 ++++++++++++++++++++++-------------- source4/libcli/raw/rawrequest.c | 1 + source4/libcli/resolve/host.c | 12 ++++------ source4/libcli/resolve/resolve.c | 1 + 8 files changed, 64 insertions(+), 64 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 998631204d..e08543a94b 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 8458eb780d..038b8e0ccb 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -14,6 +14,7 @@ REQUIRED_SUBSYSTEMS = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_COMPOSITE_BASE] ADD_OBJ_FILES = \ libcli/composite/composite.o +REQUIRED_SUBSYSTEMS = LIBEVENTS [SUBSYSTEM::LIBCLI_COMPOSITE] ADD_OBJ_FILES = \ @@ -31,7 +32,7 @@ ADD_OBJ_FILES = \ libcli/nbt/namequery.o \ libcli/nbt/nameregister.o \ libcli/nbt/namerefresh.o -REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE +REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 3d1397e019..8e6fda1ece 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -49,11 +49,11 @@ static int nbt_name_request_destructor(void *ptr) req->te = NULL; } if (req->nbtsock->send_queue == NULL) { - req->nbtsock->fde->flags &= ~EVENT_FD_WRITE; + EVENT_FD_NOT_WRITEABLE(req->nbtsock->fde); } if (req->nbtsock->num_pending == 0 && req->nbtsock->incoming.handler == NULL) { - req->nbtsock->fde->flags &= ~EVENT_FD_READ; + EVENT_FD_NOT_READABLE(req->nbtsock->fde); } return 0; } @@ -86,12 +86,12 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) talloc_free(req); } else { req->state = NBT_REQUEST_WAIT; - nbtsock->fde->flags |= EVENT_FD_READ; + EVENT_FD_READABLE(nbtsock->fde); nbtsock->num_pending++; } } - nbtsock->fde->flags &= ~EVENT_FD_WRITE; + EVENT_FD_NOT_WRITEABLE(nbtsock->fde); talloc_free(tmp_ctx); return; @@ -210,9 +210,9 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) handle fd events on a nbt_name_socket */ static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags) + struct timeval t, uint16_t flags, void *private) { - struct nbt_name_socket *nbtsock = talloc_get_type(fde->private, + struct nbt_name_socket *nbtsock = talloc_get_type(private, struct nbt_name_socket); if (flags & EVENT_FD_WRITE) { nbt_name_socket_send(nbtsock); @@ -231,7 +231,6 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, { struct nbt_name_socket *nbtsock; NTSTATUS status; - struct fd_event fde; nbtsock = talloc(mem_ctx, struct nbt_name_socket); if (nbtsock == NULL) goto failed; @@ -255,11 +254,9 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, nbtsock->num_pending = 0; nbtsock->incoming.handler = NULL; - fde.fd = socket_get_fd(nbtsock->sock); - fde.flags = 0; - fde.handler = nbt_name_socket_handler; - fde.private = nbtsock; - nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde, nbtsock); + nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock, + socket_get_fd(nbtsock->sock), 0, + nbt_name_socket_handler, nbtsock); return nbtsock; @@ -272,9 +269,9 @@ failed: handle a request timeout */ static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t) + struct timeval t, void *private) { - struct nbt_name_request *req = talloc_get_type(te->private, + struct nbt_name_request *req = talloc_get_type(private, struct nbt_name_request); nbt_name_request_destructor(req); if (req->num_replies == 0) { @@ -299,7 +296,6 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, BOOL allow_multiple_replies) { struct nbt_name_request *req; - struct timed_event te; int id; NTSTATUS status; @@ -335,10 +331,8 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, request->name_trn_id = id; req->name_trn_id = id; - te.next_event = timeout; - te.handler = nbt_name_socket_timeout; - te.private = req; - req->te = event_add_timed(nbtsock->event_ctx, &te, req); + req->te = event_add_timed(nbtsock->event_ctx, req, timeout, + nbt_name_socket_timeout, req); talloc_set_destructor(req, nbt_name_request_destructor); @@ -358,7 +352,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, NDR_PRINT_DEBUG(nbt_name_packet, request); } - nbtsock->fde->flags |= EVENT_FD_WRITE; + EVENT_FD_WRITEABLE(nbtsock->fde); return req; @@ -403,7 +397,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); - nbtsock->fde->flags |= EVENT_FD_WRITE; + EVENT_FD_WRITEABLE(nbtsock->fde); return NT_STATUS_OK; @@ -442,7 +436,7 @@ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, { nbtsock->incoming.handler = handler; nbtsock->incoming.private = private; - nbtsock->fde->flags |= EVENT_FD_READ; + EVENT_FD_READABLE(nbtsock->fde); return NT_STATUS_OK; } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 78a096fb8f..f9e662714b 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -65,16 +65,17 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx, } static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, - const char *hostaddr, int port); + const char *hostaddr, int port, + struct composite_context *c); /* handle socket write events during an async connect. These happen when the OS has either completed the connect() or has returned an error */ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags) + struct timeval t, uint16_t flags, void *private) { - struct composite_context *c = talloc_get_type(fde->private, struct composite_context); + struct composite_context *c = talloc_get_type(private, struct composite_context); struct clisocket_connect *conn = talloc_get_type(c->private, struct clisocket_connect); int i; @@ -94,10 +95,9 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even conn->port_num = i; c->status = smbcli_sock_connect_one(conn->sock, conn->dest_host, - conn->iports[i]); + conn->iports[i], c); if (NT_STATUS_IS_OK(c->status) || NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - conn->sock->event.fde->private = c; return; } } @@ -113,9 +113,9 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even try to connect to the given address/port */ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, - const char *hostaddr, int port) + const char *hostaddr, int port, + struct composite_context *c) { - struct fd_event fde; NTSTATUS status; if (sock->sock) { @@ -133,15 +133,11 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, /* we initially look for write - see the man page on non-blocking connect */ - fde.fd = socket_get_fd(sock->sock); - fde.flags = EVENT_FD_WRITE; - fde.handler = smbcli_sock_connect_handler; - fde.private = sock; - - sock->event.fde = event_add_fd(sock->event.ctx, &fde, sock); + sock->event.fde = event_add_fd(sock->event.ctx, sock, socket_get_fd(sock->sock), + EVENT_FD_WRITE, smbcli_sock_connect_handler, c); sock->port = port; - set_blocking(fde.fd, False); + set_blocking(socket_get_fd(sock->sock), False); return socket_connect(sock->sock, NULL, 0, hostaddr, port, 0); } @@ -200,10 +196,9 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, conn->sock->port = conn->iports[i]; c->status = smbcli_sock_connect_one(sock, conn->dest_host, - conn->iports[i]); + conn->iports[i], c); if (NT_STATUS_IS_OK(c->status) || NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - sock->event.fde->private = c; return c; } } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 1904618be9..21303a34aa 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -33,11 +33,13 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport); /* an event has happened on the socket */ -static void smbcli_transport_event_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags) +static void smbcli_transport_event_handler(struct event_context *ev, + struct fd_event *fde, + struct timeval t, + uint16_t flags, void *private) { - struct smbcli_transport *transport = fde->private; - + struct smbcli_transport *transport = talloc_get_type(private, + struct smbcli_transport); if (flags & EVENT_FD_READ) { smbcli_transport_process_recv(transport); return; @@ -87,9 +89,13 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, /* take over event handling from the socket layer - it only handles events up until we are connected */ - transport->socket->event.fde->handler = smbcli_transport_event_handler; - transport->socket->event.fde->private = transport; - transport->socket->event.fde->flags = EVENT_FD_READ; + talloc_free(transport->socket->event.fde); + transport->socket->event.fde = event_add_fd(transport->socket->event.ctx, + transport->socket, + socket_get_fd(transport->socket->sock), + EVENT_FD_READ, + smbcli_transport_event_handler, + transport); talloc_set_destructor(transport, transport_destructor); @@ -132,7 +138,8 @@ void smbcli_transport_dead(struct smbcli_transport *transport) */ static void smbcli_transport_write_enable(struct smbcli_transport *transport) { - transport->socket->event.fde->flags |= EVENT_FD_WRITE; + struct fd_event *fde = transport->socket->event.fde; + EVENT_FD_WRITEABLE(fde); } /* @@ -140,7 +147,8 @@ static void smbcli_transport_write_enable(struct smbcli_transport *transport) */ static void smbcli_transport_write_disable(struct smbcli_transport *transport) { - transport->socket->event.fde->flags &= ~EVENT_FD_WRITE; + struct fd_event *fde = transport->socket->event.fde; + EVENT_FD_NOT_WRITEABLE(fde); } /* @@ -296,10 +304,15 @@ again: } static void idle_handler(struct event_context *ev, - struct timed_event *te, struct timeval t) + struct timed_event *te, struct timeval t, void *private) { - struct smbcli_transport *transport = te->private; - te->next_event = timeval_add(&te->next_event, 0, transport->idle.period); + struct smbcli_transport *transport = talloc_get_type(private, + struct smbcli_transport); + struct timeval next = timeval_add(&t, 0, transport->idle.period); + transport->socket->event.te = event_add_timed(transport->socket->event.ctx, + transport, + next, + idle_handler, transport); transport->idle.func(transport, transport->idle.private); } @@ -312,7 +325,6 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, uint64_t period, void *private) { - struct timed_event te; transport->idle.func = idle_func; transport->idle.private = private; transport->idle.period = period; @@ -321,11 +333,10 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, talloc_free(transport->socket->event.te); } - te.next_event = timeval_current_ofs(0, period); - te.handler = idle_handler; - te.private = transport; transport->socket->event.te = event_add_timed(transport->socket->event.ctx, - &te, transport); + transport, + timeval_current_ofs(0, period), + idle_handler, transport); } /* diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 7dbe6b3468..420ce0a3a2 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -26,6 +26,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "dlinklist.h" +#include "events.h" /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 0 diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 9bf278154d..977c804a4a 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -83,9 +83,9 @@ static void run_child(struct composite_context *c, int fd) handle a read event on the pipe */ static void pipe_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags) + struct timeval t, uint16_t flags, void *private) { - struct composite_context *c = talloc_get_type(fde->private, struct composite_context); + struct composite_context *c = talloc_get_type(private, struct composite_context); struct host_state *state = talloc_get_type(c->private, struct host_state); char address[128]; int ret; @@ -136,7 +136,6 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, struct host_state *state; NTSTATUS status; int fd[2] = { -1, -1 }; - struct fd_event fde; int ret; c = talloc_zero(NULL, struct composite_context); @@ -161,11 +160,8 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, /* we need to put the child in our event context so we know when the gethostbyname() has finished */ - fde.fd = state->child_fd; - fde.flags = EVENT_FD_READ; - fde.handler = pipe_handler; - fde.private = c; - state->fde = event_add_fd(c->event_ctx, &fde, state); + state->fde = event_add_fd(c->event_ctx, state, state->child_fd, EVENT_FD_READ, + pipe_handler, c); if (state->fde == NULL) { close(fd[0]); close(fd[1]); diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index eb35a7cb99..e2e9462561 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -- cgit From 0798d54b4fc28be881e2c4012663b1461bc85ba7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 11:25:52 +0000 Subject: r5195: most events don't need the time of the event, so save a gettimeofday() call and just use timeval_current() when its actually needed (This used to be commit 236403cc4dc2924ed6a898acae0bb44cc1688dcc) --- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/raw/clitransport.c | 1 - source4/libcli/resolve/host.c | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 8e6fda1ece..be1b7547f1 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -210,7 +210,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) handle fd events on a nbt_name_socket */ static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags, void *private) + uint16_t flags, void *private) { struct nbt_name_socket *nbtsock = talloc_get_type(private, struct nbt_name_socket); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index f9e662714b..69de86088a 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -73,7 +73,7 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, has either completed the connect() or has returned an error */ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags, void *private) + uint16_t flags, void *private) { struct composite_context *c = talloc_get_type(private, struct composite_context); struct clisocket_connect *conn = talloc_get_type(c->private, struct clisocket_connect); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 21303a34aa..d614d80d99 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -35,7 +35,6 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport); */ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags, void *private) { struct smbcli_transport *transport = talloc_get_type(private, diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 977c804a4a..4df8f27534 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -83,7 +83,7 @@ static void run_child(struct composite_context *c, int fd) handle a read event on the pipe */ static void pipe_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags, void *private) + uint16_t flags, void *private) { struct composite_context *c = talloc_get_type(private, struct composite_context); struct host_state *state = talloc_get_type(c->private, struct host_state); @@ -160,7 +160,7 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, /* we need to put the child in our event context so we know when the gethostbyname() has finished */ - state->fde = event_add_fd(c->event_ctx, state, state->child_fd, EVENT_FD_READ, + state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ, pipe_handler, c); if (state->fde == NULL) { close(fd[0]); -- cgit From 131dc76d56df40b3511c47e54f15412a25b491f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 11:56:03 +0000 Subject: r5197: moved events code to lib/events/ (suggestion from metze) (This used to be commit 7f54c8a339f36aa43c9340be70ab7f0067593ef2) --- source4/libcli/composite/composite.c | 2 +- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/resolve/host.c | 2 +- source4/libcli/resolve/resolve.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index e08543a94b..2b8ddea897 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index be1b7547f1..94c0ced95d 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "dlinklist.h" #include "libcli/nbt/libnbt.h" diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 69de86088a..44c6a87e21 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index d614d80d99..079783435c 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -24,7 +24,7 @@ #include "libcli/raw/libcliraw.h" #include "system/time.h" #include "dlinklist.h" -#include "events.h" +#include "lib/events/events.h" static void smbcli_transport_process_recv(struct smbcli_transport *transport); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 420ce0a3a2..b49009ac22 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -26,7 +26,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "dlinklist.h" -#include "events.h" +#include "lib/events/events.h" /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 0 diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 4df8f27534..cbf0f4614e 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -30,7 +30,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "system/network.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index e2e9462561..7e3f78edb4 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -- cgit From 10c211f2afc45e7a75f024c946a5c8232d7efd6b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 3 Feb 2005 13:00:16 +0000 Subject: r5199: fix some minor configure bugs metze (This used to be commit 274ef2a206aa00b3155adc27f5b7e35d3fa52bf6) --- source4/libcli/auth/gensec.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 9e9b04a695..356f857d81 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -2,7 +2,7 @@ SMB_MODULE_DEFAULT(gensec_krb5, NOT) SMB_MODULE_DEFAULT(gensec_gssapi, NOT) if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then - /* enable this when krb5 is fully working */ + # enable this when krb5 is fully working SMB_MODULE_DEFAULT(gensec_krb5, STATIC) SMB_MODULE_DEFAULT(gensec_gssapi, STATIC) fi -- cgit From 58a957035336119a3a023384fef205ae718fdf1b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Feb 2005 14:40:47 +0000 Subject: r5237: Add error code for "class not registered" (This used to be commit b72a0ac654857273eaaf3c5e32d86abed0af3ceb) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index a9acb7335c..a584def829 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -86,6 +86,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, + { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, { NULL, W_ERROR(0) } }; -- cgit From e0caea68f5ac9f9fee1006b472bb49c2f81b21ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 6 Feb 2005 08:22:18 +0000 Subject: r5250: - added low level support for retrying nbt name queries, rather than having the 2nd layer functions do retries themselves. This makes the code simpler, and allows the TRN_ID to be reused in the retry (which is how it is supposed to work). - added support for WACK replies to nbt name requests. A WACK reply specifies a timeout to wait for the real reply. - added WINS name refresh async calls, supporting multiple wins servers and multiple IPs to register (This used to be commit 76be35cb990de830c2451d9e48cb2c40a4befdb7) --- source4/libcli/nbt/libnbt.h | 29 +++++++ source4/libcli/nbt/namequery.c | 4 +- source4/libcli/nbt/namerefresh.c | 167 +++++++++++++++++++++++++++++++++++++- source4/libcli/nbt/nameregister.c | 22 +++-- source4/libcli/nbt/nbtsocket.c | 138 ++++++++++++++++++++----------- 5 files changed, 297 insertions(+), 63 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 114d6d3b92..7ccd6a51a4 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -48,6 +48,15 @@ struct nbt_name_request { const char *dest_addr; int dest_port; + /* timeout between retries */ + int timeout; + + /* how many retries to send on timeout */ + int num_retries; + + /* whether we have received a WACK */ + BOOL received_wack; + /* the timeout event */ struct timed_event *te; @@ -116,6 +125,7 @@ struct nbt_name_query { BOOL broadcast; BOOL wins_lookup; int timeout; /* in seconds */ + int retries; } in; struct { const char *reply_from; @@ -131,6 +141,7 @@ struct nbt_name_status { struct nbt_name name; const char *dest_addr; int timeout; /* in seconds */ + int retries; } in; struct { const char *reply_from; @@ -150,6 +161,7 @@ struct nbt_name_register { BOOL broadcast; uint32_t ttl; int timeout; /* in seconds */ + int retries; } in; struct { const char *reply_from; @@ -170,6 +182,22 @@ struct nbt_name_register_bcast { } in; }; +/* wins name refresh with multiple wins servers to try and multiple + addresses to register */ +struct nbt_name_refresh_wins { + struct { + struct nbt_name name; + const char **wins_servers; + const char **addresses; + uint16_t nb_flags; + uint32_t ttl; + } in; + struct { + const char *wins_server; + uint8_t rcode; + } out; +}; + /* a name refresh request */ struct nbt_name_refresh { @@ -181,6 +209,7 @@ struct nbt_name_refresh { BOOL broadcast; uint32_t ttl; int timeout; /* in seconds */ + int retries; } in; struct { const char *reply_from; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 072b1e459a..ddef2a7d07 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -53,7 +53,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_class = NBT_QCLASS_IP; req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, - timeval_current_ofs(io->in.timeout, 0), False); + io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; talloc_free(packet); @@ -146,7 +146,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_class = NBT_QCLASS_IP; req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, - timeval_current_ofs(io->in.timeout, 0), False); + io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; talloc_free(packet); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 0d0576d764..d8dbede727 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -68,7 +68,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, talloc_strdup(packet->additional, io->in.address); req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, - timeval_current_ofs(io->in.timeout, 0), False); + io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; talloc_free(packet); @@ -83,7 +83,7 @@ failed: wait for a refresh reply */ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) + TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) { NTSTATUS status; struct nbt_name_packet *packet; @@ -115,7 +115,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, packet->answers[0].rdata.netbios.addresses[0].ipaddr); talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); - + talloc_free(req); return NT_STATUS_OK; @@ -130,3 +130,164 @@ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, struct nbt_name_request *req = nbt_name_refresh_send(nbtsock, io); return nbt_name_refresh_recv(req, mem_ctx, io); } + + + +/* + a wins name refresh with multiple WINS servers and multiple + addresses to refresh. Try each WINS server in turn, until we get a + reply for each address +*/ +struct refresh_wins_state { + struct nbt_name_socket *nbtsock; + struct nbt_name_refresh *io; + char **wins_servers; + char **addresses; + int address_idx; + struct nbt_name_request *req; +}; + + +/* + state handler for WINS multi-homed multi-server name refresh +*/ +static void name_refresh_wins_handler(struct nbt_name_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + struct refresh_wins_state *state = talloc_get_type(c->private, + struct refresh_wins_state); + NTSTATUS status; + + status = nbt_name_refresh_recv(state->req, state, state->io); + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + /* the refresh timed out - try the next WINS server */ + state->wins_servers++; + state->address_idx = 0; + if (state->wins_servers[0] == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = status; + goto done; + } + state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.address = state->addresses[0]; + state->req = nbt_name_refresh_send(state->nbtsock, state->io); + if (state->req == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } else { + state->req->async.fn = name_refresh_wins_handler; + state->req->async.private = c; + } + } else if (!NT_STATUS_IS_OK(status)) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = status; + } else { + if (state->io->out.rcode == 0 && + state->addresses[state->address_idx+1] != NULL) { + /* refresh our next address */ + state->io->in.address = state->addresses[++(state->address_idx)]; + state->req = nbt_name_refresh_send(state->nbtsock, state->io); + if (state->req == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } else { + state->req->async.fn = name_refresh_wins_handler; + state->req->async.private = c; + } + } else { + c->state = SMBCLI_REQUEST_DONE; + c->status = NT_STATUS_OK; + } + } + +done: + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); + } +} + +/* + the async send call for a multi-server WINS refresh +*/ +struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, + struct nbt_name_refresh_wins *io) +{ + struct composite_context *c; + struct refresh_wins_state *state; + + c = talloc_zero(nbtsock, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct refresh_wins_state); + if (state == NULL) goto failed; + + state->io = talloc(state, struct nbt_name_refresh); + if (state->io == NULL) goto failed; + + state->wins_servers = str_list_copy(state, io->in.wins_servers); + if (state->wins_servers == NULL || + state->wins_servers[0] == NULL) goto failed; + + state->addresses = str_list_copy(state, io->in.addresses); + if (state->addresses == NULL || + state->addresses[0] == NULL) goto failed; + + state->io->in.name = io->in.name; + state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.address = io->in.addresses[0]; + state->io->in.nb_flags = io->in.nb_flags; + state->io->in.broadcast = False; + state->io->in.ttl = io->in.ttl; + state->io->in.timeout = 2; + state->io->in.retries = 2; + + state->nbtsock = nbtsock; + state->address_idx = 0; + + state->req = nbt_name_refresh_send(nbtsock, state->io); + if (state->req == NULL) goto failed; + + state->req->async.fn = name_refresh_wins_handler; + state->req->async.private = c; + + c->private = state; + c->state = SMBCLI_REQUEST_SEND; + c->event_ctx = nbtsock->event_ctx; + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + multi-homed WINS name refresh - recv side +*/ +NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io) +{ + NTSTATUS status; + status = composite_wait(c); + if (NT_STATUS_IS_OK(status)) { + struct refresh_wins_state *state = + talloc_get_type(c->private, struct refresh_wins_state); + io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); + io->out.rcode = state->io->out.rcode; + } + talloc_free(c); + return status; +} + +/* + multi-homed WINS refresh - sync interface +*/ +NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io) +{ + struct composite_context *c = nbt_name_refresh_wins_send(nbtsock, io); + return nbt_name_refresh_wins_recv(c, mem_ctx, io); +} diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 4701d0c1bc..9e9a1e1710 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -72,7 +72,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, - timeval_current_ofs(io->in.timeout, 0), False); + io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; talloc_free(packet); @@ -143,7 +143,6 @@ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, struct register_bcast_state { struct nbt_name_socket *nbtsock; struct nbt_name_register *io; - int num_sends; struct nbt_name_request *req; }; @@ -151,7 +150,7 @@ struct register_bcast_state { /* state handler for 4 stage name registration */ -static void name_register_handler(struct nbt_name_request *req) +static void name_register_bcast_handler(struct nbt_name_request *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); struct register_bcast_state *state = talloc_get_type(c->private, struct register_bcast_state); @@ -159,23 +158,22 @@ static void name_register_handler(struct nbt_name_request *req) status = nbt_name_register_recv(state->req, state, state->io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - /* the registration timed out - good, send the next one */ - state->num_sends++; - if (state->num_sends == 4) { + if (state->io->in.register_demand == True) { /* all done */ c->state = SMBCLI_REQUEST_DONE; c->status = NT_STATUS_OK; goto done; } - if (state->num_sends == 3) { - state->io->in.register_demand = True; - } + + /* the registration timed out - good, send the demand */ + state->io->in.register_demand = True; + state->io->in.retries = 0; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { c->state = SMBCLI_REQUEST_ERROR; c->status = NT_STATUS_NO_MEMORY; } else { - state->req->async.fn = name_register_handler; + state->req->async.fn = name_register_bcast_handler; state->req->async.private = c; } } else if (!NT_STATUS_IS_OK(status)) { @@ -225,14 +223,14 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n state->io->in.broadcast = True; state->io->in.ttl = io->in.ttl; state->io->in.timeout = 1; + state->io->in.retries = 2; - state->num_sends = 0; state->nbtsock = nbtsock; state->req = nbt_name_register_send(nbtsock, state->io); if (state->req == NULL) goto failed; - state->req->async.fn = name_register_handler; + state->req->async.fn = name_register_bcast_handler; state->req->async.private = c; c->private = state; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 94c0ced95d..3567224dea 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -108,6 +108,40 @@ failed: } +/* + handle a request timeout +*/ +static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct nbt_name_request *req = talloc_get_type(private, + struct nbt_name_request); + + if (req->num_retries != 0) { + req->num_retries--; + req->te = event_add_timed(req->nbtsock->event_ctx, req, + timeval_add(&t, req->timeout, 0), + nbt_name_socket_timeout, req); + DLIST_ADD_END(req->nbtsock->send_queue, req, struct nbt_name_request *); + EVENT_FD_WRITEABLE(req->nbtsock->fde); + return; + } + + nbt_name_request_destructor(req); + if (req->num_replies == 0) { + req->state = NBT_REQUEST_TIMEOUT; + req->status = NT_STATUS_IO_TIMEOUT; + } else { + req->state = NBT_REQUEST_DONE; + req->status = NT_STATUS_OK; + } + if (req->async.fn) { + req->async.fn(req); + } +} + + + /* handle recv events on a nbt name socket */ @@ -143,6 +177,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) return; } + /* parse the request */ status = ndr_pull_struct_blob(&blob, packet, packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); if (!NT_STATUS_IS_OK(status)) { @@ -158,6 +193,8 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) NDR_PRINT_DEBUG(nbt_name_packet, packet); } + /* if its not a reply then pass it off to the incoming request + handler, if any */ if (!(packet->operation & NBT_FLAG_REPLY)) { if (nbtsock->incoming.handler) { nbtsock->incoming.handler(nbtsock, packet, src_addr, src_port); @@ -175,34 +212,61 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) return; } + /* if this is a WACK response, this we need to go back to waiting, + but perhaps increase the timeout */ + if ((packet->operation & NBT_OPCODE) == NBT_OPCODE_WACK) { + if (req->received_wack || packet->ancount < 1) { + nbt_name_request_destructor(req); + req->status = NT_STATUS_INVALID_NETWORK_RESPONSE; + req->state = NBT_REQUEST_ERROR; + goto done; + } + talloc_free(req->te); + /* we know we won't need any more retries - the server + has received our request */ + req->num_retries = 0; + req->received_wack = True; + if (packet->answers[0].ttl != 0) { + req->timeout = MIN(packet->answers[0].ttl, 20); + } + req->te = event_add_timed(req->nbtsock->event_ctx, req, + timeval_current_ofs(req->timeout, 0), + nbt_name_socket_timeout, req); + DLIST_ADD_END(req->nbtsock->send_queue, req, struct nbt_name_request *); + EVENT_FD_WRITEABLE(req->nbtsock->fde); + talloc_free(tmp_ctx); + return; + } + + req->replies = talloc_realloc(req, req->replies, struct nbt_name_reply, req->num_replies+1); if (req->replies == NULL) { nbt_name_request_destructor(req); - req->state = NBT_REQUEST_DONE; + req->state = NBT_REQUEST_ERROR; req->status = NT_STATUS_NO_MEMORY; - talloc_free(tmp_ctx); - if (req->async.fn) { - req->async.fn(req); - } - return; + goto done; } req->replies[req->num_replies].reply_addr = talloc_steal(req, src_addr); req->replies[req->num_replies].reply_port = src_port; - req->replies[req->num_replies].packet = talloc_steal(req, packet); + req->replies[req->num_replies].packet = talloc_steal(req, packet); req->num_replies++; - talloc_free(tmp_ctx); - /* if we don't want multiple replies then we are done */ - if (!req->allow_multiple_replies || - req->num_replies == NBT_MAX_REPLIES) { - nbt_name_request_destructor(req); - req->state = NBT_REQUEST_DONE; - req->status = NT_STATUS_OK; - if (req->async.fn) { - req->async.fn(req); - } + if (req->allow_multiple_replies && + req->num_replies < NBT_MAX_REPLIES) { + talloc_free(tmp_ctx); + return; + } + + nbt_name_request_destructor(req); + req->state = NBT_REQUEST_DONE; + req->status = NT_STATUS_OK; + +done: + talloc_free(tmp_ctx); + if (req->async.fn) { + req->async.fn(req); } } @@ -265,34 +329,13 @@ failed: return NULL; } -/* - handle a request timeout -*/ -static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) -{ - struct nbt_name_request *req = talloc_get_type(private, - struct nbt_name_request); - nbt_name_request_destructor(req); - if (req->num_replies == 0) { - req->state = NBT_REQUEST_TIMEOUT; - req->status = NT_STATUS_IO_TIMEOUT; - } else { - req->state = NBT_REQUEST_DONE; - req->status = NT_STATUS_OK; - } - if (req->async.fn) { - req->async.fn(req); - } -} - /* send off a nbt name request */ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, const char *dest_addr, int dest_port, struct nbt_name_packet *request, - struct timeval timeout, + int timeout, int retries, BOOL allow_multiple_replies) { struct nbt_name_request *req; @@ -302,13 +345,15 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, req = talloc_zero(nbtsock, struct nbt_name_request); if (req == NULL) goto failed; - req->nbtsock = nbtsock; - req->dest_addr = talloc_strdup(req, dest_addr); - if (req->dest_addr == NULL) goto failed; - req->dest_port = dest_port; + req->nbtsock = nbtsock; + req->dest_port = dest_port; req->allow_multiple_replies = allow_multiple_replies; - req->state = NBT_REQUEST_SEND; - req->is_reply = False; + req->state = NBT_REQUEST_SEND; + req->is_reply = False; + req->timeout = timeout; + req->num_retries = retries; + req->dest_addr = talloc_strdup(req, dest_addr); + if (req->dest_addr == NULL) goto failed; /* we select a random transaction id unless the user supplied one */ if (request->name_trn_id == 0) { @@ -331,7 +376,8 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, request->name_trn_id = id; req->name_trn_id = id; - req->te = event_add_timed(nbtsock->event_ctx, req, timeout, + req->te = event_add_timed(nbtsock->event_ctx, req, + timeval_current_ofs(req->timeout, 0), nbt_name_socket_timeout, req); talloc_set_destructor(req, nbt_name_request_destructor); -- cgit From fcb78064bf760ab72d213b604cef9688edf42b92 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 7 Feb 2005 11:56:34 +0000 Subject: r5260: - show an error message on nmblookup failure - always try to enable broadcast on nbt name sockets (this matches samba3 behaviour better) (This used to be commit 919bc14e7bbc04479cf11f7a7fd4c5e46616ef46) --- source4/libcli/nbt/nbtsocket.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 3567224dea..f6566e8a6e 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -309,6 +309,8 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, status = socket_create("ip", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0); if (!NT_STATUS_IS_OK(status)) goto failed; + socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); + talloc_steal(nbtsock, nbtsock->sock); nbtsock->idr = idr_init(nbtsock); @@ -388,10 +390,6 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); - if (request->operation & NBT_FLAG_BROADCAST) { - socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); - } - if (DEBUGLVL(10)) { DEBUG(10,("Queueing nbt packet to %s:%d\n", req->dest_addr, req->dest_port)); -- cgit From b69a2c0d6bc0643b98ace2489cbcc2d40b99baeb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 7 Feb 2005 12:10:38 +0000 Subject: r5261: translate nbt rcode errors to NTSTATUS codes (This used to be commit 554d1b70e73faeb1f5ecf88f31c5810d86d76200) --- source4/libcli/nbt/libnbt.h | 2 ++ source4/libcli/nbt/namequery.c | 2 ++ source4/libcli/nbt/nbtsocket.c | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 7ccd6a51a4..c126f59280 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -132,6 +132,7 @@ struct nbt_name_query { struct nbt_name name; int16_t num_addrs; const char **reply_addrs; + uint8_t rcode; } out; }; @@ -147,6 +148,7 @@ struct nbt_name_status { const char *reply_from; struct nbt_name name; struct nbt_rdata_status status; + uint8_t rcode; } out; }; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index ddef2a7d07..32fcad2052 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -91,6 +91,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, return NT_STATUS_INVALID_NETWORK_RESPONSE; } + io->out.rcode = packet->operation & NBT_RCODE; io->out.name = packet->answers[0].name; io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6; io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs); @@ -184,6 +185,7 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, return NT_STATUS_INVALID_NETWORK_RESPONSE; } + io->out.rcode = packet->operation & NBT_RCODE; io->out.name = packet->answers[0].name; talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index f6566e8a6e..38b356338c 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -484,3 +484,29 @@ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, return NT_STATUS_OK; } + +/* + turn a NBT rcode into a NTSTATUS +*/ +NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode) +{ + int i; + struct { + enum nbt_rcode rcode; + NTSTATUS status; + } map[] = { + { NBT_RCODE_FMT, NT_STATUS_INVALID_PARAMETER }, + { NBT_RCODE_SVR, NT_STATUS_SERVER_DISABLED }, + { NBT_RCODE_NAM, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { NBT_RCODE_IMP, NT_STATUS_NOT_SUPPORTED }, + { NBT_RCODE_RFS, NT_STATUS_ACCESS_DENIED }, + { NBT_RCODE_ACT, NT_STATUS_ADDRESS_ALREADY_EXISTS }, + { NBT_RCODE_ACT, NT_STATUS_CONFLICTING_ADDRESSES } + }; + for (i=0;i Date: Tue, 8 Feb 2005 01:05:41 +0000 Subject: r5275: - added support for NBT_OPCODE_MULTI_HOME_REG (opcode 0xf) for WINS name registrations - fixed a bug in the send queue handling on timeouts - added support for handling unexpected replies (replies to the wrong port) at the nbtsocket layer - added separate layer 2 code for wins refresh and wins registration (This used to be commit 2502b02898407e3262c09a5a4aa573c5f87b8f5f) --- source4/libcli/nbt/libnbt.h | 33 +++++++- source4/libcli/nbt/namerefresh.c | 4 +- source4/libcli/nbt/nameregister.c | 169 +++++++++++++++++++++++++++++++++++++- source4/libcli/nbt/nbtsocket.c | 28 ++++--- 4 files changed, 218 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index c126f59280..63711490fe 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -113,7 +113,13 @@ struct nbt_name_socket { const char *, int ); void *private; } incoming; - + + /* what to do with unexpected replies */ + struct { + void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, + const char *, int ); + void *private; + } unexpected; }; @@ -161,6 +167,7 @@ struct nbt_name_register { uint16_t nb_flags; BOOL register_demand; BOOL broadcast; + BOOL multi_homed; uint32_t ttl; int timeout; /* in seconds */ int retries; @@ -184,9 +191,10 @@ struct nbt_name_register_bcast { } in; }; -/* wins name refresh with multiple wins servers to try and multiple + +/* wins name register with multiple wins servers to try and multiple addresses to register */ -struct nbt_name_refresh_wins { +struct nbt_name_register_wins { struct { struct nbt_name name; const char **wins_servers; @@ -201,6 +209,7 @@ struct nbt_name_refresh_wins { }; + /* a name refresh request */ struct nbt_name_refresh { struct { @@ -220,3 +229,21 @@ struct nbt_name_refresh { uint8_t rcode; } out; }; + +/* wins name refresh with multiple wins servers to try and multiple + addresses to register */ +struct nbt_name_refresh_wins { + struct { + struct nbt_name name; + const char **wins_servers; + const char **addresses; + uint16_t nb_flags; + uint32_t ttl; + } in; + struct { + const char *wins_server; + uint8_t rcode; + } out; +}; + + diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index d8dbede727..99d79054a6 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -141,8 +141,8 @@ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, struct refresh_wins_state { struct nbt_name_socket *nbtsock; struct nbt_name_refresh *io; - char **wins_servers; - char **addresses; + const char **wins_servers; + const char **addresses; int address_idx; struct nbt_name_request *req; }; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 9e9a1e1710..b0ed1ae89c 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -40,7 +40,11 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, packet->qdcount = 1; packet->arcount = 1; - packet->operation = NBT_OPCODE_REGISTER; + if (io->in.multi_homed) { + packet->operation = NBT_OPCODE_MULTI_HOME_REG; + } else { + packet->operation = NBT_OPCODE_REGISTER; + } if (io->in.broadcast) { packet->operation |= NBT_FLAG_BROADCAST; } @@ -221,6 +225,7 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n state->io->in.nb_flags = io->in.nb_flags; state->io->in.register_demand = False; state->io->in.broadcast = True; + state->io->in.multi_homed = False; state->io->in.ttl = io->in.ttl; state->io->in.timeout = 1; state->io->in.retries = 2; @@ -264,3 +269,165 @@ NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock, struct composite_context *c = nbt_name_register_bcast_send(nbtsock, io); return nbt_name_register_bcast_recv(c); } + + +/* + a wins name register with multiple WINS servers and multiple + addresses to register. Try each WINS server in turn, until we get a + reply for each address +*/ +struct register_wins_state { + struct nbt_name_socket *nbtsock; + struct nbt_name_register *io; + const char **wins_servers; + const char **addresses; + int address_idx; + struct nbt_name_request *req; +}; + + +/* + state handler for WINS multi-homed multi-server name register +*/ +static void name_register_wins_handler(struct nbt_name_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + struct register_wins_state *state = talloc_get_type(c->private, + struct register_wins_state); + NTSTATUS status; + + status = nbt_name_register_recv(state->req, state, state->io); + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + /* the register timed out - try the next WINS server */ + state->wins_servers++; + state->address_idx = 0; + if (state->wins_servers[0] == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = status; + goto done; + } + state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.address = state->addresses[0]; + state->req = nbt_name_register_send(state->nbtsock, state->io); + if (state->req == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } else { + state->req->async.fn = name_register_wins_handler; + state->req->async.private = c; + } + } else if (!NT_STATUS_IS_OK(status)) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = status; + } else { + if (state->io->out.rcode == 0 && + state->addresses[state->address_idx+1] != NULL) { + /* register our next address */ + state->io->in.address = state->addresses[++(state->address_idx)]; + state->req = nbt_name_register_send(state->nbtsock, state->io); + if (state->req == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } else { + state->req->async.fn = name_register_wins_handler; + state->req->async.private = c; + } + } else { + c->state = SMBCLI_REQUEST_DONE; + c->status = NT_STATUS_OK; + } + } + +done: + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); + } +} + +/* + the async send call for a multi-server WINS register +*/ +struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, + struct nbt_name_register_wins *io) +{ + struct composite_context *c; + struct register_wins_state *state; + + c = talloc_zero(nbtsock, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct register_wins_state); + if (state == NULL) goto failed; + + state->io = talloc(state, struct nbt_name_register); + if (state->io == NULL) goto failed; + + state->wins_servers = str_list_copy(state, io->in.wins_servers); + if (state->wins_servers == NULL || + state->wins_servers[0] == NULL) goto failed; + + state->addresses = str_list_copy(state, io->in.addresses); + if (state->addresses == NULL || + state->addresses[0] == NULL) goto failed; + + state->io->in.name = io->in.name; + state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.address = io->in.addresses[0]; + state->io->in.nb_flags = io->in.nb_flags; + state->io->in.broadcast = False; + state->io->in.register_demand = False; + state->io->in.multi_homed = (io->in.nb_flags & NBT_NM_GROUP)?False:True; + state->io->in.ttl = io->in.ttl; + state->io->in.timeout = 3; + state->io->in.retries = 2; + + state->nbtsock = nbtsock; + state->address_idx = 0; + + state->req = nbt_name_register_send(nbtsock, state->io); + if (state->req == NULL) goto failed; + + state->req->async.fn = name_register_wins_handler; + state->req->async.private = c; + + c->private = state; + c->state = SMBCLI_REQUEST_SEND; + c->event_ctx = nbtsock->event_ctx; + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + multi-homed WINS name register - recv side +*/ +NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct nbt_name_register_wins *io) +{ + NTSTATUS status; + status = composite_wait(c); + if (NT_STATUS_IS_OK(status)) { + struct register_wins_state *state = + talloc_get_type(c->private, struct register_wins_state); + io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); + io->out.rcode = state->io->out.rcode; + } + talloc_free(c); + return status; +} + +/* + multi-homed WINS register - sync interface +*/ +NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, + struct nbt_name_register_wins *io) +{ + struct composite_context *c = nbt_name_register_wins_send(nbtsock, io); + return nbt_name_register_wins_recv(c, mem_ctx, io); +} diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 38b356338c..c771d3b4f5 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -82,10 +82,10 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) } DLIST_REMOVE(nbtsock->send_queue, req); + req->state = NBT_REQUEST_WAIT; if (req->is_reply) { talloc_free(req); } else { - req->state = NBT_REQUEST_WAIT; EVENT_FD_READABLE(nbtsock->fde); nbtsock->num_pending++; } @@ -122,7 +122,11 @@ static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event req->te = event_add_timed(req->nbtsock->event_ctx, req, timeval_add(&t, req->timeout, 0), nbt_name_socket_timeout, req); - DLIST_ADD_END(req->nbtsock->send_queue, req, struct nbt_name_request *); + if (req->state != NBT_REQUEST_SEND) { + req->state = NBT_REQUEST_SEND; + DLIST_ADD_END(req->nbtsock->send_queue, req, + struct nbt_name_request *); + } EVENT_FD_WRITEABLE(req->nbtsock->fde); return; } @@ -206,8 +210,12 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) /* find the matching request */ req = idr_find(nbtsock->idr, packet->name_trn_id); if (req == NULL) { - DEBUG(2,("Failed to match request for incoming name packet id 0x%04x\n", - packet->name_trn_id)); + if (nbtsock->unexpected.handler) { + nbtsock->unexpected.handler(nbtsock, packet, src_addr, src_port); + } else { + DEBUG(2,("Failed to match request for incoming name packet id 0x%04x on %p\n", + packet->name_trn_id, nbtsock)); + } talloc_free(tmp_ctx); return; } @@ -227,13 +235,11 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req->num_retries = 0; req->received_wack = True; if (packet->answers[0].ttl != 0) { - req->timeout = MIN(packet->answers[0].ttl, 20); + req->timeout = MIN(packet->answers[0].ttl, 20); } - req->te = event_add_timed(req->nbtsock->event_ctx, req, - timeval_current_ofs(req->timeout, 0), - nbt_name_socket_timeout, req); - DLIST_ADD_END(req->nbtsock->send_queue, req, struct nbt_name_request *); - EVENT_FD_WRITEABLE(req->nbtsock->fde); + req->te = event_add_timed(req->nbtsock->event_ctx, req, + timeval_current_ofs(req->timeout, 0), + nbt_name_socket_timeout, req); talloc_free(tmp_ctx); return; } @@ -319,6 +325,7 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, nbtsock->send_queue = NULL; nbtsock->num_pending = 0; nbtsock->incoming.handler = NULL; + nbtsock->unexpected.handler = NULL; nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock, socket_get_fd(nbtsock->sock), 0, @@ -375,6 +382,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, UINT16_MAX); } if (id == -1) goto failed; + request->name_trn_id = id; req->name_trn_id = id; -- cgit From 632acd9bc7704ac3d326354808c3d12f4f0a9f8f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 9 Feb 2005 21:10:23 +0000 Subject: r5286: Some first steps in making the pidl code somewhat more generic for the various data types: Add ndr_flags argument to all ndr push/pull scalar functions (This used to be commit ab490c0c882bb13de190546c50a0631ecb8255ad) --- source4/libcli/nbt/nbtname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 0584f55fb1..7eb48e5b9e 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -276,10 +276,10 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name /* push the components */ for (i=0;i Date: Thu, 10 Feb 2005 03:22:47 +0000 Subject: r5294: - added a separate NBT-WINS test for WINS operations (register, refresh, release and query) - change the iface_n_*() functions to return a "const char *" instead of a "struct ipv4_addr" I think that in general we should move towards "const char *" for all IP addresses, as this makes IPv6 much easier, and is also easier to debug. Andrew, when you get a chance, could you fix some of the auth code to use strings for IPs ? - return a NTSTATUS error on bad name queries and node status instead of using rcode. This makes the calling code simpler. - added low level name release code in libcli/nbt/ - use a real IP in the register and wins nbt torture tests, as w2k3 WINS server silently rejects some operations that don't come from the IP being used (eg. it says "yes" to a release, but does not in fact release the name) (This used to be commit bb1ab11d8e0ea0bd9ae34aebeb565d36fe4b495f) --- source4/libcli/config.mk | 3 +- source4/libcli/nbt/libnbt.h | 20 +++++- source4/libcli/nbt/namequery.c | 16 ++++- source4/libcli/nbt/namerelease.c | 129 +++++++++++++++++++++++++++++++++++++++ source4/libcli/resolve/bcast.c | 3 +- 5 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 source4/libcli/nbt/namerelease.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 038b8e0ccb..726d3f1184 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -31,7 +31,8 @@ ADD_OBJ_FILES = \ libcli/nbt/nbtsocket.o \ libcli/nbt/namequery.o \ libcli/nbt/nameregister.o \ - libcli/nbt/namerefresh.o + libcli/nbt/namerefresh.o \ + libcli/nbt/namerelease.o REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 63711490fe..5a53510ccf 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -138,7 +138,6 @@ struct nbt_name_query { struct nbt_name name; int16_t num_addrs; const char **reply_addrs; - uint8_t rcode; } out; }; @@ -154,7 +153,6 @@ struct nbt_name_status { const char *reply_from; struct nbt_name name; struct nbt_rdata_status status; - uint8_t rcode; } out; }; @@ -247,3 +245,21 @@ struct nbt_name_refresh_wins { }; +/* a name release request */ +struct nbt_name_release { + struct { + struct nbt_name name; + const char *dest_addr; + const char *address; + uint16_t nb_flags; + BOOL broadcast; + int timeout; /* in seconds */ + int retries; + } in; + struct { + const char *reply_from; + struct nbt_name name; + const char *reply_addr; + uint8_t rcode; + } out; +}; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 32fcad2052..5907c45b87 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -84,14 +84,19 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, packet = req->replies[0].packet; io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + if ((packet->operation & NBT_RCODE) != 0) { + status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); + talloc_free(req); + return status; + } + if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || packet->answers[0].rr_class != NBT_QCLASS_IP) { talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; + return status; } - io->out.rcode = packet->operation & NBT_RCODE; io->out.name = packet->answers[0].name; io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6; io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs); @@ -178,6 +183,12 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, packet = req->replies[0].packet; io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + if ((packet->operation & NBT_RCODE) != 0) { + status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); + talloc_free(req); + return status; + } + if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_STATUS || packet->answers[0].rr_class != NBT_QCLASS_IP) { @@ -185,7 +196,6 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, return NT_STATUS_INVALID_NETWORK_RESPONSE; } - io->out.rcode = packet->operation & NBT_RCODE; io->out.name = packet->answers[0].name; talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c new file mode 100644 index 0000000000..208c73d386 --- /dev/null +++ b/source4/libcli/nbt/namerelease.c @@ -0,0 +1,129 @@ +/* + Unix SMB/CIFS implementation. + + send out a name release request + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/nbt/libnbt.h" + +/* + send a nbt name release request +*/ +struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, + struct nbt_name_release *io) +{ + struct nbt_name_request *req; + struct nbt_name_packet *packet; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return NULL; + + packet->qdcount = 1; + packet->arcount = 1; + packet->operation = NBT_OPCODE_RELEASE; + if (io->in.broadcast) { + packet->operation |= NBT_FLAG_BROADCAST; + } + + packet->questions = talloc_array(packet, struct nbt_name_question, 1); + if (packet->questions == NULL) goto failed; + + packet->questions[0].name = io->in.name; + packet->questions[0].question_type = NBT_QTYPE_NETBIOS; + packet->questions[0].question_class = NBT_QCLASS_IP; + + packet->additional = talloc_array(packet, struct nbt_res_rec, 1); + if (packet->additional == NULL) goto failed; + + packet->additional[0].name = io->in.name; + packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; + packet->additional[0].rr_class = NBT_QCLASS_IP; + packet->additional[0].ttl = 0; + packet->additional[0].rdata.netbios.length = 6; + packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, + struct nbt_rdata_address, 1); + if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; + packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; + packet->additional[0].rdata.netbios.addresses[0].ipaddr = + talloc_strdup(packet->additional, io->in.address); + + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + io->in.timeout, io->in.retries, False); + if (req == NULL) goto failed; + + talloc_free(packet); + return req; + +failed: + talloc_free(packet); + return NULL; +} + +/* + wait for a release reply +*/ +NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_release *io) +{ + NTSTATUS status; + struct nbt_name_packet *packet; + + status = nbt_name_request_recv(req); + if (!NT_STATUS_IS_OK(status) || + req->num_replies == 0) { + talloc_free(req); + return status; + } + + packet = req->replies[0].packet; + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + + if (packet->ancount != 1 || + packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || + packet->answers[0].rr_class != NBT_QCLASS_IP) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + io->out.rcode = packet->operation & NBT_RCODE; + io->out.name = packet->answers[0].name; + if (packet->answers[0].rdata.netbios.length < 6) { + talloc_free(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + io->out.reply_addr = talloc_steal(mem_ctx, + packet->answers[0].rdata.netbios.addresses[0].ipaddr); + talloc_steal(mem_ctx, io->out.name.name); + talloc_steal(mem_ctx, io->out.name.scope); + + talloc_free(req); + + return NT_STATUS_OK; +} + +/* + synchronous name release request +*/ +NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_release *io) +{ + struct nbt_name_request *req = nbt_name_release_send(nbtsock, io); + return nbt_name_release_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 5fb6e6dd5c..c47bba38c5 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -40,8 +40,7 @@ struct composite_context *resolve_name_bcast_send(struct nbt_name *name, if (address_list == NULL) return NULL; for (i=0;i Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/libcli/auth/gensec_ntlmssp.c | 4 ++-- source4/libcli/auth/ntlmssp.c | 1 + source4/libcli/auth/ntlmssp_parse.c | 1 + source4/libcli/auth/smbencrypt.c | 1 + source4/libcli/auth/spnego.c | 2 +- source4/libcli/ldap/ldap.c | 5 +++-- source4/libcli/ldap/ldap_client.c | 1 + source4/libcli/raw/clisession.c | 1 + source4/libcli/resolve/host.c | 1 + source4/libcli/util/doserr.c | 1 + source4/libcli/util/nterr.c | 1 + 11 files changed, 14 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 59bab6ced2..524815382d 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -29,7 +29,7 @@ struct gensec_ntlmssp_state { struct auth_context *auth_context; struct auth_serversupplied_info *server_info; struct ntlmssp_state *ntlmssp_state; - uint32 have_features; + uint32_t have_features; }; @@ -470,7 +470,7 @@ static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_secur } static BOOL gensec_ntlmssp_have_feature(struct gensec_security *gensec_security, - uint32 feature) + uint32_t feature) { struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; if (gensec_ntlmssp_state->have_features & feature) { diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index d5ddcfbfb6..572ce66bb2 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -24,6 +24,7 @@ #include "includes.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" +#include "pstring.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c index 543f3d9b61..42546cb130 100644 --- a/source4/libcli/auth/ntlmssp_parse.c +++ b/source4/libcli/auth/ntlmssp_parse.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "pstring.h" /* this is a tiny msrpc packet generator. I am only using this to diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 7e2890272c..00a28a1ad9 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -26,6 +26,7 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" +#include "pstring.h" /* This implements the X/Open SMB password encryption diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index a61680c9d4..3980767165 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -844,7 +844,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } static BOOL gensec_spnego_have_feature(struct gensec_security *gensec_security, - uint32 feature) + uint32_t feature) { struct spnego_state *spnego_state = gensec_security->private_data; if (!spnego_state->sub_sec_security) { diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 655838b64f..545759c494 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/iconv.h" +#include "system/filesys.h" #include "asn_1.h" /**************************************************************************** @@ -697,7 +698,7 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, char **filter) { - uint8 filter_tag, tag_desc; + uint8_t filter_tag, tag_desc; if (!asn1_peek_uint8(data, &filter_tag)) return False; @@ -836,7 +837,7 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) { - uint8 tag; + uint8_t tag; asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_Integer(data, &msg->messageid); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 73099ec1be..ddf0932fa1 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/network.h" +#include "system/filesys.h" #include "auth/auth.h" #include "asn_1.h" #include "dlinklist.h" diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 30382e0837..4eba464274 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "system/filesys.h" #include "auth/auth.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index cbf0f4614e..9f48f83ba4 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -32,6 +32,7 @@ #include "includes.h" #include "lib/events/events.h" #include "system/network.h" +#include "system/filesys.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index a584def829..b346fea644 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -21,6 +21,7 @@ /* DOS error codes. please read doserr.h */ #include "includes.h" +#include "pstring.h" struct werror_code_struct { const char *dos_errstr; diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 9317f0e37a..d727cfe2a9 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -21,6 +21,7 @@ /* NT error codes. please read nterr.h */ #include "includes.h" +#include "pstring.h" typedef struct { -- cgit From 8674eaa5cc9b1ddeb65f05527a5b539f15e4afcb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:22:53 +0000 Subject: r5300: more uint32 and system/filesys.h build fixes when developer mode is enabled (This used to be commit 93931b1a741a3722c311ada80c4c9d3d670f91b2) --- source4/libcli/auth/gensec_gssapi.c | 2 +- source4/libcli/auth/gensec_krb5.c | 6 +++--- source4/libcli/auth/kerberos.c | 1 + source4/libcli/auth/kerberos_verify.c | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index 43113412f7..41f36b2703 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -316,7 +316,7 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, } static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, - uint32 feature) + uint32_t feature) { struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; if (feature & GENSEC_FEATURE_SIGN) { diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index e5bfd3865a..a0c2a77f4b 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -489,7 +489,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, { krb5_data inbuf; krb5_ap_rep_enc_part *repl = NULL; - uint8 tok_id[2]; + uint8_t tok_id[2]; DATA_BLOB unwrapped_in; if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { @@ -525,7 +525,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, char *principal; DATA_BLOB unwrapped_in; DATA_BLOB unwrapped_out = data_blob(NULL, 0); - uint8 tok_id[2]; + uint8_t tok_id[2]; if (!in.data) { *out = unwrapped_out; @@ -689,7 +689,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security } static BOOL gensec_krb5_have_feature(struct gensec_security *gensec_security, - uint32 feature) + uint32_t feature) { if (feature & GENSEC_FEATURE_SESSION_KEY) { return True; diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index a8d9d75a1e..4bf9e626ce 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -26,6 +26,7 @@ #include "libcli/auth/kerberos.h" #include "system/time.h" #include "secrets.h" +#include "pstring.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index b089d633ed..2aef38fcd9 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -28,6 +28,7 @@ #include "asn_1.h" #include "lib/ldb/include/ldb.h" #include "secrets.h" +#include "pstring.h" #ifdef HAVE_KRB5 -- cgit From bed7c9ec32b7d4083ba4ed2abbf3b6126bee7a25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 06:59:29 +0000 Subject: r5304: removed lib/socket/socket.h from includes.h (This used to be commit b902ea546d2d1327b23f40ddaeeaa8e7e3662454) --- source4/libcli/nbt/nbtsocket.c | 1 + source4/libcli/raw/clisocket.c | 1 + source4/libcli/raw/clitransport.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index c771d3b4f5..dd14e76706 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -24,6 +24,7 @@ #include "lib/events/events.h" #include "dlinklist.h" #include "libcli/nbt/libnbt.h" +#include "lib/socket/socket.h" #define NBT_MAX_PACKET_SIZE 2048 #define NBT_MAX_REPLIES 1000 diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 44c6a87e21..cbb479ca1a 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -25,6 +25,7 @@ #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "lib/socket/socket.h" /* this private structure is used during async connection handling diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 079783435c..ee382da3c2 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "lib/socket/socket.h" #include "system/time.h" #include "dlinklist.h" #include "lib/events/events.h" -- cgit From 501379431c7fc6c9a78e74eca43b208184debce6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:08:40 +0000 Subject: r5305: removed libcli/ldap/ldap.h from includes.h (This used to be commit 0df3fdd8178085c40f9cd776cc3e1486ca559c8e) --- source4/libcli/ldap/config.mk | 1 + source4/libcli/ldap/ldap.c | 1 + source4/libcli/ldap/ldap.h | 59 +++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_client.c | 1 + source4/libcli/ldap/ldap_ldif.c | 1 + 5 files changed, 63 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 284edfd95e..87bfdfdbba 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -4,5 +4,6 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ libcli/ldap/ldap_ldif.o +NOPROTO=YES # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 545759c494..4b449e5123 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -27,6 +27,7 @@ #include "system/iconv.h" #include "system/filesys.h" #include "asn_1.h" +#include "libcli/ldap/ldap.h" /**************************************************************************** * diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 8947562b77..3e51e4f60f 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -317,4 +317,63 @@ struct ldap_parse_tree { #define LDAP_ALL_SEP "()&|=!" #define LDAP_CONNECTION_TIMEOUT 10000 +/* The following definitions come from libcli/ldap/ldap.c */ + +BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); +BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); +BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, + char **host, uint16_t *port, BOOL *ldaps); + +/* The following definitions come from libcli/ldap/ldap_client.c */ + +struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url); +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime); +BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime); +struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, + const struct timeval *endtime); +struct ldap_message *ldap_transaction(struct ldap_connection *conn, + struct ldap_message *request); +int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password); +int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password); +struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, + const char *userdn, const char *password); +struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, + const char *username, const char *domain, const char *password); +BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, + const struct timeval *endtime); +BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime); +struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, + const struct timeval *endtime); +void ldap_endsearchent(struct ldap_connection *conn, + const struct timeval *endtime); +struct ldap_message *ldap_searchone(struct ldap_connection *conn, + struct ldap_message *msg, + const struct timeval *endtime); +BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, + DATA_BLOB *value); +BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, + TALLOC_CTX *mem_ctx, char **value); +BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, + int *value); +int ldap_error(struct ldap_connection *conn); +NTSTATUS ldap2nterror(int ldaperror); + +/* The following definitions come from libcli/ldap/ldap_ldif.c */ + +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, + struct ldap_attribute *attrib); +BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldap_attribute *attrib, + struct ldap_attribute **attribs, + int *num_attribs); +BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods); +struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); + #endif diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index ddf0932fa1..11815ddd6d 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -29,6 +29,7 @@ #include "auth/auth.h" #include "asn_1.h" #include "dlinklist.h" +#include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index a0249a4ba0..e5e5cdd6df 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/iconv.h" +#include "libcli/ldap/ldap.h" /**************************************************************************** * -- cgit From 75ddf59ea110117578acd3a7b889549bfb40473c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:39:14 +0000 Subject: r5308: trimmed back a lot of the old macros from smb_macros.h (This used to be commit bf43c9bdcf9e654d123f6a2b29feb9189ca9e561) --- source4/libcli/ldap/ldap_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 11815ddd6d..e3904c7a6b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -223,7 +223,7 @@ static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeo if (type != SOCK_STREAM) return(res); memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + sock_out.sin_addr.s_addr = addr->addr; sock_out.sin_port = htons( port ); sock_out.sin_family = PF_INET; @@ -385,7 +385,7 @@ struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) return NULL; } - putip((char *)&ip, (char *)hp->h_addr); + memcpy((char *)&ip, (char *)hp->h_addr, 4); conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); if (conn->sock < 0) { -- cgit From a0e6f6c05b438765c8bbb6f8e7f7e6478dc67293 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:43:39 +0000 Subject: r5309: removed ads.h from includes.h (This used to be commit 196c45b834c39f293b9533cec5cfe5a77382d4e2) --- source4/libcli/auth/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 4bf9e626ce..2e5a53bb00 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -27,6 +27,7 @@ #include "system/time.h" #include "secrets.h" #include "pstring.h" +#include "ads.h" #ifdef HAVE_KRB5 @@ -149,7 +150,7 @@ int kerberos_kinit_password(const char *principal, } /* run kinit to setup our ccache */ -int ads_kinit_password(ADS_STRUCT *ads) +int ads_kinit_password(struct ads_struct *ads) { char *s; int ret; -- cgit From 9515fc4406464b6a015a06d89ca0370810977486 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 02:08:39 +0000 Subject: r5322: removed a whole bunch of #include lines that minimal_includes.pl thinks are not needed. Now to see how this fares on the build farm :) (This used to be commit 80ffcc650c9c86141507edd8338b97814a85f868) --- source4/libcli/auth/clikrb5.c | 1 - source4/libcli/auth/credentials.c | 1 - source4/libcli/auth/gensec_gssapi.c | 2 -- source4/libcli/auth/gensec_krb5.c | 1 - source4/libcli/auth/gssapi_parse.c | 1 - source4/libcli/auth/kerberos.c | 1 - source4/libcli/cliconnect.c | 1 - source4/libcli/composite/fetchfile.c | 1 - source4/libcli/ldap/ldap.c | 1 - source4/libcli/nbt/namequery.c | 1 - source4/libcli/nbt/namerefresh.c | 1 - source4/libcli/nbt/nameregister.c | 1 - source4/libcli/raw/clisession.c | 1 - source4/libcli/raw/clitransport.c | 1 - source4/libcli/raw/rawacl.c | 1 - source4/libcli/raw/raweas.c | 1 - 16 files changed, 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 051798c9f1..f2536663f4 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -23,7 +23,6 @@ #include "system/network.h" #include "system/kerberos.h" #include "libcli/auth/kerberos.h" -#include "system/time.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 18ce6fec1b..bcb462ae9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -25,7 +25,6 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" -#include "librpc/gen_ndr/ndr_netlogon.h" /* initialise the credentials state for old-style 64 bit session keys diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c index 41f36b2703..c974b93952 100644 --- a/source4/libcli/auth/gensec_gssapi.c +++ b/source4/libcli/auth/gensec_gssapi.c @@ -23,8 +23,6 @@ #include "includes.h" #include "system/kerberos.h" -#include "system/time.h" -#include "libcli/auth/kerberos.h" #include "auth/auth.h" #undef DBGC_CLASS diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index a0c2a77f4b..1fc33d3644 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -26,7 +26,6 @@ #include "includes.h" #include "system/kerberos.h" -#include "system/time.h" #include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c index f984f6303f..89929c8c6d 100644 --- a/source4/libcli/auth/gssapi_parse.c +++ b/source4/libcli/auth/gssapi_parse.c @@ -25,7 +25,6 @@ #include "includes.h" #include "asn_1.h" #include "system/kerberos.h" -#include "libcli/auth/kerberos.h" #include "libcli/auth/gensec.h" /* diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 2e5a53bb00..186da0fcf4 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -24,7 +24,6 @@ #include "includes.h" #include "system/kerberos.h" #include "libcli/auth/kerberos.h" -#include "system/time.h" #include "secrets.h" #include "pstring.h" #include "ads.h" diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 263527ffc0..f391b6bc0d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "system/filesys.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index 4f63f6328f..a7d6f2ffd8 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -24,7 +24,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_security.h" enum fetchfile_stage {FETCHFILE_CONNECT, FETCHFILE_READ}; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 4b449e5123..2962f7eef4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,7 +25,6 @@ #include "includes.h" #include "system/iconv.h" -#include "system/filesys.h" #include "asn_1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 5907c45b87..a9748c7bd2 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -22,7 +22,6 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" -#include "system/network.h" /* send a nbt name query diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 99d79054a6..a344f2c6e8 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -24,7 +24,6 @@ #include "libcli/nbt/libnbt.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -#include "system/network.h" /* send a nbt name refresh request diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index b0ed1ae89c..9c1db38529 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -24,7 +24,6 @@ #include "libcli/nbt/libnbt.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -#include "system/network.h" /* send a nbt name registration request diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 4eba464274..5f75701871 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -23,7 +23,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "system/filesys.h" -#include "auth/auth.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ req = smbcli_request_setup_session(session, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index ee382da3c2..05833b2f9a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -23,7 +23,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "lib/socket/socket.h" -#include "system/time.h" #include "dlinklist.h" #include "lib/events/events.h" diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index b2dac09f81..82c69ec706 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -21,7 +21,6 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_security.h" -#include "libcli/raw/libcliraw.h" /**************************************************************************** fetch file ACL (async send) diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 49be9a43e6..4ab3344135 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" /* work out how many bytes on the wire a ea list will consume. -- cgit From 82fd60e904d93ef38c43cee423b668c1327f22aa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 06:58:07 +0000 Subject: r5325: - expanded the NBT-WINS test to include scopes - fixed the bugs that the new test found (This used to be commit 6d775f12168d51ce92a3f7e17f4bf06357d41a06) --- source4/libcli/nbt/nbtname.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 7eb48e5b9e..1b53cb3ca6 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -202,12 +202,13 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name /* combine the remaining components into the scope */ scope = components[1]; for (i=2;iscope)+1, &p); + strlen(scope)+1, &p); if (ret <= 0) { return NT_STATUS_BAD_NETWORK_NAME; } @@ -265,10 +266,12 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name num_components < MAX_COMPONENTS) { *p = 0; components[num_components] = dscope; - NT_STATUS_HAVE_NO_MEMORY(components[num_components]); dscope = p+1; num_components++; } + if (dscope && num_components < MAX_COMPONENTS) { + components[num_components++] = dscope; + } if (num_components == MAX_COMPONENTS) { return NT_STATUS_BAD_NETWORK_NAME; } -- cgit From f3d1fa124bafde1842c09fa6d408a52f99b5d984 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 07:20:16 +0000 Subject: r5326: removed the charset conversion from the nbtname code, so we no longer convert from/to DOS strings in NBT names. This will allow us to support all foreign names as a WINS server, as long as they don't contain a 0 byte. (This used to be commit 8e5d3a74d341de086d850d823cf8a1bfc9387fe8) --- source4/libcli/nbt/nbtname.c | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 1b53cb3ca6..1904b33a9b 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -160,8 +160,6 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name uint32_t max_offset = offset; uint8_t *components[MAX_COMPONENTS]; int i; - ssize_t ret; - void *p; uint8_t *scope; if (!(ndr_flags & NDR_SCALARS)) { @@ -192,12 +190,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name status = decompress_name(components[0], &r->type); NT_STATUS_NOT_OK_RETURN(status); - ret = convert_string_talloc(ndr, CH_DOS, CH_UNIX, components[0], - strlen(components[0])+1, &p); - if (ret <= 0) { - return NT_STATUS_BAD_NETWORK_NAME; - } - r->name = p; + r->name = components[0]; /* combine the remaining components into the scope */ scope = components[1]; @@ -206,16 +199,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name NT_STATUS_HAVE_NO_MEMORY(scope); } - if (scope) { - ret = convert_string_talloc(ndr, CH_DOS, CH_UNIX, scope, - strlen(scope)+1, &p); - if (ret <= 0) { - return NT_STATUS_BAD_NETWORK_NAME; - } - r->scope = p; - } else { - r->scope = NULL; - } + r->scope = scope; return NT_STATUS_OK; } @@ -227,31 +211,18 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name { uint_t num_components; uint8_t *components[MAX_COMPONENTS]; - void *ptr; char *dname, *dscope=NULL, *p; uint8_t *cname; - ssize_t ret; int i; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - /* convert to DOS format */ - ret = convert_string_talloc(ndr, CH_UNIX, CH_DOS, r->name, - strlen(r->name)+1, &ptr); - if (ret <= 0) { - return NT_STATUS_BAD_NETWORK_NAME; - } - dname = strupper_talloc(ndr, ptr); + dname = strupper_talloc(ndr, r->name); NT_STATUS_HAVE_NO_MEMORY(dname); if (r->scope) { - ret = convert_string_talloc(ndr, CH_UNIX, CH_DOS, r->scope, - strlen(r->scope)+1, &ptr); - if (ret <= 0) { - return NT_STATUS_BAD_NETWORK_NAME; - } - dscope = strupper_talloc(ndr, ptr); + dscope = strupper_talloc(ndr, r->scope); NT_STATUS_HAVE_NO_MEMORY(dscope); } -- cgit From dd689afdc807b9ff057ee7e917e12b6597fe319c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 07:54:20 +0000 Subject: r5328: - allow case sensitive nbt name lookups - added --case-sensitive option to nmblookup - added case sensitivity tests to the NBT-WINS test (This used to be commit 80a95d5688e055b36727e5c043cb36322d719763) --- source4/libcli/nbt/nbtname.c | 10 ++++------ source4/libcli/resolve/nbtlist.c | 7 +++++++ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 1904b33a9b..0d2840e0b5 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -114,7 +114,7 @@ static NTSTATUS decompress_name(char *name, enum nbt_name_type *type) compress a name component */ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, - uint8_t *name, enum nbt_name_type type) + const uint8_t *name, enum nbt_name_type type) { uint8_t *cname; int i; @@ -211,7 +211,7 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name { uint_t num_components; uint8_t *components[MAX_COMPONENTS]; - char *dname, *dscope=NULL, *p; + char *dscope=NULL, *p; uint8_t *cname; int i; @@ -219,14 +219,12 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name return NT_STATUS_OK; } - dname = strupper_talloc(ndr, r->name); - NT_STATUS_HAVE_NO_MEMORY(dname); if (r->scope) { - dscope = strupper_talloc(ndr, r->scope); + dscope = talloc_strdup(ndr, r->scope); NT_STATUS_HAVE_NO_MEMORY(dscope); } - cname = compress_name(ndr, dname, r->type); + cname = compress_name(ndr, r->name, r->type); NT_STATUS_HAVE_NO_MEMORY(cname); /* form the base components */ diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 5a9e31e09d..89e9a63748 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -101,6 +101,13 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, status = nbt_name_dup(state, name, &state->name); if (!NT_STATUS_IS_OK(status)) goto failed; + state->name.name = strupper_talloc(state, state->name.name); + if (state->name.name == NULL) goto failed; + if (state->name.scope) { + state->name.scope = strupper_talloc(state, state->name.scope); + if (state->name.scope == NULL) goto failed; + } + state->nbtsock = nbt_name_socket_init(state, event_ctx); if (state->nbtsock == NULL) goto failed; -- cgit From c8ca613e935b44488435a269957a68b48d2af90f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Feb 2005 10:15:56 +0000 Subject: r5330: Remove #include from includes.h. Add #include "system/time.h" back (it was removed in some of these places because the definitions were provided by on tridge's platform.) Andrew Bartlett (This used to be commit 34b1da730304bed7fee5bae7cbde7fbccecb6af5) --- source4/libcli/auth/clikrb5.c | 1 + source4/libcli/auth/gensec_krb5.c | 1 + source4/libcli/auth/kerberos.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index f2536663f4..5a196db7a5 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/network.h" #include "system/kerberos.h" +#include "system/time.h" #include "libcli/auth/kerberos.h" #ifdef HAVE_KRB5 diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 1fc33d3644..a0c2a77f4b 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -26,6 +26,7 @@ #include "includes.h" #include "system/kerberos.h" +#include "system/time.h" #include "libcli/auth/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 186da0fcf4..45838c6818 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -23,6 +23,7 @@ #include "includes.h" #include "system/kerberos.h" +#include "system/time.h" #include "libcli/auth/kerberos.h" #include "secrets.h" #include "pstring.h" -- cgit From 7b8f58c37c7a975b93e20bd40b5195960fe22c6f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Feb 2005 01:00:15 +0000 Subject: r5352: added a function nbt_name_string() that formats a nbt_name structure as a human readable string. The format is designed to be able to be used as the DN for the WINS database as well, while coping with arbitrary bytes in the name (except nul bytes) (This used to be commit aac3090e3504ba07124a9d480322a98efb97175e) --- source4/libcli/nbt/nameregister.c | 5 ++-- source4/libcli/nbt/nbtname.c | 57 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 9c1db38529..276b8e4ac3 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -185,10 +185,9 @@ static void name_register_bcast_handler(struct nbt_name_request *req) } else { c->state = SMBCLI_REQUEST_ERROR; c->status = NT_STATUS_CONFLICTING_ADDRESSES; - DEBUG(3,("Name registration conflict from %s for %s<%02x> with ip %s - rcode %d\n", + DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n", state->io->out.reply_from, - state->io->out.name.name, - state->io->out.name.type, + nbt_name_string(state, &state->io->out.name), state->io->out.reply_addr, state->io->out.rcode)); } diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 0d2840e0b5..da5205d818 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -25,6 +25,7 @@ */ #include "includes.h" +#include "system/iconv.h" #include "librpc/gen_ndr/ndr_nbt.h" /* don't allow an unlimited number of name components */ @@ -320,3 +321,59 @@ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, n->name = talloc_strdup(mem_ctx, name); } + + +/* + escape a string into a form containing only a small set of characters, + the rest is hex encoded. This is similar to URL encoding +*/ +static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) +{ + int i, len; + char *ret; + const char *valid_chars = "_-.$@"; + + for (len=i=0;s[i];i++,len++) { + if (!isalnum(s[i]) && !strchr(valid_chars, s[i])) { + len += 2; + } + } + + ret = talloc_array(mem_ctx, char, len+1); + if (ret == NULL) return NULL; + + for (len=i=0;s[i];i++) { + if (isalnum(s[i]) || strchr(valid_chars, s[i])) { + ret[len++] = s[i]; + } else { + snprintf(&ret[len], 3, "%02x", s[i]); + len += 3; + } + } + ret[len] = 0; + + return ret; +} + + +/* + form a string for a NBT name +*/ +const char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) +{ + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + const char *ret; + if (name->scope) { + ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s", + nbt_hex_encode(tmp_ctx, name->name), + name->type, + nbt_hex_encode(tmp_ctx, name->scope)); + } else { + ret = talloc_asprintf(mem_ctx, "%s<%02x>", + nbt_hex_encode(tmp_ctx, name->name), + name->type); + } + talloc_free(tmp_ctx); + return ret; +} + -- cgit From 907d1d413d8c907876ae832a462a21839ac3d19a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Feb 2005 03:10:50 +0000 Subject: r5356: fixed the hex coding for nbt names (This used to be commit e467715c63624e165b79b37bd21b381d7a99d0fe) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index da5205d818..adc66980c4 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -346,7 +346,7 @@ static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) if (isalnum(s[i]) || strchr(valid_chars, s[i])) { ret[len++] = s[i]; } else { - snprintf(&ret[len], 3, "%02x", s[i]); + snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]); len += 3; } } -- cgit From e199f4cef2bac3b244d08d445421975313229283 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Feb 2005 11:33:42 +0000 Subject: r5358: - added initial WINS server code. It passes most of the NBT-WINS test, but doesn't yet do secure server WACK responses - added a ldap_string_to_time() function, for converting a LDAP formatted time to a time_t (This used to be commit 9aa3313b3f93e47e3f93028e072f6a23b3c22385) --- source4/libcli/nbt/nbtname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index adc66980c4..b937d0aa26 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -359,10 +359,10 @@ static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) /* form a string for a NBT name */ -const char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) +char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) { TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - const char *ret; + char *ret; if (name->scope) { ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s", nbt_hex_encode(tmp_ctx, name->name), -- cgit From d8da32a2845b99cc4272fedd28dff570331be63e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 13 Feb 2005 09:10:33 +0000 Subject: r5371: on port 139 the called name needs to be in uppercase (This used to be commit c5aef260c4581bfc0d32ec09fac3414156c40230) --- source4/libcli/raw/clitree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index ce4dafca9f..74db1c6952 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -175,8 +175,8 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.dest_host = dest_host; io.in.port = port; - io.in.called_name = dest_host; - io.in.calling_name = my_name; + io.in.called_name = strupper_talloc(parent_ctx, dest_host); + io.in.calling_name = strupper_talloc(parent_ctx, my_name); io.in.service = service; io.in.service_type = service_type; io.in.domain = domain; -- cgit From 803ce86db9183867be31cc49b63e85ed00c6b226 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Feb 2005 01:02:47 +0000 Subject: r5382: another place where we need to uppercase the called name for port 139 connects (This used to be commit b13cea5b2b55ce3d4109666cf51af6ffd879d15d) --- source4/libcli/nbt/nbtname.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index b937d0aa26..db1e51a1a9 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -311,15 +311,17 @@ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, } if (strlen(name) > 15) { const char *p = strchr(name, '.'); + char *s; if (p - name > 15) { n->name = "*SMBSERVER"; return; } - n->name = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); + s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); + n->name = strupper_talloc(mem_ctx, s); return; } - n->name = talloc_strdup(mem_ctx, name); + n->name = strupper_talloc(mem_ctx, name); } -- cgit From 85fd954145ab9262d5e1930bb7a93d70663abe33 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Feb 2005 06:05:35 +0000 Subject: r5391: cope with w2k3 getting the timeout wrong in wack replies (This used to be commit 75766603e325d515a718b1d1ab0f08160ea1f790) --- source4/libcli/nbt/nbtsocket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index dd14e76706..1d8cf36ea4 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -235,9 +235,9 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) has received our request */ req->num_retries = 0; req->received_wack = True; - if (packet->answers[0].ttl != 0) { - req->timeout = MIN(packet->answers[0].ttl, 20); - } + /* although there can be a timeout in the packet, w2k3 screws it up, + so better to set it ourselves */ + req->timeout = lp_parm_int(-1, "nbt", "wack_timeout", 30); req->te = event_add_timed(req->nbtsock->event_ctx, req, timeval_current_ofs(req->timeout, 0), nbt_name_socket_timeout, req); -- cgit From 352de700cadbb2c4e5b5e9ddc375e9de847e2193 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Feb 2005 09:15:24 +0000 Subject: r5392: added "secure" WINS server processing. Send a WACK on name registrations from anyone who isn't a current owner, then query the owner addresses to see if they still want it. (This used to be commit 8dc2a028d3ca0115d3173df435d926d7b6a4d5d5) --- source4/libcli/nbt/namequery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index a9748c7bd2..f222148f4d 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -98,7 +98,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, io->out.name = packet->answers[0].name; io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6; - io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs); + io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs+1); if (io->out.reply_addrs == NULL) { talloc_free(req); return NT_STATUS_NO_MEMORY; @@ -108,6 +108,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, io->out.reply_addrs[i] = talloc_steal(mem_ctx, packet->answers[0].rdata.netbios.addresses[i].ipaddr); } + io->out.reply_addrs[i] = NULL; talloc_steal(mem_ctx, io->out.name.name); talloc_steal(mem_ctx, io->out.name.scope); -- cgit From 240829d53e34ede37d85de67390e4e8288b27514 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Feb 2005 11:31:48 +0000 Subject: r5396: fixed parsing of NBT type 0xc0 compressed name pointers (This used to be commit 666cc65d10012fa2a413dfa619fbc4599f752728) --- source4/libcli/nbt/nbtname.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index db1e51a1a9..6713c90285 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -55,8 +55,9 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, if (1 + *offset >= ndr->data_size) { return NT_STATUS_BAD_NETWORK_NAME; } + *max_offset = MAX(*max_offset, *offset + 2); *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset]; - *max_offset = MAX(*max_offset, *offset + 1); + *max_offset = MAX(*max_offset, *offset); loops++; continue; } -- cgit From e428eee91b3506c0c02a35dbf01e55da2c73b547 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Feb 2005 23:36:42 +0000 Subject: r5398: fixed encoding of *SMBSERVER name (thanks to Karl Melcher for spotting this) (This used to be commit 76c49851b921c137c59c45084c5dab95f1c16f58) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 6713c90285..fc87c2f4b2 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -133,7 +133,7 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, cname[2*i] = 'A' + (name[i]>>4); cname[1+2*i] = 'A' + (name[i]&0xF); } - if (name[0] == '*') { + if (strcmp(name, "*") == 0) { pad_char = 0; } else { pad_char = ' '; -- cgit From 3bbe3fe4ce33a4a8bc2d3cef640ad16c5e49b843 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Feb 2005 05:14:09 +0000 Subject: r5404: allow spaces in the string representation of nbt names (This used to be commit dd3d4ded21e50130243de3b35927368875620d47) --- source4/libcli/nbt/nbtname.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index fc87c2f4b2..bf545a6374 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -334,10 +334,11 @@ static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) { int i, len; char *ret; - const char *valid_chars = "_-.$@"; + const char *valid_chars = "_-.$@ "; +#define NBT_CHAR_ALLOW(c) (isalnum(c) || strchr(valid_chars, c)) for (len=i=0;s[i];i++,len++) { - if (!isalnum(s[i]) && !strchr(valid_chars, s[i])) { + if (!NBT_CHAR_ALLOW(s[i])) { len += 2; } } @@ -346,7 +347,7 @@ static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) if (ret == NULL) return NULL; for (len=i=0;s[i];i++) { - if (isalnum(s[i]) || strchr(valid_chars, s[i])) { + if (NBT_CHAR_ALLOW(s[i])) { ret[len++] = s[i]; } else { snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]); -- cgit From 93cd3e9022c75f026f6d0bf3a2719df662d32db1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Feb 2005 05:39:12 +0000 Subject: r5405: try to use NBT name pointers when a netbios name is repeated in a NBT packet. This allows much longer names to fit within the limits of NBT name packets (rfc1002.txt also says this should be done, although Samba3 never generates them). The main reason for doing this is it means that our NBT name pointer decoding code is tested with the smbtorture tests (This used to be commit 6e2feef125daceb143c44c0c4ab73b010b311792) --- source4/libcli/nbt/nbtname.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index bf545a6374..12b8884e2d 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -214,8 +214,9 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name uint_t num_components; uint8_t *components[MAX_COMPONENTS]; char *dscope=NULL, *p; - uint8_t *cname; + uint8_t *cname, *fullname; int i; + int fulllen; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; @@ -246,14 +247,31 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name if (num_components == MAX_COMPONENTS) { return NT_STATUS_BAD_NETWORK_NAME; } + + fullname = talloc_asprintf(ndr, "%c%s", (unsigned char)strlen(cname), cname); + NT_STATUS_HAVE_NO_MEMORY(fullname); - /* push the components */ - for (i=0;ioffset;i++) { + if (ndr->data[i] == fullname[0] && + memcmp(fullname, &ndr->data[i], fulllen) == 0) { + talloc_free(fullname); + return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i); + } + } + + NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen)); + + talloc_free(fullname); return NT_STATUS_OK; } -- cgit From a6878f6c6e17ea99baf57e5724d524548a44ada8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Feb 2005 10:03:18 +0000 Subject: r5414: - added libcli/wins/, a basic client library for WINS replication - added a new IDL type "udlongr", which is like udlong, but with the two uint32 halves reversed - modified the winsrepl.idl to cope with a wider range of packets (This used to be commit bc8d60c918f2e268d591aac464fc6a78c38a4cf9) --- source4/libcli/config.mk | 5 + source4/libcli/wins/winsrepl.c | 436 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/wins/winsrepl.h | 69 +++++++ 3 files changed, 510 insertions(+) create mode 100644 source4/libcli/wins/winsrepl.c create mode 100644 source4/libcli/wins/winsrepl.h (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 726d3f1184..e6be2ed058 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -35,6 +35,11 @@ ADD_OBJ_FILES = \ libcli/nbt/namerelease.o REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS +[SUBSYSTEM::LIBCLI_WINS] +ADD_OBJ_FILES = \ + libcli/wins/winsrepl.o +REQUIRED_SUBSYSTEMS = LIBCLI_NBT NDR_WINS SOCKET LIBEVENTS + [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ libcli/resolve/resolve.o \ diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c new file mode 100644 index 0000000000..6ee948202f --- /dev/null +++ b/source4/libcli/wins/winsrepl.c @@ -0,0 +1,436 @@ +/* + Unix SMB/CIFS implementation. + + low level WINS replication client code + + Copyright (C) Andrew Tridgell 2005 + + 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 "lib/events/events.h" +#include "dlinklist.h" +#include "lib/socket/socket.h" +#include "libcli/wins/winsrepl.h" + +/* + mark all pending requests as dead - called when a socket error happens +*/ +static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket) +{ + event_set_fd_flags(wrepl_socket->fde, 0); + + while (wrepl_socket->send_queue) { + struct wrepl_request *req = wrepl_socket->send_queue; + DLIST_REMOVE(wrepl_socket->send_queue, req); + req->state = WREPL_REQUEST_ERROR; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } + while (wrepl_socket->recv_queue) { + struct wrepl_request *req = wrepl_socket->recv_queue; + DLIST_REMOVE(wrepl_socket->recv_queue, req); + req->state = WREPL_REQUEST_ERROR; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } +} + +/* + handle send events +*/ +static void wrepl_handler_send(struct wrepl_socket *wrepl_socket) +{ + while (wrepl_socket->send_queue) { + struct wrepl_request *req = wrepl_socket->send_queue; + size_t nsent; + NTSTATUS status; + + status = socket_send(wrepl_socket->sock, &req->buffer, &nsent, 0); + if (NT_STATUS_IS_ERR(status)) { + wrepl_socket_dead(wrepl_socket); + return; + } + if (!NT_STATUS_IS_OK(status) || nsent == 0) return; + + req->buffer.data += nsent; + req->buffer.length -= nsent; + if (req->buffer.length != 0) { + return; + } + + DLIST_REMOVE(wrepl_socket->send_queue, req); + DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); + req->state = WREPL_REQUEST_RECV; + + EVENT_FD_READABLE(wrepl_socket->fde); + } + + EVENT_FD_NOT_WRITEABLE(wrepl_socket->fde); +} + + +/* + handle recv events +*/ +static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) +{ + size_t nread; + struct wrepl_request *req = wrepl_socket->recv_queue; + DATA_BLOB blob; + + if (req == NULL) { + EVENT_FD_NOT_READABLE(wrepl_socket->fde); + return; + } + + if (req->buffer.length == 0) { + req->buffer = data_blob_talloc(req, NULL, 4); + if (req->buffer.data == NULL) { + req->status = NT_STATUS_NO_MEMORY; + goto failed; + } + req->num_read = 0; + } + + /* read in the packet length */ + if (req->num_read < 4) { + uint32_t req_length; + + req->status = socket_recv(wrepl_socket->sock, + req->buffer.data + req->num_read, + 4 - req->num_read, + &nread, 0); + if (NT_STATUS_IS_ERR(req->status)) goto failed; + if (!NT_STATUS_IS_OK(req->status)) return; + + req->num_read += nread; + if (req->num_read != 4) return; + + req_length = RIVAL(req->buffer.data, 0) + 4; + + req->buffer.data = talloc_realloc(req, req->buffer.data, + uint8_t, req_length); + if (req->buffer.data == NULL) { + req->status = NT_STATUS_NO_MEMORY; + goto failed; + } + req->buffer.length = req_length; + } + + /* read in the body */ + req->status = socket_recv(wrepl_socket->sock, + req->buffer.data + req->num_read, + req->buffer.length - req->num_read, + &nread, 0); + if (NT_STATUS_IS_ERR(req->status)) goto failed; + if (!NT_STATUS_IS_OK(req->status)) return; + + req->num_read += nread; + if (req->num_read != req->buffer.length) return; + + req->packet = talloc(req, struct wrepl_packet); + if (req->packet == NULL) { + req->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + blob.data = req->buffer.data + 4; + blob.length = req->buffer.length - 4; + + /* we have a full request - parse it */ + req->status = ndr_pull_struct_blob(&blob, + req->packet, req->packet, + (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); + if (!NT_STATUS_IS_OK(req->status)) { + DEBUG(2,("Failed to parse incoming WINS packet - %s\n", + nt_errstr(req->status))); + DEBUG(10,("packet length %d\n", req->buffer.length)); + NDR_PRINT_DEBUG(wrepl_packet, req->packet); + goto failed; + } + + if (DEBUGLVL(10)) { + DEBUG(10,("Received WINS packet of length %d\n", req->buffer.length)); + NDR_PRINT_DEBUG(wrepl_packet, req->packet); + } + + DLIST_REMOVE(wrepl_socket->recv_queue, req); + req->state = WREPL_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + return; + +failed: + if (req->state == WREPL_REQUEST_RECV) { + DLIST_REMOVE(wrepl_socket->recv_queue, req); + } + req->state = WREPL_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + handler for winrepl events +*/ +static void wrepl_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct wrepl_socket *wrepl_socket = talloc_get_type(private, + struct wrepl_socket); + if (flags & EVENT_FD_WRITE) { + wrepl_handler_send(wrepl_socket); + return; + } + if (flags & EVENT_FD_READ) { + wrepl_handler_recv(wrepl_socket); + } +} + + +/* + handler for winrepl connection completion +*/ +static void wrepl_connect_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct wrepl_socket *wrepl_socket = talloc_get_type(private, + struct wrepl_socket); + struct wrepl_request *req = wrepl_socket->recv_queue; + + talloc_free(fde); + + if (req == NULL) return; + + req->status = socket_connect_complete(wrepl_socket->sock, 0); + if (NT_STATUS_IS_ERR(req->status)) goto failed; + + if (!NT_STATUS_IS_OK(req->status)) return; + + wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + 0, + wrepl_handler, wrepl_socket); + if (wrepl_socket->fde == NULL) { + req->status = NT_STATUS_NO_MEMORY; + } + + +failed: + DLIST_REMOVE(wrepl_socket->recv_queue, req); + if (!NT_STATUS_IS_OK(req->status)) { + req->state = WREPL_REQUEST_ERROR; + } else { + req->state = WREPL_REQUEST_DONE; + } + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + initialise a wrepl_socket. The event_ctx is optional, if provided then + operations will use that event context +*/ +struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) +{ + struct wrepl_socket *wrepl_socket; + NTSTATUS status; + + wrepl_socket = talloc(mem_ctx, struct wrepl_socket); + if (wrepl_socket == NULL) goto failed; + + if (event_ctx == NULL) { + wrepl_socket->event_ctx = event_context_init(wrepl_socket); + } else { + wrepl_socket->event_ctx = talloc_reference(wrepl_socket, event_ctx); + } + if (wrepl_socket->event_ctx == NULL) goto failed; + + status = socket_create("ip", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0); + if (!NT_STATUS_IS_OK(status)) goto failed; + + talloc_steal(wrepl_socket, wrepl_socket->sock); + + wrepl_socket->send_queue = NULL; + wrepl_socket->recv_queue = NULL; + + wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + EVENT_FD_WRITE, + wrepl_connect_handler, wrepl_socket); + + set_blocking(socket_get_fd(wrepl_socket->sock), False); + + return wrepl_socket; + +failed: + talloc_free(wrepl_socket); + return NULL; +} + + +/* + destroy a wrepl_request +*/ +static int wrepl_request_destructor(void *ptr) +{ + struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); + if (req->state == WREPL_REQUEST_SEND) { + DLIST_REMOVE(req->wrepl_socket->send_queue, req); + } + if (req->state == WREPL_REQUEST_RECV) { + DLIST_REMOVE(req->wrepl_socket->recv_queue, req); + } + req->state = WREPL_REQUEST_ERROR; + return 0; +} + +/* + wait for a request to complete +*/ +static NTSTATUS wrepl_request_wait(struct wrepl_request *req) +{ + NT_STATUS_HAVE_NO_MEMORY(req); + while (req->state < WREPL_REQUEST_DONE) { + event_loop_once(req->wrepl_socket->event_ctx); + } + return req->status; +} + + +/* + connect a wrepl_socket to a WINS server +*/ +struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, + const char *address) +{ + struct wrepl_request *req; + NTSTATUS status; + + req = talloc_zero(wrepl_socket, struct wrepl_request); + if (req == NULL) goto failed; + + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_RECV; + + DLIST_ADD(wrepl_socket->recv_queue, req); + + talloc_set_destructor(req, wrepl_request_destructor); + + status = socket_connect(wrepl_socket->sock, NULL, 0, address, + WINS_REPLICATION_PORT, 0); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) goto failed; + + return req; + +failed: + talloc_free(req); + return NULL; +} + +/* + connect a wrepl_socket to a WINS server - recv side +*/ +NTSTATUS wrepl_connect_recv(struct wrepl_request *req) +{ + return wrepl_request_wait(req); +} + + +/* + connect a wrepl_socket to a WINS server - sync API +*/ +NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *address) +{ + struct wrepl_request *req = wrepl_connect_send(wrepl_socket, address); + return wrepl_connect_recv(req); +} + + +/* + send a generic wins replication request +*/ +struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, + struct wrepl_packet *packet) +{ + struct wrepl_request *req; + struct wrepl_wrap wrap; + + req = talloc_zero(wrepl_socket, struct wrepl_request); + if (req == NULL) goto failed; + + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_SEND; + + wrap.packet = *packet; + req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, + (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); + if (!NT_STATUS_IS_OK(req->status)) goto failed; + + if (DEBUGLVL(10)) { + DEBUG(10,("Sending WINS packet of length %d\n", req->buffer.length)); + NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); + } + + DLIST_ADD(wrepl_socket->send_queue, req); + + talloc_set_destructor(req, wrepl_request_destructor); + + EVENT_FD_WRITEABLE(wrepl_socket->fde); + + return req; + +failed: + talloc_free(req); + return NULL; +} + +/* + receive a generic WINS replication reply +*/ +NTSTATUS wrepl_request_recv(struct wrepl_request *req, + TALLOC_CTX *mem_ctx, + struct wrepl_packet **packet) +{ + NTSTATUS status = wrepl_request_wait(req); + if (NT_STATUS_IS_OK(status)) { + *packet = talloc_steal(mem_ctx, req->packet); + } + talloc_free(req); + return status; +} + +/* + a full WINS replication request/response +*/ +NTSTATUS wrepl_request(struct wrepl_socket *wrepl_socket, + TALLOC_CTX *mem_ctx, + struct wrepl_packet *req_packet, + struct wrepl_packet **reply_packet) +{ + struct wrepl_request *req = wrepl_request_send(wrepl_socket, req_packet); + return wrepl_request_recv(req, mem_ctx, reply_packet); +} diff --git a/source4/libcli/wins/winsrepl.h b/source4/libcli/wins/winsrepl.h new file mode 100644 index 0000000000..3fd1e5406c --- /dev/null +++ b/source4/libcli/wins/winsrepl.h @@ -0,0 +1,69 @@ +/* + Unix SMB/CIFS implementation. + + structures for WINS replication client library + + Copyright (C) Andrew Tridgell 2005 + + 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 "librpc/gen_ndr/ndr_winsrepl.h" + +/* + main context structure for the wins replication client library +*/ +struct wrepl_socket { + struct socket_context *sock; + struct event_context *event_ctx; + + /* a queue of requests pending to be sent */ + struct wrepl_request *send_queue; + + /* a queue of replies waiting to be received */ + struct wrepl_request *recv_queue; + + /* the fd event */ + struct fd_event *fde; +}; + +enum wrepl_request_state { + WREPL_REQUEST_SEND = 0, + WREPL_REQUEST_RECV = 1, + WREPL_REQUEST_DONE = 2, + WREPL_REQUEST_ERROR = 3 +}; + +/* + a WINS replication request +*/ +struct wrepl_request { + struct wrepl_request *next, *prev; + struct wrepl_socket *wrepl_socket; + + enum wrepl_request_state state; + NTSTATUS status; + + DATA_BLOB buffer; + + size_t num_read; + + struct wrepl_packet *packet; + + struct { + void (*fn)(struct wrepl_request *); + void *private; + } async; +}; -- cgit From c52fb55903fc68dd6e9d13f618277b2c12e17aa6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Feb 2005 23:11:26 +0000 Subject: r5437: Allow Samba4 to be compiled by tcc (www.tinycc.org). It still crashes when linking though. (This used to be commit 2e1e8db6dc877eb32b51cfc3d9c8f463d14530ec) --- source4/libcli/auth/gensec_krb5.c | 92 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index a0c2a77f4b..71670632b9 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -42,11 +42,11 @@ struct gensec_krb5_state { DATA_BLOB session_key; DATA_BLOB pac; enum GENSEC_KRB5_STATE state_position; - krb5_context krb5_context; - krb5_auth_context krb5_auth_context; - krb5_ccache krb5_ccache; + krb5_context context; + krb5_auth_context auth_context; + krb5_ccache ccache; krb5_data ticket; - krb5_keyblock krb5_keyblock; + krb5_keyblock keyblock; char *peer_principal; }; @@ -66,8 +66,8 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, cksum.checksum.data = sig->signature; - ret = krb5_crypto_init(gensec_krb5_state->krb5_context, - &gensec_krb5_state->krb5_keyblock, + ret = krb5_crypto_init(gensec_krb5_state->context, + &gensec_krb5_state->keyblock, 0, &crypto); if (ret) { @@ -76,7 +76,7 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, } for (i=0; i < 40; i++) { keyusage = i; - ret = krb5_verify_checksum(gensec_krb5_state->krb5_context, + ret = krb5_verify_checksum(gensec_krb5_state->context, crypto, keyusage, pac_data.data, @@ -87,7 +87,7 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, break; } } - krb5_crypto_destroy(gensec_krb5_state->krb5_context, crypto); + krb5_crypto_destroy(gensec_krb5_state->context, crypto); if (ret) { DEBUG(0,("NOT verifying PAC checksums yet!\n")); @@ -232,23 +232,23 @@ static int gensec_krb5_destory(void *ptr) struct gensec_krb5_state *gensec_krb5_state = ptr; if (gensec_krb5_state->ticket.length) { - kerberos_free_data_contents(gensec_krb5_state->krb5_context, &gensec_krb5_state->ticket); + kerberos_free_data_contents(gensec_krb5_state->context, &gensec_krb5_state->ticket); } - if (gensec_krb5_state->krb5_ccache) { + if (gensec_krb5_state->ccache) { /* current heimdal - 0.6.3, which we need anyway, fixes segfaults here */ - krb5_cc_close(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache); + krb5_cc_close(gensec_krb5_state->context, gensec_krb5_state->ccache); } - krb5_free_keyblock_contents(gensec_krb5_state->krb5_context, - &gensec_krb5_state->krb5_keyblock); + krb5_free_keyblock_contents(gensec_krb5_state->context, + &gensec_krb5_state->keyblock); - if (gensec_krb5_state->krb5_auth_context) { - krb5_auth_con_free(gensec_krb5_state->krb5_context, - gensec_krb5_state->krb5_auth_context); + if (gensec_krb5_state->auth_context) { + krb5_auth_con_free(gensec_krb5_state->context, + gensec_krb5_state->auth_context); } - if (gensec_krb5_state->krb5_context) { - krb5_free_context(gensec_krb5_state->krb5_context); + if (gensec_krb5_state->context) { + krb5_free_context(gensec_krb5_state->context); } return 0; } @@ -266,31 +266,31 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) gensec_security->private_data = gensec_krb5_state; initialize_krb5_error_table(); - gensec_krb5_state->krb5_context = NULL; - gensec_krb5_state->krb5_auth_context = NULL; - gensec_krb5_state->krb5_ccache = NULL; + gensec_krb5_state->context = NULL; + gensec_krb5_state->auth_context = NULL; + gensec_krb5_state->ccache = NULL; ZERO_STRUCT(gensec_krb5_state->ticket); - ZERO_STRUCT(gensec_krb5_state->krb5_keyblock); + ZERO_STRUCT(gensec_krb5_state->keyblock); gensec_krb5_state->session_key = data_blob(NULL, 0); gensec_krb5_state->pac = data_blob(NULL, 0); talloc_set_destructor(gensec_krb5_state, gensec_krb5_destory); - ret = krb5_init_context(&gensec_krb5_state->krb5_context); + ret = krb5_init_context(&gensec_krb5_state->context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", error_message(ret))); return NT_STATUS_INTERNAL_ERROR; } if (lp_realm() && *lp_realm()) { - ret = krb5_set_default_realm(gensec_krb5_state->krb5_context, lp_realm()); + ret = krb5_set_default_realm(gensec_krb5_state->context, lp_realm()); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_set_default_realm failed (%s)\n", error_message(ret))); return NT_STATUS_INTERNAL_ERROR; } } - ret = krb5_auth_con_init(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_auth_context); + ret = krb5_auth_con_init(gensec_krb5_state->context, &gensec_krb5_state->auth_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n", error_message(ret))); return NT_STATUS_INTERNAL_ERROR; @@ -333,7 +333,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security TODO: If the user set a username, we should use an in-memory CCACHE (see below) */ - ret = krb5_cc_default(gensec_krb5_state->krb5_context, &gensec_krb5_state->krb5_ccache); + ret = krb5_cc_default(gensec_krb5_state->context, &gensec_krb5_state->ccache); if (ret) { DEBUG(1,("krb5_cc_default failed (%s)\n", error_message(ret))); @@ -343,11 +343,11 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security while (1) { if (gensec_security->target.principal) { DEBUG(5, ("Finding ticket for target [%s]\n", gensec_security->target.principal)); - ret = ads_krb5_mk_req(gensec_krb5_state->krb5_context, - &gensec_krb5_state->krb5_auth_context, + ret = ads_krb5_mk_req(gensec_krb5_state->context, + &gensec_krb5_state->auth_context, AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, gensec_security->target.principal, - gensec_krb5_state->krb5_ccache, + gensec_krb5_state->ccache, &gensec_krb5_state->ticket); } else { krb5_data in_data; @@ -359,12 +359,12 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security in_data.length = 0; - ret = krb5_mk_req(gensec_krb5_state->krb5_context, - &gensec_krb5_state->krb5_auth_context, + ret = krb5_mk_req(gensec_krb5_state->context, + &gensec_krb5_state->auth_context, AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, gensec_get_target_service(gensec_security), hostname, - &in_data, gensec_krb5_state->krb5_ccache, + &in_data, gensec_krb5_state->ccache, &gensec_krb5_state->ticket); } @@ -404,7 +404,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_get_target_principal(gensec_security), generate_random_str(gensec_krb5_state, 16)); - ret = krb5_cc_resolve(gensec_krb5_state->krb5_context, ccache_string, &gensec_krb5_state->krb5_ccache); + ret = krb5_cc_resolve(gensec_krb5_state->context, ccache_string, &gensec_krb5_state->ccache); if (ret) { DEBUG(1,("failed to generate a new krb5 keytab (%s): %s\n", ccache_string, @@ -412,7 +412,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security return NT_STATUS_INTERNAL_ERROR; } - ret = kerberos_kinit_password_cc(gensec_krb5_state->krb5_context, gensec_krb5_state->krb5_ccache, + ret = kerberos_kinit_password_cc(gensec_krb5_state->context, gensec_krb5_state->ccache, gensec_get_client_principal(gensec_security, gensec_krb5_state), password, NULL, &kdc_time); @@ -421,7 +421,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security time_t t = time(NULL); int time_offset =(unsigned)kdc_time-t; DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); - krb5_set_real_time(gensec_krb5_state->krb5_context, t + time_offset + 1, 0); + krb5_set_real_time(gensec_krb5_state->context, t + time_offset + 1, 0); } if (ret) { @@ -501,8 +501,8 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, inbuf.data = unwrapped_in.data; inbuf.length = unwrapped_in.length; - ret = krb5_rd_rep(gensec_krb5_state->krb5_context, - gensec_krb5_state->krb5_auth_context, + ret = krb5_rd_rep(gensec_krb5_state->context, + gensec_krb5_state->auth_context, &inbuf, &repl); if (ret) { DEBUG(1,("krb5_rd_rep (mutual authentication) failed (%s)\n", @@ -515,7 +515,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, gensec_krb5_state->state_position = GENSEC_KRB5_DONE; } if (repl) { - krb5_free_ap_rep_enc_part(gensec_krb5_state->krb5_context, repl); + krb5_free_ap_rep_enc_part(gensec_krb5_state->context, repl); } return nt_status; } @@ -535,22 +535,22 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, /* Parse the GSSAPI wrapping, if it's there... (win2k3 allows it to be omited) */ if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { nt_status = ads_verify_ticket(out_mem_ctx, - gensec_krb5_state->krb5_context, - gensec_krb5_state->krb5_auth_context, + gensec_krb5_state->context, + gensec_krb5_state->auth_context, lp_realm(), gensec_get_target_service(gensec_security), &in, &principal, &pac, &unwrapped_out, - &gensec_krb5_state->krb5_keyblock); + &gensec_krb5_state->keyblock); } else { /* TODO: check the tok_id */ nt_status = ads_verify_ticket(out_mem_ctx, - gensec_krb5_state->krb5_context, - gensec_krb5_state->krb5_auth_context, + gensec_krb5_state->context, + gensec_krb5_state->auth_context, lp_realm(), gensec_get_target_service(gensec_security), &unwrapped_in, &principal, &pac, &unwrapped_out, - &gensec_krb5_state->krb5_keyblock); + &gensec_krb5_state->keyblock); } if (!NT_STATUS_IS_OK(nt_status)) { @@ -584,8 +584,8 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - krb5_context context = gensec_krb5_state->krb5_context; - krb5_auth_context auth_context = gensec_krb5_state->krb5_auth_context; + krb5_context context = gensec_krb5_state->context; + krb5_auth_context auth_context = gensec_krb5_state->auth_context; krb5_keyblock *skey; krb5_error_code err; -- cgit From 42d6a4c4f0d87e8e1bdd1e3152e592822bf95337 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Feb 2005 23:13:51 +0000 Subject: r5451: - added separate wrepl_associate(), wrepl_pull_table() and wrepl_pull_names() functions, with reasonable parameters, so callers don't need to deal directly with wins replication packet structures - converted the NBT-WINSREPLICATION torture test to use the new APIs (This used to be commit cec1672662b7e5b1bdf843e9dee317aa4b03f719) --- source4/libcli/wins/winsrepl.c | 268 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/wins/winsrepl.h | 45 +++++++ 2 files changed, 313 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c index 6ee948202f..bf3593bdf8 100644 --- a/source4/libcli/wins/winsrepl.c +++ b/source4/libcli/wins/winsrepl.c @@ -434,3 +434,271 @@ NTSTATUS wrepl_request(struct wrepl_socket *wrepl_socket, struct wrepl_request *req = wrepl_request_send(wrepl_socket, req_packet); return wrepl_request_recv(req, mem_ctx, reply_packet); } + + +/* + setup an association - send +*/ +struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket, + struct wrepl_associate *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->mess_type = WREPL_START_ASSOCIATION; + packet->message.start.minor_version = 2; + packet->message.start.major_version = 5; + + req = wrepl_request_send(wrepl_socket, packet); + + talloc_free(packet); + + return req; +} + +/* + setup an association - recv +*/ +NTSTATUS wrepl_associate_recv(struct wrepl_request *req, + struct wrepl_associate *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + if (NT_STATUS_IS_OK(status)) { + io->out.assoc_ctx = packet->message.start_reply.assoc_ctx; + } + talloc_free(packet); + return status; +} + +/* + setup an association - sync api +*/ +NTSTATUS wrepl_associate(struct wrepl_socket *wrepl_socket, + struct wrepl_associate *io) +{ + struct wrepl_request *req = wrepl_associate_send(wrepl_socket, io); + return wrepl_associate_recv(req, io); +} + + +/* + fetch the partner tables - send +*/ +struct wrepl_request *wrepl_pull_table_send(struct wrepl_socket *wrepl_socket, + struct wrepl_pull_table *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->assoc_ctx = io->in.assoc_ctx; + packet->mess_type = WREPL_REPLICATION; + packet->message.replication.command = WREPL_REPL_TABLE_QUERY; + + req = wrepl_request_send(wrepl_socket, packet); + + talloc_free(packet); + + return req; +} + + +/* + fetch the partner tables - recv +*/ +NTSTATUS wrepl_pull_table_recv(struct wrepl_request *req, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_table *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + struct wrepl_table *table; + int i; + + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + if (packet->mess_type != WREPL_REPLICATION) { + status = NT_STATUS_NETWORK_ACCESS_DENIED; + } else if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + if (!NT_STATUS_IS_OK(status)) goto failed; + + table = &packet->message.replication.info.table; + io->out.num_partners = table->partner_count; + io->out.partners = talloc_steal(mem_ctx, table->partners); + for (i=0;iout.num_partners;i++) { + talloc_steal(io->out.partners, io->out.partners[i].address); + } + +failed: + talloc_free(packet); + return status; +} + + +/* + fetch the partner table - sync api +*/ +NTSTATUS wrepl_pull_table(struct wrepl_socket *wrepl_socket, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_table *io) +{ + struct wrepl_request *req = wrepl_pull_table_send(wrepl_socket, io); + return wrepl_pull_table_recv(req, mem_ctx, io); +} + + +/* + fetch the names for a WINS partner - send +*/ +struct wrepl_request *wrepl_pull_names_send(struct wrepl_socket *wrepl_socket, + struct wrepl_pull_names *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->assoc_ctx = io->in.assoc_ctx; + packet->mess_type = WREPL_REPLICATION; + packet->message.replication.command = WREPL_REPL_SEND_REQUEST; + packet->message.replication.info.owner = io->in.partner; + + req = wrepl_request_send(wrepl_socket, packet); + + talloc_free(packet); + + return req; +} + + +/* + extract a nbt_name from a WINS name buffer +*/ +static NTSTATUS wrepl_extract_name(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + uint8_t *namebuf, uint32_t len) +{ + char *s; + + /* oh wow, what a nasty bug in windows ... */ + if (namebuf[0] == 0x1b && len >= 16) { + namebuf[0] = namebuf[15]; + namebuf[15] = 0x1b; + } + + if (len < 17) { + name->name = talloc_strndup(mem_ctx, namebuf, len); + name->type = 0; + name->scope = NULL; + return NT_STATUS_OK; + } + + s = talloc_strndup(mem_ctx, namebuf, 15); + trim_string(s, NULL, " "); + name->name = s; + name->type = namebuf[15]; + if (len > 18) { + name->scope = talloc_strndup(mem_ctx, namebuf+17, len-17); + } else { + name->scope = NULL; + } + + return NT_STATUS_OK; +} + +/* + fetch the names for a WINS partner - recv +*/ +NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_names *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + int i; + + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + if (packet->mess_type != WREPL_REPLICATION || + packet->message.replication.command != WREPL_REPL_SEND_REPLY) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + if (!NT_STATUS_IS_OK(status)) goto failed; + + io->out.num_names = packet->message.replication.info.reply.num_names; + + status = NT_STATUS_NO_MEMORY; + + io->out.names = talloc_array(packet, struct wrepl_name, io->out.num_names); + if (io->out.names == NULL) goto failed; + + /* convert the list of names and addresses to a sane format */ + for (i=0;iout.num_names;i++) { + struct wrepl_wins_name *wname = &packet->message.replication.info.reply.names[i]; + struct wrepl_name *name = &io->out.names[i]; + status = wrepl_extract_name(&name->name, io->out.names, + wname->name, wname->name_len); + if (!NT_STATUS_IS_OK(status)) goto failed; + + /* trying to save 1 or 2 bytes on the wire isn't a good idea */ + if (wname->flags & 2) { + int j; + + name->num_addresses = wname->addresses.addresses.num_ips; + name->addresses = talloc_array(io->out.names, + struct wrepl_address, + name->num_addresses); + if (name->addresses == NULL) goto failed; + for (j=0;jnum_addresses;j++) { + name->addresses[j].owner = + talloc_steal(name->addresses, + wname->addresses.addresses.ips[j].owner); + name->addresses[j].address = + talloc_steal(name->addresses, + wname->addresses.addresses.ips[j].ip); + } + } else { + name->num_addresses = 1; + name->addresses = talloc(io->out.names, struct wrepl_address); + if (name->addresses == NULL) goto failed; + name->addresses[0].owner = talloc_steal(name->addresses, + wname->addresses.address.owner); + name->addresses[0].address = talloc_steal(name->addresses, + wname->addresses.address.ip); + } + } + + talloc_steal(mem_ctx, io->out.names); + status = NT_STATUS_OK; + +failed: + talloc_free(packet); + return status; +} + + + +/* + fetch the names for a WINS partner - sync api +*/ +NTSTATUS wrepl_pull_names(struct wrepl_socket *wrepl_socket, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_names *io) +{ + struct wrepl_request *req = wrepl_pull_names_send(wrepl_socket, io); + return wrepl_pull_names_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/wins/winsrepl.h b/source4/libcli/wins/winsrepl.h index 3fd1e5406c..79b7f1fd70 100644 --- a/source4/libcli/wins/winsrepl.h +++ b/source4/libcli/wins/winsrepl.h @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "librpc/gen_ndr/ndr_nbt.h" #include "librpc/gen_ndr/ndr_winsrepl.h" /* @@ -67,3 +68,47 @@ struct wrepl_request { void *private; } async; }; + + +/* + setup an association +*/ +struct wrepl_associate { + struct { + uint32_t assoc_ctx; + } out; +}; + +/* + pull the partner table +*/ +struct wrepl_pull_table { + struct { + uint32_t assoc_ctx; + } in; + struct { + uint32_t num_partners; + struct wrepl_wins_owner *partners; + } out; +}; + +/* + a full pull replication +*/ +struct wrepl_pull_names { + struct { + uint32_t assoc_ctx; + struct wrepl_wins_owner partner; + } in; + struct { + uint32_t num_names; + struct wrepl_name { + struct nbt_name name; + uint32_t num_addresses; + struct wrepl_address { + const char *owner; + const char *address; + } *addresses; + } *names; + } out; +}; -- cgit From 7fc5f4a6f7bd7a0b5c66b019377ba4ad1bc110bb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 Feb 2005 04:59:46 +0000 Subject: r5550: Initialise retry count - valgrind was freaking out because this value was not set. (This used to be commit 328f37a3e8d10f97f361fb041be24f1ac88b6b0a) --- source4/libcli/resolve/nbtlist.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 89e9a63748..d5b01e06d9 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -129,6 +129,7 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, state->io_queries[i].in.wins_lookup = wins_lookup; state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 3); + state->io_queries[i].in.retries = 0; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); if (!state->queries[i]) goto failed; -- cgit From c9b766a9af70ac7e94f7ebf872fa5b9e21220d12 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 Feb 2005 05:25:17 +0000 Subject: r5551: Protect against falling off the end of the name resolve order list if a name is not found. (This used to be commit c23f767a9f5dd2dcae31bded540263b08876ecc2) --- source4/libcli/resolve/resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 7e3f78edb4..82268dc953 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -101,7 +101,7 @@ static struct composite_context *setup_next_method(struct composite_context *c) if (method) { req = method->send_fn(&state->name, c->event_ctx); } - if (req == NULL) state->methods++; + if (req == NULL && state->methods[0]) state->methods++; } while (!req && state->methods[0]); if (req) { -- cgit From 70f7c56168056c025c6931ce6e934203a5c2c9dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2005 15:19:18 +0000 Subject: r5601: add a gsskrb5 backend that uses lorikeet-heimdal's new gssapi with GSS_C_DCE_STYLE support, it's just a start and does work correctly yet metze (This used to be commit 87ff661703f467db3dfcb33084041c3e2951e0ee) --- source4/libcli/auth/gensec.m4 | 4 + source4/libcli/auth/gensec.mk | 10 + source4/libcli/auth/gensec_gsskrb5.c | 584 +++++++++++++++++++++++++++++++++++ 3 files changed, 598 insertions(+) create mode 100644 source4/libcli/auth/gensec_gsskrb5.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 index 356f857d81..6ccf45ad7e 100644 --- a/source4/libcli/auth/gensec.m4 +++ b/source4/libcli/auth/gensec.m4 @@ -1,8 +1,12 @@ SMB_MODULE_DEFAULT(gensec_krb5, NOT) SMB_MODULE_DEFAULT(gensec_gssapi, NOT) +SMB_MODULE_DEFAULT(gensec_gsskrb5, NOT) if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then # enable this when krb5 is fully working SMB_MODULE_DEFAULT(gensec_krb5, STATIC) SMB_MODULE_DEFAULT(gensec_gssapi, STATIC) + if test x"$samba_cv_GSS_C_DCE_STYLE" = x"yes"; then + SMB_MODULE_DEFAULT(gensec_gsskrb5, STATIC) + fi fi diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index b66006ce4f..e4559bb972 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -33,6 +33,16 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 # End MODULE gensec_gssapi ################################################ +################################################ +# Start MODULE gensec_gsskrb5 +[MODULE::gensec_gsskrb5] +SUBSYSTEM = GENSEC +INIT_FUNCTION = gensec_gsskrb5_init +INIT_OBJ_FILES = libcli/auth/gensec_gsskrb5.o +REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 +# End MODULE gensec_gsskrb5 +################################################ + ################################################ # Start MODULE gensec_spnego [MODULE::gensec_spnego] diff --git a/source4/libcli/auth/gensec_gsskrb5.c b/source4/libcli/auth/gensec_gsskrb5.c new file mode 100644 index 0000000000..77e077276b --- /dev/null +++ b/source4/libcli/auth/gensec_gsskrb5.c @@ -0,0 +1,584 @@ +/* + Unix SMB/CIFS implementation. + + GSSAPI KRB5 backend for GENSEC + + Copyright (C) Andrew Bartlett 2004 + Copyright (C) Stefan Metzmacher 2005 + + 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 "system/kerberos.h" +#include "system/time.h" +#include "libcli/auth/kerberos.h" +#include "auth/auth.h" + +static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = + {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; + +enum GENSEC_GSSKRB5_STATE { + GENSEC_GSSKRB5_CLIENT_START, + GENSEC_GSSKRB5_CLIENT_MUTUAL_AUTH, + GENSEC_GSSKRB5_CLIENT_DCE_STYLE, + GENSEC_GSSKRB5_DONE +}; + +struct gensec_gsskrb5_state { + enum GENSEC_GSSKRB5_STATE state_position; + gss_ctx_id_t gssapi_context; + struct gss_channel_bindings_struct *input_chan_bindings; + gss_name_t server_name; + gss_name_t client_name; + OM_uint32 want_flags, got_flags; +}; + +static int gensec_gsskrb5_destory(void *ptr) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = ptr; + OM_uint32 maj_stat, min_stat; + + if (gensec_gsskrb5_state->gssapi_context != GSS_C_NO_CONTEXT) { + maj_stat = gss_delete_sec_context (&min_stat, + &gensec_gsskrb5_state->gssapi_context, + GSS_C_NO_BUFFER); + } + + if (gensec_gsskrb5_state->server_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat, &gensec_gsskrb5_state->server_name); + } + if (gensec_gsskrb5_state->client_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat, &gensec_gsskrb5_state->client_name); + } + return 0; +} + +static NTSTATUS gensec_gsskrb5_start(struct gensec_security *gensec_security) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state; + + gensec_gsskrb5_state = talloc(gensec_security, struct gensec_gsskrb5_state); + if (!gensec_gsskrb5_state) { + return NT_STATUS_NO_MEMORY; + } + + gensec_security->private_data = gensec_gsskrb5_state; + + gensec_gsskrb5_state->gssapi_context = GSS_C_NO_CONTEXT; + gensec_gsskrb5_state->server_name = GSS_C_NO_NAME; + gensec_gsskrb5_state->client_name = GSS_C_NO_NAME; + + talloc_set_destructor(gensec_gsskrb5_state, gensec_gsskrb5_destory); + + /* TODO: Fill in channel bindings */ + gensec_gsskrb5_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; + + gensec_gsskrb5_state->want_flags = GSS_C_MUTUAL_FLAG; + gensec_gsskrb5_state->got_flags = 0; + + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { + /* GSSAPI won't give us the session keys */ + return NT_STATUS_INVALID_PARAMETER; + } + if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { + gensec_gsskrb5_state->want_flags |= GSS_C_INTEG_FLAG; + } + if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { + gensec_gsskrb5_state->want_flags |= GSS_C_CONF_FLAG; + } + if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { + gensec_gsskrb5_state->want_flags |= GSS_C_DCE_STYLE; + } + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gsskrb5_client_start(struct gensec_security *gensec_security) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state; + NTSTATUS nt_status; + gss_buffer_desc name_token; + OM_uint32 maj_stat, min_stat; + + gss_OID_desc hostbased = {10, + (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12" + "\x01\x02\x01\x04")}; + + nt_status = gensec_gsskrb5_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_gsskrb5_state = gensec_security->private_data; + + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_START; + + name_token.value = talloc_asprintf(gensec_gsskrb5_state, "%s@%s", gensec_get_target_service(gensec_security), + gensec_get_target_hostname(gensec_security)); + DEBUG(0, ("name: %s\n", (char *)name_token.value)); + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + &hostbased, + &gensec_gsskrb5_state->server_name); + if (maj_stat) { + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + +/** + * Next state function for the GSSKRB5 GENSEC mechanism + * + * @param gensec_gsskrb5_state GSSAPI State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +static NTSTATUS gensec_gsskrb5_update(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + OM_uint32 maj_stat, min_stat; + OM_uint32 min_stat2; + gss_buffer_desc input_token, output_token; + + *out = data_blob(NULL, 0); + + input_token.length = in.length; + input_token.value = in.data; + + switch (gensec_gsskrb5_state->state_position) { + case GENSEC_GSSKRB5_CLIENT_START: + { + maj_stat = gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &gensec_gsskrb5_state->gssapi_context, + gensec_gsskrb5_state->server_name, + discard_const_p(gss_OID_desc, &gensec_gss_krb5_mechanism_oid_desc), + gensec_gsskrb5_state->want_flags, + 0, + gensec_gsskrb5_state->input_chan_bindings, + &input_token, + NULL, + &output_token, + &gensec_gsskrb5_state->got_flags, /* ret flags */ + NULL); + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + if (out->length != output_token.length) { + gss_release_buffer(&min_stat2, &output_token); + return NT_STATUS_NO_MEMORY; + } + gss_release_buffer(&min_stat2, &output_token); + + if (maj_stat == GSS_S_COMPLETE) { + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_DONE; + return NT_STATUS_OK; + } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_MUTUAL_AUTH; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + gss_buffer_desc msg1, msg2; + OM_uint32 msg_ctx = 0; + + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + DEBUG(1, ("gensec_gsskrb5_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); + gss_release_buffer(&min_stat2, &msg1); + gss_release_buffer(&min_stat2, &msg2); + + return nt_status; + } + break; + } + case GENSEC_GSSKRB5_CLIENT_MUTUAL_AUTH: + { + maj_stat = gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &gensec_gsskrb5_state->gssapi_context, + gensec_gsskrb5_state->server_name, + discard_const_p(gss_OID_desc, &gensec_gss_krb5_mechanism_oid_desc), + gensec_gsskrb5_state->want_flags, + 0, + gensec_gsskrb5_state->input_chan_bindings, + &input_token, + NULL, + &output_token, + &gensec_gsskrb5_state->got_flags, /* ret flags */ + NULL); + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + if (out->length != output_token.length) { + gss_release_buffer(&min_stat2, &output_token); + return NT_STATUS_NO_MEMORY; + } + gss_release_buffer(&min_stat2, &output_token); + + if (maj_stat == GSS_S_COMPLETE) { + if (gensec_gsskrb5_state->got_flags & GSS_C_DCE_STYLE) { + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_DCE_STYLE; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_DONE; + return NT_STATUS_OK; + } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_DCE_STYLE; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + gss_buffer_desc msg1, msg2; + OM_uint32 msg_ctx = 0; + + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + DEBUG(1, ("gensec_gsskrb5_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); + gss_release_buffer(&min_stat2, &msg1); + gss_release_buffer(&min_stat2, &msg2); + + return nt_status; + } + break; + } + case GENSEC_GSSKRB5_CLIENT_DCE_STYLE: + { + gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_DONE; + return NT_STATUS_OK; + } + case GENSEC_GSSKRB5_DONE: + { + return NT_STATUS_OK; + } + default: + return NT_STATUS_INVALID_PARAMETER; + } + + return NT_STATUS_INVALID_PARAMETER; +} + +static NTSTATUS gensec_gsskrb5_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + input_token.length = in->length; + input_token.value = in->data; + + maj_stat = gss_wrap(&min_stat, + gensec_gsskrb5_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gsskrb5_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + input_token.length = in->length; + input_token.value = in->data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gsskrb5_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static size_t gensec_gsskrb5_sig_size(struct gensec_security *gensec_security) +{ + /* not const but work for DCERPC packets and arcfour */ + return 45; +} + +static NTSTATUS gensec_gsskrb5_seal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + ssize_t sig_length = 0; + + input_token.length = length; + input_token.value = data; + + maj_stat = gss_wrap(&min_stat, + gensec_gsskrb5_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length < length) { + return NT_STATUS_INTERNAL_ERROR; + } + + sig_length = 45; + + memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); + *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); + +DEBUG(0,("gensec_gsskrb5_seal_packet: siglen: %d inlen: %d, wrap_len: %d\n", sig->length, length, output_token.length - sig_length)); +dump_data(0,sig->data, sig->length); +dump_data(0,data, length); +dump_data(0,((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gsskrb5_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + DATA_BLOB in; + +DEBUG(0,("gensec_gsskrb5_unseal_packet: siglen: %d\n", sig->length)); +dump_data(0,sig->data, sig->length); + + in = data_blob_talloc(mem_ctx, NULL, sig->length + length); + + memcpy(in.data, sig->data, sig->length); + memcpy(in.data + sig->length, data, length); + + input_token.length = in.length; + input_token.value = in.data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gsskrb5_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length != length) { + return NT_STATUS_INTERNAL_ERROR; + } + + memcpy(data, output_token.value, length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gsskrb5_sign_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + ssize_t sig_length = 0; + + input_token.length = length; + input_token.value = data; + + maj_stat = gss_wrap(&min_stat, + gensec_gsskrb5_state->gssapi_context, + 0, + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length < length) { + return NT_STATUS_INTERNAL_ERROR; + } + + sig_length = 45; + + /*memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);*/ + *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); + +DEBUG(0,("gensec_gsskrb5_sign_packet: siglen: %d\n", sig->length)); +dump_data(0,sig->data, sig->length); + + gss_release_buffer(&min_stat, &output_token); + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gsskrb5_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + DATA_BLOB in; + +DEBUG(0,("gensec_gsskrb5_check_packet: siglen: %d\n", sig->length)); +dump_data(0,sig->data, sig->length); + + in = data_blob_talloc(mem_ctx, NULL, sig->length + length); + + memcpy(in.data, sig->data, sig->length); + memcpy(in.data + sig->length, data, length); + + input_token.length = in.length; + input_token.value = in.data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gsskrb5_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length != length) { + return NT_STATUS_INTERNAL_ERROR; + } + + /*memcpy(data, output_token.value, length);*/ + + gss_release_buffer(&min_stat, &output_token); + + return NT_STATUS_OK; +} + +static BOOL gensec_gsskrb5_have_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; + if (feature & GENSEC_FEATURE_SIGN) { + return gensec_gsskrb5_state->got_flags & GSS_C_INTEG_FLAG; + } + if (feature & GENSEC_FEATURE_SEAL) { + return gensec_gsskrb5_state->got_flags & GSS_C_CONF_FLAG; + } + return False; +} + +static const struct gensec_security_ops gensec_gsskrb5_security_ops = { + .name = "gsskrb5", + .auth_type = DCERPC_AUTH_TYPE_KRB5, + .oid = GENSEC_OID_KERBEROS5, + .client_start = gensec_gsskrb5_client_start, + .update = gensec_gsskrb5_update, + .sig_size = gensec_gsskrb5_sig_size, + .sign_packet = gensec_gsskrb5_sign_packet, + .check_packet = gensec_gsskrb5_check_packet, + .seal_packet = gensec_gsskrb5_seal_packet, + .unseal_packet = gensec_gsskrb5_unseal_packet, + .wrap = gensec_gsskrb5_wrap, + .unwrap = gensec_gsskrb5_unwrap, + .have_feature = gensec_gsskrb5_have_feature, + .enabled = False +}; + +NTSTATUS gensec_gsskrb5_init(void) +{ + NTSTATUS ret; + + ret = gensec_register(&gensec_gsskrb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_gsskrb5_security_ops.name)); + return ret; + } + + return ret; +} -- cgit From 3a5529922178fbc5e759da89ac1ab0fa3038ee15 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Thu, 3 Mar 2005 09:26:08 +0000 Subject: r5646: state->loadfile might be NULL after allocation so this is really should be NT_STATUS_HAVE_NO_MEMORY(state->loadfile) instead of NT_STATUS_NOT_OK_RETURN(status). (This used to be commit eb57a587889611bcf39d75d4e15b627f36899a53) --- source4/libcli/composite/fetchfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index a7d6f2ffd8..2bf6ef9023 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -49,7 +49,7 @@ static NTSTATUS fetchfile_connect(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); state->loadfile = talloc(state, struct smb_composite_loadfile); - NT_STATUS_NOT_OK_RETURN(status); + NT_STATUS_HAVE_NO_MEMORY(state->loadfile); state->loadfile->in.fname = io->in.filename; -- cgit From 765832748b4ef6141802ff72e3dea99453bf23d8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 6 Mar 2005 06:37:38 +0000 Subject: r5667: Move schannel state into libcli/auth (as it belongs with schannel, which will move in with the rest of GENSEC shortly). Add the RID as another element in the schannel state. Andrew Bartlett (This used to be commit 69114b4a8e1c937ab5ff12ca91dd22bd83fd9a3b) --- source4/libcli/auth/credentials.h | 1 + source4/libcli/auth/gensec.mk | 10 ++ source4/libcli/auth/schannel_state.c | 225 +++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 source4/libcli/auth/schannel_state.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 7c3c4379d1..d1417bf83e 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -32,6 +32,7 @@ struct creds_CredentialState { uint16_t secure_channel_type; const char *computer_name; const char *account_name; + uint32_t rid; }; /* for the timebeing, use the same neg flags as Samba3. */ diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index e4559bb972..7e2e34081d 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -67,3 +67,13 @@ ADD_OBJ_FILES = \ REQUIRED_SUBSYSTEMS = AUTH # End MODULE gensec_ntlmssp ################################################ + +################################################ +# Start SUBSYSTEM SCHANNELDB +[SUBSYSTEM::SCHANNELDB] +INIT_OBJ_FILES = \ + libcli/auth/schannel_state.o +# +# End SUBSYSTEM SCHANNELDB +################################################ + diff --git a/source4/libcli/auth/schannel_state.c b/source4/libcli/auth/schannel_state.c new file mode 100644 index 0000000000..2a9e0a3ec3 --- /dev/null +++ b/source4/libcli/auth/schannel_state.c @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS implementation. + + module to store/fetch session keys for the schannel server + + Copyright (C) Andrew Tridgell 2004 + + 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 "system/time.h" +#include "auth/auth.h" +#include "lib/ldb/include/ldb.h" +#include "db_wrap.h" + +/* a reasonable amount of time to keep credentials live */ +#define SCHANNEL_CREDENTIALS_EXPIRY 600 + +/* + connect to the schannel ldb +*/ +static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) +{ + char *path; + struct ldb_context *ldb; + + path = smbd_tmp_path(mem_ctx, "schannel.ldb"); + if (!path) { + return NULL; + } + + ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL); + talloc_free(path); + if (!ldb) { + return NULL; + } + + return ldb; +} + +/* + remember an established session key for a netr server authentication + use a simple ldb structure +*/ +NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, + struct creds_CredentialState *creds) +{ + struct ldb_context *ldb; + struct ldb_message *msg; + struct ldb_val val, seed; + char *s; + char *f; + char *sct; + char *rid; + time_t expiry = time(NULL) + SCHANNEL_CREDENTIALS_EXPIRY; + int ret; + + ldb = schannel_db_connect(mem_ctx); + if (ldb == NULL) { + return NT_STATUS_NO_MEMORY; + } + + s = talloc_asprintf(mem_ctx, "%u", (unsigned int)expiry); + + if (s == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + + f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags); + + if (f == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + + sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type); + + if (sct == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + + rid = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->rid); + + if (rid == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + + msg = ldb_msg_new(mem_ctx); + if (msg == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + + msg->dn = talloc_asprintf(msg, "computerName=%s", creds->computer_name); + if (msg->dn == NULL) { + talloc_free(ldb); + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + + val.data = creds->session_key; + val.length = sizeof(creds->session_key); + + seed.data = creds->seed.data; + seed.length = sizeof(creds->seed.data); + + ldb_msg_add_value(ldb, msg, "sessionKey", &val); + ldb_msg_add_value(ldb, msg, "seed", &seed); + ldb_msg_add_string(ldb, msg, "expiry", s); + ldb_msg_add_string(ldb, msg, "negotiateFlags", f); + ldb_msg_add_string(ldb, msg, "secureChannelType", sct); + ldb_msg_add_string(ldb, msg, "accountName", creds->account_name); + ldb_msg_add_string(ldb, msg, "computerName", creds->computer_name); + ldb_msg_add_string(ldb, msg, "rid", rid); + + ldb_delete(ldb, msg->dn); + + ret = ldb_add(ldb, msg); + + talloc_free(s); + + if (ret != 0) { + DEBUG(0,("Unable to add %s to session key db - %s\n", + msg->dn, ldb_errstring(ldb))); + talloc_free(ldb); + talloc_free(msg); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + talloc_free(msg); + talloc_free(ldb); + + return NT_STATUS_OK; +} + + +/* + read back a credentials back for a computer +*/ +NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, + const char *computer_name, + struct creds_CredentialState **creds) +{ + struct ldb_context *ldb; + time_t expiry; + struct ldb_message **res; + int ret; + const struct ldb_val *val; + char *expr=NULL; + + *creds = talloc_zero(mem_ctx, struct creds_CredentialState); + if (!*creds) { + return NT_STATUS_NO_MEMORY; + } + + ldb = schannel_db_connect(mem_ctx); + if (ldb == NULL) { + return NT_STATUS_NO_MEMORY; + } + + expr = talloc_asprintf(mem_ctx, "(dn=computerName=%s)", computer_name); + if (expr == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + + ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res); + if (ret != 1) { + talloc_free(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + expiry = ldb_msg_find_uint(res[0], "expiry", 0); + if (expiry < time(NULL)) { + DEBUG(1,("schannel: attempt to use expired session key for %s\n", computer_name)); + talloc_free(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + val = ldb_msg_find_ldb_val(res[0], "sessionKey"); + if (val == NULL || val->length != 16) { + talloc_free(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + memcpy((*creds)->session_key, val->data, 16); + + val = ldb_msg_find_ldb_val(res[0], "seed"); + if (val == NULL || val->length != 8) { + talloc_free(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + memcpy((*creds)->seed.data, val->data, 8); + + (*creds)->negotiate_flags = ldb_msg_find_int(res[0], "negotiateFlags", 0); + + (*creds)->secure_channel_type = ldb_msg_find_int(res[0], "secureChannelType", 0); + + (*creds)->account_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "accountName", NULL)); + + (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL)); + + (*creds)->rid = ldb_msg_find_uint(res[0], "rid", 0); + + talloc_free(ldb); + + return NT_STATUS_OK; +} -- cgit From 42031bc4be2516872ccf832b6b09d141cb13c76b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 6 Mar 2005 08:24:34 +0000 Subject: r5668: Add tests to RPC-SAMLOGON to test for user@REALM style logins. These need a NULL domain (or a "" domain, except this breaks NTLMv2, and I need to look into it a bit more). Add support to the Samba4 server for these logins. This will need extension when we handle trusted domains as a DC, as it is a principal name, not just another format for the username. Andrew Bartlett (This used to be commit de02c7c222a32d2b3fb8ee8b715749b96cb647f9) --- source4/libcli/auth/smbencrypt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 00a28a1ad9..f2b6eb00d7 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -121,6 +121,14 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], return False; } + if (!user_in) { + user_in = ""; + } + + if (!domain_in) { + domain_in = ""; + } + user_in = strupper_talloc(mem_ctx, user_in); if (user_in == NULL) { talloc_free(mem_ctx); -- cgit From 736797ef7fe3b9cf542fa69281272501f95bfa3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2005 10:33:01 +0000 Subject: r5737: add some error codes metze (This used to be commit f543eb4ede54ac361017878574b3f4b6ffc9f2d5) --- source4/libcli/util/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index b346fea644..83553448a3 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -77,10 +77,12 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_DS_DRA_INVALID_PARAMETER", WERR_DS_DRA_INVALID_PARAMETER }, { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, + { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE }, { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, -- cgit From ef213b02482194a8fed7f37123e08624072694b2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Mar 2005 20:28:01 +0000 Subject: r5866: Add InitShutdown IDL and torture test. Implement push side of NDR_LEN4|NDR_NOTERM strings (pull side was already present) (This used to be commit ea61ec1122841716ed5d90085ba79e7bf691bd6a) --- source4/libcli/util/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 83553448a3..577c004422 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -90,6 +90,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, + { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS }, + { "WERR_SHUTDOWN_ALREADY_IN_PROGRESS", WERR_SHUTDOWN_ALREADY_IN_PROGRESS }, { NULL, W_ERROR(0) } }; -- cgit From 928af7e6ff8f9051d0e7827ffea2dfa432692d63 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Mar 2005 03:17:30 +0000 Subject: r5877: It is not an error to have a zero-length secret, after decryption. Andrew Bartlett (This used to be commit b484776cc4d48690d45c668f9253015eb0d6207d) --- source4/libcli/auth/session.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 9b4132a490..fda0aab055 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -178,6 +178,8 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT int slen; if (blob->length < 8) { + DEBUG(0, ("Unexpected length %d in session crypted secret (BLOB)\n", + blob->length)); return NT_STATUS_INVALID_PARAMETER; } @@ -189,19 +191,19 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT sess_crypt_blob(&out, blob, session_key, False); if (IVAL(out.data, 4) != 1) { - DEBUG(0,("Unexpected revision number %d in session crypted string\n", + DEBUG(0,("Unexpected revision number %d in session crypted secret (BLOB)\n", IVAL(out.data, 4))); return NT_STATUS_UNKNOWN_REVISION; } slen = IVAL(out.data, 0); if (slen > blob->length - 8) { - DEBUG(0,("Invalid crypt length %d\n", slen)); + DEBUG(0,("Invalid crypt length %d in session crypted secret (BLOB)\n", slen)); return NT_STATUS_WRONG_PASSWORD; } *ret = data_blob_talloc(mem_ctx, out.data+8, slen); - if (!ret->data) { + if (slen && !ret->data) { return NT_STATUS_NO_MEMORY; } -- cgit From df643022136a4b229aca817f5b57f7302a97f852 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Mar 2005 08:34:43 +0000 Subject: r5902: A rather large change... I wanted to add a simple 'workstation' argument to the DCERPC authenticated binding calls, but this patch kind of grew from there. With SCHANNEL, the 'workstation' name (the netbios name of the client) matters, as this is what ties the session between the NETLOGON ops and the SCHANNEL bind. This changes a lot of files, and these will again be changed when jelmer does the credentials work. I also correct some schannel IDL to distinguish between workstation names and account names. The distinction matters for domain trust accounts. Issues in handling this (issues with lifetime of talloc pointers) caused me to change the 'creds_CredentialsState' and 'struct dcerpc_binding' pointers to always be talloc()ed pointers. In the schannel DB, we now store both the domain and computername, and query on both. This should ensure we fault correctly when the domain is specified incorrectly in the SCHANNEL bind. In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out, where the comment claimed we re-used a connection, but in fact we made a new connection. This was achived by breaking apart some of the dcerpc_secondary_connection() logic. The addition of workstation handling was also propogated to NTLMSSP and GENSEC, for completeness. The RPC-SAMSYNC test has been cleaned up a little, using a loop over usernames/passwords rather than manually expanded tests. This will be expanded further (the code in #if 0 in this patch) to use a newly created user account for testing. In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO server, caused by the removal of [ref] and the assoicated pointer from the IDL. This has been re-added, until the underlying pidl issues are solved. (This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9) --- source4/libcli/auth/credentials.c | 6 ++++++ source4/libcli/auth/credentials.h | 1 + source4/libcli/auth/gensec.c | 30 +++++++++++++++++++++++++++++- source4/libcli/auth/gensec.h | 3 ++- source4/libcli/auth/gensec_ntlmssp.c | 3 +++ source4/libcli/auth/ntlmssp.c | 16 +++++++++------- source4/libcli/auth/ntlmssp.h | 4 ++-- source4/libcli/auth/schannel.c | 16 +++------------- source4/libcli/auth/schannel_state.c | 6 +++++- 9 files changed, 60 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index bcb462ae9d..90b8313c9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -192,12 +192,18 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, + const char *computer_name, + const char *domain, + const char *account_name, const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { creds->sequence = time(NULL); creds->negotiate_flags = negotiate_flags; + creds->computer_name = talloc_strdup(creds, computer_name); + creds->domain = talloc_strdup(creds, domain); + creds->account_name = talloc_strdup(creds, account_name); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index d1417bf83e..6ce3288b01 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -30,6 +30,7 @@ struct creds_CredentialState { struct netr_Credential client; struct netr_Credential server; uint16_t secure_channel_type; + const char *domain; const char *computer_name; const char *account_name; uint32_t rid; diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index e0fa27359a..d3fa7daae3 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -148,7 +148,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense * @param mem_ctx The parent TALLOC memory context. * @param parent The parent GENSEC context * @param gensec_security Returned GENSEC context pointer. - * @note Used by SPENGO in particular, for the actual implementation mechanism + * @note Used by SPNEGO in particular, for the actual implementation mechanism */ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, @@ -617,6 +617,34 @@ const char *gensec_get_domain(struct gensec_security *gensec_security) return gensec_security->default_user.domain; } +/** + * Set the client workstation on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_workstation(struct gensec_security *gensec_security, const char *workstation) +{ + gensec_security->user.workstation = talloc_strdup(gensec_security, workstation); + if (!gensec_security->user.workstation) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Return the client workstation on a GENSEC context - ensures it is talloc()ed + * + */ + +const char *gensec_get_workstation(struct gensec_security *gensec_security) +{ + if (gensec_security->user.workstation) { + return gensec_security->user.workstation; + } else { + return lp_netbios_name(); + } +} + /** * Set a kerberos realm on a GENSEC context - ensures it is talloc()ed * diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index a555584840..a4383d852c 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -29,6 +29,7 @@ struct gensec_security; struct gensec_user { + const char *workstation; const char *domain; const char *realm; const char *name; @@ -59,7 +60,7 @@ struct gensec_security_ops { const char *name; const char *sasl_name; uint8_t auth_type; /* 0 if not offered on DCE-RPC */ - const char *oid; /* NULL if not offered by SPENGO */ + const char *oid; /* NULL if not offered by SPNEGO */ NTSTATUS (*client_start)(struct gensec_security *gensec_security); NTSTATUS (*server_start)(struct gensec_security *gensec_security); NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 524815382d..51456d9107 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -245,6 +245,9 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur NT_STATUS_NOT_OK_RETURN(nt_status); } + nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state, + gensec_get_workstation(gensec_security)); + gensec_security->private_data = gensec_ntlmssp_state; return NT_STATUS_OK; diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 572ce66bb2..91bc9eadbd 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -194,7 +194,7 @@ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *dom NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) { ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation); - if (!ntlmssp_state->domain) { + if (!ntlmssp_state->workstation) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; @@ -346,7 +346,7 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, *chal_flags |= NTLMSSP_REQUEST_TARGET; if (ntlmssp_state->server_role == ROLE_STANDALONE) { *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; - return ntlmssp_state->get_global_myname(); + return ntlmssp_state->server_name; } else { *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; return ntlmssp_state->get_domain(); @@ -531,7 +531,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, msrpc_gen(out_mem_ctx, &struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, - NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name, NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, 0, ""); @@ -923,7 +923,9 @@ NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmss (*ntlmssp_state)->set_challenge = set_challenge; (*ntlmssp_state)->may_set_challenge = may_set_challenge; - (*ntlmssp_state)->get_global_myname = lp_netbios_name; + (*ntlmssp_state)->workstation = NULL; + (*ntlmssp_state)->server_name = lp_netbios_name(); + (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ @@ -990,7 +992,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, ntlmssp_state->get_domain(), - ntlmssp_state->get_global_myname()); + ntlmssp_state->workstation); ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; @@ -1240,7 +1242,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, nt_response.data, nt_response.length, ntlmssp_state->domain, ntlmssp_state->user, - ntlmssp_state->get_global_myname(), + ntlmssp_state->workstation, encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { @@ -1279,7 +1281,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmss (*ntlmssp_state)->role = NTLMSSP_CLIENT; - (*ntlmssp_state)->get_global_myname = lp_netbios_name; + (*ntlmssp_state)->workstation = lp_netbios_name(); (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True); diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index e8a2356e2c..e17c133c8b 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -95,7 +95,7 @@ struct ntlmssp_state char *user; char *domain; - char *workstation; + const char *workstation; char *password; char *server_domain; @@ -161,7 +161,7 @@ struct ntlmssp_state */ NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); - const char *(*get_global_myname)(void); + const char *server_name; const char *(*get_domain)(void); /* SMB Signing */ diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 92442234bd..a5521d4626 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -271,25 +271,15 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, return NT_STATUS_OK; } -/* - destroy an schannel context - */ -void schannel_end(struct schannel_state **state) -{ - if (*state) { - talloc_free(*state); - (*state) = NULL; - } -} - /* create an schannel context state */ -NTSTATUS schannel_start(struct schannel_state **state, +NTSTATUS schannel_start(TALLOC_CTX *mem_ctx, + struct schannel_state **state, const uint8_t session_key[16], BOOL initiator) { - (*state) = talloc(NULL, struct schannel_state); + (*state) = talloc(mem_ctx, struct schannel_state); if (!(*state)) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/auth/schannel_state.c b/source4/libcli/auth/schannel_state.c index 2a9e0a3ec3..b2d632a1f0 100644 --- a/source4/libcli/auth/schannel_state.c +++ b/source4/libcli/auth/schannel_state.c @@ -127,6 +127,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, ldb_msg_add_string(ldb, msg, "secureChannelType", sct); ldb_msg_add_string(ldb, msg, "accountName", creds->account_name); ldb_msg_add_string(ldb, msg, "computerName", creds->computer_name); + ldb_msg_add_string(ldb, msg, "flatname", creds->domain); ldb_msg_add_string(ldb, msg, "rid", rid); ldb_delete(ldb, msg->dn); @@ -155,6 +156,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, */ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, const char *computer_name, + const char *domain, struct creds_CredentialState **creds) { struct ldb_context *ldb; @@ -174,7 +176,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - expr = talloc_asprintf(mem_ctx, "(dn=computerName=%s)", computer_name); + expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", computer_name, domain); if (expr == NULL) { talloc_free(ldb); return NT_STATUS_NO_MEMORY; @@ -217,6 +219,8 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL)); + (*creds)->domain = talloc_reference(*creds, ldb_msg_find_string(res[0], "flatname", NULL)); + (*creds)->rid = ldb_msg_find_uint(res[0], "rid", 0); talloc_free(ldb); -- cgit From 02075be0bbc2095073f8898350fded64a7c97c79 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 21 Mar 2005 02:08:38 +0000 Subject: r5917: First step in using the new cli_credentials structure. This patch puts support for it into popt_common, adds a few utility functions (in lib/credentials.c) and the callback functions for the command-line (lib/cmdline/credentials.c). Comments are welcome :-) (This used to be commit 1d49b57c50fe8c2683ea23e9df41ce8ad774db98) --- source4/libcli/climessage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 113b752e8b..febd7db65c 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -26,7 +26,7 @@ /**************************************************************************** start a message sequence ****************************************************************************/ -BOOL smbcli_message_start(struct smbcli_tree *tree, char *host, char *username, +BOOL smbcli_message_start(struct smbcli_tree *tree, char *host, const char *username, int *grp) { struct smbcli_request *req; -- cgit From 05bc2d7b2c11a3583a6d1221cfbd618eb6730518 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 21 Mar 2005 21:22:07 +0000 Subject: r5928: Use cli_credentials in: - gtk+ (returned by GtkHostBindingDialog as well now) - torture/ - librpc/ - lib/com/dcom/ (This used to be commit ccefd782335e01e8e6ecb2bcd28a4f999c53b1a6) --- source4/libcli/auth/gensec.c | 63 +++----------------------------------------- 1 file changed, 4 insertions(+), 59 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index d3fa7daae3..69de016156 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -506,61 +506,6 @@ BOOL gensec_have_feature(struct gensec_security *gensec_security, return gensec_security->ops->have_feature(gensec_security, feature); } -/** - * Set a username on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, const char *user) -{ - char *p; - char *u = talloc_strdup(gensec_security, user); - if (!u) { - return NT_STATUS_NO_MEMORY; - } - - p = strchr_m(user, '@'); - - if (p) { - *p = '\0'; - gensec_security->user.name = talloc_strdup(gensec_security, u); - if (!gensec_security->user.name) { - return NT_STATUS_NO_MEMORY; - } - - gensec_security->user.realm = talloc_strdup(gensec_security, p+1); - if (!gensec_security->user.realm) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; - } - - p = strchr_m(user, '\\'); - if (!p) { - p = strchr_m(user, '/'); - } - - if (p) { - *p = '\0'; - gensec_security->user.domain = talloc_strdup(gensec_security, u); - if (!gensec_security->user.domain) { - return NT_STATUS_NO_MEMORY; - } - gensec_security->user.name = talloc_strdup(gensec_security, p+1); - if (!gensec_security->user.name) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; - } - - gensec_security->user.name = u; - if (!gensec_security->user.name) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - /** * Set a username on a GENSEC context - ensures it is talloc()ed * @@ -569,7 +514,7 @@ NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, c NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) { gensec_security->user.name = talloc_strdup(gensec_security, user); - if (!gensec_security->user.name) { + if (user && !gensec_security->user.name) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; @@ -596,7 +541,7 @@ const char *gensec_get_username(struct gensec_security *gensec_security) NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain) { gensec_security->user.domain = talloc_strdup(gensec_security, domain); - if (!gensec_security->user.domain) { + if (domain && !gensec_security->user.domain) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; @@ -625,7 +570,7 @@ const char *gensec_get_domain(struct gensec_security *gensec_security) NTSTATUS gensec_set_workstation(struct gensec_security *gensec_security, const char *workstation) { gensec_security->user.workstation = talloc_strdup(gensec_security, workstation); - if (!gensec_security->user.workstation) { + if (workstation && !gensec_security->user.workstation) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; @@ -653,7 +598,7 @@ const char *gensec_get_workstation(struct gensec_security *gensec_security) NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *realm) { gensec_security->user.realm = talloc_strdup(gensec_security, realm); - if (!gensec_security->user.realm) { + if (realm && !gensec_security->user.realm) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; -- cgit From 13b0776f60f6a0f35a4afc2b3d3c6b5ec9c1ca6a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 21 Mar 2005 23:35:58 +0000 Subject: r5929: Use cli_credentials for the SMB functions as well. Fix a couple of bugs in the new cli_credentials code (This used to be commit 4ad481cfe5cde514d2ef9646147239f3faaa6173) --- source4/libcli/cliconnect.c | 26 +++++++------------------- source4/libcli/raw/clitree.c | 11 +++++------ 2 files changed, 12 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index f391b6bc0d..3834d49e49 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -63,9 +63,7 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli) /* wrapper around smb_raw_session_setup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, - const char *user, - const char *password, - const char *domain) + struct cli_credentials *credentials) { struct smb_composite_sesssetup setup; NTSTATUS status; @@ -79,19 +77,19 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; - if (!user || !user[0]) { + if (cli_credentials_is_anonymous(credentials)) { setup.in.password = NULL; setup.in.user = ""; setup.in.domain = ""; setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; } else { if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { - setup.in.password = password; + setup.in.password = cli_credentials_get_password(credentials); } else { setup.in.password = NULL; } - setup.in.user = user; - setup.in.domain = domain; + setup.in.user = cli_credentials_get_username(credentials); + setup.in.domain = cli_credentials_get_domain(credentials); } status = smb_composite_sesssetup(cli->session, &setup); @@ -155,29 +153,19 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, const char *host, const char *sharename, const char *devtype, - const char *username, - const char *domain, - const char *password) + struct cli_credentials *credentials) { struct smbcli_tree *tree; NTSTATUS status; - char *p; TALLOC_CTX *mem_ctx; mem_ctx = talloc_init("smbcli_full_connection"); *ret_cli = NULL; - /* if the username is of the form DOMAIN\username then split out the domain */ - p = strpbrk(username, "\\/"); - if (p) { - domain = talloc_strndup(mem_ctx, username, PTR_DIFF(p, username)); - username = talloc_strdup(mem_ctx, p+1); - } - status = smbcli_tree_full_connection(parent_ctx, &tree, myname, host, 0, sharename, devtype, - username, domain, password); + credentials); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 74db1c6952..0559c64dc1 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -167,8 +167,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, const char *my_name, const char *dest_host, int port, const char *service, const char *service_type, - const char *user, const char *domain, - const char *password) + struct cli_credentials *credentials) { struct smb_composite_connect io; NTSTATUS status; @@ -179,10 +178,10 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.calling_name = strupper_talloc(parent_ctx, my_name); io.in.service = service; io.in.service_type = service_type; - io.in.domain = domain; - io.in.user = user; - if (user && user[0]) { - io.in.password = password; + io.in.domain = cli_credentials_get_domain(credentials); + io.in.user = cli_credentials_get_username(credentials); + if (!cli_credentials_is_anonymous(credentials)) { + io.in.password = cli_credentials_get_password(credentials); } else { io.in.password = NULL; } -- cgit From 376b03ebd895b221b70058ee18bea50587388182 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Mar 2005 06:58:27 +0000 Subject: r5940: fix schannel against w2k, it skips the confounder in the signature (24 bytes) for singed packets but it accepts 32 bytes from the client. (w2k3 accept it the otherway arround too) metze (This used to be commit 08d4c3b9f8558ee40c73a22b3ec110b052f28110) --- source4/libcli/auth/schannel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index a5521d4626..d582ff2dd0 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/libcli/auth/schannel.c @@ -158,7 +158,8 @@ NTSTATUS schannel_check_packet(struct schannel_state *state, uint8_t seq_num[8]; static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; - if (sig->length != 32) { + /* w2k sends just 24 bytes and skip the confounder */ + if (sig->length != 32 && sig->length != 24) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 645711c602313940dcf80ec786557920ecfbf884 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Mar 2005 08:00:45 +0000 Subject: r5941: Commit this patch much earlier than I would normally prefer, but metze needs a working tree... The main volume of this patch was what I started working on today: - Cleans up memory handling around DCE/RPC pipes, to have a parent talloc context. - Uses sepereate inner loops for some of the DCE/RPC tests The other and more important part of this patch fixes issues surrounding the new credentials framwork: This makes the struct cli_credentials always a talloc() structure, rather than on the stack. Parts of the cli_credentials code already assumed this. There were other issues, particularly in the DCERPC over SMB handling, as well as little things that had to be tidied up before test_w2k3.sh would start to pass. Andrew Bartlett (This used to be commit 0453f9d05d2e336fba1f85dbf2718d01fa2bf778) --- source4/libcli/cliconnect.c | 5 ----- source4/libcli/raw/clitree.c | 8 ++------ 2 files changed, 2 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 3834d49e49..7459460137 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -78,11 +78,6 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; if (cli_credentials_is_anonymous(credentials)) { - setup.in.password = NULL; - setup.in.user = ""; - setup.in.domain = ""; - setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; - } else { if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { setup.in.password = cli_credentials_get_password(credentials); } else { diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 0559c64dc1..f333cf7a98 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -167,7 +167,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, const char *my_name, const char *dest_host, int port, const char *service, const char *service_type, - struct cli_credentials *credentials) + struct cli_credentials *credentials) { struct smb_composite_connect io; NTSTATUS status; @@ -180,11 +180,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service_type = service_type; io.in.domain = cli_credentials_get_domain(credentials); io.in.user = cli_credentials_get_username(credentials); - if (!cli_credentials_is_anonymous(credentials)) { - io.in.password = cli_credentials_get_password(credentials); - } else { - io.in.password = NULL; - } + io.in.password = cli_credentials_get_password(credentials); status = smb_composite_connect(&io, parent_ctx); if (NT_STATUS_IS_OK(status)) { -- cgit From 79f6bcd5ae1711075ce0e75392ce83a72766698e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Mar 2005 01:30:43 +0000 Subject: r5988: Fix the -P option (use machine account credentials) to use the Samba4 secrets system, and not the old system from Samba3. This allowed the code from auth_domain to be shared - we now only lookup the secrets.ldb in lib/credentials.c. In order to link the resultant binary, samdb_search() has been moved from deep inside rpc_server into lib/gendb.c, along with the existing gendb_search_v(). The vast majority of this patch is the simple rename that followed, (Depending on the whole SAMDB for just this function seemed pointless, and brought in futher dependencies, such as smbencrypt.c). Andrew Bartlett (This used to be commit e13c671619bd290a8b3cae8555cb281a9a185ee0) --- source4/libcli/auth/kerberos_verify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 2aef38fcd9..6e7907fc43 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -204,9 +204,9 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte } /* search for the secret record */ - ldb_ret = samdb_search(ldb, + ldb_ret = gendb_search(ldb, mem_ctx, base_dn, &msgs, attrs, - "(&(realm=%s)(objectclass=primaryDomain))", + SECRETS_PRIMARY_REALM_FILTER, lp_realm()); if (ldb_ret == 0) { DEBUG(1, ("Could not find domain join record for %s\n", -- cgit From b8f395cf78d6983f6a9ee139e99968bde3455795 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Mar 2005 09:05:40 +0000 Subject: r5992: Rename schannel.c -> schannel_sign.c. The rest of the schannel code (from librpc) will be moved into schannel.c soon. Andrew Bartlett (This used to be commit d6c80ff74b0550641c253316b37f1050c207791c) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/auth/schannel.c | 293 ------------------------------------ source4/libcli/auth/schannel_sign.c | 293 ++++++++++++++++++++++++++++++++++++ 3 files changed, 294 insertions(+), 294 deletions(-) delete mode 100644 source4/libcli/auth/schannel.c create mode 100644 source4/libcli/auth/schannel_sign.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index c40a1346db..b37e214360 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,7 +1,7 @@ ################################# # Start SUBSYSTEM GENSEC [SUBSYSTEM::LIBCLI_AUTH] -ADD_OBJ_FILES = libcli/auth/schannel.o \ +ADD_OBJ_FILES = libcli/auth/schannel_sign.o \ libcli/auth/credentials.o \ libcli/auth/session.o \ libcli/auth/smbencrypt.o diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c deleted file mode 100644 index d582ff2dd0..0000000000 --- a/source4/libcli/auth/schannel.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - schannel library code - - Copyright (C) Andrew Tridgell 2004 - - 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 "lib/crypto/crypto.h" - -struct schannel_state { - uint8_t session_key[16]; - uint32_t seq_num; - BOOL initiator; -}; - -#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } -#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } - -/******************************************************************* - Encode or Decode the sequence number (which is symmetric) - ********************************************************************/ -static void netsec_deal_with_seq_num(struct schannel_state *state, - const uint8_t packet_digest[8], - uint8_t seq_num[8]) -{ - static const uint8_t zeros[4]; - uint8_t sequence_key[16]; - uint8_t digest1[16]; - - hmac_md5(state->session_key, zeros, sizeof(zeros), digest1); - hmac_md5(digest1, packet_digest, 8, sequence_key); - arcfour_crypt(seq_num, sequence_key, 8); - - state->seq_num++; -} - - -/******************************************************************* - Calculate the key with which to encode the data payload - ********************************************************************/ -static void netsec_get_sealing_key(const uint8_t session_key[16], - const uint8_t seq_num[8], - uint8_t sealing_key[16]) -{ - static const uint8_t zeros[4]; - uint8_t digest2[16]; - uint8_t sess_kf0[16]; - int i; - - for (i = 0; i < 16; i++) { - sess_kf0[i] = session_key[i] ^ 0xf0; - } - - hmac_md5(sess_kf0, zeros, 4, digest2); - hmac_md5(digest2, seq_num, 8, sealing_key); -} - - -/******************************************************************* - Create a digest over the entire packet (including the data), and - MD5 it with the session key. - ********************************************************************/ -static void schannel_digest(const uint8_t sess_key[16], - const uint8_t netsec_sig[8], - const uint8_t *confounder, - const uint8_t *data, size_t data_len, - uint8_t digest_final[16]) -{ - uint8_t packet_digest[16]; - static const uint8_t zeros[4]; - struct MD5Context ctx; - - MD5Init(&ctx); - MD5Update(&ctx, zeros, 4); - MD5Update(&ctx, netsec_sig, 8); - if (confounder) { - MD5Update(&ctx, confounder, 8); - } - MD5Update(&ctx, data, data_len); - MD5Final(packet_digest, &ctx); - - hmac_md5(sess_key, packet_digest, sizeof(packet_digest), digest_final); -} - - -/* - unseal a packet -*/ -NTSTATUS schannel_unseal_packet(struct schannel_state *state, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - DATA_BLOB *sig) -{ - uint8_t digest_final[16]; - uint8_t confounder[8]; - uint8_t seq_num[8]; - uint8_t sealing_key[16]; - static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; - - if (sig->length != 32) { - return NT_STATUS_ACCESS_DENIED; - } - - memcpy(confounder, sig->data+24, 8); - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0:0x80); - - netsec_get_sealing_key(state->session_key, seq_num, sealing_key); - arcfour_crypt(confounder, sealing_key, 8); - arcfour_crypt(data, sealing_key, length); - - schannel_digest(state->session_key, - netsec_sig, confounder, - data, length, digest_final); - - if (memcmp(digest_final, sig->data+16, 8) != 0) { - dump_data_pw("calc digest:", digest_final, 8); - dump_data_pw("wire digest:", sig->data+16, 8); - return NT_STATUS_ACCESS_DENIED; - } - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - if (memcmp(seq_num, sig->data+8, 8) != 0) { - dump_data_pw("calc seq num:", seq_num, 8); - dump_data_pw("wire seq num:", sig->data+8, 8); - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - -/* - check the signature on a packet -*/ -NTSTATUS schannel_check_packet(struct schannel_state *state, - const uint8_t *data, size_t length, - const DATA_BLOB *sig) -{ - uint8_t digest_final[16]; - uint8_t seq_num[8]; - static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; - - /* w2k sends just 24 bytes and skip the confounder */ - if (sig->length != 32 && sig->length != 24) { - return NT_STATUS_ACCESS_DENIED; - } - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0:0x80); - - dump_data_pw("seq_num:\n", seq_num, 8); - dump_data_pw("sess_key:\n", state->session_key, 16); - - schannel_digest(state->session_key, - netsec_sig, NULL, - data, length, digest_final); - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - if (memcmp(seq_num, sig->data+8, 8) != 0) { - dump_data_pw("calc seq num:", seq_num, 8); - dump_data_pw("wire seq num:", sig->data+8, 8); - return NT_STATUS_ACCESS_DENIED; - } - - if (memcmp(digest_final, sig->data+16, 8) != 0) { - dump_data_pw("calc digest:", digest_final, 8); - dump_data_pw("wire digest:", sig->data+16, 8); - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - - -/* - seal a packet -*/ -NTSTATUS schannel_seal_packet(struct schannel_state *state, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - DATA_BLOB *sig) -{ - uint8_t digest_final[16]; - uint8_t confounder[8]; - uint8_t seq_num[8]; - uint8_t sealing_key[16]; - static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; - - generate_random_buffer(confounder, 8); - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0x80:0); - - schannel_digest(state->session_key, - netsec_sig, confounder, - data, length, digest_final); - - netsec_get_sealing_key(state->session_key, seq_num, sealing_key); - arcfour_crypt(confounder, sealing_key, 8); - arcfour_crypt(data, sealing_key, length); - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - (*sig) = data_blob_talloc(mem_ctx, NULL, 32); - - memcpy(sig->data, netsec_sig, 8); - memcpy(sig->data+8, seq_num, 8); - memcpy(sig->data+16, digest_final, 8); - memcpy(sig->data+24, confounder, 8); - - dump_data_pw("signature:", sig->data+ 0, 8); - dump_data_pw("seq_num :", sig->data+ 8, 8); - dump_data_pw("digest :", sig->data+16, 8); - dump_data_pw("confound :", sig->data+24, 8); - - return NT_STATUS_OK; -} - - -/* - sign a packet -*/ -NTSTATUS schannel_sign_packet(struct schannel_state *state, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - DATA_BLOB *sig) -{ - uint8_t digest_final[16]; - uint8_t seq_num[8]; - static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0x80:0); - - schannel_digest(state->session_key, - netsec_sig, NULL, - data, length, digest_final); - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - (*sig) = data_blob_talloc(mem_ctx, NULL, 32); - - memcpy(sig->data, netsec_sig, 8); - memcpy(sig->data+8, seq_num, 8); - memcpy(sig->data+16, digest_final, 8); - memset(sig->data+24, 0, 8); - - dump_data_pw("signature:", sig->data+ 0, 8); - dump_data_pw("seq_num :", sig->data+ 8, 8); - dump_data_pw("digest :", sig->data+16, 8); - dump_data_pw("confound :", sig->data+24, 8); - - return NT_STATUS_OK; -} - -/* - create an schannel context state -*/ -NTSTATUS schannel_start(TALLOC_CTX *mem_ctx, - struct schannel_state **state, - const uint8_t session_key[16], - BOOL initiator) -{ - (*state) = talloc(mem_ctx, struct schannel_state); - if (!(*state)) { - return NT_STATUS_NO_MEMORY; - } - - memcpy((*state)->session_key, session_key, 16); - (*state)->initiator = initiator; - (*state)->seq_num = 0; - - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/schannel_sign.c b/source4/libcli/auth/schannel_sign.c new file mode 100644 index 0000000000..d582ff2dd0 --- /dev/null +++ b/source4/libcli/auth/schannel_sign.c @@ -0,0 +1,293 @@ +/* + Unix SMB/CIFS implementation. + + schannel library code + + Copyright (C) Andrew Tridgell 2004 + + 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 "lib/crypto/crypto.h" + +struct schannel_state { + uint8_t session_key[16]; + uint32_t seq_num; + BOOL initiator; +}; + +#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } + +/******************************************************************* + Encode or Decode the sequence number (which is symmetric) + ********************************************************************/ +static void netsec_deal_with_seq_num(struct schannel_state *state, + const uint8_t packet_digest[8], + uint8_t seq_num[8]) +{ + static const uint8_t zeros[4]; + uint8_t sequence_key[16]; + uint8_t digest1[16]; + + hmac_md5(state->session_key, zeros, sizeof(zeros), digest1); + hmac_md5(digest1, packet_digest, 8, sequence_key); + arcfour_crypt(seq_num, sequence_key, 8); + + state->seq_num++; +} + + +/******************************************************************* + Calculate the key with which to encode the data payload + ********************************************************************/ +static void netsec_get_sealing_key(const uint8_t session_key[16], + const uint8_t seq_num[8], + uint8_t sealing_key[16]) +{ + static const uint8_t zeros[4]; + uint8_t digest2[16]; + uint8_t sess_kf0[16]; + int i; + + for (i = 0; i < 16; i++) { + sess_kf0[i] = session_key[i] ^ 0xf0; + } + + hmac_md5(sess_kf0, zeros, 4, digest2); + hmac_md5(digest2, seq_num, 8, sealing_key); +} + + +/******************************************************************* + Create a digest over the entire packet (including the data), and + MD5 it with the session key. + ********************************************************************/ +static void schannel_digest(const uint8_t sess_key[16], + const uint8_t netsec_sig[8], + const uint8_t *confounder, + const uint8_t *data, size_t data_len, + uint8_t digest_final[16]) +{ + uint8_t packet_digest[16]; + static const uint8_t zeros[4]; + struct MD5Context ctx; + + MD5Init(&ctx); + MD5Update(&ctx, zeros, 4); + MD5Update(&ctx, netsec_sig, 8); + if (confounder) { + MD5Update(&ctx, confounder, 8); + } + MD5Update(&ctx, data, data_len); + MD5Final(packet_digest, &ctx); + + hmac_md5(sess_key, packet_digest, sizeof(packet_digest), digest_final); +} + + +/* + unseal a packet +*/ +NTSTATUS schannel_unseal_packet(struct schannel_state *state, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + uint8_t digest_final[16]; + uint8_t confounder[8]; + uint8_t seq_num[8]; + uint8_t sealing_key[16]; + static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; + + if (sig->length != 32) { + return NT_STATUS_ACCESS_DENIED; + } + + memcpy(confounder, sig->data+24, 8); + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0:0x80); + + netsec_get_sealing_key(state->session_key, seq_num, sealing_key); + arcfour_crypt(confounder, sealing_key, 8); + arcfour_crypt(data, sealing_key, length); + + schannel_digest(state->session_key, + netsec_sig, confounder, + data, length, digest_final); + + if (memcmp(digest_final, sig->data+16, 8) != 0) { + dump_data_pw("calc digest:", digest_final, 8); + dump_data_pw("wire digest:", sig->data+16, 8); + return NT_STATUS_ACCESS_DENIED; + } + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + if (memcmp(seq_num, sig->data+8, 8) != 0) { + dump_data_pw("calc seq num:", seq_num, 8); + dump_data_pw("wire seq num:", sig->data+8, 8); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + +/* + check the signature on a packet +*/ +NTSTATUS schannel_check_packet(struct schannel_state *state, + const uint8_t *data, size_t length, + const DATA_BLOB *sig) +{ + uint8_t digest_final[16]; + uint8_t seq_num[8]; + static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; + + /* w2k sends just 24 bytes and skip the confounder */ + if (sig->length != 32 && sig->length != 24) { + return NT_STATUS_ACCESS_DENIED; + } + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0:0x80); + + dump_data_pw("seq_num:\n", seq_num, 8); + dump_data_pw("sess_key:\n", state->session_key, 16); + + schannel_digest(state->session_key, + netsec_sig, NULL, + data, length, digest_final); + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + if (memcmp(seq_num, sig->data+8, 8) != 0) { + dump_data_pw("calc seq num:", seq_num, 8); + dump_data_pw("wire seq num:", sig->data+8, 8); + return NT_STATUS_ACCESS_DENIED; + } + + if (memcmp(digest_final, sig->data+16, 8) != 0) { + dump_data_pw("calc digest:", digest_final, 8); + dump_data_pw("wire digest:", sig->data+16, 8); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + + +/* + seal a packet +*/ +NTSTATUS schannel_seal_packet(struct schannel_state *state, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + uint8_t digest_final[16]; + uint8_t confounder[8]; + uint8_t seq_num[8]; + uint8_t sealing_key[16]; + static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; + + generate_random_buffer(confounder, 8); + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0x80:0); + + schannel_digest(state->session_key, + netsec_sig, confounder, + data, length, digest_final); + + netsec_get_sealing_key(state->session_key, seq_num, sealing_key); + arcfour_crypt(confounder, sealing_key, 8); + arcfour_crypt(data, sealing_key, length); + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + (*sig) = data_blob_talloc(mem_ctx, NULL, 32); + + memcpy(sig->data, netsec_sig, 8); + memcpy(sig->data+8, seq_num, 8); + memcpy(sig->data+16, digest_final, 8); + memcpy(sig->data+24, confounder, 8); + + dump_data_pw("signature:", sig->data+ 0, 8); + dump_data_pw("seq_num :", sig->data+ 8, 8); + dump_data_pw("digest :", sig->data+16, 8); + dump_data_pw("confound :", sig->data+24, 8); + + return NT_STATUS_OK; +} + + +/* + sign a packet +*/ +NTSTATUS schannel_sign_packet(struct schannel_state *state, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + uint8_t digest_final[16]; + uint8_t seq_num[8]; + static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; + + RSIVAL(seq_num, 0, state->seq_num); + SIVAL(seq_num, 4, state->initiator?0x80:0); + + schannel_digest(state->session_key, + netsec_sig, NULL, + data, length, digest_final); + + netsec_deal_with_seq_num(state, digest_final, seq_num); + + (*sig) = data_blob_talloc(mem_ctx, NULL, 32); + + memcpy(sig->data, netsec_sig, 8); + memcpy(sig->data+8, seq_num, 8); + memcpy(sig->data+16, digest_final, 8); + memset(sig->data+24, 0, 8); + + dump_data_pw("signature:", sig->data+ 0, 8); + dump_data_pw("seq_num :", sig->data+ 8, 8); + dump_data_pw("digest :", sig->data+16, 8); + dump_data_pw("confound :", sig->data+24, 8); + + return NT_STATUS_OK; +} + +/* + create an schannel context state +*/ +NTSTATUS schannel_start(TALLOC_CTX *mem_ctx, + struct schannel_state **state, + const uint8_t session_key[16], + BOOL initiator) +{ + (*state) = talloc(mem_ctx, struct schannel_state); + if (!(*state)) { + return NT_STATUS_NO_MEMORY; + } + + memcpy((*state)->session_key, session_key, 16); + (*state)->initiator = initiator; + (*state)->seq_num = 0; + + return NT_STATUS_OK; +} -- cgit From f312d91d60aa9d5ce688d589fd0bdde6f81ab82f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 03:35:51 +0000 Subject: r6025: Remove unused variables. This code will be modified again for the new cli_credentials code shortly. Andrew Bartlett (This used to be commit 13d09c8e9a50ae265059e4a0d92a07c651018a6c) --- source4/libcli/auth/kerberos.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c index 45838c6818..89b4108280 100644 --- a/source4/libcli/auth/kerberos.c +++ b/source4/libcli/auth/kerberos.c @@ -5,6 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Nalin Dahyabhai 2004. Copyright (C) Jeremy Allison 2004. + Copyright (C) Andrew Bartlett 2004-2005 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 @@ -442,17 +443,13 @@ static BOOL verify_service_password(krb5_context ctx, krb5_keyblock key; krb5_data passdata; char *salting_s = NULL; - char *machine_account = NULL, *password = NULL; + char *password = NULL; krb5_auth_context auth_context = NULL; krb5_error_code err; memset(&passdata, '\0', sizeof(passdata)); memset(&key, '\0', sizeof(key)); - asprintf(&machine_account, "%s$@%s", lp_netbios_name(), lp_realm()); - if (machine_account == NULL) { - goto out; - } password = secrets_fetch_machine_password(lp_workgroup()); if (password == NULL) { goto out; @@ -506,7 +503,6 @@ static BOOL verify_service_password(krb5_context ctx, } SAFE_FREE(salting_s); SAFE_FREE(password); - SAFE_FREE(machine_account); return ret; } -- cgit From f82bafa0674947a932e0ee47a57d9485a31d8286 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 03:36:53 +0000 Subject: r6026: Update the kerberos keytab code to match Samba3 again. (untested at this point). Andrew Bartlett (This used to be commit ef7f9a01b4f3fa41fd7981b260fa2fadc7ce10ad) --- source4/libcli/auth/kerberos_verify.c | 202 ++++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 80 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index 6e7907fc43..fd4c3f6ba3 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -6,6 +6,7 @@ Copyright (C) Luke Howard 2003 Copyright (C) Guenther Deschner 2003 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 + Copyright (C) Andrew Bartlett 2004-2005 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 @@ -79,15 +80,34 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex krb5_keyblock *keyblock) { krb5_error_code ret = 0; - BOOL auth_ok = False; + krb5_error_code our_ret = 0; krb5_keytab keytab = NULL; - char *my_fqdn; - fstring my_name; - fstring my_Fqdn, my_NAME; - char *p_fqdn; - char *host_princ_s[18]; - krb5_principal host_princ; + krb5_kt_cursor kt_cursor; + krb5_keytab_entry kt_entry; + char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char *entry_princ_s = NULL; + const char *my_name, *my_fqdn; int i; + int number_matched_principals = 0; + + /* Generate the list of principal names which we expect + * clients might want to use for authenticating to the file + * service. We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */ + + my_name = lp_netbios_name(); + + my_fqdn = name_to_fqdn(mem_ctx, my_name); + + asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm()); + asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm()); + asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); + + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(kt_cursor); ret = krb5_kt_default(context, &keytab); if (ret) { @@ -95,73 +115,90 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex goto out; } - /* Generate the list of principal names which we expect clients might - * want to use for authenticating to the file service. */ + /* Iterate through the keytab. For each key, if the principal + * name case-insensitively matches one of the allowed formats, + * try verifying the ticket using that principal. */ - fstrcpy(my_name, lp_netbios_name()); - strlower_m(my_name); + ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); + if (ret != KRB5_KT_END && ret != ENOENT ) { + while (ret && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { + ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + break; + } + ret = KRB5_BAD_ENCTYPE; + for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + if (strequal(entry_princ_s, valid_princ_formats[i])) { + number_matched_principals++; + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + *pp_tkt = NULL; + our_ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); + if (our_ret != KRB5_BAD_ENCTYPE) { + ret = our_ret; + } + if (our_ret) { + DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", + entry_princ_s, error_message(our_ret))); + } else { + DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", + entry_princ_s)); + break; + } + } + } + + /* Free the name we parsed. */ + krb5_free_unparsed_name(context, entry_princ_s); + entry_princ_s = NULL; + + /* Free the entry we just read. */ + smb_krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); + } + krb5_kt_end_seq_get(context, keytab, &kt_cursor); + } - fstrcpy(my_NAME, lp_netbios_name()); - strupper_m(my_NAME); + ZERO_STRUCT(kt_cursor); - my_fqdn = name_to_fqdn(mem_ctx, lp_netbios_name()); - strlower_m(my_fqdn); + out: - p_fqdn = strchr_m(my_fqdn, '.'); - fstrcpy(my_Fqdn, my_NAME); - if (p_fqdn) { - fstrcat(my_Fqdn, p_fqdn); + if (ret) { + if (!number_matched_principals) { + DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n")); + } else { + DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n", + number_matched_principals)); + } + DEBUG(3, ("ads_keytab_verify_ticket: last error: %s\n", error_message(ret))); } - asprintf(&host_princ_s[0], "%s$@%s", my_name, lp_realm()); - asprintf(&host_princ_s[1], "%s$@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[2], "host/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[3], "host/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[6], "HOST/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[10], "%s/%s@%s", service, my_name, lp_realm()); - asprintf(&host_princ_s[11], "%s/%s@%s", service, my_NAME, lp_realm()); - asprintf(&host_princ_s[12], "%s/%s@%s", service, my_fqdn, lp_realm()); - asprintf(&host_princ_s[13], "%s/%s@%s", service, my_Fqdn, lp_realm()); - asprintf(&host_princ_s[14], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_name, lp_realm()); - asprintf(&host_princ_s[15], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_NAME, lp_realm()); - asprintf(&host_princ_s[16], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_fqdn, lp_realm()); - asprintf(&host_princ_s[17], "%s/%s@%s", strupper_talloc(mem_ctx, service), my_Fqdn, lp_realm()); - - /* Now try to verify the ticket using the key associated with each of - * the principals which we think clients will expect us to be - * participating as. */ - for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { - host_princ = NULL; - ret = krb5_parse_name(context, host_princ_s[i], &host_princ); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n", - host_princ_s[i], error_message(ret))); - goto out; - } - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - *pp_tkt = NULL; - ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt); - krb5_free_principal(context, host_princ); - if (ret) { - DEBUG(0, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); - } else { - DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i])); - auth_ok = True; - break; - } + if (entry_princ_s) { + krb5_free_unparsed_name(context, entry_princ_s); } - for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { - SAFE_FREE(host_princ_s[i]); + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + smb_krb5_kt_free_entry(context, &kt_entry); + } } - out: + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &kt_cursor); + } + } if (keytab) { krb5_kt_close(context, keytab); @@ -182,11 +219,12 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte krb5_keyblock *keyblock) { krb5_error_code ret = 0; + krb5_error_code our_ret; krb5_data password; krb5_enctype *enctypes = NULL; int i; const struct ldb_val *password_v; - struct ldb_wrap *ldb; + struct ldb_context *ldb; int ldb_ret; struct ldb_message **msgs; const char *base_dn = SECRETS_PRIMARY_DOMAIN_DN; @@ -228,36 +266,42 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { DEBUG(1,("ads_secrets_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", error_message(ret))); - goto out; + return ret; } p_packet->length = ticket->length; p_packet->data = (krb5_pointer)ticket->data; - ret = KRB5_BAD_ENCTYPE; /* We need to setup a auth context with each possible encoding type in turn. */ + + ret = KRB5_BAD_ENCTYPE; for (i=0;enctypes[i];i++) { - krb5_error_code our_ret; - our_ret = create_kerberos_key_from_string(context, host_princ, &password, keyblock, enctypes[i]); - if (our_ret) { - ret = our_ret; + krb5_keyblock *key = NULL; + + if (!(key = malloc_p(krb5_keyblock))) { + break; + } + + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + SAFE_FREE(key); continue; } - krb5_auth_con_setuseruserkey(context, auth_context, keyblock); + krb5_auth_con_setuseruserkey(context, auth_context, key); + + krb5_free_keyblock(context, key); our_ret = krb5_rd_req(context, &auth_context, p_packet, - NULL, - NULL, NULL, pp_tkt); + NULL, + NULL, NULL, pp_tkt); if (!our_ret) { + DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", - (unsigned int)enctypes[i] )); + (unsigned int)enctypes[i] )); ret = our_ret; break; } - - krb5_free_keyblock_contents(context, keyblock); - + DEBUG((our_ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", (unsigned int)enctypes[i], error_message(our_ret))); @@ -267,8 +311,6 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte } } - out: - free_kerberos_etypes(context, enctypes); return ret; -- cgit From 46b22b073cf0d0c93f2e70dd4d670dc373d5a26a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 04:11:39 +0000 Subject: r6027: Add copyright, and add a useful debug message. Andrew Bartlett (This used to be commit b5260cf0d4c4f2e81a310d1c94160c9fbaaa331f) --- source4/libcli/auth/ntlmssp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 91bc9eadbd..37374d9d39 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/libcli/auth/ntlmssp.c @@ -1,10 +1,10 @@ /* Unix SMB/Netbios implementation. Version 3.0 - handle NLTMSSP, server side + handle NLTMSSP, client server side parsing Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Andrew Bartlett 2001-2005 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 @@ -148,6 +148,7 @@ NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *u { if (!user) { /* it should be at least "" */ + DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n")); return NT_STATUS_INVALID_PARAMETER; } ntlmssp_state->user = talloc_strdup(ntlmssp_state, user); -- cgit From 2eb3d680625286431a3a60e37b75f47e0738f253 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 04:14:06 +0000 Subject: r6028: A MAJOR update to intergrate the new credentails system fully with GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'. GENSEC now no longer has it's own handling of 'set username' etc, instead it uses cli_credentials calls. In order to link the credentails code right though Samba, a lot of interfaces have changed to remove 'username, domain, password' arguments, and these have been replaced with a single 'struct cli_credentials'. In the session setup code, a new parameter 'workgroup' contains the client/server current workgroup, which seems unrelated to the authentication exchange (it was being filled in from the auth info). This allows in particular kerberos to only call back for passwords when it actually needs to perform the kinit. The kerberos code has been modified not to use the SPNEGO provided 'principal name' (in the mechListMIC), but to instead use the name the host was connected to as. This better matches Microsoft behaviour, is more secure and allows better use of standard kerberos functions. To achieve this, I made changes to our socket code so that the hostname (before name resolution) is now recorded on the socket. In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now in libcli/auth/schannel.c, and it looks much more like a standard GENSEC module. The actual sign/seal code moved to libcli/auth/schannel_sign.c in a previous commit. The schannel credentails structure is now merged with the rest of the credentails, as many of the values (username, workstation, domain) where already present there. This makes handling this in a generic manner much easier, as there is no longer a custom entry-point. The auth_domain module continues to be developed, but is now just as functional as auth_winbind. The changes here are consequential to the schannel changes. The only removed function at this point is the RPC-LOGIN test (simulating the load of a WinXP login), which needs much more work to clean it up (it contains copies of too much code from all over the torture suite, and I havn't been able to penetrate its 'structure'). Andrew Bartlett (This used to be commit 2301a4b38a21aa60917973451687063d83d18d66) --- source4/libcli/auth/config.mk | 3 +- source4/libcli/auth/credentials.c | 6 - source4/libcli/auth/gensec.c | 210 +-------------------------- source4/libcli/auth/gensec.h | 12 +- source4/libcli/auth/gensec.mk | 12 ++ source4/libcli/auth/gensec_krb5.c | 57 ++++---- source4/libcli/auth/gensec_ntlmssp.c | 21 ++- source4/libcli/auth/kerberos.h | 1 + source4/libcli/auth/ntlmssp_sign.c | 2 +- source4/libcli/auth/schannel.c | 268 +++++++++++++++++++++++++++++++++++ source4/libcli/auth/schannel_sign.c | 67 ++++----- source4/libcli/auth/spnego.c | 10 +- source4/libcli/cliconnect.c | 16 +-- source4/libcli/composite/composite.h | 17 +-- source4/libcli/composite/connect.c | 9 +- source4/libcli/composite/fetchfile.c | 6 +- source4/libcli/composite/sesssetup.c | 54 ++++--- source4/libcli/ldap/ldap.h | 4 +- source4/libcli/ldap/ldap_client.c | 27 +--- source4/libcli/raw/clisession.c | 4 +- source4/libcli/raw/clisocket.c | 28 ++-- source4/libcli/raw/clitree.c | 7 +- 22 files changed, 431 insertions(+), 410 deletions(-) create mode 100644 source4/libcli/auth/schannel.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index b37e214360..0c013ce0ef 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,8 +1,7 @@ ################################# # Start SUBSYSTEM GENSEC [SUBSYSTEM::LIBCLI_AUTH] -ADD_OBJ_FILES = libcli/auth/schannel_sign.o \ - libcli/auth/credentials.o \ +ADD_OBJ_FILES = libcli/auth/credentials.o \ libcli/auth/session.o \ libcli/auth/smbencrypt.o REQUIRED_SUBSYSTEMS = \ diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 90b8313c9d..bcb462ae9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -192,18 +192,12 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const char *computer_name, - const char *domain, - const char *account_name, const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { creds->sequence = time(NULL); creds->negotiate_flags = negotiate_flags; - creds->computer_name = talloc_strdup(creds, computer_name); - creds->domain = talloc_strdup(creds, domain); - creds->account_name = talloc_strdup(creds, account_name); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 69de016156..cc7327187c 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -4,7 +4,7 @@ Generic Authentication Interface Copyright (C) Andrew Tridgell 2003 - Copyright (C) Andrew Bartlett 2004 + Copyright (C) Andrew Bartlett 2004-2005 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 @@ -130,13 +130,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense (*gensec_security)->ops = NULL; - ZERO_STRUCT((*gensec_security)->user); ZERO_STRUCT((*gensec_security)->target); - ZERO_STRUCT((*gensec_security)->default_user); - - (*gensec_security)->default_user.name = ""; - (*gensec_security)->default_user.domain = talloc_strdup(*gensec_security, lp_workgroup()); - (*gensec_security)->default_user.realm = talloc_strdup(*gensec_security, lp_realm()); (*gensec_security)->subcontext = False; (*gensec_security)->want_features = 0; @@ -185,8 +179,6 @@ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense (*gensec_security)->gensec_role = GENSEC_CLIENT; (*gensec_security)->password_callback = NULL; - ZERO_STRUCT((*gensec_security)->user); - return status; } @@ -507,163 +499,24 @@ BOOL gensec_have_feature(struct gensec_security *gensec_security, } /** - * Set a username on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) -{ - gensec_security->user.name = talloc_strdup(gensec_security, user); - if (user && !gensec_security->user.name) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set a username on a GENSEC context - ensures it is talloc()ed - * - */ - -const char *gensec_get_username(struct gensec_security *gensec_security) -{ - if (gensec_security->user.name) { - return gensec_security->user.name; - } - return gensec_security->default_user.name; -} - -/** - * Set a domain on a GENSEC context - ensures it is talloc()ed + * Associate a credentails structure with a GENSEC context - talloc_reference()s it to the context * */ -NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain) +NTSTATUS gensec_set_credentials(struct gensec_security *gensec_security, struct cli_credentials *credentials) { - gensec_security->user.domain = talloc_strdup(gensec_security, domain); - if (domain && !gensec_security->user.domain) { - return NT_STATUS_NO_MEMORY; - } + gensec_security->credentials = talloc_reference(gensec_security, credentials); return NT_STATUS_OK; } /** - * Return the NT domain for this GENSEC context + * Return the credentails structure associated with a GENSEC context * */ -const char *gensec_get_domain(struct gensec_security *gensec_security) +struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security) { - if (gensec_security->user.domain) { - return gensec_security->user.domain; - } else if (gensec_security->user.realm) { - return gensec_security->user.realm; - } - return gensec_security->default_user.domain; -} - -/** - * Set the client workstation on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_workstation(struct gensec_security *gensec_security, const char *workstation) -{ - gensec_security->user.workstation = talloc_strdup(gensec_security, workstation); - if (workstation && !gensec_security->user.workstation) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Return the client workstation on a GENSEC context - ensures it is talloc()ed - * - */ - -const char *gensec_get_workstation(struct gensec_security *gensec_security) -{ - if (gensec_security->user.workstation) { - return gensec_security->user.workstation; - } else { - return lp_netbios_name(); - } -} - -/** - * Set a kerberos realm on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *realm) -{ - gensec_security->user.realm = talloc_strdup(gensec_security, realm); - if (realm && !gensec_security->user.realm) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Return the Krb5 realm for this context - * - */ - -const char *gensec_get_realm(struct gensec_security *gensec_security) -{ - if (gensec_security->user.realm) { - return gensec_security->user.realm; - } else if (gensec_security->user.domain) { - return gensec_security->user.domain; - } - return gensec_security->default_user.realm; -} - -/** - * Return a kerberos principal for this context, if one has been set - * - */ - -char *gensec_get_client_principal(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx) -{ - const char *realm = gensec_get_realm(gensec_security); - if (realm) { - return talloc_asprintf(mem_ctx, "%s@%s", - gensec_get_username(gensec_security), - gensec_get_realm(gensec_security)); - } else { - return talloc_strdup(mem_ctx, gensec_get_username(gensec_security)); - } -} - -/** - * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will - * not do a callback - * - */ - -NTSTATUS gensec_set_password(struct gensec_security *gensec_security, - const char *password) -{ - gensec_security->user.password = talloc_strdup(gensec_security, password); - if (password && !gensec_security->user.password) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set the target principal name (if already known) on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) -{ - gensec_security->target.principal = talloc_strdup(gensec_security, principal); - if (!gensec_security->target.principal) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; + return gensec_security->credentials; } /** @@ -713,54 +566,6 @@ const char *gensec_get_target_service(struct gensec_security *gensec_security) return "host"; } -const char *gensec_get_target_principal(struct gensec_security *gensec_security) -{ - const char *mechListMIC; - - if (gensec_security->target.principal) { - return gensec_security->target.principal; - } - - mechListMIC = talloc_asprintf(gensec_security,"%s$@%s", - lp_netbios_name(), - lp_realm()); - return mechListMIC; -} - -/** - * Set a password callback, if the gensec module we use demands a password - */ - -void gensec_set_password_callback(struct gensec_security *gensec_security, - gensec_password_callback callback, void *callback_private_data) -{ - gensec_security->password_callback = callback; - gensec_security->password_callback_private = callback_private_data; -} - -/** - * Get (or call back for) a password. - */ - -NTSTATUS gensec_get_password(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - char **password) -{ - if (gensec_security->user.password) { - *password = talloc_strdup(mem_ctx, gensec_security->user.password); - if (!*password) { - return NT_STATUS_NO_MEMORY; - } else { - return NT_STATUS_OK; - } - } - if (!gensec_security->password_callback) { - *password = NULL; - return NT_STATUS_OK; - } - return gensec_security->password_callback(gensec_security, mem_ctx, password); -} - /* register a GENSEC backend. @@ -821,6 +626,5 @@ const struct gensec_critical_sizes *gensec_interface_version(void) */ NTSTATUS gensec_init(void) { - gensec_dcerpc_schannel_init(); return NT_STATUS_OK; } diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index a4383d852c..91c817d48a 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -4,7 +4,7 @@ Generic Authentication Interface Copyright (C) Andrew Tridgell 2003 - Copyright (C) Andrew Bartlett 2004 + Copyright (C) Andrew Bartlett 2004-2005 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 @@ -28,13 +28,6 @@ #define GENSEC_OID_KERBEROS5_USER2USER "1 2 840 113554 1 2 2 3" struct gensec_security; -struct gensec_user { - const char *workstation; - const char *domain; - const char *realm; - const char *name; - const char *password; -}; struct gensec_target { const char *principal; const char *hostname; @@ -105,8 +98,7 @@ struct gensec_security { void *password_callback_private; const struct gensec_security_ops *ops; void *private_data; - struct gensec_user user; - struct gensec_user default_user; + struct cli_credentials *credentials; struct gensec_target target; enum gensec_role gensec_role; BOOL subcontext; diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk index 7e2e34081d..b4c612da14 100644 --- a/source4/libcli/auth/gensec.mk +++ b/source4/libcli/auth/gensec.mk @@ -68,6 +68,18 @@ REQUIRED_SUBSYSTEMS = AUTH # End MODULE gensec_ntlmssp ################################################ +################################################ +# Start MODULE gensec_schannel +[MODULE::gensec_schannel] +SUBSYSTEM = GENSEC +INIT_FUNCTION = gensec_schannel_init +INIT_OBJ_FILES = libcli/auth/schannel.o +ADD_OBJ_FILES = \ + libcli/auth/schannel_sign.o +REQUIRED_SUBSYSTEMS = AUTH SCHANNELDB +# End MODULE gensec_ntlmssp +################################################ + ################################################ # Start SUBSYSTEM SCHANNELDB [SUBSYSTEM::SCHANNELDB] diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 71670632b9..453485d816 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -320,7 +320,12 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security struct gensec_krb5_state *gensec_krb5_state; krb5_error_code ret; NTSTATUS nt_status; - + const char *hostname = gensec_get_target_hostname(gensec_security); + if (!hostname) { + DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); + return NT_STATUS_ACCESS_DENIED; + } + nt_status = gensec_krb5_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -341,22 +346,8 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } while (1) { - if (gensec_security->target.principal) { - DEBUG(5, ("Finding ticket for target [%s]\n", gensec_security->target.principal)); - ret = ads_krb5_mk_req(gensec_krb5_state->context, - &gensec_krb5_state->auth_context, - AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, - gensec_security->target.principal, - gensec_krb5_state->ccache, - &gensec_krb5_state->ticket); - } else { + { krb5_data in_data; - const char *hostname = gensec_get_target_hostname(gensec_security); - if (!hostname) { - DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); - return NT_STATUS_ACCESS_DENIED; - } - in_data.length = 0; ret = krb5_mk_req(gensec_krb5_state->context, @@ -372,36 +363,40 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security case 0: return NT_STATUS_OK; case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: - DEBUG(3, ("Server is not registered with our KDC: %s\n", - error_message(ret))); + DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n", + hostname, error_message(ret))); return NT_STATUS_ACCESS_DENIED; case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5KRB_AP_ERR_TKT_EXPIRED: case KRB5_CC_END: + /* Too much clock skew - we will need to kinit to re-skew the clock */ + case KRB5KRB_AP_ERR_SKEW: + case KRB5_KDCREP_SKEW: { DEBUG(3, ("kerberos (mk_req) failed: %s\n", error_message(ret))); /* fall down to remaining code */ } + + /* just don't print a message for these really ordinary messages */ case KRB5_FCC_NOFILE: case KRB5_CC_NOTFOUND: case ENOENT: + { - char *password; + const char *password; char *ccache_string; time_t kdc_time = 0; - nt_status = gensec_get_password(gensec_security, - gensec_security, - &password); + password = cli_credentials_get_password(gensec_security->credentials); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } /* this string should be unique */ ccache_string = talloc_asprintf(gensec_krb5_state, "MEMORY:%s:%s:%s", - gensec_get_client_principal(gensec_security, gensec_krb5_state), - gensec_get_target_principal(gensec_security), + cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), + gensec_get_target_hostname(gensec_security), generate_random_str(gensec_krb5_state, 16)); ret = krb5_cc_resolve(gensec_krb5_state->context, ccache_string, &gensec_krb5_state->ccache); @@ -413,8 +408,8 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } ret = kerberos_kinit_password_cc(gensec_krb5_state->context, gensec_krb5_state->ccache, - gensec_get_client_principal(gensec_security, gensec_krb5_state), - password, NULL, &kdc_time); + cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), + password, NULL, &kdc_time); /* cope with ticket being in the future due to clock skew */ if ((unsigned)kdc_time > time(NULL)) { @@ -422,10 +417,18 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security int time_offset =(unsigned)kdc_time-t; DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(gensec_krb5_state->context, t + time_offset + 1, 0); + break; } + if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) { + DEBUG(1,("kinit for %s failed (%s)\n", + cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), + error_message(ret))); + return NT_STATUS_TIME_DIFFERENCE_AT_DC; + } if (ret) { - DEBUG(1,("kinit failed (%s)\n", + DEBUG(1,("kinit for %s failed (%s)\n", + cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), error_message(ret))); return NT_STATUS_WRONG_PASSWORD; } diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 51456d9107..5955904886 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -109,7 +109,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, NT_STATUS_NOT_OK_RETURN(nt_status); nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, gensec_ntlmssp_state, - user_info, &gensec_ntlmssp_state->server_info); + user_info, &gensec_ntlmssp_state->server_info); talloc_free(user_info); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -197,7 +197,7 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) { struct gensec_ntlmssp_state *gensec_ntlmssp_state; - char *password = NULL; + const char *password = NULL; NTSTATUS nt_status; nt_status = gensec_ntlmssp_start(gensec_security); @@ -228,25 +228,20 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur } nt_status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, - gensec_security->user.domain); + cli_credentials_get_domain(gensec_security->credentials)); NT_STATUS_NOT_OK_RETURN(nt_status); nt_status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, - gensec_security->user.name); + cli_credentials_get_username(gensec_security->credentials)); NT_STATUS_NOT_OK_RETURN(nt_status); - if (gensec_security->user.name) { - nt_status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password); - NT_STATUS_NOT_OK_RETURN(nt_status); - } + password = cli_credentials_get_password(gensec_security->credentials); - if (password) { - nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password); - NT_STATUS_NOT_OK_RETURN(nt_status); - } + nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password); + NT_STATUS_NOT_OK_RETURN(nt_status); nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state, - gensec_get_workstation(gensec_security)); + cli_credentials_get_workstation(gensec_security->credentials)); gensec_security->private_data = gensec_ntlmssp_state; diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index 9bb6d22eb6..c9b2eae55c 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -93,5 +93,6 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype); BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2); void kerberos_free_data_contents(krb5_context context, krb5_data *pdata); +krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry); #endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index 1b391306bc..347a85da77 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -3,7 +3,7 @@ * Version 3.0 * NTLMSSP Signing routines * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 - * Copyright (C) Andrew Bartlett 2003 + * Copyright (C) Andrew Bartlett 2003-2004 * * 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 diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c new file mode 100644 index 0000000000..3dbf10580b --- /dev/null +++ b/source4/libcli/auth/schannel.c @@ -0,0 +1,268 @@ +/* + Unix SMB/CIFS implementation. + + dcerpc schannel operations + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Andrew Bartlett 2004-2005 + + 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 "librpc/gen_ndr/ndr_schannel.h" +#include "auth/auth.h" +#include "libcli/auth/schannel.h" + +static size_t schannel_sig_size(struct gensec_security *gensec_security) +{ + return 32; +} + +static NTSTATUS schannel_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + struct schannel_state *state = gensec_security->private_data; + NTSTATUS status; + struct schannel_bind bind_schannel; + struct schannel_bind_ack bind_schannel_ack; + struct creds_CredentialState *creds; + + const char *workstation; + const char *domain; + *out = data_blob(NULL, 0); + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + if (state->state != SCHANNEL_STATE_START) { + /* we could parse the bind ack, but we don't know what it is yet */ + return NT_STATUS_OK; + } + + state->creds = talloc_reference(state, cli_credentials_get_netlogon_creds(gensec_security->credentials)); + + bind_schannel.unknown1 = 0; +#if 0 + /* to support this we'd need to have access to the full domain name */ + bind_schannel.bind_type = 23; + bind_schannel.u.info23.domain = cli_credentials_get_domain(gensec_security->credentials); + bind_schannel.u.info23.account_name = cli_credentials_get_username(gensec_security->credentials); + bind_schannel.u.info23.dnsdomain = str_format_nbt_domain(out_mem_ctx, fulldomainname); + bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, cli_credentials_get_workstation(gensec_security->credentials)); +#else + bind_schannel.bind_type = 3; + bind_schannel.u.info3.domain = cli_credentials_get_domain(gensec_security->credentials); + bind_schannel.u.info3.workstation = cli_credentials_get_workstation(gensec_security->credentials); +#endif + + status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel, + (ndr_push_flags_fn_t)ndr_push_schannel_bind); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not create schannel bind: %s\n", + nt_errstr(status))); + return status; + } + + state->state = SCHANNEL_STATE_UPDATE_1; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; + case GENSEC_SERVER: + + if (state->state != SCHANNEL_STATE_START) { + /* no third leg on this protocol */ + return NT_STATUS_INVALID_PARAMETER; + } + + /* parse the schannel startup blob */ + status = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, + (ndr_pull_flags_fn_t)ndr_pull_schannel_bind); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (bind_schannel.bind_type == 23) { + workstation = bind_schannel.u.info23.workstation; + domain = bind_schannel.u.info23.domain; + } else { + workstation = bind_schannel.u.info3.workstation; + domain = bind_schannel.u.info3.domain; + } + + /* pull the session key for this client */ + status = schannel_fetch_session_key(out_mem_ctx, workstation, + domain, &creds); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", + workstation, nt_errstr(status))); + return status; + } + + state->creds = talloc_reference(state, creds); + + bind_schannel_ack.unknown1 = 1; + bind_schannel_ack.unknown2 = 0; + bind_schannel_ack.unknown3 = 0x6c0000; + + status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack, + (ndr_push_flags_fn_t)ndr_push_schannel_bind_ack); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not return schannel bind ack for client %s: %s\n", + workstation, nt_errstr(status))); + return status; + } + + state->state = SCHANNEL_STATE_UPDATE_1; + + return NT_STATUS_OK; + } + return NT_STATUS_INVALID_PARAMETER; +} + +/** + * Return the struct creds_CredentialState. + * + * Make sure not to call this unless gensec is using schannel... + */ + +NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + struct creds_CredentialState **creds) +{ + struct schannel_state *state = gensec_security->private_data; + + *creds = talloc_reference(mem_ctx, state->creds); + if (!*creds) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + + +/** + * Return the credentials of a logged on user, including session keys + * etc. + * + * Only valid after a successful authentication + * + * May only be called once per authentication. + * + */ + +static NTSTATUS schannel_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info) +{ + (*session_info) = talloc(gensec_security, struct auth_session_info); + NT_STATUS_HAVE_NO_MEMORY(*session_info); + + ZERO_STRUCTP(*session_info); + + return NT_STATUS_OK; +} + +static NTSTATUS schannel_start(struct gensec_security *gensec_security) +{ + struct schannel_state *state; + + state = talloc(gensec_security, struct schannel_state); + if (!state) { + return NT_STATUS_NO_MEMORY; + } + + state->state = SCHANNEL_STATE_START; + state->seq_num = 0; + gensec_security->private_data = state; + + return NT_STATUS_OK; +} + +static NTSTATUS schannel_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS status; + struct schannel_state *state; + + status = schannel_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + state = gensec_security->private_data; + state->initiator = False; + + return NT_STATUS_OK; +} + +static NTSTATUS schannel_client_start(struct gensec_security *gensec_security) +{ + NTSTATUS status; + struct schannel_state *state; + + status = schannel_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + state = gensec_security->private_data; + state->initiator = True; + + return NT_STATUS_OK; +} + + +static BOOL schannel_have_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + if (feature & (GENSEC_FEATURE_SIGN | + GENSEC_FEATURE_SEAL)) { + return True; + } + return False; +} + + +static const struct gensec_security_ops gensec_schannel_security_ops = { + .name = "schannel", + .auth_type = DCERPC_AUTH_TYPE_SCHANNEL, + .client_start = schannel_client_start, + .server_start = schannel_server_start, + .update = schannel_update, + .seal_packet = schannel_seal_packet, + .sign_packet = schannel_sign_packet, + .check_packet = schannel_check_packet, + .unseal_packet = schannel_unseal_packet, + .session_key = schannel_session_key, + .session_info = schannel_session_info, + .sig_size = schannel_sig_size, + .have_feature = schannel_have_feature, + .enabled = True +}; + +NTSTATUS gensec_schannel_init(void) +{ + NTSTATUS ret; + ret = gensec_register(&gensec_schannel_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_schannel_security_ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/libcli/auth/schannel_sign.c b/source4/libcli/auth/schannel_sign.c index d582ff2dd0..3b493bd0d3 100644 --- a/source4/libcli/auth/schannel_sign.c +++ b/source4/libcli/auth/schannel_sign.c @@ -4,6 +4,7 @@ schannel library code Copyright (C) Andrew Tridgell 2004 + Copyright (C) Andrew Bartlett 2005 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 @@ -22,12 +23,9 @@ #include "includes.h" #include "lib/crypto/crypto.h" - -struct schannel_state { - uint8_t session_key[16]; - uint32_t seq_num; - BOOL initiator; -}; +#include "libcli/auth/schannel.h" +#include "libcli/auth/gensec.h" +#include "libcli/auth/credentials.h" #define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } #define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } @@ -43,7 +41,7 @@ static void netsec_deal_with_seq_num(struct schannel_state *state, uint8_t sequence_key[16]; uint8_t digest1[16]; - hmac_md5(state->session_key, zeros, sizeof(zeros), digest1); + hmac_md5(state->creds->session_key, zeros, sizeof(zeros), digest1); hmac_md5(digest1, packet_digest, 8, sequence_key); arcfour_crypt(seq_num, sequence_key, 8); @@ -102,11 +100,14 @@ static void schannel_digest(const uint8_t sess_key[16], /* unseal a packet */ -NTSTATUS schannel_unseal_packet(struct schannel_state *state, +NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { + struct schannel_state *state = gensec_security->private_data; + uint8_t digest_final[16]; uint8_t confounder[8]; uint8_t seq_num[8]; @@ -122,11 +123,11 @@ NTSTATUS schannel_unseal_packet(struct schannel_state *state, RSIVAL(seq_num, 0, state->seq_num); SIVAL(seq_num, 4, state->initiator?0:0x80); - netsec_get_sealing_key(state->session_key, seq_num, sealing_key); + netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key); arcfour_crypt(confounder, sealing_key, 8); arcfour_crypt(data, sealing_key, length); - schannel_digest(state->session_key, + schannel_digest(state->creds->session_key, netsec_sig, confounder, data, length, digest_final); @@ -150,10 +151,14 @@ NTSTATUS schannel_unseal_packet(struct schannel_state *state, /* check the signature on a packet */ -NTSTATUS schannel_check_packet(struct schannel_state *state, +NTSTATUS schannel_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { + struct schannel_state *state = gensec_security->private_data; + uint8_t digest_final[16]; uint8_t seq_num[8]; static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; @@ -167,9 +172,9 @@ NTSTATUS schannel_check_packet(struct schannel_state *state, SIVAL(seq_num, 4, state->initiator?0:0x80); dump_data_pw("seq_num:\n", seq_num, 8); - dump_data_pw("sess_key:\n", state->session_key, 16); + dump_data_pw("sess_key:\n", state->creds->session_key, 16); - schannel_digest(state->session_key, + schannel_digest(state->creds->session_key, netsec_sig, NULL, data, length, digest_final); @@ -194,11 +199,14 @@ NTSTATUS schannel_check_packet(struct schannel_state *state, /* seal a packet */ -NTSTATUS schannel_seal_packet(struct schannel_state *state, +NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { + struct schannel_state *state = gensec_security->private_data; + uint8_t digest_final[16]; uint8_t confounder[8]; uint8_t seq_num[8]; @@ -210,11 +218,11 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, RSIVAL(seq_num, 0, state->seq_num); SIVAL(seq_num, 4, state->initiator?0x80:0); - schannel_digest(state->session_key, + schannel_digest(state->creds->session_key, netsec_sig, confounder, data, length, digest_final); - netsec_get_sealing_key(state->session_key, seq_num, sealing_key); + netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key); arcfour_crypt(confounder, sealing_key, 8); arcfour_crypt(data, sealing_key, length); @@ -239,11 +247,14 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state, /* sign a packet */ -NTSTATUS schannel_sign_packet(struct schannel_state *state, +NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { + struct schannel_state *state = gensec_security->private_data; + uint8_t digest_final[16]; uint8_t seq_num[8]; static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; @@ -251,7 +262,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, RSIVAL(seq_num, 0, state->seq_num); SIVAL(seq_num, 4, state->initiator?0x80:0); - schannel_digest(state->session_key, + schannel_digest(state->creds->session_key, netsec_sig, NULL, data, length, digest_final); @@ -271,23 +282,3 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, return NT_STATUS_OK; } - -/* - create an schannel context state -*/ -NTSTATUS schannel_start(TALLOC_CTX *mem_ctx, - struct schannel_state **state, - const uint8_t session_key[16], - BOOL initiator) -{ - (*state) = talloc(mem_ctx, struct schannel_state); - if (!(*state)) { - return NT_STATUS_NO_MEMORY; - } - - memcpy((*state)->session_key, session_key, 16); - (*state)->initiator = initiator; - (*state)->seq_num = 0; - - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 3980767165..f5a091cd78 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -610,7 +610,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego_out.negTokenInit.mechTypes = mechlist; spnego_out.negTokenInit.reqFlags = 0; spnego_out.negTokenInit.mechListMIC - = data_blob_string_const(gensec_get_target_principal(gensec_security)); + = data_blob_string_const(talloc_asprintf(out_mem_ctx, "%s$@%s", lp_netbios_name(), lp_realm())); spnego_out.negTokenInit.mechToken = unwrapped_out; if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { @@ -657,13 +657,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } if (spnego.negTokenInit.targetPrincipal) { - DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal)); - nt_status = gensec_set_target_principal(gensec_security, - spnego.negTokenInit.targetPrincipal); - if (!NT_STATUS_IS_OK(nt_status)) { - spnego_free_data(&spnego); - return nt_status; - } + DEBUG(5, ("Server claims it's principal name is %s (ignored)\n", spnego.negTokenInit.targetPrincipal)); } nt_status = gensec_spnego_client_parse_negTokenInit(gensec_security, diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 7459460137..53a97da168 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -63,7 +63,7 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli) /* wrapper around smb_raw_session_setup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, - struct cli_credentials *credentials) + struct cli_credentials *credentials) { struct smb_composite_sesssetup setup; NTSTATUS status; @@ -77,15 +77,8 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; - if (cli_credentials_is_anonymous(credentials)) { - if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { - setup.in.password = cli_credentials_get_password(credentials); - } else { - setup.in.password = NULL; - } - setup.in.user = cli_credentials_get_username(credentials); - setup.in.domain = cli_credentials_get_domain(credentials); - } + setup.in.credentials = credentials; + setup.in.workgroup = lp_workgroup(); status = smb_composite_sesssetup(cli->session, &setup); @@ -144,7 +137,6 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, */ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_state **ret_cli, - const char *myname, const char *host, const char *sharename, const char *devtype, @@ -159,7 +151,7 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, *ret_cli = NULL; status = smbcli_tree_full_connection(parent_ctx, - &tree, myname, host, 0, sharename, devtype, + &tree, host, 0, sharename, devtype, credentials); if (!NT_STATUS_IS_OK(status)) { goto done; diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index bf0fb9ed48..18922127ee 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -70,12 +70,10 @@ struct smb_composite_fetchfile { const char *dest_host; int port; const char *called_name; - const char *calling_name; const char *service; const char *service_type; - const char *user; - const char *domain; - const char *password; + struct cli_credentials *credentials; + const char *workgroup; const char *filename; } in; struct { @@ -111,12 +109,10 @@ struct smb_composite_connect { const char *dest_host; int port; const char *called_name; - const char *calling_name; const char *service; const char *service_type; - const char *user; - const char *domain; - const char *password; + struct cli_credentials *credentials; + const char *workgroup; } in; struct { struct smbcli_tree *tree; @@ -132,9 +128,8 @@ struct smb_composite_sesssetup { struct { uint32_t sesskey; uint32_t capabilities; - const char *password; - const char *user; - const char *domain; + struct cli_credentials *credentials; + const char *workgroup; } in; struct { uint16_t vuid; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 5f5275f7e6..0da71df992 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -166,9 +166,8 @@ static NTSTATUS connect_negprot(struct composite_context *c, /* prepare a session setup to establish a security context */ state->io_setup->in.sesskey = state->transport->negotiate.sesskey; state->io_setup->in.capabilities = state->transport->negotiate.capabilities; - state->io_setup->in.domain = io->in.domain; - state->io_setup->in.user = io->in.user; - state->io_setup->in.password = io->in.password; + state->io_setup->in.credentials = io->in.credentials; + state->io_setup->in.workgroup = io->in.workgroup; state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); NT_STATUS_HAVE_NO_MEMORY(state->creq); @@ -214,7 +213,7 @@ static NTSTATUS connect_socket(struct composite_context *c, state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); - calling.name = io->in.calling_name; + calling.name = cli_credentials_get_workstation(io->in.credentials); calling.type = NBT_NAME_CLIENT; calling.scope = NULL; @@ -254,7 +253,7 @@ static NTSTATUS connect_resolve(struct composite_context *c, status = resolve_name_recv(state->creq, state, &address); NT_STATUS_NOT_OK_RETURN(status); - state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port); + state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port, io->in.dest_host); NT_STATUS_HAVE_NO_MEMORY(state->creq); state->stage = CONNECT_SOCKET; diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index 2bf6ef9023..fb9226985e 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -140,12 +140,10 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.dest_host = io->in.dest_host; state->connect->in.port = io->in.port; state->connect->in.called_name = io->in.called_name; - state->connect->in.calling_name = io->in.calling_name; state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; - state->connect->in.user = io->in.user; - state->connect->in.domain = io->in.domain; - state->connect->in.password = io->in.password; + state->connect->in.credentials = io->in.credentials; + state->connect->in.workgroup = io->in.workgroup; state->req = smb_composite_connect_send(state->connect, event_ctx); if (state->req == NULL) goto failed; diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 07c718b05b..31ca5caed7 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -142,7 +142,7 @@ static void request_handler(struct smbcli_request *req) } /* enforce the local signing required flag */ - if (NT_STATUS_IS_OK(c->status) && state->io->in.user && state->io->in.user[0]) { + if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) { if (!session->transport->negotiate.sign_info.doing_signing && session->transport->negotiate.sign_info.mandatory_signing) { DEBUG(0, ("SMB signing required, but server does not support it\n")); @@ -169,6 +169,7 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, struct smb_composite_sesssetup *io) { struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); + const char *password = cli_credentials_get_password(io->in.credentials); state->setup.nt1.level = RAW_SESSSETUP_NT1; state->setup.nt1.in.bufsize = session->transport->options.max_xmit; @@ -176,23 +177,23 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, state->setup.nt1.in.vc_num = 1; state->setup.nt1.in.sesskey = io->in.sesskey; state->setup.nt1.in.capabilities = io->in.capabilities; - state->setup.nt1.in.domain = io->in.domain; - state->setup.nt1.in.user = io->in.user; state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = "Samba"; - if (!io->in.password) { + state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); + state->setup.old.in.user = cli_credentials_get_username(io->in.credentials); + if (!password) { state->setup.nt1.in.password1 = data_blob(NULL, 0); state->setup.nt1.in.password2 = data_blob(NULL, 0); } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - state->setup.nt1.in.password1 = lanman_blob(state, io->in.password, + state->setup.nt1.in.password1 = lanman_blob(state, password, session->transport->negotiate.secblob); - state->setup.nt1.in.password2 = nt_blob(state, io->in.password, + state->setup.nt1.in.password2 = nt_blob(state, password, session->transport->negotiate.secblob); - use_nt1_session_keys(session, io->in.password, &state->setup.nt1.in.password2); + use_nt1_session_keys(session, password, &state->setup.nt1.in.password2); } else { - state->setup.nt1.in.password1 = data_blob_talloc(state, io->in.password, strlen(io->in.password)); + state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); } @@ -208,26 +209,27 @@ static struct smbcli_request *session_setup_old(struct composite_context *c, struct smb_composite_sesssetup *io) { struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); + const char *password = cli_credentials_get_password(io->in.credentials); state->setup.old.level = RAW_SESSSETUP_OLD; state->setup.old.in.bufsize = session->transport->options.max_xmit; state->setup.old.in.mpx_max = session->transport->options.max_mux; state->setup.old.in.vc_num = 1; state->setup.old.in.sesskey = io->in.sesskey; - state->setup.old.in.domain = io->in.domain; - state->setup.old.in.user = io->in.user; + state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); + state->setup.old.in.user = cli_credentials_get_username(io->in.credentials); state->setup.old.in.os = "Unix"; state->setup.old.in.lanman = "Samba"; - if (!io->in.password) { + if (!password) { state->setup.old.in.password = data_blob(NULL, 0); } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - state->setup.old.in.password = lanman_blob(state, io->in.password, + state->setup.old.in.password = lanman_blob(state, password, session->transport->negotiate.secblob); } else { state->setup.old.in.password = data_blob_talloc(state, - io->in.password, - strlen(io->in.password)); + password, + strlen(password)); } return smb_raw_session_setup_send(session, &state->setup); @@ -253,9 +255,10 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, state->setup.spnego.in.vc_num = 1; state->setup.spnego.in.sesskey = io->in.sesskey; state->setup.spnego.in.capabilities = io->in.capabilities; - state->setup.spnego.in.domain = io->in.domain; state->setup.spnego.in.os = "Unix"; state->setup.spnego.in.lanman = "Samba"; + state->setup.spnego.in.workgroup = io->in.workgroup; + state->setup.spnego.out.vuid = session->vuid; smbcli_temp_set_signing(session->transport); @@ -268,30 +271,23 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); - status = gensec_set_domain(session->gensec, io->in.domain); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", - io->in.domain, nt_errstr(status))); - return NULL; - } - - status = gensec_set_username(session->gensec, io->in.user); + status = gensec_set_credentials(session->gensec, io->in.credentials); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", - io->in.user, nt_errstr(status))); + DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", + nt_errstr(status))); return NULL; } - status = gensec_set_password(session->gensec, io->in.password); + status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", nt_errstr(status))); return NULL; } - status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); + status = gensec_set_target_service(session->gensec, "cifs"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", nt_errstr(status))); return NULL; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 3e51e4f60f..710c022a3c 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -337,11 +337,11 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, struct ldap_message *ldap_transaction(struct ldap_connection *conn, struct ldap_message *request); int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password); -int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password); +int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds); struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, const char *userdn, const char *password); struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, - const char *username, const char *domain, const char *password); + struct cli_credentials *creds); BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, const struct timeval *endtime); BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index e3904c7a6b..71b57e116e 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -605,7 +605,7 @@ int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const cha return result; } -int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) +int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) { NTSTATUS status; TALLOC_CTX *mem_ctx = NULL; @@ -626,23 +626,9 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); - status = gensec_set_domain(conn->gensec, domain); + status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", - domain, nt_errstr(status))); - goto done; - } - - status = gensec_set_username(conn->gensec, username); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", - username, nt_errstr(status))); - goto done; - } - - status = gensec_set_password(conn->gensec, password); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + DEBUG(1, ("Failed to start set GENSEC creds: %s\n", nt_errstr(status))); goto done; } @@ -739,8 +725,9 @@ struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *u return conn; } -struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, - const char *username, const char *domain, const char *password) +struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, + const char *url, + struct cli_credentials *creds) { struct ldap_connection *conn; int result; @@ -750,7 +737,7 @@ struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, con return NULL; } - result = ldap_bind_sasl(conn, username, domain, password); + result = ldap_bind_sasl(conn, creds); if (result != LDAP_SUCCESS) { talloc_free(conn); return NULL; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 5f75701871..3156624589 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -134,7 +134,7 @@ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session smbcli_req_append_blob(req, &parms->spnego.in.secblob); smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE); smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); - smbcli_req_append_string(req, parms->spnego.in.domain, STR_TERMINATE); + smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE); break; } @@ -210,7 +210,7 @@ NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req, p += parms->spnego.out.secblob.length; p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE); p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.domain, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE); break; } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index cbb479ca1a..7cb7040131 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -34,7 +34,8 @@ struct clisocket_connect { int port_num; int *iports; struct smbcli_socket *sock; - const char *dest_host; + const char *dest_host_addr; + const char *dest_hostname; }; @@ -83,7 +84,7 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even c->status = socket_connect_complete(conn->sock->sock, 0); if (NT_STATUS_IS_OK(c->status)) { socket_set_option(conn->sock->sock, lp_socket_options(), NULL); - conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_host); + conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_hostname); c->state = SMBCLI_REQUEST_DONE; if (c->async.fn) { c->async.fn(c); @@ -95,7 +96,7 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even for (i=conn->port_num+1;conn->iports[i];i++) { conn->port_num = i; c->status = smbcli_sock_connect_one(conn->sock, - conn->dest_host, + conn->dest_host_addr, conn->iports[i], c); if (NT_STATUS_IS_OK(c->status) || NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -151,7 +152,8 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, this is the async send side of the interface */ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, - const char *host_addr, int port) + const char *host_addr, int port, + const char *host_name) { struct composite_context *c; struct clisocket_connect *conn; @@ -184,8 +186,11 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, conn->iports[1] = 0; } - conn->dest_host = talloc_strdup(c, host_addr); - if (conn->dest_host == NULL) goto failed; + conn->dest_host_addr = talloc_strdup(c, host_addr); + if (conn->dest_host_addr == NULL) goto failed; + + conn->dest_hostname = talloc_strdup(c, host_name); + if (conn->dest_hostname == NULL) goto failed; c->private = conn; c->state = SMBCLI_REQUEST_SEND; @@ -196,7 +201,7 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, conn->port_num = i; conn->sock->port = conn->iports[i]; c->status = smbcli_sock_connect_one(sock, - conn->dest_host, + conn->dest_host_addr, conn->iports[i], c); if (NT_STATUS_IS_OK(c->status) || NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -229,11 +234,12 @@ NTSTATUS smbcli_sock_connect_recv(struct composite_context *c) sync version of the function */ -NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port) +NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port, + const char *host_name) { struct composite_context *c; - c = smbcli_sock_connect_send(sock, host_addr, port); + c = smbcli_sock_connect_send(sock, host_addr, port, host_name); if (c == NULL) { return NT_STATUS_NO_MEMORY; } @@ -337,9 +343,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in return False; } - sock->hostname = name; - - status = smbcli_sock_connect(sock, address, port); + status = smbcli_sock_connect(sock, address, port, name); return NT_STATUS_IS_OK(status); } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index f333cf7a98..87c2dbba7c 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -164,7 +164,6 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) */ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_tree **ret_tree, - const char *my_name, const char *dest_host, int port, const char *service, const char *service_type, struct cli_credentials *credentials) @@ -175,12 +174,10 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.dest_host = dest_host; io.in.port = port; io.in.called_name = strupper_talloc(parent_ctx, dest_host); - io.in.calling_name = strupper_talloc(parent_ctx, my_name); io.in.service = service; io.in.service_type = service_type; - io.in.domain = cli_credentials_get_domain(credentials); - io.in.user = cli_credentials_get_username(credentials); - io.in.password = cli_credentials_get_password(credentials); + io.in.credentials = credentials; + io.in.workgroup = lp_workgroup(); status = smb_composite_connect(&io, parent_ctx); if (NT_STATUS_IS_OK(status)) { -- cgit From 73b77ee15159207870d7c18cd12c02daf4fd2bc0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 04:45:41 +0000 Subject: r6030: Missing from previous commit, a small header file to link libcli/auth/schannel.c and libcli/auth/schannel_sign.c Andrew Bartlett (This used to be commit 1e0e66d7202d3f0e7fb3c90f2ca608fa08a713a6) --- source4/libcli/auth/schannel.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 source4/libcli/auth/schannel.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/schannel.h b/source4/libcli/auth/schannel.h new file mode 100644 index 0000000000..c109387c7c --- /dev/null +++ b/source4/libcli/auth/schannel.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + dcerpc schannel operations + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Andrew Bartlett 2004-2005 + + 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. +*/ + +enum schannel_position { + SCHANNEL_STATE_START = 0, + SCHANNEL_STATE_UPDATE_1 +}; + +struct schannel_state { + enum schannel_position state; + uint32_t seq_num; + BOOL initiator; + struct creds_CredentialState *creds; +}; + -- cgit From 0c936acc47062f2c3589bd2916c10037c49e0db9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 26 Mar 2005 10:22:02 +0000 Subject: r6074: fixed non-spnego connections for new credentials code (This used to be commit ff6663aac8ed475bf65d9c06d7f2447a9827898c) --- source4/libcli/composite/sesssetup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 31ca5caed7..a33ace2420 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -179,6 +179,10 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, state->setup.nt1.in.capabilities = io->in.capabilities; state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = "Samba"; + state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials); + if (state->setup.nt1.in.user == NULL) return NULL; + state->setup.nt1.in.domain = cli_credentials_get_domain(io->in.credentials); + if (state->setup.nt1.in.domain == NULL) return NULL; state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); state->setup.old.in.user = cli_credentials_get_username(io->in.credentials); @@ -330,7 +334,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, the spnego varient */ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session, - struct smb_composite_sesssetup *io) + struct smb_composite_sesssetup *io) { struct composite_context *c; struct sesssetup_state *state; -- cgit From 68d7a5e38346393a66e1d97da0348f474dd2ae4c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Mar 2005 06:26:00 +0000 Subject: r6078: Correctly fix the failures for NT1 (not SPNEGO) session setups in the client. The issue was actually a cut-and-paste bug, I was filling in the .old not the .nt1 part of the union. I've also removed the 'error checks' - I'll shortly document the API for the credentials code to clarify that it will always return a pointer here, except in cases of programmer error. Tridge: I hope this is OK. Andrew Bartlett (This used to be commit 6439de9ec8c8d24197ea69dc337473e54c8b36b8) --- source4/libcli/composite/sesssetup.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index a33ace2420..ab46c198ef 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -180,12 +180,8 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = "Samba"; state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials); - if (state->setup.nt1.in.user == NULL) return NULL; state->setup.nt1.in.domain = cli_credentials_get_domain(io->in.credentials); - if (state->setup.nt1.in.domain == NULL) return NULL; - state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); - state->setup.old.in.user = cli_credentials_get_username(io->in.credentials); if (!password) { state->setup.nt1.in.password1 = data_blob(NULL, 0); state->setup.nt1.in.password2 = data_blob(NULL, 0); -- cgit From e6aeeb5269a4953e48dd023e03aeba0cf47f6698 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Mar 2005 06:40:18 +0000 Subject: r6094: Work on the Kerberos code recently merged from Samba 3.0. This fixes up issues I introduced during the merge, that caused a segfault. I've still not got the keytab code to work for me (using Samba3 to generate the keytab) so this is still not fully tested, but it's better than it was. To add debugging, I now use the krb5_get_error_message() function from Heimdal when present, to return the custom error string, which contains far, far more information than the simple error code does. (This last point may well be worth merging back into 3.0) Andrew Bartlett (This used to be commit ed5755d9d1e48df7ae77a9410d30e10cb8b0cbd7) --- source4/libcli/auth/clikrb5.c | 14 +++++++ source4/libcli/auth/kerberos.h | 1 + source4/libcli/auth/kerberos_verify.c | 69 +++++++++++++++++++---------------- 3 files changed, 53 insertions(+), 31 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 5a196db7a5..b7bd710304 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -461,4 +461,18 @@ cleanup_princ: #endif } + char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx) +{ + char *ret; + +#if defined(HAVE_KRB5_GET_ERROR_STRING) && defined(HAVE_KRB5_FREE_ERROR_STRING) + char *context_error = krb5_get_error_string(context); + ret = talloc_asprintf(mem_ctx, "%s: %s", error_message(code), context_error); + krb5_free_error_string(context, context_error); +#else + ret = talloc_strdup(mem_ctx, error_message(code)); +#endif + return ret; +} + #endif diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h index c9b2eae55c..4daf0ea07a 100644 --- a/source4/libcli/auth/kerberos.h +++ b/source4/libcli/auth/kerberos.h @@ -94,5 +94,6 @@ void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype); BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2); void kerberos_free_data_contents(krb5_context context, krb5_data *pdata); krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry); +char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx); #endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c index fd4c3f6ba3..a1dfe1056e 100644 --- a/source4/libcli/auth/kerberos_verify.c +++ b/source4/libcli/auth/kerberos_verify.c @@ -80,7 +80,6 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex krb5_keyblock *keyblock) { krb5_error_code ret = 0; - krb5_error_code our_ret = 0; krb5_keytab keytab = NULL; krb5_kt_cursor kt_cursor; krb5_keytab_entry kt_entry; @@ -89,6 +88,7 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex const char *my_name, *my_fqdn; int i; int number_matched_principals = 0; + const char *last_error_message; /* Generate the list of principal names which we expect * clients might want to use for authenticating to the file @@ -111,7 +111,8 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex ret = krb5_kt_default(context, &keytab); if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret))); + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", + smb_get_krb5_error_message(context, ret, mem_ctx))); goto out; } @@ -121,37 +122,43 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); + last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", + last_error_message)); goto out; } ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { + ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; /* Pick an error... */ while (ret && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { - ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + krb5_error_code upn_ret; + upn_ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); + if (upn_ret) { + last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); + DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", + last_error_message)); + ret = upn_ret; break; } - ret = KRB5_BAD_ENCTYPE; - for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { - if (strequal(entry_princ_s, valid_princ_formats[i])) { - number_matched_principals++; - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - *pp_tkt = NULL; - our_ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); - if (our_ret != KRB5_BAD_ENCTYPE) { - ret = our_ret; - } - if (our_ret) { - DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", - entry_princ_s, error_message(our_ret))); - } else { - DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", - entry_princ_s)); - break; - } + for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) { + if (!strequal(entry_princ_s, valid_princ_formats[i])) { + continue; + } + + number_matched_principals++; + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + *pp_tkt = NULL; + ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); + if (ret) { + last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); + DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", + entry_princ_s, last_error_message)); + } else { + DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", + entry_princ_s)); + break; } } @@ -177,7 +184,7 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n", number_matched_principals)); } - DEBUG(3, ("ads_keytab_verify_ticket: last error: %s\n", error_message(ret))); + DEBUG(3, ("ads_keytab_verify_ticket: last error: %s\n", last_error_message)); } if (entry_princ_s) { @@ -304,7 +311,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte DEBUG((our_ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", - (unsigned int)enctypes[i], error_message(our_ret))); + (unsigned int)enctypes[i], smb_get_krb5_error_message(context, our_ret, mem_ctx))); if (our_ret != KRB5_BAD_ENCTYPE) { ret = our_ret; @@ -355,7 +362,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", - host_princ_s, error_message(ret))); + host_princ_s, error_message(ret))); goto out; } @@ -400,14 +407,14 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte if (ret) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", - error_message(ret))); + smb_get_krb5_error_message(context, ret, mem_ctx))); goto out; } ret = krb5_mk_rep(context, auth_context, &packet); if (ret) { DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", - error_message(ret))); + smb_get_krb5_error_message(context, ret, mem_ctx))); goto out; } @@ -434,7 +441,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), &malloc_principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", - error_message(ret))); + smb_get_krb5_error_message(context, ret, mem_ctx))); sret = NT_STATUS_LOGON_FAILURE; goto out; } -- cgit From 7cabdeb7ec84c7c0b3e9b907e19f4e240b7fc4ca Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 Mar 2005 08:24:03 +0000 Subject: r6113: Move GENSEC and the kerberos code out of libcli/auth, and into auth/gensec and auth/kerberos. This also pulls the kerberos configure code out of libads (which is otherwise dead), and into auth/kerberos/kerberos.m4 Andrew Bartlett (This used to be commit e074d63f3dcf4f84239a10879112ebaf1cfa6c4f) --- source4/libcli/auth/clikrb5.c | 478 ------------ source4/libcli/auth/gensec.c | 630 ---------------- source4/libcli/auth/gensec.h | 117 --- source4/libcli/auth/gensec.m4 | 12 - source4/libcli/auth/gensec.mk | 91 --- source4/libcli/auth/gensec_gssapi.c | 376 ---------- source4/libcli/auth/gensec_gsskrb5.c | 584 --------------- source4/libcli/auth/gensec_krb5.c | 751 ------------------- source4/libcli/auth/gensec_ntlmssp.c | 514 ------------- source4/libcli/auth/gssapi_parse.c | 95 --- source4/libcli/auth/kerberos.c | 788 -------------------- source4/libcli/auth/kerberos.h | 99 --- source4/libcli/auth/kerberos_verify.c | 486 ------------ source4/libcli/auth/ntlmssp.c | 1322 --------------------------------- source4/libcli/auth/ntlmssp.h | 190 ----- source4/libcli/auth/ntlmssp_parse.c | 338 --------- source4/libcli/auth/ntlmssp_sign.c | 449 ----------- source4/libcli/auth/schannel.c | 268 ------- source4/libcli/auth/schannel.h | 35 - source4/libcli/auth/schannel_sign.c | 284 ------- source4/libcli/auth/schannel_state.c | 229 ------ source4/libcli/auth/spnego.c | 884 ---------------------- source4/libcli/auth/spnego.h | 69 -- source4/libcli/auth/spnego_parse.c | 375 ---------- 24 files changed, 9464 deletions(-) delete mode 100644 source4/libcli/auth/clikrb5.c delete mode 100644 source4/libcli/auth/gensec.c delete mode 100644 source4/libcli/auth/gensec.h delete mode 100644 source4/libcli/auth/gensec.m4 delete mode 100644 source4/libcli/auth/gensec.mk delete mode 100644 source4/libcli/auth/gensec_gssapi.c delete mode 100644 source4/libcli/auth/gensec_gsskrb5.c delete mode 100644 source4/libcli/auth/gensec_krb5.c delete mode 100644 source4/libcli/auth/gensec_ntlmssp.c delete mode 100644 source4/libcli/auth/gssapi_parse.c delete mode 100644 source4/libcli/auth/kerberos.c delete mode 100644 source4/libcli/auth/kerberos.h delete mode 100644 source4/libcli/auth/kerberos_verify.c delete mode 100644 source4/libcli/auth/ntlmssp.c delete mode 100644 source4/libcli/auth/ntlmssp.h delete mode 100644 source4/libcli/auth/ntlmssp_parse.c delete mode 100644 source4/libcli/auth/ntlmssp_sign.c delete mode 100644 source4/libcli/auth/schannel.c delete mode 100644 source4/libcli/auth/schannel.h delete mode 100644 source4/libcli/auth/schannel_sign.c delete mode 100644 source4/libcli/auth/schannel_state.c delete mode 100644 source4/libcli/auth/spnego.c delete mode 100644 source4/libcli/auth/spnego.h delete mode 100644 source4/libcli/auth/spnego_parse.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c deleted file mode 100644 index b7bd710304..0000000000 --- a/source4/libcli/auth/clikrb5.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5 routines for active directory - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002-2003 - - 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 "system/network.h" -#include "system/kerberos.h" -#include "system/time.h" -#include "libcli/auth/kerberos.h" - -#ifdef HAVE_KRB5 - -#ifndef HAVE_KRB5_SET_REAL_TIME -/* - * This function is not in the Heimdal mainline. - */ - krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) -{ - krb5_error_code ret; - int32_t sec, usec; - - ret = krb5_us_timeofday(context, &sec, &usec); - if (ret) - return ret; - - context->kdc_sec_offset = seconds - sec; - context->kdc_usec_offset = microseconds - usec; - - return 0; -} -#endif - -#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) - krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) -{ - return krb5_set_default_in_tkt_etypes(ctx, enc); -} -#endif - -#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) -/* HEIMDAL */ - void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) -{ - pkaddr->addr_type = KRB5_ADDRESS_INET; - pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); -} -#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) -/* MIT */ - void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) -{ - pkaddr->addrtype = ADDRTYPE_INET; - pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); -} -#else -#error UNKNOWN_ADDRTYPE -#endif - -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) && defined(HAVE_KRB5_ENCRYPT_BLOCK) - int create_kerberos_key_from_string_direct(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) -{ - int ret; - krb5_data salt; - krb5_encrypt_block eblock; - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return ret; - } - krb5_use_enctype(context, &eblock, enctype); - ret = krb5_string_to_key(context, &eblock, key, password, &salt); - SAFE_FREE(salt.data); - return ret; -} -#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string_direct(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) -{ - int ret; - krb5_salt salt; - - ret = krb5_get_pw_salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); - return ret; - } - return krb5_string_to_key_salt(context, enctype, password->data, - salt, key); -} -#else -#error UNKNOWN_CREATE_KEY_FUNCTIONS -#endif - - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) -{ - krb5_principal salt_princ = NULL; - int ret; - /* - * Check if we've determined that the KDC is salting keys for this - * principal/enctype in a non-obvious way. If it is, try to match - * its behavior. - */ - salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype); - ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype); - if (salt_princ) { - krb5_free_principal(context, salt_princ); - } - return ret; -} - -#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) - krb5_error_code get_kerberos_allowed_etypes(krb5_context context, - krb5_enctype **enctypes) -{ - return krb5_get_permitted_enctypes(context, enctypes); -} -#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) - krb5_error_code get_kerberos_allowed_etypes(krb5_context context, - krb5_enctype **enctypes) -{ - return krb5_get_default_in_tkt_etypes(context, enctypes); -} -#else -#error UNKNOWN_GET_ENCTYPES_FUNCTIONS -#endif - - void free_kerberos_etypes(krb5_context context, - krb5_enctype *enctypes) -{ -#if defined(HAVE_KRB5_FREE_KTYPES) - krb5_free_ktypes(context, enctypes); - return; -#else - SAFE_FREE(enctypes); - return; -#endif -} - -#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) - krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, - krb5_auth_context auth_context, - krb5_keyblock *keyblock) -{ - return krb5_auth_con_setkey(context, auth_context, keyblock); -} -#endif - - DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, - krb5_ticket *tkt) -{ - DATA_BLOB auth_data = data_blob(NULL, 0); -#if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt && tkt->enc_part2 - && tkt->enc_part2->authorization_data - && tkt->enc_part2->authorization_data[0] - && tkt->enc_part2->authorization_data[0]->length) - auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); -#else - if (tkt && tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) - auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, - tkt->ticket.authorization_data->val->ad_data.length); -#endif - return auth_data; -} - - krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) -{ -#if defined(HAVE_KRB5_TKT_ENC_PART2) - return tkt->enc_part2->client; -#else - return tkt->client; -#endif -} - -#if !defined(HAVE_KRB5_LOCATE_KDC) - krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) -{ - krb5_krbhst_handle hnd; - krb5_krbhst_info *hinfo; - krb5_error_code rc; - int num_kdcs, i; - struct sockaddr *sa; - struct addrinfo *ai; - - *addr_pp = NULL; - *naddrs = 0; - - rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); - if (rc) { - DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); - return rc; - } - - for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) - ; - - krb5_krbhst_reset(ctx, hnd); - - if (!num_kdcs) { - DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); - krb5_krbhst_free(ctx, hnd); - return -1; - } - - sa = malloc_array_p(struct sockaddr, num_kdcs); - if (!sa) { - DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); - krb5_krbhst_free(ctx, hnd); - naddrs = 0; - return -1; - } - - memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs ); - - for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { - -#if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO) - rc = krb5_krbhst_get_addrinfo(ctx, hinfo, &ai); - if (rc) { - DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc))); - continue; - } -#endif - if (hinfo->ai && hinfo->ai->ai_family == AF_INET) - memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); - } - - krb5_krbhst_free(ctx, hnd); - - *naddrs = num_kdcs; - *addr_pp = sa; - return 0; -} -#endif - -#if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) - void krb5_free_unparsed_name(krb5_context context, char *val) -{ - SAFE_FREE(val); -} -#endif - - void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) -{ -#if defined(HAVE_KRB5_FREE_DATA_CONTENTS) - if (pdata->data) { - krb5_free_data_contents(context, pdata); - } -#else - SAFE_FREE(pdata->data); -#endif -} - - void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) -{ -#if defined(HAVE_KRB5_KEYBLOCK_IN_CREDS) - KRB5_KEY_TYPE((&pcreds->keyblock)) = enctype; -#elif defined(HAVE_KRB5_SESSION_IN_CREDS) - KRB5_KEY_TYPE((&pcreds->session)) = enctype; -#else -#error UNKNOWN_KEYBLOCK_MEMBER_IN_KRB5_CREDS_STRUCT -#endif -} - - BOOL kerberos_compatible_enctypes(krb5_context context, - krb5_enctype enctype1, - krb5_enctype enctype2) -{ -#if defined(HAVE_KRB5_C_ENCTYPE_COMPARE) - krb5_boolean similar = 0; - - krb5_c_enctype_compare(context, enctype1, enctype2, &similar); - return similar ? True : False; -#elif defined(HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS) - return krb5_enctypes_compatible_keys(context, enctype1, enctype2) ? True : False; -#endif -} - -static BOOL ads_cleanup_expired_creds(krb5_context context, - krb5_ccache ccache, - krb5_creds *credsp) -{ - krb5_error_code retval; - TALLOC_CTX *mem_ctx = talloc_init("ticket expied time"); - if (!mem_ctx) { - return False; - } - - DEBUG(3, ("Ticket in ccache[%s] expiration %s\n", - krb5_cc_default_name(context), - http_timestring(mem_ctx, credsp->times.endtime))); - - talloc_free(mem_ctx); - - /* we will probably need new tickets if the current ones - will expire within 10 seconds. - */ - if (credsp->times.endtime >= (time(NULL) + 10)) - return False; - - /* heimdal won't remove creds from a file ccache, and - perhaps we shouldn't anyway, since internally we - use memory ccaches, and a FILE one probably means that - we're using creds obtained outside of our exectuable - */ - if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { - DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a FILE ccache\n")); - return False; - } - - retval = krb5_cc_remove_cred(context, ccache, 0, credsp); - if (retval) { - DEBUG(1, ("ads_cleanup_expired_creds: krb5_cc_remove_cred failed, err %s\n", - error_message(retval))); - /* If we have an error in this, we want to display it, - but continue as though we deleted it */ - } - return True; -} - -/* - we can't use krb5_mk_req because w2k wants the service to be in a particular format -*/ -krb5_error_code ads_krb5_mk_req(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf) -{ - krb5_error_code retval; - krb5_principal server; - krb5_creds * credsp; - krb5_creds creds; - krb5_data in_data; - BOOL creds_ready = False; - - TALLOC_CTX *mem_ctx = NULL; - - retval = krb5_parse_name(context, principal, &server); - if (retval) { - DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); - return retval; - } - - /* obtain ticket & session key */ - ZERO_STRUCT(creds); - if ((retval = krb5_copy_principal(context, server, &creds.server))) { - DEBUG(1,("krb5_copy_principal failed (%s)\n", - error_message(retval))); - goto cleanup_princ; - } - - if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { - /* This can commonly fail on smbd startup with no ticket in the cache. - * Report at higher level than 1. */ - DEBUG(3,("ads_krb5_mk_req: krb5_cc_get_principal failed (%s)\n", - error_message(retval))); - goto cleanup_creds; - } - - while(!creds_ready) { - if ((retval = krb5_get_credentials(context, 0, ccache, - &creds, &credsp))) { - DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", - principal, error_message(retval))); - goto cleanup_creds; - } - - /* cope with ticket being in the future due to clock skew */ - if ((unsigned)credsp->times.starttime > time(NULL)) { - time_t t = time(NULL); - int time_offset =(unsigned)credsp->times.starttime-t; - DEBUG(4,("ads_krb5_mk_req: Advancing clock by %d seconds to cope with clock skew\n", time_offset)); - krb5_set_real_time(context, t + time_offset + 1, 0); - } - - if (!ads_cleanup_expired_creds(context, ccache, credsp)) - creds_ready = True; - } - - mem_ctx = talloc_init("ticket expied time"); - if (!mem_ctx) { - retval = ENOMEM; - goto cleanup_creds; - } - DEBUG(10,("Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", - principal, krb5_cc_default_name(context), - http_timestring(mem_ctx, (unsigned)credsp->times.endtime), - (unsigned)credsp->times.endtime)); - - in_data.length = 0; - retval = krb5_mk_req_extended(context, auth_context, ap_req_options, - &in_data, credsp, outbuf); - if (retval) { - DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", - error_message(retval))); - } - - krb5_free_creds(context, credsp); - -cleanup_creds: - krb5_free_cred_contents(context, &creds); - -cleanup_princ: - krb5_free_principal(context, server); - - return retval; -} - -#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) - const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) -{ - static krb5_data kdata; - - kdata.data = discard_const(krb5_principal_get_comp_string(context, principal, i)); - kdata.length = strlen(kdata.data); - return &kdata; -} -#endif - - krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) -{ -#if defined(HAVE_KRB5_KT_FREE_ENTRY) - return krb5_kt_free_entry(context, kt_entry); -#elif defined(HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS) - return krb5_free_keytab_entry_contents(context, kt_entry); -#else -#error UNKNOWN_KT_FREE_FUNCTION -#endif -} - - char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx) -{ - char *ret; - -#if defined(HAVE_KRB5_GET_ERROR_STRING) && defined(HAVE_KRB5_FREE_ERROR_STRING) - char *context_error = krb5_get_error_string(context); - ret = talloc_asprintf(mem_ctx, "%s: %s", error_message(code), context_error); - krb5_free_error_string(context, context_error); -#else - ret = talloc_strdup(mem_ctx, error_message(code)); -#endif - return ret; -} - -#endif diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c deleted file mode 100644 index cc7327187c..0000000000 --- a/source4/libcli/auth/gensec.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Generic Authentication Interface - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Andrew Bartlett 2004-2005 - - 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 "auth/auth.h" - -/* the list of currently registered GENSEC backends */ -const static struct gensec_security_ops **generic_security_ops; -static int gensec_num_backends; - -static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) -{ - int i; - for (i=0; i < gensec_num_backends; i++) { - if (generic_security_ops[i]->auth_type == auth_type) { - return generic_security_ops[i]; - } - } - - return NULL; -} - -static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_string) -{ - int i; - for (i=0; i < gensec_num_backends; i++) { - if (generic_security_ops[i]->oid && - (strcmp(generic_security_ops[i]->oid, oid_string) == 0)) { - return generic_security_ops[i]; - } - } - - return NULL; -} - -static const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) -{ - int i; - for (i=0; i < gensec_num_backends; i++) { - if (generic_security_ops[i]->sasl_name - && (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) { - return generic_security_ops[i]; - } - } - - return NULL; -} - -static const struct gensec_security_ops *gensec_security_by_name(const char *name) -{ - int i; - for (i=0; i < gensec_num_backends; i++) { - if (generic_security_ops[i]->name - && (strcmp(generic_security_ops[i]->name, name) == 0)) { - return generic_security_ops[i]; - } - } - - return NULL; -} - -const struct gensec_security_ops **gensec_security_all(int *num_backends_out) -{ - *num_backends_out = gensec_num_backends; - return generic_security_ops; -} - -const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip) -{ - int i, j = 0; - const char **oid_list; - int num_backends; - const struct gensec_security_ops **ops = gensec_security_all(&num_backends); - if (!ops) { - return NULL; - } - oid_list = talloc_array(mem_ctx, const char *, num_backends + 1); - if (!oid_list) { - return NULL; - } - - for (i=0; ioid) { - continue; - } - - if (skip && strcmp(skip, ops[i]->oid)==0) { - continue; - } - - oid_list[j] = ops[i]->oid; - j++; - } - oid_list[j] = NULL; - return oid_list; -} - -/** - Start the GENSEC system, returning a context pointer. - @param mem_ctx The parent TALLOC memory context. - @param gensec_security Returned GENSEC context pointer. - @note The mem_ctx is only a parent and may be NULL. -*/ -static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) -{ - (*gensec_security) = talloc(mem_ctx, struct gensec_security); - if (!(*gensec_security)) { - return NT_STATUS_NO_MEMORY; - } - - (*gensec_security)->ops = NULL; - - ZERO_STRUCT((*gensec_security)->target); - - (*gensec_security)->subcontext = False; - (*gensec_security)->want_features = 0; - return NT_STATUS_OK; -} - -/** - * Start a GENSEC subcontext, with a copy of the properties of the parent - * @param mem_ctx The parent TALLOC memory context. - * @param parent The parent GENSEC context - * @param gensec_security Returned GENSEC context pointer. - * @note Used by SPNEGO in particular, for the actual implementation mechanism - */ - -NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, - struct gensec_security *parent, - struct gensec_security **gensec_security) -{ - (*gensec_security) = talloc(mem_ctx, struct gensec_security); - if (!(*gensec_security)) { - return NT_STATUS_NO_MEMORY; - } - - (**gensec_security) = *parent; - (*gensec_security)->ops = NULL; - (*gensec_security)->private_data = NULL; - - (*gensec_security)->subcontext = True; - - return NT_STATUS_OK; -} - -/** - Start the GENSEC system, in client mode, returning a context pointer. - @param mem_ctx The parent TALLOC memory context. - @param gensec_security Returned GENSEC context pointer. - @note The mem_ctx is only a parent and may be NULL. -*/ -NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) -{ - NTSTATUS status; - status = gensec_start(mem_ctx, gensec_security); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - (*gensec_security)->gensec_role = GENSEC_CLIENT; - (*gensec_security)->password_callback = NULL; - - return status; -} - -/** - Start the GENSEC system, in server mode, returning a context pointer. - @param mem_ctx The parent TALLOC memory context. - @param gensec_security Returned GENSEC context pointer. - @note The mem_ctx is only a parent and may be NULL. -*/ -NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security) -{ - NTSTATUS status; - status = gensec_start(mem_ctx, gensec_security); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - (*gensec_security)->gensec_role = GENSEC_SERVER; - - return status; -} - -static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) -{ - NTSTATUS status; - DEBUG(5, ("Starting GENSEC %smechanism %s\n", - gensec_security->subcontext ? "sub" : "", - gensec_security->ops->name)); - switch (gensec_security->gensec_role) { - case GENSEC_CLIENT: - if (gensec_security->ops->client_start) { - status = gensec_security->ops->client_start(gensec_security); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC client mech %s: %s\n", - gensec_security->ops->name, nt_errstr(status))); - } - return status; - } - case GENSEC_SERVER: - if (gensec_security->ops->server_start) { - status = gensec_security->ops->server_start(gensec_security); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n", - gensec_security->ops->name, nt_errstr(status))); - } - return status; - } - } - return NT_STATUS_INVALID_PARAMETER; -} - -/** - * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number - * @param gensec_security GENSEC context pointer. - * @param auth_type DCERPC auth type - * @param auth_level DCERPC auth level - */ - -NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, - uint8_t auth_type, uint8_t auth_level) -{ - gensec_security->ops = gensec_security_by_authtype(auth_type); - if (!gensec_security->ops) { - DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type)); - return NT_STATUS_INVALID_PARAMETER; - } - gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE); - if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { - gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); - } - if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { - gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); - gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL); - } - - return gensec_start_mech(gensec_security); -} - -const char *gensec_get_name_by_authtype(uint8_t authtype) -{ - const struct gensec_security_ops *ops; - ops = gensec_security_by_authtype(authtype); - if (ops) { - return ops->name; - } - return NULL; -} - - -const char *gensec_get_name_by_oid(const char *oid_string) -{ - const struct gensec_security_ops *ops; - ops = gensec_security_by_oid(oid_string); - if (ops) { - return ops->name; - } - return NULL; -} - - -/** - * Start a GENSEC sub-mechanism by OID, used in SPNEGO - * - * @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a - * well-known #define to hook it in. - */ - -NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, - const char *mech_oid) -{ - gensec_security->ops = gensec_security_by_oid(mech_oid); - if (!gensec_security->ops) { - DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); - return NT_STATUS_INVALID_PARAMETER; - } - return gensec_start_mech(gensec_security); -} - -/** - * Start a GENSEC sub-mechanism by a well know SASL name - * - */ - -NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, - const char *sasl_name) -{ - gensec_security->ops = gensec_security_by_sasl_name(sasl_name); - if (!gensec_security->ops) { - DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name)); - return NT_STATUS_INVALID_PARAMETER; - } - return gensec_start_mech(gensec_security); -} - -/* - wrappers for the gensec function pointers -*/ -NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - if (!gensec_security->ops->unseal_packet) { - return NT_STATUS_NOT_IMPLEMENTED; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - return gensec_check_packet(gensec_security, mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); - } - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - if (!gensec_security->ops->check_packet) { - return NT_STATUS_NOT_IMPLEMENTED; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - if (!gensec_security->ops->seal_packet) { - return NT_STATUS_NOT_IMPLEMENTED; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - return gensec_sign_packet(gensec_security, mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); - } - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - if (!gensec_security->ops->sign_packet) { - return NT_STATUS_NOT_IMPLEMENTED; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -size_t gensec_sig_size(struct gensec_security *gensec_security) -{ - if (!gensec_security->ops->sig_size) { - return 0; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - return 0; - } - - return gensec_security->ops->sig_size(gensec_security); -} - -NTSTATUS gensec_wrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - if (!gensec_security->ops->wrap) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return gensec_security->ops->wrap(gensec_security, mem_ctx, in, out); -} - -NTSTATUS gensec_unwrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - if (!gensec_security->ops->unwrap) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return gensec_security->ops->unwrap(gensec_security, mem_ctx, in, out); -} - -NTSTATUS gensec_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) -{ - if (!gensec_security->ops->session_key) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return gensec_security->ops->session_key(gensec_security, session_key); -} - -/** - * Return the credentials of a logged on user, including session keys - * etc. - * - * Only valid after a successful authentication - * - * May only be called once per authentication. - * - */ - -NTSTATUS gensec_session_info(struct gensec_security *gensec_security, - struct auth_session_info **session_info) -{ - if (!gensec_security->ops->session_info) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return gensec_security->ops->session_info(gensec_security, session_info); -} - -/** - * Next state function for the GENSEC state machine - * - * @param gensec_security GENSEC State - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, - * or NT_STATUS_OK if the user is authenticated. - */ - -NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - return gensec_security->ops->update(gensec_security, out_mem_ctx, in, out); -} - -/** - * Set the requirement for a certain feature on the connection - * - */ - -void gensec_want_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - gensec_security->want_features |= feature; -} - -/** - * Check the requirement for a certain feature on the connection - * - */ - -BOOL gensec_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - if (!gensec_security->ops->have_feature) { - return False; - } - return gensec_security->ops->have_feature(gensec_security, feature); -} - -/** - * Associate a credentails structure with a GENSEC context - talloc_reference()s it to the context - * - */ - -NTSTATUS gensec_set_credentials(struct gensec_security *gensec_security, struct cli_credentials *credentials) -{ - gensec_security->credentials = talloc_reference(gensec_security, credentials); - return NT_STATUS_OK; -} - -/** - * Return the credentails structure associated with a GENSEC context - * - */ - -struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security) -{ - return gensec_security->credentials; -} - -/** - * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service) -{ - gensec_security->target.service = talloc_strdup(gensec_security, service); - if (!gensec_security->target.service) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed - * - */ - -NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname) -{ - gensec_security->target.hostname = talloc_strdup(gensec_security, hostname); - if (!gensec_security->target.hostname) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -const char *gensec_get_target_hostname(struct gensec_security *gensec_security) -{ - if (gensec_security->target.hostname) { - return gensec_security->target.hostname; - } - - /* TODO: Add a 'set sockaddr' call, and do a reverse lookup */ - return NULL; -} - -const char *gensec_get_target_service(struct gensec_security *gensec_security) -{ - if (gensec_security->target.service) { - return gensec_security->target.service; - } - - return "host"; -} - -/* - register a GENSEC backend. - - The 'name' can be later used by other backends to find the operations - structure for this backend. -*/ -NTSTATUS gensec_register(const void *_ops) -{ - const struct gensec_security_ops *ops = _ops; - - if (!lp_parm_bool(-1, "gensec", ops->name, ops->enabled)) { - DEBUG(2,("gensec subsystem %s is disabled\n", ops->name)); - return NT_STATUS_OK; - } - - if (gensec_security_by_name(ops->name) != NULL) { - /* its already registered! */ - DEBUG(0,("GENSEC backend '%s' already registered\n", - ops->name)); - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - generic_security_ops = realloc_p(generic_security_ops, - const struct gensec_security_ops *, - gensec_num_backends+1); - if (!generic_security_ops) { - smb_panic("out of memory in gensec_register"); - } - - generic_security_ops[gensec_num_backends] = ops; - - gensec_num_backends++; - - DEBUG(3,("GENSEC backend '%s' registered\n", - ops->name)); - - return NT_STATUS_OK; -} - -/* - return the GENSEC interface version, and the size of some critical types - This can be used by backends to either detect compilation errors, or provide - multiple implementations for different smbd compilation options in one module -*/ -const struct gensec_critical_sizes *gensec_interface_version(void) -{ - static const struct gensec_critical_sizes critical_sizes = { - GENSEC_INTERFACE_VERSION, - sizeof(struct gensec_security_ops), - sizeof(struct gensec_security), - }; - - return &critical_sizes; -} - -/* - initialise the GENSEC subsystem -*/ -NTSTATUS gensec_init(void) -{ - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h deleted file mode 100644 index 91c817d48a..0000000000 --- a/source4/libcli/auth/gensec.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Generic Authentication Interface - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Andrew Bartlett 2004-2005 - - 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 GENSEC_OID_NTLMSSP "1 3 6 1 4 1 311 2 2 10" -#define GENSEC_OID_SPNEGO "1 3 6 1 5 5 2" -#define GENSEC_OID_KERBEROS5 "1 2 840 113554 1 2 2" -#define GENSEC_OID_KERBEROS5_OLD "1 2 840 48018 1 2 2" -#define GENSEC_OID_KERBEROS5_USER2USER "1 2 840 113554 1 2 2 3" - -struct gensec_security; -struct gensec_target { - const char *principal; - const char *hostname; - const struct sock_addr *addr; - const char *service; -}; - -#define GENSEC_FEATURE_SESSION_KEY 0x00000001 -#define GENSEC_FEATURE_SIGN 0x00000002 -#define GENSEC_FEATURE_SEAL 0x00000004 -#define GENSEC_FEATURE_DCE_STYLE 0x00000008 - -/* GENSEC mode */ -enum gensec_role -{ - GENSEC_SERVER, - GENSEC_CLIENT -}; - -struct auth_session_info; - -struct gensec_security_ops { - const char *name; - const char *sasl_name; - uint8_t auth_type; /* 0 if not offered on DCE-RPC */ - const char *oid; /* NULL if not offered by SPNEGO */ - NTSTATUS (*client_start)(struct gensec_security *gensec_security); - NTSTATUS (*server_start)(struct gensec_security *gensec_security); - NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out); - NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig); - NTSTATUS (*sign_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig); - size_t (*sig_size)(struct gensec_security *gensec_security); - NTSTATUS (*check_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig); - NTSTATUS (*unseal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig); - NTSTATUS (*wrap)(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out); - NTSTATUS (*unwrap)(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out); - NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); - NTSTATUS (*session_info)(struct gensec_security *gensec_security, - struct auth_session_info **session_info); - BOOL (*have_feature)(struct gensec_security *gensec_security, - uint32_t feature); - BOOL enabled; -}; - -#define GENSEC_INTERFACE_VERSION 0 - -struct gensec_security { - gensec_password_callback password_callback; - void *password_callback_private; - const struct gensec_security_ops *ops; - void *private_data; - struct cli_credentials *credentials; - struct gensec_target target; - enum gensec_role gensec_role; - BOOL subcontext; - uint32_t want_features; -}; - -/* this structure is used by backends to determine the size of some critical types */ -struct gensec_critical_sizes { - int interface_version; - int sizeof_gensec_security_ops; - int sizeof_gensec_security; -}; - - -/* pre-declare schannel structure for schannel backend */ -struct schannel_state; diff --git a/source4/libcli/auth/gensec.m4 b/source4/libcli/auth/gensec.m4 deleted file mode 100644 index 6ccf45ad7e..0000000000 --- a/source4/libcli/auth/gensec.m4 +++ /dev/null @@ -1,12 +0,0 @@ -SMB_MODULE_DEFAULT(gensec_krb5, NOT) -SMB_MODULE_DEFAULT(gensec_gssapi, NOT) -SMB_MODULE_DEFAULT(gensec_gsskrb5, NOT) - -if test x"$SMB_EXT_LIB_ENABLE_KRB5" = x"YES"; then - # enable this when krb5 is fully working - SMB_MODULE_DEFAULT(gensec_krb5, STATIC) - SMB_MODULE_DEFAULT(gensec_gssapi, STATIC) - if test x"$samba_cv_GSS_C_DCE_STYLE" = x"yes"; then - SMB_MODULE_DEFAULT(gensec_gsskrb5, STATIC) - fi -fi diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk deleted file mode 100644 index b4c612da14..0000000000 --- a/source4/libcli/auth/gensec.mk +++ /dev/null @@ -1,91 +0,0 @@ -################################# -# Start SUBSYSTEM GENSEC -[SUBSYSTEM::GENSEC] -INIT_FUNCTION = gensec_init -INIT_OBJ_FILES = libcli/auth/gensec.o -REQUIRED_SUBSYSTEMS = \ - SCHANNELDB -# End SUBSYSTEM GENSEC -################################# - -################################################ -# Start MODULE gensec_krb5 -[MODULE::gensec_krb5] -SUBSYSTEM = GENSEC -INIT_FUNCTION = gensec_krb5_init -INIT_OBJ_FILES = libcli/auth/gensec_krb5.o -ADD_OBJ_FILES = \ - libcli/auth/clikrb5.o \ - libcli/auth/kerberos.o \ - libcli/auth/kerberos_verify.o \ - libcli/auth/gssapi_parse.o -REQUIRED_SUBSYSTEMS = NDR_KRB5PAC EXT_LIB_KRB5 -# End MODULE gensec_krb5 -################################################ - -################################################ -# Start MODULE gensec_gssapi -[MODULE::gensec_gssapi] -SUBSYSTEM = GENSEC -INIT_FUNCTION = gensec_gssapi_init -INIT_OBJ_FILES = libcli/auth/gensec_gssapi.o -REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 -# End MODULE gensec_gssapi -################################################ - -################################################ -# Start MODULE gensec_gsskrb5 -[MODULE::gensec_gsskrb5] -SUBSYSTEM = GENSEC -INIT_FUNCTION = gensec_gsskrb5_init -INIT_OBJ_FILES = libcli/auth/gensec_gsskrb5.o -REQUIRED_SUBSYSTEMS = EXT_LIB_KRB5 -# End MODULE gensec_gsskrb5 -################################################ - -################################################ -# Start MODULE gensec_spnego -[MODULE::gensec_spnego] -SUBSYSTEM = GENSEC -INIT_FUNCTION = gensec_spnego_init -INIT_OBJ_FILES = libcli/auth/spnego.o -ADD_OBJ_FILES = \ - libcli/auth/spnego_parse.o -# End MODULE gensec_spnego -################################################ - -################################################ -# Start MODULE gensec_ntlmssp -[MODULE::gensec_ntlmssp] -SUBSYSTEM = GENSEC -INIT_FUNCTION = gensec_ntlmssp_init -INIT_OBJ_FILES = libcli/auth/gensec_ntlmssp.o -ADD_OBJ_FILES = \ - libcli/auth/ntlmssp.o \ - libcli/auth/ntlmssp_parse.o \ - libcli/auth/ntlmssp_sign.o -REQUIRED_SUBSYSTEMS = AUTH -# End MODULE gensec_ntlmssp -################################################ - -################################################ -# Start MODULE gensec_schannel -[MODULE::gensec_schannel] -SUBSYSTEM = GENSEC -INIT_FUNCTION = gensec_schannel_init -INIT_OBJ_FILES = libcli/auth/schannel.o -ADD_OBJ_FILES = \ - libcli/auth/schannel_sign.o -REQUIRED_SUBSYSTEMS = AUTH SCHANNELDB -# End MODULE gensec_ntlmssp -################################################ - -################################################ -# Start SUBSYSTEM SCHANNELDB -[SUBSYSTEM::SCHANNELDB] -INIT_OBJ_FILES = \ - libcli/auth/schannel_state.o -# -# End SUBSYSTEM SCHANNELDB -################################################ - diff --git a/source4/libcli/auth/gensec_gssapi.c b/source4/libcli/auth/gensec_gssapi.c deleted file mode 100644 index c974b93952..0000000000 --- a/source4/libcli/auth/gensec_gssapi.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Kerberos backend for GENSEC - - Copyright (C) Andrew Bartlett 2004 - - 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 "system/kerberos.h" -#include "auth/auth.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -struct gensec_gssapi_state { - gss_ctx_id_t gssapi_context; - struct gss_channel_bindings_struct *input_chan_bindings; - gss_name_t server_name; - gss_name_t client_name; - OM_uint32 want_flags, got_flags; - const gss_OID_desc *gss_oid; -}; -static int gensec_gssapi_destory(void *ptr) -{ - struct gensec_gssapi_state *gensec_gssapi_state = ptr; - OM_uint32 maj_stat, min_stat; - - if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { - maj_stat = gss_delete_sec_context (&min_stat, - &gensec_gssapi_state->gssapi_context, - GSS_C_NO_BUFFER); - } - - if (gensec_gssapi_state->server_name != GSS_C_NO_NAME) { - maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->server_name); - } - if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { - maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); - } - return 0; -} - -static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) -{ - struct gensec_gssapi_state *gensec_gssapi_state; - - gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state); - if (!gensec_gssapi_state) { - return NT_STATUS_NO_MEMORY; - } - - gensec_security->private_data = gensec_gssapi_state; - - gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT; - gensec_gssapi_state->server_name = GSS_C_NO_NAME; - gensec_gssapi_state->client_name = GSS_C_NO_NAME; - - talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); - - /* TODO: Fill in channel bindings */ - gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; - - gensec_gssapi_state->want_flags = 0; - gensec_gssapi_state->got_flags = 0; - - if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { - /* GSSAPI won't give us the session keys */ - return NT_STATUS_INVALID_PARAMETER; - } - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; - } - - if (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) { - static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = - {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; - - gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; - } else if (strcmp(gensec_security->ops->oid, GENSEC_OID_SPNEGO) == 0) { - static const gss_OID_desc gensec_gss_spnego_mechanism_oid_desc = - {6, (void *)discard_const_p(char, "\x2b\x06\x01\x05\x05\x02")}; - gensec_gssapi_state->gss_oid = &gensec_gss_spnego_mechanism_oid_desc; - } else { - return NT_STATUS_INVALID_PARAMETER; - } - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_security) -{ - NTSTATUS nt_status; - struct gensec_gssapi_state *gensec_gssapi_state; - - nt_status = gensec_gssapi_start(gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - gensec_gssapi_state = gensec_security->private_data; - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) -{ - struct gensec_gssapi_state *gensec_gssapi_state; - NTSTATUS nt_status; - gss_buffer_desc name_token; - OM_uint32 maj_stat, min_stat; - - gss_OID_desc hostbased = {10, - (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12" - "\x01\x02\x01\x04")}; - - nt_status = gensec_gssapi_start(gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - gensec_gssapi_state = gensec_security->private_data; - - name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), - gensec_get_target_hostname(gensec_security)); - DEBUG(0, ("name: %s\n", (char *)name_token.value)); - name_token.length = strlen(name_token.value); - - maj_stat = gss_import_name (&min_stat, - &name_token, - &hostbased, - &gensec_gssapi_state->server_name); - - - if (maj_stat) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; -} - - - -/** - * Next state function for the GSSAPI GENSEC mechanism - * - * @param gensec_gssapi_state GSSAPI State - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, - * or NT_STATUS_OK if the user is authenticated. - */ - -static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - OM_uint32 maj_stat, min_stat; - OM_uint32 min_stat2; - gss_buffer_desc input_token, output_token; - gss_OID gss_oid_p; - input_token.length = in.length; - input_token.value = in.data; - - switch (gensec_security->gensec_role) { - case GENSEC_CLIENT: - { - maj_stat = gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, - &gensec_gssapi_state->gssapi_context, - gensec_gssapi_state->server_name, - discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), - gensec_gssapi_state->want_flags, - 0, - gensec_gssapi_state->input_chan_bindings, - &input_token, - NULL, - &output_token, - &gensec_gssapi_state->got_flags, /* ret flags */ - NULL); - break; - } - case GENSEC_SERVER: - { - maj_stat = gss_accept_sec_context(&min_stat, - &gensec_gssapi_state->gssapi_context, - GSS_C_NO_CREDENTIAL, - &input_token, - gensec_gssapi_state->input_chan_bindings, - &gensec_gssapi_state->client_name, - &gss_oid_p, - &output_token, - &gensec_gssapi_state->got_flags, - NULL, - NULL); - gensec_gssapi_state->gss_oid = gss_oid_p; - break; - } - default: - return NT_STATUS_INVALID_PARAMETER; - - } - - *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); - gss_release_buffer(&min_stat2, &output_token); - - if (maj_stat == GSS_S_COMPLETE) { - return NT_STATUS_OK; - } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } else { - gss_buffer_desc msg1, msg2; - OM_uint32 msg_ctx = 0; - - msg1.value = NULL; - msg2.value = NULL; - gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg1); - gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg2); - DEBUG(1, ("gensec_gssapi_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); - gss_release_buffer(&min_stat2, &msg1); - gss_release_buffer(&min_stat2, &msg2); - - return nt_status; - } - -} - -static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - input_token.length = in->length; - input_token.value = in->data; - - maj_stat = gss_wrap(&min_stat, - gensec_gssapi_state->gssapi_context, - gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), - GSS_C_QOP_DEFAULT, - &input_token, - &conf_state, - &output_token); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - gss_qop_t qop_state; - input_token.length = in->length; - input_token.value = in->data; - - maj_stat = gss_unwrap(&min_stat, - gensec_gssapi_state->gssapi_context, - &input_token, - &output_token, - &conf_state, - &qop_state); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - -static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - if (feature & GENSEC_FEATURE_SIGN) { - return gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG; - } - if (feature & GENSEC_FEATURE_SEAL) { - return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG; - } - return False; -} - -/* As a server, this could in theory accept any GSSAPI mech */ -static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { - .name = "gssapi_krb5", - .sasl_name = "GSSAPI", - .oid = GENSEC_OID_KERBEROS5, - .client_start = gensec_gssapi_client_start, - .server_start = gensec_gssapi_server_start, - .update = gensec_gssapi_update, - .wrap = gensec_gssapi_wrap, - .unwrap = gensec_gssapi_unwrap, - .have_feature = gensec_gssapi_have_feature, - .enabled = False - -}; - -static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { - .name = "gssapi_spnego", - .sasl_name = "GSS-SPNEGO", - .oid = GENSEC_OID_SPNEGO, - .client_start = gensec_gssapi_client_start, - .server_start = gensec_gssapi_server_start, - .update = gensec_gssapi_update, - .wrap = gensec_gssapi_wrap, - .unwrap = gensec_gssapi_unwrap, - .have_feature = gensec_gssapi_have_feature, - .enabled = False -}; - -NTSTATUS gensec_gssapi_init(void) -{ - NTSTATUS ret; - - ret = gensec_register(&gensec_gssapi_krb5_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_gssapi_krb5_security_ops.name)); - return ret; - } - - ret = gensec_register(&gensec_gssapi_spnego_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_gssapi_spnego_security_ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/libcli/auth/gensec_gsskrb5.c b/source4/libcli/auth/gensec_gsskrb5.c deleted file mode 100644 index 77e077276b..0000000000 --- a/source4/libcli/auth/gensec_gsskrb5.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - GSSAPI KRB5 backend for GENSEC - - Copyright (C) Andrew Bartlett 2004 - Copyright (C) Stefan Metzmacher 2005 - - 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 "system/kerberos.h" -#include "system/time.h" -#include "libcli/auth/kerberos.h" -#include "auth/auth.h" - -static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = - {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; - -enum GENSEC_GSSKRB5_STATE { - GENSEC_GSSKRB5_CLIENT_START, - GENSEC_GSSKRB5_CLIENT_MUTUAL_AUTH, - GENSEC_GSSKRB5_CLIENT_DCE_STYLE, - GENSEC_GSSKRB5_DONE -}; - -struct gensec_gsskrb5_state { - enum GENSEC_GSSKRB5_STATE state_position; - gss_ctx_id_t gssapi_context; - struct gss_channel_bindings_struct *input_chan_bindings; - gss_name_t server_name; - gss_name_t client_name; - OM_uint32 want_flags, got_flags; -}; - -static int gensec_gsskrb5_destory(void *ptr) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = ptr; - OM_uint32 maj_stat, min_stat; - - if (gensec_gsskrb5_state->gssapi_context != GSS_C_NO_CONTEXT) { - maj_stat = gss_delete_sec_context (&min_stat, - &gensec_gsskrb5_state->gssapi_context, - GSS_C_NO_BUFFER); - } - - if (gensec_gsskrb5_state->server_name != GSS_C_NO_NAME) { - maj_stat = gss_release_name(&min_stat, &gensec_gsskrb5_state->server_name); - } - if (gensec_gsskrb5_state->client_name != GSS_C_NO_NAME) { - maj_stat = gss_release_name(&min_stat, &gensec_gsskrb5_state->client_name); - } - return 0; -} - -static NTSTATUS gensec_gsskrb5_start(struct gensec_security *gensec_security) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state; - - gensec_gsskrb5_state = talloc(gensec_security, struct gensec_gsskrb5_state); - if (!gensec_gsskrb5_state) { - return NT_STATUS_NO_MEMORY; - } - - gensec_security->private_data = gensec_gsskrb5_state; - - gensec_gsskrb5_state->gssapi_context = GSS_C_NO_CONTEXT; - gensec_gsskrb5_state->server_name = GSS_C_NO_NAME; - gensec_gsskrb5_state->client_name = GSS_C_NO_NAME; - - talloc_set_destructor(gensec_gsskrb5_state, gensec_gsskrb5_destory); - - /* TODO: Fill in channel bindings */ - gensec_gsskrb5_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; - - gensec_gsskrb5_state->want_flags = GSS_C_MUTUAL_FLAG; - gensec_gsskrb5_state->got_flags = 0; - - if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { - /* GSSAPI won't give us the session keys */ - return NT_STATUS_INVALID_PARAMETER; - } - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - gensec_gsskrb5_state->want_flags |= GSS_C_INTEG_FLAG; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - gensec_gsskrb5_state->want_flags |= GSS_C_CONF_FLAG; - } - if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { - gensec_gsskrb5_state->want_flags |= GSS_C_DCE_STYLE; - } - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gsskrb5_client_start(struct gensec_security *gensec_security) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state; - NTSTATUS nt_status; - gss_buffer_desc name_token; - OM_uint32 maj_stat, min_stat; - - gss_OID_desc hostbased = {10, - (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12" - "\x01\x02\x01\x04")}; - - nt_status = gensec_gsskrb5_start(gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - gensec_gsskrb5_state = gensec_security->private_data; - - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_START; - - name_token.value = talloc_asprintf(gensec_gsskrb5_state, "%s@%s", gensec_get_target_service(gensec_security), - gensec_get_target_hostname(gensec_security)); - DEBUG(0, ("name: %s\n", (char *)name_token.value)); - name_token.length = strlen(name_token.value); - - maj_stat = gss_import_name (&min_stat, - &name_token, - &hostbased, - &gensec_gsskrb5_state->server_name); - if (maj_stat) { - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -/** - * Next state function for the GSSKRB5 GENSEC mechanism - * - * @param gensec_gsskrb5_state GSSAPI State - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, - * or NT_STATUS_OK if the user is authenticated. - */ - -static NTSTATUS gensec_gsskrb5_update(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - OM_uint32 maj_stat, min_stat; - OM_uint32 min_stat2; - gss_buffer_desc input_token, output_token; - - *out = data_blob(NULL, 0); - - input_token.length = in.length; - input_token.value = in.data; - - switch (gensec_gsskrb5_state->state_position) { - case GENSEC_GSSKRB5_CLIENT_START: - { - maj_stat = gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, - &gensec_gsskrb5_state->gssapi_context, - gensec_gsskrb5_state->server_name, - discard_const_p(gss_OID_desc, &gensec_gss_krb5_mechanism_oid_desc), - gensec_gsskrb5_state->want_flags, - 0, - gensec_gsskrb5_state->input_chan_bindings, - &input_token, - NULL, - &output_token, - &gensec_gsskrb5_state->got_flags, /* ret flags */ - NULL); - *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); - if (out->length != output_token.length) { - gss_release_buffer(&min_stat2, &output_token); - return NT_STATUS_NO_MEMORY; - } - gss_release_buffer(&min_stat2, &output_token); - - if (maj_stat == GSS_S_COMPLETE) { - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_DONE; - return NT_STATUS_OK; - } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_MUTUAL_AUTH; - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } else { - gss_buffer_desc msg1, msg2; - OM_uint32 msg_ctx = 0; - - msg1.value = NULL; - msg2.value = NULL; - gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg1); - gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg2); - DEBUG(1, ("gensec_gsskrb5_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); - gss_release_buffer(&min_stat2, &msg1); - gss_release_buffer(&min_stat2, &msg2); - - return nt_status; - } - break; - } - case GENSEC_GSSKRB5_CLIENT_MUTUAL_AUTH: - { - maj_stat = gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, - &gensec_gsskrb5_state->gssapi_context, - gensec_gsskrb5_state->server_name, - discard_const_p(gss_OID_desc, &gensec_gss_krb5_mechanism_oid_desc), - gensec_gsskrb5_state->want_flags, - 0, - gensec_gsskrb5_state->input_chan_bindings, - &input_token, - NULL, - &output_token, - &gensec_gsskrb5_state->got_flags, /* ret flags */ - NULL); - *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); - if (out->length != output_token.length) { - gss_release_buffer(&min_stat2, &output_token); - return NT_STATUS_NO_MEMORY; - } - gss_release_buffer(&min_stat2, &output_token); - - if (maj_stat == GSS_S_COMPLETE) { - if (gensec_gsskrb5_state->got_flags & GSS_C_DCE_STYLE) { - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_DCE_STYLE; - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_DONE; - return NT_STATUS_OK; - } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_CLIENT_DCE_STYLE; - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } else { - gss_buffer_desc msg1, msg2; - OM_uint32 msg_ctx = 0; - - msg1.value = NULL; - msg2.value = NULL; - gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg1); - gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg2); - DEBUG(1, ("gensec_gsskrb5_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); - gss_release_buffer(&min_stat2, &msg1); - gss_release_buffer(&min_stat2, &msg2); - - return nt_status; - } - break; - } - case GENSEC_GSSKRB5_CLIENT_DCE_STYLE: - { - gensec_gsskrb5_state->state_position = GENSEC_GSSKRB5_DONE; - return NT_STATUS_OK; - } - case GENSEC_GSSKRB5_DONE: - { - return NT_STATUS_OK; - } - default: - return NT_STATUS_INVALID_PARAMETER; - } - - return NT_STATUS_INVALID_PARAMETER; -} - -static NTSTATUS gensec_gsskrb5_wrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - input_token.length = in->length; - input_token.value = in->data; - - maj_stat = gss_wrap(&min_stat, - gensec_gsskrb5_state->gssapi_context, - gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), - GSS_C_QOP_DEFAULT, - &input_token, - &conf_state, - &output_token); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gsskrb5_unwrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - gss_qop_t qop_state; - input_token.length = in->length; - input_token.value = in->data; - - maj_stat = gss_unwrap(&min_stat, - gensec_gsskrb5_state->gssapi_context, - &input_token, - &output_token, - &conf_state, - &qop_state); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - -static size_t gensec_gsskrb5_sig_size(struct gensec_security *gensec_security) -{ - /* not const but work for DCERPC packets and arcfour */ - return 45; -} - -static NTSTATUS gensec_gsskrb5_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - ssize_t sig_length = 0; - - input_token.length = length; - input_token.value = data; - - maj_stat = gss_wrap(&min_stat, - gensec_gsskrb5_state->gssapi_context, - gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), - GSS_C_QOP_DEFAULT, - &input_token, - &conf_state, - &output_token); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - - if (output_token.length < length) { - return NT_STATUS_INTERNAL_ERROR; - } - - sig_length = 45; - - memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); - *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); - -DEBUG(0,("gensec_gsskrb5_seal_packet: siglen: %d inlen: %d, wrap_len: %d\n", sig->length, length, output_token.length - sig_length)); -dump_data(0,sig->data, sig->length); -dump_data(0,data, length); -dump_data(0,((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gsskrb5_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - gss_qop_t qop_state; - DATA_BLOB in; - -DEBUG(0,("gensec_gsskrb5_unseal_packet: siglen: %d\n", sig->length)); -dump_data(0,sig->data, sig->length); - - in = data_blob_talloc(mem_ctx, NULL, sig->length + length); - - memcpy(in.data, sig->data, sig->length); - memcpy(in.data + sig->length, data, length); - - input_token.length = in.length; - input_token.value = in.data; - - maj_stat = gss_unwrap(&min_stat, - gensec_gsskrb5_state->gssapi_context, - &input_token, - &output_token, - &conf_state, - &qop_state); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - - if (output_token.length != length) { - return NT_STATUS_INTERNAL_ERROR; - } - - memcpy(data, output_token.value, length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gsskrb5_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - ssize_t sig_length = 0; - - input_token.length = length; - input_token.value = data; - - maj_stat = gss_wrap(&min_stat, - gensec_gsskrb5_state->gssapi_context, - 0, - GSS_C_QOP_DEFAULT, - &input_token, - &conf_state, - &output_token); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - - if (output_token.length < length) { - return NT_STATUS_INTERNAL_ERROR; - } - - sig_length = 45; - - /*memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);*/ - *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); - -DEBUG(0,("gensec_gsskrb5_sign_packet: siglen: %d\n", sig->length)); -dump_data(0,sig->data, sig->length); - - gss_release_buffer(&min_stat, &output_token); - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_gsskrb5_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - gss_qop_t qop_state; - DATA_BLOB in; - -DEBUG(0,("gensec_gsskrb5_check_packet: siglen: %d\n", sig->length)); -dump_data(0,sig->data, sig->length); - - in = data_blob_talloc(mem_ctx, NULL, sig->length + length); - - memcpy(in.data, sig->data, sig->length); - memcpy(in.data + sig->length, data, length); - - input_token.length = in.length; - input_token.value = in.data; - - maj_stat = gss_unwrap(&min_stat, - gensec_gsskrb5_state->gssapi_context, - &input_token, - &output_token, - &conf_state, - &qop_state); - if (GSS_ERROR(maj_stat)) { - return NT_STATUS_ACCESS_DENIED; - } - - if (output_token.length != length) { - return NT_STATUS_INTERNAL_ERROR; - } - - /*memcpy(data, output_token.value, length);*/ - - gss_release_buffer(&min_stat, &output_token); - - return NT_STATUS_OK; -} - -static BOOL gensec_gsskrb5_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct gensec_gsskrb5_state *gensec_gsskrb5_state = gensec_security->private_data; - if (feature & GENSEC_FEATURE_SIGN) { - return gensec_gsskrb5_state->got_flags & GSS_C_INTEG_FLAG; - } - if (feature & GENSEC_FEATURE_SEAL) { - return gensec_gsskrb5_state->got_flags & GSS_C_CONF_FLAG; - } - return False; -} - -static const struct gensec_security_ops gensec_gsskrb5_security_ops = { - .name = "gsskrb5", - .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = GENSEC_OID_KERBEROS5, - .client_start = gensec_gsskrb5_client_start, - .update = gensec_gsskrb5_update, - .sig_size = gensec_gsskrb5_sig_size, - .sign_packet = gensec_gsskrb5_sign_packet, - .check_packet = gensec_gsskrb5_check_packet, - .seal_packet = gensec_gsskrb5_seal_packet, - .unseal_packet = gensec_gsskrb5_unseal_packet, - .wrap = gensec_gsskrb5_wrap, - .unwrap = gensec_gsskrb5_unwrap, - .have_feature = gensec_gsskrb5_have_feature, - .enabled = False -}; - -NTSTATUS gensec_gsskrb5_init(void) -{ - NTSTATUS ret; - - ret = gensec_register(&gensec_gsskrb5_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_gsskrb5_security_ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c deleted file mode 100644 index 453485d816..0000000000 --- a/source4/libcli/auth/gensec_krb5.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Kerberos backend for GENSEC - - Copyright (C) Andrew Bartlett 2004 - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002-2003 - Copyright (C) Stefan Metzmacher 2004-2005 - - 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 "system/kerberos.h" -#include "system/time.h" -#include "libcli/auth/kerberos.h" -#include "librpc/gen_ndr/ndr_krb5pac.h" -#include "auth/auth.h" - -enum GENSEC_KRB5_STATE { - GENSEC_KRB5_SERVER_START, - GENSEC_KRB5_CLIENT_START, - GENSEC_KRB5_CLIENT_MUTUAL_AUTH, - GENSEC_KRB5_DONE -}; - -struct gensec_krb5_state { - DATA_BLOB session_key; - DATA_BLOB pac; - enum GENSEC_KRB5_STATE state_position; - krb5_context context; - krb5_auth_context auth_context; - krb5_ccache ccache; - krb5_data ticket; - krb5_keyblock keyblock; - char *peer_principal; -}; - -#ifdef KRB5_DO_VERIFY_PAC -static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data, - struct PAC_SIGNATURE_DATA *sig, - struct gensec_krb5_state *gensec_krb5_state, - uint32 keyusage) -{ - krb5_error_code ret; - krb5_crypto crypto; - Checksum cksum; - int i; - - cksum.cksumtype = (CKSUMTYPE)sig->type; - cksum.checksum.length = sizeof(sig->signature); - cksum.checksum.data = sig->signature; - - - ret = krb5_crypto_init(gensec_krb5_state->context, - &gensec_krb5_state->keyblock, - 0, - &crypto); - if (ret) { - DEBUG(0,("krb5_crypto_init() failed\n")); - return NT_STATUS_FOOBAR; - } - for (i=0; i < 40; i++) { - keyusage = i; - ret = krb5_verify_checksum(gensec_krb5_state->context, - crypto, - keyusage, - pac_data.data, - pac_data.length, - &cksum); - if (!ret) { - DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage)); - break; - } - } - krb5_crypto_destroy(gensec_krb5_state->context, crypto); - - if (ret) { - DEBUG(0,("NOT verifying PAC checksums yet!\n")); - //return NT_STATUS_LOGON_FAILURE; - } else { - DEBUG(0,("PAC checksums verified!\n")); - } - - return NT_STATUS_OK; -} -#endif - -static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx, - struct PAC_LOGON_INFO **logon_info_out, - DATA_BLOB blob, - struct gensec_krb5_state *gensec_krb5_state) -{ - NTSTATUS status; - struct PAC_SIGNATURE_DATA srv_sig; - struct PAC_SIGNATURE_DATA *srv_sig_ptr; - struct PAC_SIGNATURE_DATA kdc_sig; - struct PAC_SIGNATURE_DATA *kdc_sig_ptr; - struct PAC_LOGON_INFO *logon_info = NULL; - struct PAC_DATA pac_data; -#ifdef KRB5_DO_VERIFY_PAC - DATA_BLOB tmp_blob = data_blob(NULL, 0); -#endif - int i; - - status = ndr_pull_struct_blob(&blob, mem_ctx, &pac_data, - (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("can't parse the PAC\n")); - return status; - } - NDR_PRINT_DEBUG(PAC_DATA, &pac_data); - - if (pac_data.num_buffers < 3) { - /* we need logon_ingo, service_key and kdc_key */ - DEBUG(0,("less than 3 PAC buffers\n")); - return NT_STATUS_FOOBAR; - } - - for (i=0; i < pac_data.num_buffers; i++) { - switch (pac_data.buffers[i].type) { - case PAC_TYPE_LOGON_INFO: - if (!pac_data.buffers[i].info) { - break; - } - logon_info = &pac_data.buffers[i].info->logon_info; - break; - case PAC_TYPE_SRV_CHECKSUM: - if (!pac_data.buffers[i].info) { - break; - } - srv_sig_ptr = &pac_data.buffers[i].info->srv_cksum; - srv_sig = pac_data.buffers[i].info->srv_cksum; - break; - case PAC_TYPE_KDC_CHECKSUM: - if (!pac_data.buffers[i].info) { - break; - } - kdc_sig_ptr = &pac_data.buffers[i].info->kdc_cksum; - kdc_sig = pac_data.buffers[i].info->kdc_cksum; - break; - case PAC_TYPE_UNKNOWN_10: - break; - default: - break; - } - } - - if (!logon_info) { - DEBUG(0,("PAC no logon_info\n")); - return NT_STATUS_FOOBAR; - } - - if (!srv_sig_ptr) { - DEBUG(0,("PAC no srv_key\n")); - return NT_STATUS_FOOBAR; - } - - if (!kdc_sig_ptr) { - DEBUG(0,("PAC no kdc_key\n")); - return NT_STATUS_FOOBAR; - } -#ifdef KRB5_DO_VERIFY_PAC - /* clear the kdc_key */ -/* memset((void *)kdc_sig_ptr , '\0', sizeof(*kdc_sig_ptr));*/ - - status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_push_flags_fn_t)ndr_push_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("can't parse the PAC\n")); - return status; - } - /*NDR_PRINT_DEBUG(PAC_DATA, &pac_data);*/ - - /* verify by kdc_key */ - status = gensec_krb5_pac_checksum(tmp_blob, &kdc_sig, gensec_krb5_state, 0); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* clear the service_key */ -/* memset((void *)srv_sig_ptr , '\0', sizeof(*srv_sig_ptr));*/ - - status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_push_flags_fn_t)ndr_push_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("can't parse the PAC\n")); - return status; - } - NDR_PRINT_DEBUG(PAC_DATA, &pac_data); - - /* verify by servie_key */ - status = gensec_krb5_pac_checksum(tmp_blob, &srv_sig, gensec_krb5_state, 0); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } -#endif - DEBUG(0,("account_name: %s [%s]\n",logon_info->info3.base.account_name.string, logon_info->info3.base.full_name.string)); - *logon_info_out = logon_info; - - return status; -} - -static int gensec_krb5_destory(void *ptr) -{ - struct gensec_krb5_state *gensec_krb5_state = ptr; - - if (gensec_krb5_state->ticket.length) { - kerberos_free_data_contents(gensec_krb5_state->context, &gensec_krb5_state->ticket); - } - if (gensec_krb5_state->ccache) { - /* current heimdal - 0.6.3, which we need anyway, fixes segfaults here */ - krb5_cc_close(gensec_krb5_state->context, gensec_krb5_state->ccache); - } - - krb5_free_keyblock_contents(gensec_krb5_state->context, - &gensec_krb5_state->keyblock); - - if (gensec_krb5_state->auth_context) { - krb5_auth_con_free(gensec_krb5_state->context, - gensec_krb5_state->auth_context); - } - - if (gensec_krb5_state->context) { - krb5_free_context(gensec_krb5_state->context); - } - return 0; -} - -static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) -{ - struct gensec_krb5_state *gensec_krb5_state; - krb5_error_code ret = 0; - - gensec_krb5_state = talloc(gensec_security, struct gensec_krb5_state); - if (!gensec_krb5_state) { - return NT_STATUS_NO_MEMORY; - } - - gensec_security->private_data = gensec_krb5_state; - - initialize_krb5_error_table(); - gensec_krb5_state->context = NULL; - gensec_krb5_state->auth_context = NULL; - gensec_krb5_state->ccache = NULL; - ZERO_STRUCT(gensec_krb5_state->ticket); - ZERO_STRUCT(gensec_krb5_state->keyblock); - gensec_krb5_state->session_key = data_blob(NULL, 0); - gensec_krb5_state->pac = data_blob(NULL, 0); - - talloc_set_destructor(gensec_krb5_state, gensec_krb5_destory); - - ret = krb5_init_context(&gensec_krb5_state->context); - if (ret) { - DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", error_message(ret))); - return NT_STATUS_INTERNAL_ERROR; - } - - if (lp_realm() && *lp_realm()) { - ret = krb5_set_default_realm(gensec_krb5_state->context, lp_realm()); - if (ret) { - DEBUG(1,("gensec_krb5_start: krb5_set_default_realm failed (%s)\n", error_message(ret))); - return NT_STATUS_INTERNAL_ERROR; - } - } - - ret = krb5_auth_con_init(gensec_krb5_state->context, &gensec_krb5_state->auth_context); - if (ret) { - DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n", error_message(ret))); - return NT_STATUS_INTERNAL_ERROR; - } - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security) -{ - NTSTATUS nt_status; - struct gensec_krb5_state *gensec_krb5_state; - - nt_status = gensec_krb5_start(gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - gensec_krb5_state = gensec_security->private_data; - gensec_krb5_state->state_position = GENSEC_KRB5_SERVER_START; - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security) -{ - struct gensec_krb5_state *gensec_krb5_state; - krb5_error_code ret; - NTSTATUS nt_status; - const char *hostname = gensec_get_target_hostname(gensec_security); - if (!hostname) { - DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); - return NT_STATUS_ACCESS_DENIED; - } - - nt_status = gensec_krb5_start(gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - gensec_krb5_state = gensec_security->private_data; - gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; - - /* TODO: This is effecivly a static/global variable... - - TODO: If the user set a username, we should use an in-memory CCACHE (see below) - */ - ret = krb5_cc_default(gensec_krb5_state->context, &gensec_krb5_state->ccache); - if (ret) { - DEBUG(1,("krb5_cc_default failed (%s)\n", - error_message(ret))); - return NT_STATUS_INTERNAL_ERROR; - } - - while (1) { - { - krb5_data in_data; - in_data.length = 0; - - ret = krb5_mk_req(gensec_krb5_state->context, - &gensec_krb5_state->auth_context, - AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED, - gensec_get_target_service(gensec_security), - hostname, - &in_data, gensec_krb5_state->ccache, - &gensec_krb5_state->ticket); - - } - switch (ret) { - case 0: - return NT_STATUS_OK; - case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: - DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n", - hostname, error_message(ret))); - return NT_STATUS_ACCESS_DENIED; - case KRB5KDC_ERR_PREAUTH_FAILED: - case KRB5KRB_AP_ERR_TKT_EXPIRED: - case KRB5_CC_END: - /* Too much clock skew - we will need to kinit to re-skew the clock */ - case KRB5KRB_AP_ERR_SKEW: - case KRB5_KDCREP_SKEW: - { - DEBUG(3, ("kerberos (mk_req) failed: %s\n", - error_message(ret))); - /* fall down to remaining code */ - } - - - /* just don't print a message for these really ordinary messages */ - case KRB5_FCC_NOFILE: - case KRB5_CC_NOTFOUND: - case ENOENT: - - { - const char *password; - char *ccache_string; - time_t kdc_time = 0; - password = cli_credentials_get_password(gensec_security->credentials); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - /* this string should be unique */ - ccache_string = talloc_asprintf(gensec_krb5_state, "MEMORY:%s:%s:%s", - cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), - gensec_get_target_hostname(gensec_security), - generate_random_str(gensec_krb5_state, 16)); - - ret = krb5_cc_resolve(gensec_krb5_state->context, ccache_string, &gensec_krb5_state->ccache); - if (ret) { - DEBUG(1,("failed to generate a new krb5 keytab (%s): %s\n", - ccache_string, - error_message(ret))); - return NT_STATUS_INTERNAL_ERROR; - } - - ret = kerberos_kinit_password_cc(gensec_krb5_state->context, gensec_krb5_state->ccache, - cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), - password, NULL, &kdc_time); - - /* cope with ticket being in the future due to clock skew */ - if ((unsigned)kdc_time > time(NULL)) { - time_t t = time(NULL); - int time_offset =(unsigned)kdc_time-t; - DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); - krb5_set_real_time(gensec_krb5_state->context, t + time_offset + 1, 0); - break; - } - - if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) { - DEBUG(1,("kinit for %s failed (%s)\n", - cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), - error_message(ret))); - return NT_STATUS_TIME_DIFFERENCE_AT_DC; - } - if (ret) { - DEBUG(1,("kinit for %s failed (%s)\n", - cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), - error_message(ret))); - return NT_STATUS_WRONG_PASSWORD; - } - break; - } - default: - DEBUG(0, ("kerberos: %s\n", - error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; - } - } -} - - -/** - * Next state function for the Krb5 GENSEC mechanism - * - * @param gensec_krb5_state KRB5 State - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, - * or NT_STATUS_OK if the user is authenticated. - */ - -static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - krb5_error_code ret = 0; - DATA_BLOB pac; - NTSTATUS nt_status; - - switch (gensec_krb5_state->state_position) { - case GENSEC_KRB5_CLIENT_START: - { - if (ret) { - DEBUG(1,("ads_krb5_mk_req (request ticket) failed (%s)\n", - error_message(ret))); - nt_status = NT_STATUS_LOGON_FAILURE; - } else { - DATA_BLOB unwrapped_out; - -#ifndef GENSEC_SEND_UNWRAPPED_KRB5 /* This should be a switch for the torture code to set */ - unwrapped_out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->ticket.data, gensec_krb5_state->ticket.length); - - /* wrap that up in a nice GSS-API wrapping */ - *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REQ); -#else - *out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->ticket.data, gensec_krb5_state->ticket.length); -#endif - gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; - nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; - } - - return nt_status; - } - - case GENSEC_KRB5_CLIENT_MUTUAL_AUTH: - { - krb5_data inbuf; - krb5_ap_rep_enc_part *repl = NULL; - uint8_t tok_id[2]; - DATA_BLOB unwrapped_in; - - if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { - DEBUG(1,("gensec_gssapi_parse_krb5_wrap(mutual authentication) failed to parse\n")); - dump_data_pw("Mutual authentication message:\n", in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; - } - /* TODO: check the tok_id */ - - inbuf.data = unwrapped_in.data; - inbuf.length = unwrapped_in.length; - ret = krb5_rd_rep(gensec_krb5_state->context, - gensec_krb5_state->auth_context, - &inbuf, &repl); - if (ret) { - DEBUG(1,("krb5_rd_rep (mutual authentication) failed (%s)\n", - error_message(ret))); - dump_data_pw("Mutual authentication message:\n", inbuf.data, inbuf.length); - nt_status = NT_STATUS_ACCESS_DENIED; - } else { - *out = data_blob(NULL, 0); - nt_status = NT_STATUS_OK; - gensec_krb5_state->state_position = GENSEC_KRB5_DONE; - } - if (repl) { - krb5_free_ap_rep_enc_part(gensec_krb5_state->context, repl); - } - return nt_status; - } - - case GENSEC_KRB5_SERVER_START: - { - char *principal; - DATA_BLOB unwrapped_in; - DATA_BLOB unwrapped_out = data_blob(NULL, 0); - uint8_t tok_id[2]; - - if (!in.data) { - *out = unwrapped_out; - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - - /* Parse the GSSAPI wrapping, if it's there... (win2k3 allows it to be omited) */ - if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) { - nt_status = ads_verify_ticket(out_mem_ctx, - gensec_krb5_state->context, - gensec_krb5_state->auth_context, - lp_realm(), - gensec_get_target_service(gensec_security), &in, - &principal, &pac, &unwrapped_out, - &gensec_krb5_state->keyblock); - } else { - /* TODO: check the tok_id */ - nt_status = ads_verify_ticket(out_mem_ctx, - gensec_krb5_state->context, - gensec_krb5_state->auth_context, - lp_realm(), - gensec_get_target_service(gensec_security), - &unwrapped_in, - &principal, &pac, &unwrapped_out, - &gensec_krb5_state->keyblock); - } - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - if (pac.data) { - gensec_krb5_state->pac = data_blob_talloc_reference(gensec_krb5_state, &pac); - } - - if (NT_STATUS_IS_OK(nt_status)) { - gensec_krb5_state->state_position = GENSEC_KRB5_DONE; - /* wrap that up in a nice GSS-API wrapping */ -#ifndef GENSEC_SEND_UNWRAPPED_KRB5 - *out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REP); -#else - *out = unwrapped_out; -#endif - gensec_krb5_state->peer_principal = talloc_steal(gensec_krb5_state, principal); - } - return nt_status; - } - case GENSEC_KRB5_DONE: - return NT_STATUS_OK; - } - - return NT_STATUS_INVALID_PARAMETER; -} - -static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) -{ - struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - krb5_context context = gensec_krb5_state->context; - krb5_auth_context auth_context = gensec_krb5_state->auth_context; - krb5_keyblock *skey; - krb5_error_code err; - - if (gensec_krb5_state->session_key.data) { - *session_key = gensec_krb5_state->session_key; - return NT_STATUS_OK; - } - - switch (gensec_security->gensec_role) { - case GENSEC_CLIENT: - err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); - break; - case GENSEC_SERVER: - err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); - break; - } - if (err == 0 && skey != NULL) { - DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); - gensec_krb5_state->session_key = data_blob_talloc(gensec_krb5_state, - KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - *session_key = gensec_krb5_state->session_key; - dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); - - krb5_free_keyblock(context, skey); - return NT_STATUS_OK; - } else { - DEBUG(10, ("KRB5 error getting session key %d\n", err)); - return NT_STATUS_NO_USER_SESSION_KEY; - } -} - -static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, - struct auth_session_info **_session_info) -{ - NTSTATUS nt_status; - struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; - struct auth_serversupplied_info *server_info = NULL; - struct auth_session_info *session_info = NULL; - struct PAC_LOGON_INFO *logon_info; - char *p; - char *principal; - const char *account_name; - const char *realm; - - principal = talloc_strdup(gensec_krb5_state, gensec_krb5_state->peer_principal); - NT_STATUS_HAVE_NO_MEMORY(principal); - - p = strchr(principal, '@'); - if (p) { - *p = '\0'; - p++; - realm = p; - } else { - realm = lp_realm(); - } - account_name = principal; - - /* decode and verify the pac */ - nt_status = gensec_krb5_decode_pac(gensec_krb5_state, &logon_info, gensec_krb5_state->pac, - gensec_krb5_state); - - /* IF we have the PAC - otherwise we need to get this - * data from elsewere - local ldb, or (TODO) lookup of some - * kind... - * - * when heimdal can generate the PAC, we should fail if there's - * no PAC present - */ - - if (NT_STATUS_IS_OK(nt_status)) { - union netr_Validation validation; - validation.sam3 = &logon_info->info3; - nt_status = make_server_info_netlogon_validation(gensec_krb5_state, - account_name, - 3, &validation, - &server_info); - talloc_free(principal); - NT_STATUS_NOT_OK_RETURN(nt_status); - } else { - DATA_BLOB user_sess_key = data_blob(NULL, 0); - DATA_BLOB lm_sess_key = data_blob(NULL, 0); - /* TODO: should we pass the krb5 session key in here? */ - nt_status = sam_get_server_info(gensec_krb5_state, account_name, realm, - user_sess_key, lm_sess_key, - &server_info); - talloc_free(principal); - NT_STATUS_NOT_OK_RETURN(nt_status); - } - - /* references the server_info into the session_info */ - nt_status = auth_generate_session_info(gensec_krb5_state, server_info, &session_info); - talloc_free(server_info); - NT_STATUS_NOT_OK_RETURN(nt_status); - - nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key); - NT_STATUS_NOT_OK_RETURN(nt_status); - - *_session_info = session_info; - - return NT_STATUS_OK; -} - -static BOOL gensec_krb5_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - if (feature & GENSEC_FEATURE_SESSION_KEY) { - return True; - } - - return False; -} - - -static const struct gensec_security_ops gensec_krb5_security_ops = { - .name = "krb5", - .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = GENSEC_OID_KERBEROS5, - .client_start = gensec_krb5_client_start, - .server_start = gensec_krb5_server_start, - .update = gensec_krb5_update, - .session_key = gensec_krb5_session_key, - .session_info = gensec_krb5_session_info, - .have_feature = gensec_krb5_have_feature, - .enabled = False -}; - -static const struct gensec_security_ops gensec_ms_krb5_security_ops = { - .name = "ms_krb5", - .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = GENSEC_OID_KERBEROS5_OLD, - .client_start = gensec_krb5_client_start, - .server_start = gensec_krb5_server_start, - .update = gensec_krb5_update, - .session_key = gensec_krb5_session_key, - .session_info = gensec_krb5_session_info, - .have_feature = gensec_krb5_have_feature, - .enabled = False -}; - - -NTSTATUS gensec_krb5_init(void) -{ - NTSTATUS ret; - - ret = gensec_register(&gensec_krb5_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_krb5_security_ops.name)); - return ret; - } - - ret = gensec_register(&gensec_ms_krb5_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_krb5_security_ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c deleted file mode 100644 index 5955904886..0000000000 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - dcerpc authentication operations - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Andrew Bartlett 2004 - Copyright (C) Stefan Metzmacher 2005 - - 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 "auth/auth.h" - -struct gensec_ntlmssp_state { - struct auth_context *auth_context; - struct auth_serversupplied_info *server_info; - struct ntlmssp_state *ntlmssp_state; - uint32_t have_features; -}; - - -/** - * Return the challenge as determined by the authentication subsystem - * @return an 8 byte random challenge - */ - -static const uint8_t *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; - NTSTATUS status; - const uint8_t *chal; - - status = auth_get_challenge(gensec_ntlmssp_state->auth_context, &chal); - if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - - return chal; -} - -/** - * Some authentication methods 'fix' the challenge, so we may not be able to set it - * - * @return If the effective challenge used by the auth subsystem may be modified - */ -static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; - - return auth_challenge_may_be_modified(gensec_ntlmssp_state->auth_context); -} - -/** - * NTLM2 authentication modifies the effective challenge, - * @param challenge The new challenge value - */ -static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) -{ - NTSTATUS nt_status; - struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; - struct auth_context *auth_context = gensec_ntlmssp_state->auth_context; - const uint8_t *chal; - - if (challenge->length != 8) { - return NT_STATUS_INVALID_PARAMETER; - } - - chal = challenge->data; - - nt_status = auth_context_set_challenge(auth_context, chal, "NTLMSSP callback (NTLM2)"); - - return nt_status; -} - -/** - * Check the password on an NTLMSSP login. - * - * Return the session keys used on the connection. - */ - -static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; - struct auth_usersupplied_info *user_info = NULL; - NTSTATUS nt_status; - - nt_status = make_user_info_map(ntlmssp_state, - gensec_ntlmssp_state->ntlmssp_state->user, - gensec_ntlmssp_state->ntlmssp_state->domain, - gensec_ntlmssp_state->ntlmssp_state->workstation, - gensec_ntlmssp_state->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->lm_resp : NULL, - gensec_ntlmssp_state->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->nt_resp : NULL, - NULL, NULL, NULL, True, - &user_info); - NT_STATUS_NOT_OK_RETURN(nt_status); - - nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, gensec_ntlmssp_state, - user_info, &gensec_ntlmssp_state->server_info); - talloc_free(user_info); - NT_STATUS_NOT_OK_RETURN(nt_status); - - if (gensec_ntlmssp_state->server_info->user_session_key.length) { - DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length)); - *user_session_key = data_blob_talloc(ntlmssp_state, - gensec_ntlmssp_state->server_info->user_session_key.data, - gensec_ntlmssp_state->server_info->user_session_key.length); - } - if (gensec_ntlmssp_state->server_info->lm_session_key.length) { - DEBUG(10, ("Got LM session key of length %u\n", gensec_ntlmssp_state->server_info->lm_session_key.length)); - *lm_session_key = data_blob_talloc(ntlmssp_state, - gensec_ntlmssp_state->server_info->lm_session_key.data, - gensec_ntlmssp_state->server_info->lm_session_key.length); - } - return nt_status; -} - -static int gensec_ntlmssp_destroy(void *ptr) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = ptr; - - if (gensec_ntlmssp_state->ntlmssp_state) { - ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state); - } - - return 0; -} - -static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state; - - gensec_ntlmssp_state = talloc(gensec_security, struct gensec_ntlmssp_state); - if (!gensec_ntlmssp_state) { - return NT_STATUS_NO_MEMORY; - } - - gensec_ntlmssp_state->ntlmssp_state = NULL; - gensec_ntlmssp_state->auth_context = NULL; - gensec_ntlmssp_state->server_info = NULL; - gensec_ntlmssp_state->have_features = 0; - - talloc_set_destructor(gensec_ntlmssp_state, gensec_ntlmssp_destroy); - - gensec_security->private_data = gensec_ntlmssp_state; - return NT_STATUS_OK; -} - -static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) -{ - NTSTATUS nt_status; - struct ntlmssp_state *ntlmssp_state; - struct gensec_ntlmssp_state *gensec_ntlmssp_state; - - nt_status = gensec_ntlmssp_start(gensec_security); - NT_STATUS_NOT_OK_RETURN(nt_status); - - gensec_ntlmssp_state = gensec_security->private_data; - - nt_status = ntlmssp_server_start(gensec_ntlmssp_state, &gensec_ntlmssp_state->ntlmssp_state); - NT_STATUS_NOT_OK_RETURN(nt_status); - - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - - nt_status = auth_context_create(gensec_ntlmssp_state, lp_auth_methods(), &gensec_ntlmssp_state->auth_context); - NT_STATUS_NOT_OK_RETURN(nt_status); - - ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; - ntlmssp_state->auth_context = gensec_ntlmssp_state; - ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; - ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; - ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; - ntlmssp_state->check_password = auth_ntlmssp_check_password; - ntlmssp_state->server_role = lp_server_role(); - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state; - const char *password = NULL; - NTSTATUS nt_status; - - nt_status = gensec_ntlmssp_start(gensec_security); - NT_STATUS_NOT_OK_RETURN(nt_status); - - gensec_ntlmssp_state = gensec_security->private_data; - nt_status = ntlmssp_client_start(gensec_ntlmssp_state, - &gensec_ntlmssp_state->ntlmssp_state); - NT_STATUS_NOT_OK_RETURN(nt_status); - - if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { - /* - * We need to set this to allow a later SetPassword - * via the SAMR pipe to succeed. Strange.... We could - * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - * - * Without this, Windows will not create the master key - * that it thinks is only used for NTLMSSP signing and - * sealing. (It is actually pulled out and used directly) - */ - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - - nt_status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, - cli_credentials_get_domain(gensec_security->credentials)); - NT_STATUS_NOT_OK_RETURN(nt_status); - - nt_status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, - cli_credentials_get_username(gensec_security->credentials)); - NT_STATUS_NOT_OK_RETURN(nt_status); - - password = cli_credentials_get_password(gensec_security->credentials); - - nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password); - NT_STATUS_NOT_OK_RETURN(nt_status); - - nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state, - cli_credentials_get_workstation(gensec_security->credentials)); - - gensec_security->private_data = gensec_ntlmssp_state; - - return NT_STATUS_OK; -} - -/* - wrappers for the ntlmssp_*() functions -*/ -static NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -static NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -static NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - return ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -static NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - return ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig); -} - -static size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security) -{ - return NTLMSSP_SIG_SIZE; -} - -static NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - DATA_BLOB sig; - NTSTATUS nt_status; - - if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { - - *out = data_blob_talloc(mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE); - memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length); - - nt_status = ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, - out->data + NTLMSSP_SIG_SIZE, - out->length - NTLMSSP_SIG_SIZE, - out->data + NTLMSSP_SIG_SIZE, - out->length - NTLMSSP_SIG_SIZE, - &sig); - - if (NT_STATUS_IS_OK(nt_status)) { - memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE); - } - return nt_status; - - } else if ((gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) - || (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { - - *out = data_blob_talloc(mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE); - memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length); - - nt_status = ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, - out->data + NTLMSSP_SIG_SIZE, - out->length - NTLMSSP_SIG_SIZE, - out->data + NTLMSSP_SIG_SIZE, - out->length - NTLMSSP_SIG_SIZE, - &sig); - - if (NT_STATUS_IS_OK(nt_status)) { - memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE); - } - return nt_status; - - } else { - *out = *in; - return NT_STATUS_OK; - } -} - - -static NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - DATA_BLOB sig; - - if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { - if (in->length < NTLMSSP_SIG_SIZE) { - return NT_STATUS_INVALID_PARAMETER; - } - sig.data = in->data; - sig.length = NTLMSSP_SIG_SIZE; - - *out = data_blob_talloc(mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); - - return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, - out->data, out->length, - out->data, out->length, - &sig); - - } else if ((gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) - || (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { - if (in->length < NTLMSSP_SIG_SIZE) { - return NT_STATUS_INVALID_PARAMETER; - } - sig.data = in->data; - sig.length = NTLMSSP_SIG_SIZE; - - *out = data_blob_talloc(mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); - - return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, - out->data, out->length, - out->data, out->length, - &sig); - } else { - *out = *in; - return NT_STATUS_OK; - } -} - -static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - return ntlmssp_session_key(gensec_ntlmssp_state->ntlmssp_state, session_key); -} - -/** - * Next state function for the wrapped NTLMSSP state machine - * - * @param gensec_security GENSEC state, initialised to NTLMSSP - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, - * or NT_STATUS_OK if the user is authenticated. - */ - -static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - NTSTATUS status; - - status = ntlmssp_update(gensec_ntlmssp_state->ntlmssp_state, out_mem_ctx, in, out); - - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - return status; - } - - gensec_ntlmssp_state->have_features = 0; - - if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { - gensec_ntlmssp_state->have_features |= GENSEC_FEATURE_SIGN; - } - - if (gensec_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { - gensec_ntlmssp_state->have_features |= GENSEC_FEATURE_SEAL; - } - - if (gensec_ntlmssp_state->ntlmssp_state->session_key.data) { - gensec_ntlmssp_state->have_features |= GENSEC_FEATURE_SESSION_KEY; - } - - return status; -} - -/** - * Return the credentials of a logged on user, including session keys - * etc. - * - * Only valid after a successful authentication - * - * May only be called once per authentication. - * - */ - -static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security, - struct auth_session_info **session_info) -{ - NTSTATUS nt_status; - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - - nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info); - NT_STATUS_NOT_OK_RETURN(nt_status); - - (*session_info)->session_key = data_blob_talloc(*session_info, - gensec_ntlmssp_state->ntlmssp_state->session_key.data, - gensec_ntlmssp_state->ntlmssp_state->session_key.length); - - return NT_STATUS_OK; -} - -static BOOL gensec_ntlmssp_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - if (gensec_ntlmssp_state->have_features & feature) { - return True; - } - - return False; -} - -static const struct gensec_security_ops gensec_ntlmssp_security_ops = { - .name = "ntlmssp", - .sasl_name = "NTLM", - .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, - .oid = GENSEC_OID_NTLMSSP, - .client_start = gensec_ntlmssp_client_start, - .server_start = gensec_ntlmssp_server_start, - .update = gensec_ntlmssp_update, - .sig_size = gensec_ntlmssp_sig_size, - .sign_packet = gensec_ntlmssp_sign_packet, - .check_packet = gensec_ntlmssp_check_packet, - .seal_packet = gensec_ntlmssp_seal_packet, - .unseal_packet = gensec_ntlmssp_unseal_packet, - .wrap = gensec_ntlmssp_wrap, - .unwrap = gensec_ntlmssp_unwrap, - .session_key = gensec_ntlmssp_session_key, - .session_info = gensec_ntlmssp_session_info, - .have_feature = gensec_ntlmssp_have_feature, - .enabled = True -}; - - -NTSTATUS gensec_ntlmssp_init(void) -{ - NTSTATUS ret; - ret = gensec_register(&gensec_ntlmssp_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_ntlmssp_security_ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/libcli/auth/gssapi_parse.c b/source4/libcli/auth/gssapi_parse.c deleted file mode 100644 index 89929c8c6d..0000000000 --- a/source4/libcli/auth/gssapi_parse.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - simple GSSAPI wrappers - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 - Copyright (C) Luke Howard 2003 - - 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 "asn_1.h" -#include "system/kerberos.h" -#include "libcli/auth/gensec.h" - -/* - generate a krb5 GSS-API wrapper packet given a ticket -*/ -DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2]) -{ - struct asn1_data data; - DATA_BLOB ret = data_blob(NULL,0); - - if (!ticket->data) { - return ret; - } - - ZERO_STRUCT(data); - - asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data, GENSEC_OID_KERBEROS5); - - asn1_write(&data, tok_id, 2); - asn1_write(&data, ticket->data, ticket->length); - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - ret = data_blob_talloc(mem_ctx, data.data, data.length); - asn1_free(&data); - - return ret; -} - -/* - parse a krb5 GSS-API wrapper packet giving a ticket -*/ -BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2]) -{ - BOOL ret; - struct asn1_data data; - int data_remaining; - - asn1_load(&data, *blob); - asn1_start_tag(&data, ASN1_APPLICATION(0)); - asn1_check_OID(&data, GENSEC_OID_KERBEROS5); - - data_remaining = asn1_tag_remaining(&data); - - if (data_remaining < 3) { - data.has_error = True; - } else { - asn1_read(&data, tok_id, 2); - data_remaining -= 2; - *ticket = data_blob_talloc(mem_ctx, NULL, data_remaining); - asn1_read(&data, ticket->data, ticket->length); - } - - asn1_end_tag(&data); - - ret = !data.has_error; - - asn1_free(&data); - - return ret; -} - - diff --git a/source4/libcli/auth/kerberos.c b/source4/libcli/auth/kerberos.c deleted file mode 100644 index 89b4108280..0000000000 --- a/source4/libcli/auth/kerberos.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - Unix SMB/CIFS implementation. - kerberos utility library - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Remus Koos 2001 - Copyright (C) Nalin Dahyabhai 2004. - Copyright (C) Jeremy Allison 2004. - Copyright (C) Andrew Bartlett 2004-2005 - - 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 "system/kerberos.h" -#include "system/time.h" -#include "libcli/auth/kerberos.h" -#include "secrets.h" -#include "pstring.h" -#include "ads.h" - -#ifdef HAVE_KRB5 - -#define LIBADS_CCACHE_NAME "MEMORY:libads" - -/* - we use a prompter to avoid a crash bug in the kerberos libs when - dealing with empty passwords - this prompter is just a string copy ... -*/ -static krb5_error_code -kerb_prompter(krb5_context ctx, void *data, - const char *name, - const char *banner, - int num_prompts, - krb5_prompt prompts[]) -{ - if (num_prompts == 0) return 0; - - memset(prompts[0].reply->data, '\0', prompts[0].reply->length); - if (prompts[0].reply->length > 0) { - if (data) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); - prompts[0].reply->length = strlen(prompts[0].reply->data); - } else { - prompts[0].reply->length = 0; - } - } - return 0; -} - -/* - simulate a kinit, putting the tgt in the given credentials cache. - Orignally by remus@snapserver.com -*/ - int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - const char *principal, const char *password, - time_t *expire_time, time_t *kdc_time) -{ - krb5_error_code code = 0; - krb5_principal me; - krb5_creds my_creds; - krb5_get_init_creds_opt options; - - if ((code = krb5_parse_name(ctx, principal, &me))) { - return code; - } - - krb5_get_init_creds_opt_init(&options); - - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, - kerb_prompter, - NULL, 0, NULL, &options))) { - krb5_free_principal(ctx, me); - return code; - } - - if ((code = krb5_cc_initialize(ctx, cc, me))) { - krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - return code; - } - - if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - return code; - } - - if (expire_time) { - *expire_time = (time_t) my_creds.times.endtime; - } - - if (kdc_time) { - *kdc_time = (time_t) my_creds.times.starttime; - } - - krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - - return 0; -} - -/* - simulate a kinit, putting the tgt in the given credentials cache. - If cache_name == NULL place in default cache location. - - Orignally by remus@snapserver.com -*/ -int kerberos_kinit_password(const char *principal, - const char *password, - int time_offset, - time_t *expire_time, - const char *cache_name, - time_t *kdc_time) -{ - int code; - krb5_context ctx = NULL; - krb5_ccache cc = NULL; - - if ((code = krb5_init_context(&ctx))) - return code; - - if (time_offset != 0) { - krb5_set_real_time(ctx, time(NULL) + time_offset, 0); - } - - if ((code = krb5_cc_resolve(ctx, cache_name ? - cache_name : krb5_cc_default_name(ctx), &cc))) { - krb5_free_context(ctx); - return code; - } - - code = kerberos_kinit_password_cc(ctx, cc, principal, password, expire_time, kdc_time); - - krb5_cc_close(ctx, cc); - krb5_free_context(ctx); - - return code; -} - -/* run kinit to setup our ccache */ -int ads_kinit_password(struct ads_struct *ads) -{ - char *s; - int ret; - - if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { - return KRB5_CC_NOMEM; - } - - if (!ads->auth.password) { - return KRB5_LIBOS_CANTREADPWD; - } - - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL, NULL); - - if (ret) { - DEBUG(0,("kerberos_kinit_password %s failed: %s\n", - s, error_message(ret))); - } - free(s); - return ret; -} - -int ads_kdestroy(const char *cc_name) -{ - krb5_error_code code; - krb5_context ctx = NULL; - krb5_ccache cc = NULL; - - if ((code = krb5_init_context (&ctx))) { - DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", - error_message(code))); - return code; - } - - if (!cc_name) { - if ((code = krb5_cc_default(ctx, &cc))) { - krb5_free_context(ctx); - return code; - } - } else { - if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n", - error_message(code))); - krb5_free_context(ctx); - return code; - } - } - - if ((code = krb5_cc_destroy (ctx, cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", - error_message(code))); - } - - krb5_free_context (ctx); - return code; -} - -/************************************************************************ - Routine to fetch the salting principal for a service. Active - Directory may use a non-obvious principal name to generate the salt - when it determines the key to use for encrypting tickets for a service, - and hopefully we detected that when we joined the domain. - ************************************************************************/ - -static char *kerberos_secrets_fetch_salting_principal(const char *service, int enctype) -{ - char *ret = NULL; - -#if 0 - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); - if (!key) { - return NULL; - } - ret = (char *)secrets_fetch(key, NULL); - SAFE_FREE(key); -#endif - return ret; -} - -/************************************************************************ - Routine to get the salting principal for this service. Active - Directory may use a non-obvious principal name to generate the salt - when it determines the key to use for encrypting tickets for a service, - and hopefully we detected that when we joined the domain. - Caller must free if return is not null. - ************************************************************************/ - -krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, - krb5_principal host_princ, - int enctype) -{ - char *unparsed_name = NULL, *salt_princ_s = NULL; - krb5_principal ret_princ = NULL; - - if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { - return (krb5_principal)NULL; - } - - if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { - krb5_free_unparsed_name(context, unparsed_name); - return (krb5_principal)NULL; - } - - if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { - krb5_free_unparsed_name(context, unparsed_name); - SAFE_FREE(salt_princ_s); - return (krb5_principal)NULL; - } - krb5_free_unparsed_name(context, unparsed_name); - SAFE_FREE(salt_princ_s); - return ret_princ; -} - -/************************************************************************ - Routine to set the salting principal for this service. Active - Directory may use a non-obvious principal name to generate the salt - when it determines the key to use for encrypting tickets for a service, - and hopefully we detected that when we joined the domain. - Setting principal to NULL deletes this entry. - ************************************************************************/ - - BOOL kerberos_secrets_store_salting_principal(const char *service, - int enctype, - const char *principal) -{ - char *key = NULL; - BOOL ret = False; - krb5_context context = NULL; - krb5_principal princ = NULL; - char *princ_s = NULL; - char *unparsed_name = NULL; - - krb5_init_context(&context); - if (!context) { - return False; - } - if (strchr_m(service, '@')) { - asprintf(&princ_s, "%s", service); - } else { - asprintf(&princ_s, "%s@%s", service, lp_realm()); - } - - if (krb5_parse_name(context, princ_s, &princ) != 0) { - goto out; - - } - if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { - goto out; - } - - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); - if (!key) { - goto out; - } - -#if 0 - if ((principal != NULL) && (strlen(principal) > 0)) { - ret = secrets_store(key, principal, strlen(principal) + 1); - } else { - ret = secrets_delete(key); - } -#endif - - out: - - SAFE_FREE(key); - SAFE_FREE(princ_s); - - if (unparsed_name) { - krb5_free_unparsed_name(context, unparsed_name); - } - if (context) { - krb5_free_context(context); - } - - return ret; -} - -/************************************************************************ - Routine to get initial credentials as a service ticket for the local machine. - Returns a buffer initialized with krb5_mk_req_extended. - ************************************************************************/ - -static krb5_error_code get_service_ticket(krb5_context ctx, - krb5_ccache ccache, - const char *service_principal, - int enctype, - krb5_data *p_outbuf) -{ - krb5_creds creds, *new_creds = NULL; - char *service_s = NULL; - char *machine_account = NULL, *password = NULL; - krb5_data in_data; - krb5_auth_context auth_context = NULL; - krb5_error_code err = 0; - - ZERO_STRUCT(creds); - - asprintf(&machine_account, "%s$@%s", lp_netbios_name(), lp_realm()); - if (machine_account == NULL) { - goto out; - } - password = secrets_fetch_machine_password(lp_workgroup()); - if (password == NULL) { - goto out; - } - if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME, NULL)) != 0) { - DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", - machine_account, - lp_realm(), - error_message(err))); - goto out; - } - - /* Ok - the above call has gotten a TGT. Now we need to get a service - ticket to ourselves. */ - - /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ - kerberos_set_creds_enctype(&creds, enctype); - - if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { - DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", - error_message(err))); - goto out; - } - - if (strchr_m(service_principal, '@')) { - asprintf(&service_s, "%s", service_principal); - } else { - asprintf(&service_s, "%s@%s", service_principal, lp_realm()); - } - - if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { - DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", - service_s, error_message(err))); - goto out; - } - - if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { - DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", - service_s, enctype, error_message(err))); - goto out; - } - - memset(&in_data, '\0', sizeof(in_data)); - if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, - new_creds, p_outbuf)) != 0) { - DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", - error_message(err))); - goto out; - } - - out: - - if (auth_context) { - krb5_auth_con_free(ctx, auth_context); - } - if (new_creds) { - krb5_free_creds(ctx, new_creds); - } - if (creds.server) { - krb5_free_principal(ctx, creds.server); - } - if (creds.client) { - krb5_free_principal(ctx, creds.client); - } - - SAFE_FREE(service_s); - SAFE_FREE(password); - SAFE_FREE(machine_account); - return err; -} - -/************************************************************************ - Check if the machine password can be used in conjunction with the salting_principal - to generate a key which will successfully decrypt the AP_REQ already - gotten as a message to the local machine. - ************************************************************************/ - -static BOOL verify_service_password(krb5_context ctx, - int enctype, - const char *salting_principal, - krb5_data *in_data) -{ - BOOL ret = False; - krb5_principal salting_kprinc = NULL; - krb5_ticket *ticket = NULL; - krb5_keyblock key; - krb5_data passdata; - char *salting_s = NULL; - char *password = NULL; - krb5_auth_context auth_context = NULL; - krb5_error_code err; - - memset(&passdata, '\0', sizeof(passdata)); - memset(&key, '\0', sizeof(key)); - - password = secrets_fetch_machine_password(lp_workgroup()); - if (password == NULL) { - goto out; - } - - if (strchr_m(salting_principal, '@')) { - asprintf(&salting_s, "%s", salting_principal); - } else { - asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); - } - - if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { - DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", - salting_s, error_message(err))); - goto out; - } - - passdata.length = strlen(password); - passdata.data = (char*)password; - if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { - DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", - enctype, error_message(err))); - goto out; - } - - if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { - DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); - goto out; - } - - if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { - DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); - goto out; - } - - if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { - DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", - (unsigned int)enctype, salting_s)); - ret = True; - } - - out: - - memset(&passdata, 0, sizeof(passdata)); - krb5_free_keyblock_contents(ctx, &key); - if (ticket != NULL) { - krb5_free_ticket(ctx, ticket); - } - if (salting_kprinc) { - krb5_free_principal(ctx, salting_kprinc); - } - SAFE_FREE(salting_s); - SAFE_FREE(password); - return ret; -} - -/************************************************************************ - * - * From the current draft of kerberos-clarifications: - * - * It is not possible to reliably generate a user's key given a pass - * phrase without contacting the KDC, since it will not be known - * whether alternate salt or parameter values are required. - * - * And because our server has a password, we have this exact problem. We - * make multiple guesses as to which principal name provides the salt which - * the KDC is using. - * - ************************************************************************/ - -static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, - krb5_context ctx, - krb5_ccache ccache, - krb5_enctype enctype, - krb5_enctype *enctypes) -{ - char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; - krb5_error_code err = 0; - krb5_data outbuf; - int i, j; - - memset(&outbuf, '\0', sizeof(outbuf)); - - /* Check that the service_principal is useful. */ - if ((service_principal == NULL) || (strlen(service_principal) == 0)) { - return; - } - - /* Generate our first guess -- the principal as-given. */ - asprintf(&salting_principals[0], "%s", service_principal); - if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { - return; - } - - /* Generate our second guess -- the computer's principal, as Win2k3. */ - asprintf(&second_principal, "host/%s.%s", lp_netbios_name(), lp_realm()); - if (second_principal != NULL) { - strlower_m(second_principal); - asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); - SAFE_FREE(second_principal); - } - if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { - goto out; - } - - /* Generate our third guess -- the computer's principal, as Win2k. */ - asprintf(&second_principal, "HOST/%s", lp_netbios_name()); - if (second_principal != NULL) { - strlower_m(second_principal + 5); - asprintf(&salting_principals[2], "%s@%s", - second_principal, lp_realm()); - SAFE_FREE(second_principal); - } - if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { - goto out; - } - - /* Get a service ticket for ourselves into our memory ccache. */ - /* This will commonly fail if there is no principal by that name (and we're trying - many names). So don't print a debug 0 error. */ - - if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { - DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", - error_message(err))); - goto out; - } - - /* At this point we have a message to ourselves, salted only the KDC knows how. We - have to work out what that salting is. */ - - /* Try and find the correct salting principal. */ - for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { - if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { - break; - } - } - - /* If we failed to get a match, return. */ - if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { - goto out; - } - - /* If we succeeded, store the principal for use for all enctypes which - * share the same cipher and string-to-key function. Doing this here - * allows servers which just pass a keytab to krb5_rd_req() to work - * correctly. */ - for (j = 0; enctypes[j] != 0; j++) { - if (enctype != enctypes[j]) { - /* If this enctype isn't compatible with the one which - * we used, skip it. */ - - if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) - continue; - } - /* If the principal which gives us the proper salt is the one - * which we would normally guess, don't bother noting anything - * in the secrets tdb. */ - if (strcmp(service_principal, salting_principals[i]) != 0) { - kerberos_secrets_store_salting_principal(service_principal, - enctypes[j], - salting_principals[i]); - } - } - - out : - - kerberos_free_data_contents(ctx, &outbuf); - SAFE_FREE(salting_principals[0]); - SAFE_FREE(salting_principals[1]); - SAFE_FREE(salting_principals[2]); - SAFE_FREE(second_principal); -} - -/************************************************************************ - Go through all the possible enctypes for this principal. - ************************************************************************/ - -static void kerberos_derive_salting_principal_direct(krb5_context context, - krb5_ccache ccache, - krb5_enctype *enctypes, - char *service_principal) -{ - int i; - - /* Try for each enctype separately, because the rules are - * different for different enctypes. */ - for (i = 0; enctypes[i] != 0; i++) { - /* Delete secrets entry first. */ - kerberos_secrets_store_salting_principal(service_principal, 0, NULL); -#ifdef ENCTYPE_ARCFOUR_HMAC - if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { - /* Of course this'll always work, so just save - * ourselves the effort. */ - continue; - } -#endif - /* Try to figure out what's going on with this - * principal. */ - kerberos_derive_salting_principal_for_enctype(service_principal, - context, - ccache, - enctypes[i], - enctypes); - } -} - -/************************************************************************ - Wrapper function for the above. - ************************************************************************/ - -BOOL kerberos_derive_salting_principal(char *service_principal) -{ - krb5_context context = NULL; - krb5_enctype *enctypes = NULL; - krb5_ccache ccache = NULL; - krb5_error_code ret = 0; - - initialize_krb5_error_table(); - if ((ret = krb5_init_context(&context)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", - error_message(ret))); - return False; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", - error_message(ret))); - goto out; - } - - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - goto out; - } - - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); - - out: - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - if (ccache) { - krb5_cc_destroy(context, ccache); - } - if (context) { - krb5_free_context(context); - } - - return ret ? False : True; -} - -/************************************************************************ - Core function to try and determine what salt is being used for any keytab - keys. - ************************************************************************/ - -BOOL kerberos_derive_cifs_salting_principals(void) -{ - fstring my_fqdn; - char *service = NULL; - krb5_context context = NULL; - krb5_enctype *enctypes = NULL; - krb5_ccache ccache = NULL; - krb5_error_code ret = 0; - BOOL retval = False; - - initialize_krb5_error_table(); - if ((ret = krb5_init_context(&context)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", - error_message(ret))); - return False; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", - error_message(ret))); - goto out; - } - - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - goto out; - } - - if (asprintf(&service, "%s$", lp_netbios_name()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "cifs/%s", lp_netbios_name()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s", lp_netbios_name()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "cifs/%s.%s", lp_netbios_name(), lp_realm()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s.%s", lp_netbios_name(), lp_realm()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - name_to_fqdn(my_fqdn, lp_netbios_name()); - if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s", my_fqdn) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - - retval = True; - - out: - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - if (ccache) { - krb5_cc_destroy(context, ccache); - } - if (context) { - krb5_free_context(context); - } - return retval; -} -#endif diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h deleted file mode 100644 index 4daf0ea07a..0000000000 --- a/source4/libcli/auth/kerberos.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5 routines for active directory - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002-2003 - - 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. -*/ - -#if defined(HAVE_KRB5) - -/* not really ASN.1, but RFC 1964 */ -#define TOK_ID_KRB_AP_REQ "\x01\x00" -#define TOK_ID_KRB_AP_REP "\x02\x00" -#define TOK_ID_KRB_ERROR "\x03\x00" -#define TOK_ID_GSS_GETMIC "\x01\x01" -#define TOK_ID_GSS_WRAP "\x02\x01" - -#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE -#define KRB5_KEY_TYPE(k) ((k)->keytype) -#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) -#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -#else -#define KRB5_KEY_TYPE(k) ((k)->enctype) -#define KRB5_KEY_LENGTH(k) ((k)->length) -#define KRB5_KEY_DATA(k) ((k)->contents) -#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ - -#ifndef HAVE_KRB5_SET_REAL_TIME -krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds); -#endif - -#ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES -krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc); -#endif - -#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) -krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock); -#endif - -#ifndef HAVE_KRB5_FREE_UNPARSED_NAME -void krb5_free_unparsed_name(krb5_context ctx, char *val); -#endif - -#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) -const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ); -#endif - -/* Samba wrapper function for krb5 functionality. */ -void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr); -int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); -int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); -krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); -krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); -void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); -BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote); -krb5_error_code ads_krb5_mk_req(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf); -DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, - krb5_ticket *tkt); - -NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, - krb5_context context, - krb5_auth_context auth_context, - const char *realm, const char *service, - const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep, - krb5_keyblock *keyblock); -int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - const char *principal, const char *password, - time_t *expire_time, time_t *kdc_time); -krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, - krb5_principal host_princ, - int enctype); -void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype); -BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2); -void kerberos_free_data_contents(krb5_context context, krb5_data *pdata); -krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry); -char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx); -#endif /* HAVE_KRB5 */ - diff --git a/source4/libcli/auth/kerberos_verify.c b/source4/libcli/auth/kerberos_verify.c deleted file mode 100644 index a1dfe1056e..0000000000 --- a/source4/libcli/auth/kerberos_verify.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - Unix SMB/CIFS implementation. - kerberos utility library - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Remus Koos 2001 - Copyright (C) Luke Howard 2003 - Copyright (C) Guenther Deschner 2003 - Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 - Copyright (C) Andrew Bartlett 2004-2005 - - 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 "system/kerberos.h" -#include "libcli/auth/kerberos.h" -#include "asn_1.h" -#include "lib/ldb/include/ldb.h" -#include "secrets.h" -#include "pstring.h" - -#ifdef HAVE_KRB5 - -#if !defined(HAVE_KRB5_PRINC_COMPONENT) -const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int ); -#endif -static DATA_BLOB unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data) -{ - DATA_BLOB out; - DATA_BLOB pac_contents = data_blob(NULL, 0); - struct asn1_data data; - int data_type; - if (!auth_data->length) { - return data_blob(NULL, 0); - } - - asn1_load(&data, *auth_data); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_Integer(&data, &data_type); - asn1_end_tag(&data); - asn1_start_tag(&data, ASN1_CONTEXT(1)); - asn1_read_OctetString(&data, &pac_contents); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_free(&data); - - out = data_blob_talloc(mem_ctx, pac_contents.data, pac_contents.length); - - data_blob_free(&pac_contents); - - return out; -} - -/********************************************************************************** - Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so - it's more like what microsoft does... see comment in utils/net_ads.c in the - ads_keytab_add_entry function for details. -***********************************************************************************/ - -static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, - krb5_auth_context auth_context, - const char *service, - const DATA_BLOB *ticket, krb5_data *p_packet, - krb5_ticket **pp_tkt, - krb5_keyblock *keyblock) -{ - krb5_error_code ret = 0; - krb5_keytab keytab = NULL; - krb5_kt_cursor kt_cursor; - krb5_keytab_entry kt_entry; - char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - char *entry_princ_s = NULL; - const char *my_name, *my_fqdn; - int i; - int number_matched_principals = 0; - const char *last_error_message; - - /* Generate the list of principal names which we expect - * clients might want to use for authenticating to the file - * service. We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */ - - my_name = lp_netbios_name(); - - my_fqdn = name_to_fqdn(mem_ctx, my_name); - - asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm()); - asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm()); - asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm()); - asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); - asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm()); - asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm()); - asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); - - ZERO_STRUCT(kt_entry); - ZERO_STRUCT(kt_cursor); - - ret = krb5_kt_default(context, &keytab); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", - smb_get_krb5_error_message(context, ret, mem_ctx))); - goto out; - } - - /* Iterate through the keytab. For each key, if the principal - * name case-insensitively matches one of the allowed formats, - * try verifying the ticket using that principal. */ - - ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); - if (ret) { - last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", - last_error_message)); - goto out; - } - - ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); - if (ret != KRB5_KT_END && ret != ENOENT ) { - ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; /* Pick an error... */ - while (ret && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { - krb5_error_code upn_ret; - upn_ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); - if (upn_ret) { - last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); - DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", - last_error_message)); - ret = upn_ret; - break; - } - for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) { - if (!strequal(entry_princ_s, valid_princ_formats[i])) { - continue; - } - - number_matched_principals++; - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - *pp_tkt = NULL; - ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); - if (ret) { - last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); - DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", - entry_princ_s, last_error_message)); - } else { - DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", - entry_princ_s)); - break; - } - } - - /* Free the name we parsed. */ - krb5_free_unparsed_name(context, entry_princ_s); - entry_princ_s = NULL; - - /* Free the entry we just read. */ - smb_krb5_kt_free_entry(context, &kt_entry); - ZERO_STRUCT(kt_entry); - } - krb5_kt_end_seq_get(context, keytab, &kt_cursor); - } - - ZERO_STRUCT(kt_cursor); - - out: - - if (ret) { - if (!number_matched_principals) { - DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n")); - } else { - DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n", - number_matched_principals)); - } - DEBUG(3, ("ads_keytab_verify_ticket: last error: %s\n", last_error_message)); - } - - if (entry_princ_s) { - krb5_free_unparsed_name(context, entry_princ_s); - } - - { - krb5_keytab_entry zero_kt_entry; - ZERO_STRUCT(zero_kt_entry); - if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - smb_krb5_kt_free_entry(context, &kt_entry); - } - } - - { - krb5_kt_cursor zero_csr; - ZERO_STRUCT(zero_csr); - if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { - krb5_kt_end_seq_get(context, keytab, &kt_cursor); - } - } - - if (keytab) { - krb5_kt_close(context, keytab); - } - - return ret; -} - -/********************************************************************************** - Try to verify a ticket using the secrets.tdb. -***********************************************************************************/ - -static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, - krb5_auth_context auth_context, - krb5_principal host_princ, - const DATA_BLOB *ticket, krb5_data *p_packet, - krb5_ticket **pp_tkt, - krb5_keyblock *keyblock) -{ - krb5_error_code ret = 0; - krb5_error_code our_ret; - krb5_data password; - krb5_enctype *enctypes = NULL; - int i; - const struct ldb_val *password_v; - struct ldb_context *ldb; - int ldb_ret; - struct ldb_message **msgs; - const char *base_dn = SECRETS_PRIMARY_DOMAIN_DN; - const char *attrs[] = { - "secret", - NULL - }; - - ZERO_STRUCTP(keyblock); - - /* Local secrets are stored in secrets.ldb */ - ldb = secrets_db_connect(mem_ctx); - if (!ldb) { - return ENOENT; - } - - /* search for the secret record */ - ldb_ret = gendb_search(ldb, - mem_ctx, base_dn, &msgs, attrs, - SECRETS_PRIMARY_REALM_FILTER, - lp_realm()); - if (ldb_ret == 0) { - DEBUG(1, ("Could not find domain join record for %s\n", - lp_realm())); - return ENOENT; - } else if (ldb_ret != 1) { - DEBUG(1, ("Found %d records matching cn=%s under DN %s\n", ldb_ret, - lp_realm(), base_dn)); - return ENOENT; - } - - password_v = ldb_msg_find_ldb_val(msgs[0], "secret"); - - password.data = password_v->data; - password.length = password_v->length; - - /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ - - if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { - DEBUG(1,("ads_secrets_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); - return ret; - } - - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - - /* We need to setup a auth context with each possible encoding type in turn. */ - - ret = KRB5_BAD_ENCTYPE; - for (i=0;enctypes[i];i++) { - krb5_keyblock *key = NULL; - - if (!(key = malloc_p(krb5_keyblock))) { - break; - } - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { - SAFE_FREE(key); - continue; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - krb5_free_keyblock(context, key); - - our_ret = krb5_rd_req(context, &auth_context, p_packet, - NULL, - NULL, NULL, pp_tkt); - if (!our_ret) { - - DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", - (unsigned int)enctypes[i] )); - ret = our_ret; - break; - } - - DEBUG((our_ret != KRB5_BAD_ENCTYPE) ? 3 : 10, - ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", - (unsigned int)enctypes[i], smb_get_krb5_error_message(context, our_ret, mem_ctx))); - - if (our_ret != KRB5_BAD_ENCTYPE) { - ret = our_ret; - } - } - - free_kerberos_etypes(context, enctypes); - - return ret; -} - -/********************************************************************************** - Verify an incoming ticket and parse out the principal name and - authorization_data if available. -***********************************************************************************/ - - NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, - krb5_context context, - krb5_auth_context auth_context, - const char *realm, const char *service, - const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data, - DATA_BLOB *ap_rep, - krb5_keyblock *keyblock) -{ - NTSTATUS sret = NT_STATUS_LOGON_FAILURE; - krb5_data packet; - krb5_ticket *tkt = NULL; - krb5_rcache rcache = NULL; - int ret; - - krb5_principal host_princ = NULL; - char *host_princ_s = NULL; - BOOL got_replay_mutex = False; - - char *malloc_principal; - - ZERO_STRUCT(packet); - ZERO_STRUCTP(auth_data); - ZERO_STRUCTP(ap_rep); - - /* This whole process is far more complex than I would - like. We have to go through all this to allow us to store - the secret internally, instead of using /etc/krb5.keytab */ - - asprintf(&host_princ_s, "%s$", lp_netbios_name()); - strlower_m(host_princ_s); - ret = krb5_parse_name(context, host_princ_s, &host_princ); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", - host_princ_s, error_message(ret))); - goto out; - } - - - /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 - * code surrounding the replay cache... */ - - if (!grab_server_mutex("replay cache mutex")) { - DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); - goto out; - } - - got_replay_mutex = True; - - /* - * JRA. We must set the rcache here. This will prevent replay attacks. - */ - - ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); - goto out; - } - - ret = krb5_auth_con_setrcache(context, auth_context, rcache); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); - goto out; - } - - ret = ads_keytab_verify_ticket(mem_ctx, context, auth_context, - service, ticket, &packet, &tkt, keyblock); - if (ret) { - DEBUG(10, ("ads_secrets_verify_ticket: using host principal: [%s]\n", host_princ_s)); - ret = ads_secrets_verify_ticket(mem_ctx, context, auth_context, - host_princ, ticket, - &packet, &tkt, keyblock); - } - - release_server_mutex(); - got_replay_mutex = False; - - if (ret) { - DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", - smb_get_krb5_error_message(context, ret, mem_ctx))); - goto out; - } - - ret = krb5_mk_rep(context, auth_context, &packet); - if (ret) { - DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", - smb_get_krb5_error_message(context, ret, mem_ctx))); - goto out; - } - - *ap_rep = data_blob_talloc(mem_ctx, packet.data, packet.length); - SAFE_FREE(packet.data); - packet.length = 0; - -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - *auth_data = get_auth_data_from_tkt(mem_ctx, tkt); - - *auth_data = unwrap_pac(mem_ctx, auth_data); - -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif - - if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), - &malloc_principal))) { - DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", - smb_get_krb5_error_message(context, ret, mem_ctx))); - sret = NT_STATUS_LOGON_FAILURE; - goto out; - } - - *principal = talloc_strdup(mem_ctx, malloc_principal); - SAFE_FREE(malloc_principal); - if (!principal) { - DEBUG(3,("ads_verify_ticket: talloc_strdup() failed\n")); - sret = NT_STATUS_NO_MEMORY; - goto out; - } - - sret = NT_STATUS_OK; - - out: - - if (got_replay_mutex) { - release_server_mutex(); - } - - if (!NT_STATUS_IS_OK(sret)) { - data_blob_free(auth_data); - } - - if (!NT_STATUS_IS_OK(sret)) { - data_blob_free(ap_rep); - } - - if (host_princ) { - krb5_free_principal(context, host_princ); - } - - if (tkt != NULL) { - krb5_free_ticket(context, tkt); - } - - SAFE_FREE(host_princ_s); - - return sret; -} - -#endif /* HAVE_KRB5 */ diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c deleted file mode 100644 index 37374d9d39..0000000000 --- a/source4/libcli/auth/ntlmssp.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 3.0 - handle NLTMSSP, client server side parsing - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2005 - - 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 "auth/auth.h" -#include "lib/crypto/crypto.h" -#include "pstring.h" - -static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out); -static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out); -static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out); -static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out); - -/** - * Callbacks for NTLMSSP - for both client and server operating modes - * - */ - -static const struct ntlmssp_callbacks { - enum ntlmssp_role role; - enum ntlmssp_message_type ntlmssp_command; - NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out); -} ntlmssp_callbacks[] = { - {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial}, - {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate}, - {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge}, - {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth}, - {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL}, - {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL} -}; - - -/** - * Print out the NTLMSSP flags for debugging - * @param neg_flags The flags from the packet - */ - -void debug_ntlmssp_flags(uint32_t neg_flags) -{ - DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); -} - -/** - * Default challenge generation code. - * - */ - -static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state) -{ - uint8_t *chal = talloc_size(ntlmssp_state, 8); - generate_random_buffer(chal, 8); - - return chal; -} - -/** - * Default 'we can set the challenge to anything we like' implementation - * - */ - -static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state) -{ - return True; -} - -/** - * Default 'we can set the challenge to anything we like' implementation - * - * Does not actually do anything, as the value is always in the structure anyway. - * - */ - -static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) -{ - SMB_ASSERT(challenge->length == 8); - return NT_STATUS_OK; -} - -/** - * Set a username on an NTLMSSP context - ensures it is talloc()ed - * - */ - -NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) -{ - if (!user) { - /* it should be at least "" */ - DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n")); - return NT_STATUS_INVALID_PARAMETER; - } - ntlmssp_state->user = talloc_strdup(ntlmssp_state, user); - if (!ntlmssp_state->user) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set a password on an NTLMSSP context - ensures it is talloc()ed - * - */ -NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) -{ - if (!password) { - ntlmssp_state->password = NULL; - } else { - ntlmssp_state->password = talloc_strdup(ntlmssp_state, password); - if (!ntlmssp_state->password) { - return NT_STATUS_NO_MEMORY; - } - } - return NT_STATUS_OK; -} - -/** - * Set a domain on an NTLMSSP context - ensures it is talloc()ed - * - */ -NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) -{ - ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain); - if (!ntlmssp_state->domain) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set a workstation on an NTLMSSP context - ensures it is talloc()ed - * - */ -NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) -{ - ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation); - if (!ntlmssp_state->workstation) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Store a DATA_BLOB containing an NTLMSSP response, for use later. - * This copies the data blob - */ - -NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB response) -{ - ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state, - response.data, response.length); - return NT_STATUS_OK; -} - -/** - * Next state function for the NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, - * or NT_STATUS_OK if the user is authenticated. - */ - -NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - DATA_BLOB input; - uint32_t ntlmssp_command; - int i; - - *out = data_blob(NULL, 0); - - if (ntlmssp_state->expected_state == NTLMSSP_DONE) { - return NT_STATUS_OK; - } - - if (!out_mem_ctx) { - /* if the caller doesn't want to manage/own the memory, - we can put it on our context */ - out_mem_ctx = ntlmssp_state; - } - - if (!in.length && ntlmssp_state->stored_response.length) { - input = ntlmssp_state->stored_response; - - /* we only want to read the stored response once - overwrite it */ - ntlmssp_state->stored_response = data_blob(NULL, 0); - } else { - input = in; - } - - if (!input.length) { - switch (ntlmssp_state->role) { - case NTLMSSP_CLIENT: - ntlmssp_command = NTLMSSP_INITIAL; - break; - case NTLMSSP_SERVER: - /* 'datagram' mode - no neg packet */ - ntlmssp_command = NTLMSSP_NEGOTIATE; - break; - } - } else { - if (!msrpc_parse(ntlmssp_state, - &input, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); - dump_data(2, input.data, input.length); - return NT_STATUS_INVALID_PARAMETER; - } - } - - if (ntlmssp_command != ntlmssp_state->expected_state) { - DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } - - for (i=0; ntlmssp_callbacks[i].fn; i++) { - if (ntlmssp_callbacks[i].role == ntlmssp_state->role - && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command - && ntlmssp_callbacks[i].fn) { - return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out); - } - } - - DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", - ntlmssp_state->role, ntlmssp_command)); - - return NT_STATUS_INVALID_PARAMETER; -} - -/** - * Return the NTLMSSP master session key - * - * @param ntlmssp_state NTLMSSP State - */ - -NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB *session_key) -{ - if (!ntlmssp_state->session_key.data) { - return NT_STATUS_NO_USER_SESSION_KEY; - } - *session_key = ntlmssp_state->session_key; - - return NT_STATUS_OK; -} - -/** - * End an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, free()ed by this function - */ - -void ntlmssp_end(struct ntlmssp_state **ntlmssp_state) -{ - (*ntlmssp_state)->ref_count--; - - if ((*ntlmssp_state)->ref_count == 0) { - talloc_free(*ntlmssp_state); - } - - *ntlmssp_state = NULL; - return; -} - -/** - * Determine correct target name flags for reply, given server role - * and negotiated flags - * - * @param ntlmssp_state NTLMSSP State - * @param neg_flags The flags from the packet - * @param chal_flags The flags to be set in the reply packet - * @return The 'target name' string. - */ - -static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, - uint32_t neg_flags, uint32_t *chal_flags) -{ - if (neg_flags & NTLMSSP_REQUEST_TARGET) { - *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; - *chal_flags |= NTLMSSP_REQUEST_TARGET; - if (ntlmssp_state->server_role == ROLE_STANDALONE) { - *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; - return ntlmssp_state->server_name; - } else { - *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; - return ntlmssp_state->get_domain(); - }; - } else { - return ""; - } -} - -static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32_t neg_flags, BOOL allow_lm) { - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; - ntlmssp_state->unicode = True; - } else { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - ntlmssp_state->unicode = False; - } - - if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) { - /* other end forcing us to use LM */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } else { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } - - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; - } - - if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; - } - - if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; - } - - if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } - - if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; - if (neg_flags & NTLMSSP_NEGOTIATE_56) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; - } - } - - if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56; - } - - if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; - } - - if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { - ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; - } - -} - -/** - Weaken NTLMSSP keys to cope with down-level clients and servers. - - We probably should have some parameters to control this, but as - it only occours for LM_KEY connections, and this is controlled - by the client lanman auth/lanman auth parameters, it isn't too bad. -*/ - -static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) { - /* Key weakening not performed on the master key for NTLM2 - and does not occour for NTLM1. Therefore we only need - to do this for the LM_KEY. - */ - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { - - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { - ntlmssp_state->session_key.data[7] = 0xa0; - } else { /* forty bits */ - ntlmssp_state->session_key.data[5] = 0xe5; - ntlmssp_state->session_key.data[6] = 0x38; - ntlmssp_state->session_key.data[7] = 0xb0; - } - ntlmssp_state->session_key.length = 8; - } -} - -/** - * Next state function for the Negotiate packet - * - * @param ntlmssp_state NTLMSSP State - * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on - * @param in The request, as a DATA_BLOB - * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx - * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. - */ - -static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - DATA_BLOB struct_blob; - fstring dnsname, dnsdomname; - uint32_t neg_flags = 0; - uint32_t ntlmssp_command, chal_flags; - char *cliname=NULL, *domname=NULL; - const uint8_t *cryptkey; - const char *target_name; - - /* parse the NTLMSSP packet */ -#if 0 - file_save("ntlmssp_negotiate.dat", request.data, request.length); -#endif - - if (in.length) { - if (!msrpc_parse(ntlmssp_state, - &in, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); - dump_data(2, in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; - } - - debug_ntlmssp_flags(neg_flags); - } - - ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key); - - /* Ask our caller what challenge they would like in the packet */ - cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); - - /* Check if we may set the challenge */ - if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } - - /* The flags we send back are not just the negotiated flags, - * they are also 'what is in this packet'. Therfore, we - * operate on 'chal_flags' from here on - */ - - chal_flags = ntlmssp_state->neg_flags; - - /* get the right name to fill in as 'target' */ - target_name = ntlmssp_target_name(ntlmssp_state, - neg_flags, &chal_flags); - if (target_name == NULL) - return NT_STATUS_INVALID_PARAMETER; - - ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); - ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); - - /* This should be a 'netbios domain -> DNS domain' mapping */ - dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); - strlower_m(dnsdomname); - - dnsname[0] = '\0'; - get_myfullname(dnsname); - - /* This creates the 'blob' of names that appears at the end of the packet */ - if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) - { - const char *target_name_dns = ""; - if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { - target_name_dns = dnsdomname; - } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { - target_name_dns = dnsname; - } - - msrpc_gen(out_mem_ctx, - &struct_blob, "aaaaa", - NTLMSSP_NAME_TYPE_DOMAIN, target_name, - NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name, - NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, - NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, - 0, ""); - } else { - struct_blob = data_blob(NULL, 0); - } - - { - /* Marshel the packet in the right format, be it unicode or ASCII */ - const char *gen_string; - if (ntlmssp_state->unicode) { - gen_string = "CdUdbddB"; - } else { - gen_string = "CdAdbddB"; - } - - msrpc_gen(out_mem_ctx, - out, gen_string, - "NTLMSSP", - NTLMSSP_CHALLENGE, - target_name, - chal_flags, - cryptkey, 8, - 0, 0, - struct_blob.data, struct_blob.length); - } - - ntlmssp_state->expected_state = NTLMSSP_AUTH; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -/** - * Next state function for the Authenticate packet - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB request) -{ - uint32_t ntlmssp_command, auth_flags; - NTSTATUS nt_status; - - uint8_t session_nonce_hash[16]; - - const char *parse_string; - char *domain = NULL; - char *user = NULL; - char *workstation = NULL; - -#if 0 - file_save("ntlmssp_auth.dat", request.data, request.length); -#endif - - if (ntlmssp_state->unicode) { - parse_string = "CdBBUUUBd"; - } else { - parse_string = "CdBBAAABd"; - } - - /* zero these out */ - data_blob_free(&ntlmssp_state->lm_resp); - data_blob_free(&ntlmssp_state->nt_resp); - - ntlmssp_state->user = NULL; - ntlmssp_state->domain = NULL; - ntlmssp_state->workstation = NULL; - - /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state, - &request, parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation, - &ntlmssp_state->encrypted_session_key, - &auth_flags)) { - DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); - dump_data(10, request.data, request.length); - - /* zero this out */ - data_blob_free(&ntlmssp_state->encrypted_session_key); - auth_flags = 0; - - /* Try again with a shorter string (Win9X truncates this packet) */ - if (ntlmssp_state->unicode) { - parse_string = "CdBBUUU"; - } else { - parse_string = "CdBBAAA"; - } - - /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state, - &request, parse_string, - "NTLMSSP", - &ntlmssp_command, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation)) { - DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); - dump_data(2, request.data, request.length); - - return NT_STATUS_INVALID_PARAMETER; - } - } - - if (auth_flags) - ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key); - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { - /* zero this out */ - data_blob_free(&ntlmssp_state->encrypted_session_key); - return nt_status; - } - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - /* zero this out */ - data_blob_free(&ntlmssp_state->encrypted_session_key); - return nt_status; - } - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { - /* zero this out */ - data_blob_free(&ntlmssp_state->encrypted_session_key); - return nt_status; - } - - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", - ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); - -#if 0 - file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); - file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); -#endif - - /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a - client challenge - - However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful. - */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) { - struct MD5Context md5_session_nonce_ctx; - SMB_ASSERT(ntlmssp_state->internal_chal.data - && ntlmssp_state->internal_chal.length == 8); - - ntlmssp_state->doing_ntlm2 = True; - - memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8); - memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8); - - MD5Init(&md5_session_nonce_ctx); - MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16); - MD5Final(session_nonce_hash, &md5_session_nonce_ctx); - - ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, - session_nonce_hash, 8); - - /* LM response is no longer useful, zero it out */ - data_blob_free(&ntlmssp_state->lm_resp); - - /* We changed the effective challenge - set it */ - if (!NT_STATUS_IS_OK(nt_status = - ntlmssp_state->set_challenge(ntlmssp_state, - &ntlmssp_state->chal))) { - /* zero this out */ - data_blob_free(&ntlmssp_state->encrypted_session_key); - return nt_status; - } - - /* LM Key is incompatible... */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } - } - return NT_STATUS_OK; -} - -/** - * Next state function for the Authenticate packet - * (after authentication - figures out the session keys etc) - * - * @param ntlmssp_state NTLMSSP State - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB *user_session_key, - DATA_BLOB *lm_session_key) -{ - NTSTATUS nt_status; - DATA_BLOB session_key = data_blob(NULL, 0); - - if (user_session_key) - dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length); - - if (lm_session_key) - dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length); - - /* Handle the different session key derivation for NTLM2 */ - if (ntlmssp_state->doing_ntlm2) { - if (user_session_key && user_session_key->data && user_session_key->length == 16) { - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - hmac_md5(user_session_key->data, ntlmssp_state->session_nonce, - sizeof(ntlmssp_state->session_nonce), session_key.data); - DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); - dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - - } else { - DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); - session_key = data_blob(NULL, 0); - } - } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - /* Ensure we can never get here on NTLMv2 */ - && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) { - - if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) { - if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data, - session_key.data); - DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); - } else { - - /* When there is no LM response, just use zeros */ - static const uint8_t zeros[24]; - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - SMBsesskeygen_lm_sess_key(zeros, zeros, - session_key.data); - DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); - } - } else { - /* LM Key not selected */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - - DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); - session_key = data_blob(NULL, 0); - } - - } else if (user_session_key && user_session_key->data) { - session_key = *user_session_key; - DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); - dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); - - /* LM Key not selected */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - - } else if (lm_session_key && lm_session_key->data) { - /* Very weird to have LM key, but no user session key, but anyway.. */ - session_key = *lm_session_key; - DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); - dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); - - /* LM Key not selected */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - - } else { - DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); - session_key = data_blob(NULL, 0); - - /* LM Key not selected */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } - - /* With KEY_EXCH, the client supplies the proposed session key, - but encrypts it with the long-term key */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - if (!ntlmssp_state->encrypted_session_key.data - || ntlmssp_state->encrypted_session_key.length != 16) { - data_blob_free(&ntlmssp_state->encrypted_session_key); - DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", - ntlmssp_state->encrypted_session_key.length)); - return NT_STATUS_INVALID_PARAMETER; - } else if (!session_key.data || session_key.length != 16) { - DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", - session_key.length)); - ntlmssp_state->session_key = session_key; - } else { - dump_data_pw("KEY_EXCH session key (enc):\n", - ntlmssp_state->encrypted_session_key.data, - ntlmssp_state->encrypted_session_key.length); - arcfour_crypt(ntlmssp_state->encrypted_session_key.data, - session_key.data, - ntlmssp_state->encrypted_session_key.length); - ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, - ntlmssp_state->encrypted_session_key.data, - ntlmssp_state->encrypted_session_key.length); - dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data, - ntlmssp_state->encrypted_session_key.length); - } - } else { - ntlmssp_state->session_key = session_key; - } - - /* The server might need us to use a partial-strength session key */ - ntlmssp_weaken_keys(ntlmssp_state); - - nt_status = ntlmssp_sign_init(ntlmssp_state); - - data_blob_free(&ntlmssp_state->encrypted_session_key); - - /* allow arbitarily many authentications, but watch that this will cause a - memory leak, until the ntlmssp_state is shutdown - */ - - if (ntlmssp_state->server_multiple_authentications) { - ntlmssp_state->expected_state = NTLMSSP_AUTH; - } else { - ntlmssp_state->expected_state = NTLMSSP_DONE; - } - - return nt_status; -} - - -/** - * Next state function for the Authenticate packet - * - * @param ntlmssp_state NTLMSSP State - * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB - * @param out The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - DATA_BLOB user_session_key = data_blob(NULL, 0); - DATA_BLOB lm_session_key = data_blob(NULL, 0); - NTSTATUS nt_status; - - /* zero the outbound NTLMSSP packet */ - *out = data_blob_talloc(out_mem_ctx, NULL, 0); - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) { - return nt_status; - } - - /* - * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth - * is required (by "ntlm auth = no" and "lm auth = no" being set in the - * smb.conf file) and no NTLMv2 response was sent then the password check - * will fail here. JRA. - */ - - /* Finally, actually ask if the password is OK */ - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, - &user_session_key, &lm_session_key))) { - return nt_status; - } - - if (ntlmssp_state->server_use_session_keys) { - return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key); - } else { - ntlmssp_state->session_key = data_blob(NULL, 0); - return NT_STATUS_OK; - } -} - -/** - * Create an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, allocated by this function - */ - -NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) -{ - *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); - return NT_STATUS_NO_MEMORY; - } - ZERO_STRUCTP(*ntlmssp_state); - - (*ntlmssp_state)->role = NTLMSSP_SERVER; - - (*ntlmssp_state)->get_challenge = get_challenge; - (*ntlmssp_state)->set_challenge = set_challenge; - (*ntlmssp_state)->may_set_challenge = may_set_challenge; - - (*ntlmssp_state)->workstation = NULL; - (*ntlmssp_state)->server_name = lp_netbios_name(); - - (*ntlmssp_state)->get_domain = lp_workgroup; - (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ - - (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; - - (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() - && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False)); - - (*ntlmssp_state)->server_use_session_keys = True; - (*ntlmssp_state)->server_multiple_authentications = False; - - (*ntlmssp_state)->ref_count = 1; - - (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_NTLM; - - if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) { - (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128; - } - - if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) { - (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; - } - - if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) { - (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - - return NT_STATUS_OK; -} - -/********************************************************************* - Client side NTLMSSP -*********************************************************************/ - -/** - * Next state function for the Initial packet - * - * @param ntlmssp_state NTLMSSP State - * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context - * @param in The request, as a DATA_BLOB. reply.data must be NULL - * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out) -{ - if (ntlmssp_state->unicode) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - } else { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } - - if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(out_mem_ctx, - out, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - ntlmssp_state->neg_flags, - ntlmssp_state->get_domain(), - ntlmssp_state->workstation); - - ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -/** - * Next state function for the Challenge Packet. Generate an auth packet. - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; - DATA_BLOB server_domain_blob; - DATA_BLOB challenge_blob; - DATA_BLOB struct_blob = data_blob(NULL, 0); - char *server_domain; - const char *chal_parse_string; - const char *auth_gen_string; - uint8_t lm_hash[16]; - DATA_BLOB lm_response = data_blob(NULL, 0); - DATA_BLOB nt_response = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB lm_session_key = data_blob(NULL, 0); - DATA_BLOB encrypted_session_key = data_blob(NULL, 0); - NTSTATUS nt_status; - - if (!msrpc_parse(ntlmssp_state, - &in, "CdBd", - "NTLMSSP", - &ntlmssp_command, - &server_domain_blob, - &chal_flags)) { - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, in.data, in.length); - - return NT_STATUS_INVALID_PARAMETER; - } - - data_blob_free(&server_domain_blob); - - DEBUG(3, ("Got challenge flags:\n")); - debug_ntlmssp_flags(chal_flags); - - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key); - - if (ntlmssp_state->unicode) { - if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { - chal_parse_string = "CdUdbddB"; - } else { - chal_parse_string = "CdUdbdd"; - } - auth_gen_string = "CdBBUUUBd"; - } else { - if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { - chal_parse_string = "CdAdbddB"; - } else { - chal_parse_string = "CdAdbdd"; - } - - auth_gen_string = "CdBBAAABd"; - } - - DEBUG(3, ("NTLMSSP: Set final flags:\n")); - debug_ntlmssp_flags(ntlmssp_state->neg_flags); - - if (!msrpc_parse(ntlmssp_state, - &in, chal_parse_string, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - dump_data(2, in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; - } - - ntlmssp_state->server_domain = server_domain; - - if (challenge_blob.length != 8) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (!ntlmssp_state->password) { - static const uint8_t zeros[16]; - /* do nothing - blobs are zero length */ - - /* session key is all zeros */ - session_key = data_blob_talloc(ntlmssp_state, zeros, 16); - lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16); - - /* not doing NLTM2 without a password */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } else if (ntlmssp_state->use_ntlmv2) { - - if (!struct_blob.length) { - /* be lazy, match win2k - we can't do NTLMv2 without it */ - DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* TODO: if the remote server is standalone, then we should replace 'domain' - with the server name as supplied above */ - - if (!SMBNTLMv2encrypt(ntlmssp_state->user, - ntlmssp_state->domain, - ntlmssp_state->password, &challenge_blob, - &struct_blob, - &lm_response, &nt_response, - NULL, &session_key)) { - data_blob_free(&challenge_blob); - data_blob_free(&struct_blob); - return NT_STATUS_NO_MEMORY; - } - - /* LM Key is incompatible... */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - struct MD5Context md5_session_nonce_ctx; - uint8_t nt_hash[16]; - uint8_t session_nonce[16]; - uint8_t session_nonce_hash[16]; - uint8_t user_session_key[16]; - E_md4hash(ntlmssp_state->password, nt_hash); - - lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); - generate_random_buffer(lm_response.data, 8); - memset(lm_response.data+8, 0, 16); - - memcpy(session_nonce, challenge_blob.data, 8); - memcpy(&session_nonce[8], lm_response.data, 8); - - MD5Init(&md5_session_nonce_ctx); - MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); - MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); - MD5Final(session_nonce_hash, &md5_session_nonce_ctx); - - DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); - DEBUG(5, ("challenge is: \n")); - dump_data(5, session_nonce_hash, 8); - - nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); - SMBNTencrypt(ntlmssp_state->password, - session_nonce_hash, - nt_response.data); - - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - - SMBsesskeygen_ntv1(nt_hash, user_session_key); - hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); - dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - - /* LM Key is incompatible... */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } else { - uint8_t nt_hash[16]; - - if (ntlmssp_state->use_nt_response) { - nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); - SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, - nt_response.data); - E_md4hash(ntlmssp_state->password, nt_hash); - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - SMBsesskeygen_ntv1(nt_hash, session_key.data); - dump_data_pw("NT session key:\n", session_key.data, session_key.length); - } - - /* lanman auth is insecure, it may be disabled */ - if (lp_client_lanman_auth()) { - lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); - if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data, - lm_response.data)) { - /* If the LM password was too long (and therefore the LM hash being - of the first 14 chars only), don't send it */ - data_blob_free(&lm_response); - - /* LM Key is incompatible with 'long' passwords */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } else { - E_deshash(ntlmssp_state->password, lm_hash); - lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - memcpy(lm_session_key.data, lm_hash, 8); - memset(&lm_session_key.data[8], '\0', 8); - - if (!ntlmssp_state->use_nt_response) { - session_key = lm_session_key; - } - } - } else { - /* LM Key is incompatible... */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } - } - - if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lp_client_lanman_auth() && lm_session_key.length == 16) { - DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - if (lm_response.length == 24) { - SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, - new_session_key.data); - } else { - static const uint8_t zeros[24]; - SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros, - new_session_key.data); - } - new_session_key.length = 16; - session_key = new_session_key; - dump_data_pw("LM session key\n", session_key.data, session_key.length); - } - - - /* Key exchange encryptes a new client-generated session key with - the password-derived key */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - /* Make up a new session key */ - uint8_t client_session_key[16]; - generate_random_buffer(client_session_key, sizeof(client_session_key)); - - /* Encrypt the new session key with the old one */ - encrypted_session_key = data_blob_talloc(ntlmssp_state, - client_session_key, sizeof(client_session_key)); - dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length); - dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); - - /* Mark the new session key as the 'real' session key */ - session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key)); - } - - /* this generates the actual auth packet */ - if (!msrpc_gen(out_mem_ctx, - out, auth_gen_string, - "NTLMSSP", - NTLMSSP_AUTH, - lm_response.data, lm_response.length, - nt_response.data, nt_response.length, - ntlmssp_state->domain, - ntlmssp_state->user, - ntlmssp_state->workstation, - encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags)) { - - return NT_STATUS_NO_MEMORY; - } - - ntlmssp_state->session_key = session_key; - - /* The client might be using 56 or 40 bit weakened keys */ - ntlmssp_weaken_keys(ntlmssp_state); - - ntlmssp_state->chal = challenge_blob; - ntlmssp_state->lm_resp = lm_response; - ntlmssp_state->nt_resp = nt_response; - - ntlmssp_state->expected_state = NTLMSSP_DONE; - - nt_status = ntlmssp_sign_init(ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", - nt_errstr(nt_status))); - return nt_status; - } - - return nt_status; -} - -NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state) -{ - *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); - return NT_STATUS_NO_MEMORY; - } - ZERO_STRUCTP(*ntlmssp_state); - - (*ntlmssp_state)->role = NTLMSSP_CLIENT; - - (*ntlmssp_state)->workstation = lp_netbios_name(); - (*ntlmssp_state)->get_domain = lp_workgroup; - - (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True); - - (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True); - - (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() - && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False)); - - (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); - - (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL; - - (*ntlmssp_state)->ref_count = 1; - - (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_REQUEST_TARGET; - - if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) { - (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128; - } - - if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) { - (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; - } - - if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) { - (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } else { - /* apparently we can't do ntlmv2 if we don't do ntlm2 */ - (*ntlmssp_state)->use_ntlmv2 = False; - } - - return NT_STATUS_OK; -} - diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h deleted file mode 100644 index e17c133c8b..0000000000 --- a/source4/libcli/auth/ntlmssp.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1997 - Copyright (C) Luke Kenneth Casson Leighton 1996-1997 - Copyright (C) Paul Ashton 1997 - - 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 "librpc/gen_ndr/ndr_samr.h" - -/* NTLMSSP mode */ -enum ntlmssp_role -{ - NTLMSSP_SERVER, - NTLMSSP_CLIENT -}; - -/* NTLMSSP message types */ -enum ntlmssp_message_type -{ - NTLMSSP_INITIAL = 0 /* samba internal state */, - NTLMSSP_NEGOTIATE = 1, - NTLMSSP_CHALLENGE = 2, - NTLMSSP_AUTH = 3, - NTLMSSP_UNKNOWN = 4, - NTLMSSP_DONE = 5 /* samba final state */ -}; - -/* NTLMSSP negotiation flags */ -#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 -#define NTLMSSP_NEGOTIATE_OEM 0x00000002 -#define NTLMSSP_REQUEST_TARGET 0x00000004 -#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 /* Message integrity */ -#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 /* Message confidentiality */ -#define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040 -#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 -#define NTLMSSP_NEGOTIATE_NETWARE 0x00000100 -#define NTLMSSP_NEGOTIATE_NTLM 0x00000200 -#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000 -#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000 -#define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000 -#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 -#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000 -#define NTLMSSP_TARGET_TYPE_SERVER 0x20000 -#define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000 - -#define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000 -#define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000 -#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 -#define NTLMSSP_CHAL_TARGET_INFO 0x00800000 -#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */ -#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 -#define NTLMSSP_NEGOTIATE_56 0x80000000 - -#define NTLMSSP_NAME_TYPE_SERVER 0x01 -#define NTLMSSP_NAME_TYPE_DOMAIN 0x02 -#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 -#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04 - -#define NTLMSSP_SIGN_VERSION 1 - -#define NTLMSSP_SIG_SIZE 16 - -struct ntlmssp_state -{ - uint_t ref_count; - enum ntlmssp_role role; - enum samr_Role server_role; - uint32_t expected_state; - - BOOL unicode; - BOOL use_ntlmv2; - BOOL use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ - BOOL allow_lm_key; /* The LM_KEY code is not functional at this point, and it's not - very secure anyway */ - - BOOL server_use_session_keys; /* Set to 'False' for authentication only, - that will never return a session key */ - BOOL server_multiple_authentications; /* Set to 'True' to allow squid 2.5 - style 'challenge caching' */ - - char *user; - char *domain; - const char *workstation; - char *password; - char *server_domain; - - DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ - - DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */ - DATA_BLOB lm_resp; - DATA_BLOB nt_resp; - DATA_BLOB session_key; - - uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ - - /* internal variables used by NTLM2 */ - BOOL doing_ntlm2; - uint8_t session_nonce[16]; - - /* internal variables used by KEY_EXCH (client-supplied user session key */ - DATA_BLOB encrypted_session_key; - - void *auth_context; - - /** - * Callback to get the 'challenge' used for NTLM authentication. - * - * @param ntlmssp_state This structure - * @return 8 bytes of challenge data, determined by the server to be the challenge for NTLM authentication - * - */ - const uint8_t *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); - - /** - * Callback to find if the challenge used by NTLM authentication may be modified - * - * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the - * current 'security=server' implementation.. - * - * @param ntlmssp_state This structure - * @return Can the challenge be set to arbitary values? - * - */ - BOOL (*may_set_challenge)(const struct ntlmssp_state *ntlmssp_state); - - /** - * Callback to set the 'challenge' used for NTLM authentication. - * - * The callback may use the void *auth_context to store state information, but the same value is always available - * from the DATA_BLOB chal on this structure. - * - * @param ntlmssp_state This structure - * @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication - * - */ - NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge); - - /** - * Callback to check the user's password. - * - * The callback must reads the feilds of this structure for the information it needs on the user - * @param ntlmssp_state This structure - * @param nt_session_key If an NT session key is returned by the authentication process, return it here - * @param lm_session_key If an LM session key is returned by the authentication process, return it here - * - */ - NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); - - const char *server_name; - const char *(*get_domain)(void); - - /* SMB Signing */ - uint32_t ntlm_seq_num; - uint32_t ntlm2_send_seq_num; - uint32_t ntlm2_recv_seq_num; - - /* ntlmv2 */ - DATA_BLOB send_sign_key; - DATA_BLOB send_seal_key; - DATA_BLOB recv_sign_key; - DATA_BLOB recv_seal_key; - - uint8_t send_seal_hash[258]; - uint8_t recv_seal_hash[258]; - - /* ntlmv1 */ - uint8_t ntlmssp_hash[258]; - - /* it turns out that we don't always get the - response in at the time we want to process it. - Store it here, until we need it */ - DATA_BLOB stored_response; - -}; - diff --git a/source4/libcli/auth/ntlmssp_parse.c b/source4/libcli/auth/ntlmssp_parse.c deleted file mode 100644 index 42546cb130..0000000000 --- a/source4/libcli/auth/ntlmssp_parse.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5/SPNEGO routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 - Copyright (C) Andrew Bartlett 2002-2003 - - 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 "pstring.h" - -/* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_gen(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - const char *format, ...) -{ - int i; - ssize_t n; - va_list ap; - char *s; - uint8_t *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - int *intargs; - - DATA_BLOB *pointers; - - pointers = talloc_array(mem_ctx, DATA_BLOB, strlen(format)); - intargs = talloc_array(pointers, int, strlen(format)); - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - n = push_ucs2_talloc(pointers, (void **)&pointers[i].data, s); - if (n == -1) { - return False; - } - pointers[i].length = n; - pointers[i].length -= 2; - data_size += pointers[i].length; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - n = push_ascii_talloc(pointers, (char **)&pointers[i].data, s); - if (n == -1) { - return False; - } - pointers[i].length = n; - pointers[i].length -= 1; - data_size += pointers[i].length; - break; - case 'a': - n = va_arg(ap, int); - intargs[i] = n; - s = va_arg(ap, char *); - n = push_ucs2_talloc(pointers, (void **)&pointers[i].data, s); - if (n == -1) { - return False; - } - pointers[i].length = n; - pointers[i].length -= 2; - data_size += pointers[i].length + 4; - break; - case 'B': - b = va_arg(ap, uint8_t *); - head_size += 8; - pointers[i].data = b; - pointers[i].length = va_arg(ap, int); - data_size += pointers[i].length; - break; - case 'b': - b = va_arg(ap, uint8_t *); - pointers[i].data = b; - pointers[i].length = va_arg(ap, int); - head_size += pointers[i].length; - break; - case 'd': - n = va_arg(ap, int); - intargs[i] = n; - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - pointers[i].data = (uint8_t *)s; - pointers[i].length = strlen(s)+1; - head_size += pointers[i].length; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob_talloc(mem_ctx, NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - case 'A': - case 'B': - n = pointers[i].length; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - if (pointers[i].data && n) /* don't follow null pointers... */ - memcpy(blob->data+data_ofs, pointers[i].data, n); - data_ofs += n; - break; - case 'a': - n = intargs[i]; - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - - n = pointers[i].length; - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (n >= 0) { - memcpy(blob->data+data_ofs, pointers[i].data, n); - } - data_ofs += n; - break; - case 'd': - n = intargs[i]; - SIVAL(blob->data, head_ofs, n); - head_ofs += 4; - break; - case 'b': - n = pointers[i].length; - memcpy(blob->data + head_ofs, pointers[i].data, n); - head_ofs += n; - break; - case 'C': - n = pointers[i].length; - memcpy(blob->data + head_ofs, pointers[i].data, n); - head_ofs += n; - break; - } - } - va_end(ap); - - talloc_free(pointers); - - return True; -} - - -/* a helpful macro to avoid running over the end of our blob */ -#define NEED_DATA(amount) \ -if ((head_ofs + amount) > blob->length) { \ - return False; \ -} - -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ - -BOOL msrpc_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - const char **ps, *s; - DATA_BLOB *b; - size_t head_ofs = 0; - uint16_t len1, len2; - uint32_t ptr; - uint32_t *v; - pstring p; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = (const char **)va_arg(ap, char **); - if (len1 == 0 && len2 == 0) { - *ps = ""; - } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; - } - if (len1 & 1) { - /* if odd length and unicode */ - return False; - } - if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) - return False; - - if (0 < len1) { - pull_string(p, blob->data + ptr, sizeof(p), - len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = talloc_strdup(mem_ctx, p); - if (!(*ps)) { - return False; - } - } else { - (*ps) = ""; - } - } - break; - case 'A': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = (const char **)va_arg(ap, char **); - /* make sure its in the right format - be strict */ - if (len1 == 0 && len2 == 0) { - *ps = ""; - } else { - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; - } - - if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) - return False; - - if (0 < len1) { - pull_string(p, blob->data + ptr, sizeof(p), - len1, - STR_ASCII|STR_NOALIGN); - (*ps) = talloc_strdup(mem_ctx, p); - if (!(*ps)) { - return False; - } - } else { - (*ps) = ""; - } - } - break; - case 'B': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - b = (DATA_BLOB *)va_arg(ap, void *); - if (len1 == 0 && len2 == 0) { - *b = data_blob_talloc(mem_ctx, NULL, 0); - } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; - } - - if (blob->data + ptr < (uint8_t *)ptr || blob->data + ptr < blob->data) - return False; - - *b = data_blob_talloc(mem_ctx, blob->data + ptr, len1); - } - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, uint_t); - /* make sure its in the right format - be strict */ - NEED_DATA(len1); - if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) - return False; - - *b = data_blob_talloc(mem_ctx, blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32_t *); - NEED_DATA(4); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - - if (blob->data + head_ofs < (uint8_t *)head_ofs || blob->data + head_ofs < blob->data) - return False; - - head_ofs += pull_string(p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; - } - break; - } - } - va_end(ap); - - return True; -} diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c deleted file mode 100644 index 347a85da77..0000000000 --- a/source4/libcli/auth/ntlmssp_sign.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Version 3.0 - * NTLMSSP Signing routines - * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 - * Copyright (C) Andrew Bartlett 2003-2004 - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "includes.h" -#include "auth/auth.h" -#include "lib/crypto/crypto.h" - -#define CLI_SIGN "session key to client-to-server signing key magic constant" -#define CLI_SEAL "session key to client-to-server sealing key magic constant" -#define SRV_SIGN "session key to server-to-client signing key magic constant" -#define SRV_SEAL "session key to server-to-client sealing key magic constant" - -/** - * Some notes on then NTLM2 code: - * - * This code works correctly for the sealing part of the problem. If - * we disable the check for valid client signatures, then we see that - * the output of a rpcecho 'sinkdata' at smbd is correct. We get the - * valid data, and it is validly decrypted. - * - * This means that the quantity of data passing though the RC4 sealing - * pad is correct. - * - * This code also correctly matches test values that I have obtained, - * claiming to be the correct output of NTLM2 signature generation. - * - */ - -static void calc_ntlmv2_key(TALLOC_CTX *mem_ctx, - DATA_BLOB *subkey, - DATA_BLOB session_key, - const char *constant) -{ - struct MD5Context ctx3; - *subkey = data_blob_talloc(mem_ctx, NULL, 16); - MD5Init(&ctx3); - MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, constant, strlen(constant)+1); - MD5Final(subkey->data, &ctx3); -} - -enum ntlmssp_direction { - NTLMSSP_SEND, - NTLMSSP_RECEIVE -}; - -static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - enum ntlmssp_direction direction, - DATA_BLOB *sig, BOOL encrypt_sig) -{ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - - HMACMD5Context ctx; - uint8_t digest[16]; - uint8_t seq_num[4]; - - *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE); - if (!sig->data) { - return NT_STATUS_NO_MEMORY; - } - - switch (direction) { - case NTLMSSP_SEND: - SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num); - ntlmssp_state->ntlm2_send_seq_num++; - hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key.data, - ntlmssp_state->send_sign_key.length, &ctx); - break; - case NTLMSSP_RECEIVE: - SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num); - ntlmssp_state->ntlm2_recv_seq_num++; - hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key.data, - ntlmssp_state->recv_sign_key.length, &ctx); - break; - } - hmac_md5_update(seq_num, sizeof(seq_num), &ctx); - hmac_md5_update(whole_pdu, pdu_length, &ctx); - hmac_md5_final(digest, &ctx); - - if (encrypt_sig && ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - switch (direction) { - case NTLMSSP_SEND: - arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, digest, 8); - break; - case NTLMSSP_RECEIVE: - arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, digest, 8); - break; - } - } - - SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); - memcpy(sig->data + 4, digest, 8); - memcpy(sig->data + 12, seq_num, 4); - - } else { - uint32_t crc; - crc = crc32_calc_buffer(data, length); - if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlm_seq_num)) { - return NT_STATUS_NO_MEMORY; - } - ntlmssp_state->ntlm_seq_num++; - - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); - } - dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - if (!ntlmssp_state->session_key.length) { - DEBUG(3, ("NO session key, cannot check sign packet\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { - DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, - data, length, - whole_pdu, pdu_length, - NTLMSSP_SEND, sig, True); -} - -/** - * Check the signature of an incoming packet - * - */ - -NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - DATA_BLOB local_sig; - NTSTATUS nt_status; - - if (!ntlmssp_state->session_key.length) { - DEBUG(3, ("NO session key, cannot check packet signature\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - if (sig->length < 8) { - DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", - (unsigned long)sig->length)); - } - - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, - data, length, - whole_pdu, pdu_length, - NTLMSSP_RECEIVE, &local_sig, True); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); - return nt_status; - } - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - if (local_sig.length != sig->length || - memcmp(local_sig.data, - sig->data, sig->length) != 0) { - DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); - - DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); - - DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); - return NT_STATUS_ACCESS_DENIED; - } - } else { - if (local_sig.length != sig->length || - memcmp(local_sig.data + 8, - sig->data + 8, sig->length - 8) != 0) { - DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); - - DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); - - DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length); - - return NT_STATUS_OK; -} - - -/** - * Seal data with the NTLMSSP algorithm - * - */ - -NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - NTSTATUS nt_status; - if (!ntlmssp_state->session_key.length) { - DEBUG(3, ("NO session key, cannot seal packet\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { - DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - DEBUG(10,("ntlmssp_seal_data: seal\n")); - dump_data_pw("ntlmssp clear data\n", data, length); - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - /* The order of these two operations matters - we must first seal the packet, - then seal the sequence number - this is becouse the send_seal_hash is not - constant, but is is rather updated with each iteration */ - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, - data, length, - whole_pdu, pdu_length, - NTLMSSP_SEND, sig, False); - arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, data, length); - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - arcfour_crypt_sbox(ntlmssp_state->send_seal_hash, sig->data+4, 8); - } - } else { - uint32_t crc; - crc = crc32_calc_buffer(data, length); - if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlm_seq_num)) { - return NT_STATUS_NO_MEMORY; - } - - /* The order of these two operations matters - we must - first seal the packet, then seal the sequence - number - this is becouse the ntlmssp_hash is not - constant, but is is rather updated with each - iteration */ - - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); - /* increment counter on send */ - ntlmssp_state->ntlm_seq_num++; - nt_status = NT_STATUS_OK; - } - dump_data_pw("ntlmssp signature\n", sig->data, sig->length); - dump_data_pw("ntlmssp sealed data\n", data, length); - - - return nt_status; -} - -/** - * Unseal data with the NTLMSSP algorithm - * - */ - -NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - DATA_BLOB local_sig; - NTSTATUS nt_status; - if (!ntlmssp_state->session_key.length) { - DEBUG(3, ("NO session key, cannot unseal packet\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - dump_data_pw("ntlmssp sealed data\n", data, length); - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - arcfour_crypt_sbox(ntlmssp_state->recv_seal_hash, data, length); - - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, - data, length, - whole_pdu, pdu_length, - NTLMSSP_RECEIVE, &local_sig, True); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - if (local_sig.length != sig->length || - memcmp(local_sig.data, - sig->data, sig->length) != 0) { - DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); - - DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); - - DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); - return NT_STATUS_ACCESS_DENIED; - } - - dump_data_pw("ntlmssp clear data\n", data, length); - return NT_STATUS_OK; - } else { - arcfour_crypt_sbox(ntlmssp_state->ntlmssp_hash, data, length); - dump_data_pw("ntlmssp clear data\n", data, length); - return ntlmssp_check_packet(ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); - } -} - -/** - Initialise the state for NTLMSSP signing. -*/ -NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) -{ - uint8_t p24[24]; - ZERO_STRUCT(p24); - - DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); - debug_ntlmssp_flags(ntlmssp_state->neg_flags); - - if (!ntlmssp_state->session_key.length) { - DEBUG(3, ("NO session key, cannot intialise signing\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - { - DATA_BLOB weak_session_key = ntlmssp_state->session_key; - const char *send_sign_const; - const char *send_seal_const; - const char *recv_sign_const; - const char *recv_seal_const; - - switch (ntlmssp_state->role) { - case NTLMSSP_CLIENT: - send_sign_const = CLI_SIGN; - send_seal_const = CLI_SEAL; - recv_sign_const = SRV_SIGN; - recv_seal_const = SRV_SEAL; - break; - case NTLMSSP_SERVER: - send_sign_const = SRV_SIGN; - send_seal_const = SRV_SEAL; - recv_sign_const = CLI_SIGN; - recv_seal_const = CLI_SEAL; - break; - default: - return NT_STATUS_INTERNAL_ERROR; - } - - /** - Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions. - - We probably should have some parameters to control this, once we get NTLM2 working. - */ - - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { - - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { - weak_session_key.length = 6; - } else { /* forty bits */ - weak_session_key.length = 5; - } - dump_data_pw("NTLMSSP weakend master key:\n", - weak_session_key.data, - weak_session_key.length); - - /* SEND */ - calc_ntlmv2_key(ntlmssp_state, - &ntlmssp_state->send_sign_key, - ntlmssp_state->session_key, send_sign_const); - dump_data_pw("NTLMSSP send sign key:\n", - ntlmssp_state->send_sign_key.data, - ntlmssp_state->send_sign_key.length); - - calc_ntlmv2_key(ntlmssp_state, - &ntlmssp_state->send_seal_key, - weak_session_key, send_seal_const); - dump_data_pw("NTLMSSP send seal key:\n", - ntlmssp_state->send_seal_key.data, - ntlmssp_state->send_seal_key.length); - - arcfour_init(ntlmssp_state->send_seal_hash, - &ntlmssp_state->send_seal_key); - - dump_data_pw("NTLMSSP send sesl hash:\n", - ntlmssp_state->send_seal_hash, - sizeof(ntlmssp_state->send_seal_hash)); - - /* RECV */ - calc_ntlmv2_key(ntlmssp_state, - &ntlmssp_state->recv_sign_key, - ntlmssp_state->session_key, recv_sign_const); - dump_data_pw("NTLMSSP recv sign key:\n", - ntlmssp_state->recv_sign_key.data, - ntlmssp_state->recv_sign_key.length); - - calc_ntlmv2_key(ntlmssp_state, - &ntlmssp_state->recv_seal_key, - weak_session_key, recv_seal_const); - dump_data_pw("NTLMSSP recv seal key:\n", - ntlmssp_state->recv_seal_key.data, - ntlmssp_state->recv_seal_key.length); - arcfour_init(ntlmssp_state->recv_seal_hash, - &ntlmssp_state->recv_seal_key); - - dump_data_pw("NTLMSSP receive seal hash:\n", - ntlmssp_state->recv_seal_hash, - sizeof(ntlmssp_state->recv_seal_hash)); - } else { - DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); - - arcfour_init(ntlmssp_state->ntlmssp_hash, - &ntlmssp_state->session_key); - dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); - } - - ntlmssp_state->ntlm_seq_num = 0; - ntlmssp_state->ntlm2_send_seq_num = 0; - ntlmssp_state->ntlm2_recv_seq_num = 0; - - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c deleted file mode 100644 index 3dbf10580b..0000000000 --- a/source4/libcli/auth/schannel.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - dcerpc schannel operations - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Andrew Bartlett 2004-2005 - - 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 "librpc/gen_ndr/ndr_schannel.h" -#include "auth/auth.h" -#include "libcli/auth/schannel.h" - -static size_t schannel_sig_size(struct gensec_security *gensec_security) -{ - return 32; -} - -static NTSTATUS schannel_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct schannel_state *state = gensec_security->private_data; - NTSTATUS status; - struct schannel_bind bind_schannel; - struct schannel_bind_ack bind_schannel_ack; - struct creds_CredentialState *creds; - - const char *workstation; - const char *domain; - *out = data_blob(NULL, 0); - - switch (gensec_security->gensec_role) { - case GENSEC_CLIENT: - if (state->state != SCHANNEL_STATE_START) { - /* we could parse the bind ack, but we don't know what it is yet */ - return NT_STATUS_OK; - } - - state->creds = talloc_reference(state, cli_credentials_get_netlogon_creds(gensec_security->credentials)); - - bind_schannel.unknown1 = 0; -#if 0 - /* to support this we'd need to have access to the full domain name */ - bind_schannel.bind_type = 23; - bind_schannel.u.info23.domain = cli_credentials_get_domain(gensec_security->credentials); - bind_schannel.u.info23.account_name = cli_credentials_get_username(gensec_security->credentials); - bind_schannel.u.info23.dnsdomain = str_format_nbt_domain(out_mem_ctx, fulldomainname); - bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, cli_credentials_get_workstation(gensec_security->credentials)); -#else - bind_schannel.bind_type = 3; - bind_schannel.u.info3.domain = cli_credentials_get_domain(gensec_security->credentials); - bind_schannel.u.info3.workstation = cli_credentials_get_workstation(gensec_security->credentials); -#endif - - status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel, - (ndr_push_flags_fn_t)ndr_push_schannel_bind); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not create schannel bind: %s\n", - nt_errstr(status))); - return status; - } - - state->state = SCHANNEL_STATE_UPDATE_1; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; - case GENSEC_SERVER: - - if (state->state != SCHANNEL_STATE_START) { - /* no third leg on this protocol */ - return NT_STATUS_INVALID_PARAMETER; - } - - /* parse the schannel startup blob */ - status = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, - (ndr_pull_flags_fn_t)ndr_pull_schannel_bind); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (bind_schannel.bind_type == 23) { - workstation = bind_schannel.u.info23.workstation; - domain = bind_schannel.u.info23.domain; - } else { - workstation = bind_schannel.u.info3.workstation; - domain = bind_schannel.u.info3.domain; - } - - /* pull the session key for this client */ - status = schannel_fetch_session_key(out_mem_ctx, workstation, - domain, &creds); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", - workstation, nt_errstr(status))); - return status; - } - - state->creds = talloc_reference(state, creds); - - bind_schannel_ack.unknown1 = 1; - bind_schannel_ack.unknown2 = 0; - bind_schannel_ack.unknown3 = 0x6c0000; - - status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack, - (ndr_push_flags_fn_t)ndr_push_schannel_bind_ack); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not return schannel bind ack for client %s: %s\n", - workstation, nt_errstr(status))); - return status; - } - - state->state = SCHANNEL_STATE_UPDATE_1; - - return NT_STATUS_OK; - } - return NT_STATUS_INVALID_PARAMETER; -} - -/** - * Return the struct creds_CredentialState. - * - * Make sure not to call this unless gensec is using schannel... - */ - -NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - struct creds_CredentialState **creds) -{ - struct schannel_state *state = gensec_security->private_data; - - *creds = talloc_reference(mem_ctx, state->creds); - if (!*creds) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - - -/** - * Return the credentials of a logged on user, including session keys - * etc. - * - * Only valid after a successful authentication - * - * May only be called once per authentication. - * - */ - -static NTSTATUS schannel_session_info(struct gensec_security *gensec_security, - struct auth_session_info **session_info) -{ - (*session_info) = talloc(gensec_security, struct auth_session_info); - NT_STATUS_HAVE_NO_MEMORY(*session_info); - - ZERO_STRUCTP(*session_info); - - return NT_STATUS_OK; -} - -static NTSTATUS schannel_start(struct gensec_security *gensec_security) -{ - struct schannel_state *state; - - state = talloc(gensec_security, struct schannel_state); - if (!state) { - return NT_STATUS_NO_MEMORY; - } - - state->state = SCHANNEL_STATE_START; - state->seq_num = 0; - gensec_security->private_data = state; - - return NT_STATUS_OK; -} - -static NTSTATUS schannel_server_start(struct gensec_security *gensec_security) -{ - NTSTATUS status; - struct schannel_state *state; - - status = schannel_start(gensec_security); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - state = gensec_security->private_data; - state->initiator = False; - - return NT_STATUS_OK; -} - -static NTSTATUS schannel_client_start(struct gensec_security *gensec_security) -{ - NTSTATUS status; - struct schannel_state *state; - - status = schannel_start(gensec_security); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - state = gensec_security->private_data; - state->initiator = True; - - return NT_STATUS_OK; -} - - -static BOOL schannel_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - if (feature & (GENSEC_FEATURE_SIGN | - GENSEC_FEATURE_SEAL)) { - return True; - } - return False; -} - - -static const struct gensec_security_ops gensec_schannel_security_ops = { - .name = "schannel", - .auth_type = DCERPC_AUTH_TYPE_SCHANNEL, - .client_start = schannel_client_start, - .server_start = schannel_server_start, - .update = schannel_update, - .seal_packet = schannel_seal_packet, - .sign_packet = schannel_sign_packet, - .check_packet = schannel_check_packet, - .unseal_packet = schannel_unseal_packet, - .session_key = schannel_session_key, - .session_info = schannel_session_info, - .sig_size = schannel_sig_size, - .have_feature = schannel_have_feature, - .enabled = True -}; - -NTSTATUS gensec_schannel_init(void) -{ - NTSTATUS ret; - ret = gensec_register(&gensec_schannel_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_schannel_security_ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/libcli/auth/schannel.h b/source4/libcli/auth/schannel.h deleted file mode 100644 index c109387c7c..0000000000 --- a/source4/libcli/auth/schannel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - dcerpc schannel operations - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Andrew Bartlett 2004-2005 - - 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. -*/ - -enum schannel_position { - SCHANNEL_STATE_START = 0, - SCHANNEL_STATE_UPDATE_1 -}; - -struct schannel_state { - enum schannel_position state; - uint32_t seq_num; - BOOL initiator; - struct creds_CredentialState *creds; -}; - diff --git a/source4/libcli/auth/schannel_sign.c b/source4/libcli/auth/schannel_sign.c deleted file mode 100644 index 3b493bd0d3..0000000000 --- a/source4/libcli/auth/schannel_sign.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - schannel library code - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Andrew Bartlett 2005 - - 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 "lib/crypto/crypto.h" -#include "libcli/auth/schannel.h" -#include "libcli/auth/gensec.h" -#include "libcli/auth/credentials.h" - -#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } -#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } - -/******************************************************************* - Encode or Decode the sequence number (which is symmetric) - ********************************************************************/ -static void netsec_deal_with_seq_num(struct schannel_state *state, - const uint8_t packet_digest[8], - uint8_t seq_num[8]) -{ - static const uint8_t zeros[4]; - uint8_t sequence_key[16]; - uint8_t digest1[16]; - - hmac_md5(state->creds->session_key, zeros, sizeof(zeros), digest1); - hmac_md5(digest1, packet_digest, 8, sequence_key); - arcfour_crypt(seq_num, sequence_key, 8); - - state->seq_num++; -} - - -/******************************************************************* - Calculate the key with which to encode the data payload - ********************************************************************/ -static void netsec_get_sealing_key(const uint8_t session_key[16], - const uint8_t seq_num[8], - uint8_t sealing_key[16]) -{ - static const uint8_t zeros[4]; - uint8_t digest2[16]; - uint8_t sess_kf0[16]; - int i; - - for (i = 0; i < 16; i++) { - sess_kf0[i] = session_key[i] ^ 0xf0; - } - - hmac_md5(sess_kf0, zeros, 4, digest2); - hmac_md5(digest2, seq_num, 8, sealing_key); -} - - -/******************************************************************* - Create a digest over the entire packet (including the data), and - MD5 it with the session key. - ********************************************************************/ -static void schannel_digest(const uint8_t sess_key[16], - const uint8_t netsec_sig[8], - const uint8_t *confounder, - const uint8_t *data, size_t data_len, - uint8_t digest_final[16]) -{ - uint8_t packet_digest[16]; - static const uint8_t zeros[4]; - struct MD5Context ctx; - - MD5Init(&ctx); - MD5Update(&ctx, zeros, 4); - MD5Update(&ctx, netsec_sig, 8); - if (confounder) { - MD5Update(&ctx, confounder, 8); - } - MD5Update(&ctx, data, data_len); - MD5Final(packet_digest, &ctx); - - hmac_md5(sess_key, packet_digest, sizeof(packet_digest), digest_final); -} - - -/* - unseal a packet -*/ -NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct schannel_state *state = gensec_security->private_data; - - uint8_t digest_final[16]; - uint8_t confounder[8]; - uint8_t seq_num[8]; - uint8_t sealing_key[16]; - static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; - - if (sig->length != 32) { - return NT_STATUS_ACCESS_DENIED; - } - - memcpy(confounder, sig->data+24, 8); - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0:0x80); - - netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key); - arcfour_crypt(confounder, sealing_key, 8); - arcfour_crypt(data, sealing_key, length); - - schannel_digest(state->creds->session_key, - netsec_sig, confounder, - data, length, digest_final); - - if (memcmp(digest_final, sig->data+16, 8) != 0) { - dump_data_pw("calc digest:", digest_final, 8); - dump_data_pw("wire digest:", sig->data+16, 8); - return NT_STATUS_ACCESS_DENIED; - } - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - if (memcmp(seq_num, sig->data+8, 8) != 0) { - dump_data_pw("calc seq num:", seq_num, 8); - dump_data_pw("wire seq num:", sig->data+8, 8); - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - -/* - check the signature on a packet -*/ -NTSTATUS schannel_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - struct schannel_state *state = gensec_security->private_data; - - uint8_t digest_final[16]; - uint8_t seq_num[8]; - static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; - - /* w2k sends just 24 bytes and skip the confounder */ - if (sig->length != 32 && sig->length != 24) { - return NT_STATUS_ACCESS_DENIED; - } - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0:0x80); - - dump_data_pw("seq_num:\n", seq_num, 8); - dump_data_pw("sess_key:\n", state->creds->session_key, 16); - - schannel_digest(state->creds->session_key, - netsec_sig, NULL, - data, length, digest_final); - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - if (memcmp(seq_num, sig->data+8, 8) != 0) { - dump_data_pw("calc seq num:", seq_num, 8); - dump_data_pw("wire seq num:", sig->data+8, 8); - return NT_STATUS_ACCESS_DENIED; - } - - if (memcmp(digest_final, sig->data+16, 8) != 0) { - dump_data_pw("calc digest:", digest_final, 8); - dump_data_pw("wire digest:", sig->data+16, 8); - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - - -/* - seal a packet -*/ -NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct schannel_state *state = gensec_security->private_data; - - uint8_t digest_final[16]; - uint8_t confounder[8]; - uint8_t seq_num[8]; - uint8_t sealing_key[16]; - static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE; - - generate_random_buffer(confounder, 8); - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0x80:0); - - schannel_digest(state->creds->session_key, - netsec_sig, confounder, - data, length, digest_final); - - netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key); - arcfour_crypt(confounder, sealing_key, 8); - arcfour_crypt(data, sealing_key, length); - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - (*sig) = data_blob_talloc(mem_ctx, NULL, 32); - - memcpy(sig->data, netsec_sig, 8); - memcpy(sig->data+8, seq_num, 8); - memcpy(sig->data+16, digest_final, 8); - memcpy(sig->data+24, confounder, 8); - - dump_data_pw("signature:", sig->data+ 0, 8); - dump_data_pw("seq_num :", sig->data+ 8, 8); - dump_data_pw("digest :", sig->data+16, 8); - dump_data_pw("confound :", sig->data+24, 8); - - return NT_STATUS_OK; -} - - -/* - sign a packet -*/ -NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct schannel_state *state = gensec_security->private_data; - - uint8_t digest_final[16]; - uint8_t seq_num[8]; - static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE; - - RSIVAL(seq_num, 0, state->seq_num); - SIVAL(seq_num, 4, state->initiator?0x80:0); - - schannel_digest(state->creds->session_key, - netsec_sig, NULL, - data, length, digest_final); - - netsec_deal_with_seq_num(state, digest_final, seq_num); - - (*sig) = data_blob_talloc(mem_ctx, NULL, 32); - - memcpy(sig->data, netsec_sig, 8); - memcpy(sig->data+8, seq_num, 8); - memcpy(sig->data+16, digest_final, 8); - memset(sig->data+24, 0, 8); - - dump_data_pw("signature:", sig->data+ 0, 8); - dump_data_pw("seq_num :", sig->data+ 8, 8); - dump_data_pw("digest :", sig->data+16, 8); - dump_data_pw("confound :", sig->data+24, 8); - - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/schannel_state.c b/source4/libcli/auth/schannel_state.c deleted file mode 100644 index b2d632a1f0..0000000000 --- a/source4/libcli/auth/schannel_state.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - module to store/fetch session keys for the schannel server - - Copyright (C) Andrew Tridgell 2004 - - 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 "system/time.h" -#include "auth/auth.h" -#include "lib/ldb/include/ldb.h" -#include "db_wrap.h" - -/* a reasonable amount of time to keep credentials live */ -#define SCHANNEL_CREDENTIALS_EXPIRY 600 - -/* - connect to the schannel ldb -*/ -static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) -{ - char *path; - struct ldb_context *ldb; - - path = smbd_tmp_path(mem_ctx, "schannel.ldb"); - if (!path) { - return NULL; - } - - ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL); - talloc_free(path); - if (!ldb) { - return NULL; - } - - return ldb; -} - -/* - remember an established session key for a netr server authentication - use a simple ldb structure -*/ -NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds) -{ - struct ldb_context *ldb; - struct ldb_message *msg; - struct ldb_val val, seed; - char *s; - char *f; - char *sct; - char *rid; - time_t expiry = time(NULL) + SCHANNEL_CREDENTIALS_EXPIRY; - int ret; - - ldb = schannel_db_connect(mem_ctx); - if (ldb == NULL) { - return NT_STATUS_NO_MEMORY; - } - - s = talloc_asprintf(mem_ctx, "%u", (unsigned int)expiry); - - if (s == NULL) { - talloc_free(ldb); - return NT_STATUS_NO_MEMORY; - } - - f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags); - - if (f == NULL) { - talloc_free(ldb); - return NT_STATUS_NO_MEMORY; - } - - sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type); - - if (sct == NULL) { - talloc_free(ldb); - return NT_STATUS_NO_MEMORY; - } - - rid = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->rid); - - if (rid == NULL) { - talloc_free(ldb); - return NT_STATUS_NO_MEMORY; - } - - msg = ldb_msg_new(mem_ctx); - if (msg == NULL) { - talloc_free(ldb); - return NT_STATUS_NO_MEMORY; - } - - msg->dn = talloc_asprintf(msg, "computerName=%s", creds->computer_name); - if (msg->dn == NULL) { - talloc_free(ldb); - talloc_free(msg); - return NT_STATUS_NO_MEMORY; - } - - val.data = creds->session_key; - val.length = sizeof(creds->session_key); - - seed.data = creds->seed.data; - seed.length = sizeof(creds->seed.data); - - ldb_msg_add_value(ldb, msg, "sessionKey", &val); - ldb_msg_add_value(ldb, msg, "seed", &seed); - ldb_msg_add_string(ldb, msg, "expiry", s); - ldb_msg_add_string(ldb, msg, "negotiateFlags", f); - ldb_msg_add_string(ldb, msg, "secureChannelType", sct); - ldb_msg_add_string(ldb, msg, "accountName", creds->account_name); - ldb_msg_add_string(ldb, msg, "computerName", creds->computer_name); - ldb_msg_add_string(ldb, msg, "flatname", creds->domain); - ldb_msg_add_string(ldb, msg, "rid", rid); - - ldb_delete(ldb, msg->dn); - - ret = ldb_add(ldb, msg); - - talloc_free(s); - - if (ret != 0) { - DEBUG(0,("Unable to add %s to session key db - %s\n", - msg->dn, ldb_errstring(ldb))); - talloc_free(ldb); - talloc_free(msg); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - talloc_free(msg); - talloc_free(ldb); - - return NT_STATUS_OK; -} - - -/* - read back a credentials back for a computer -*/ -NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, - const char *computer_name, - const char *domain, - struct creds_CredentialState **creds) -{ - struct ldb_context *ldb; - time_t expiry; - struct ldb_message **res; - int ret; - const struct ldb_val *val; - char *expr=NULL; - - *creds = talloc_zero(mem_ctx, struct creds_CredentialState); - if (!*creds) { - return NT_STATUS_NO_MEMORY; - } - - ldb = schannel_db_connect(mem_ctx); - if (ldb == NULL) { - return NT_STATUS_NO_MEMORY; - } - - expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", computer_name, domain); - if (expr == NULL) { - talloc_free(ldb); - return NT_STATUS_NO_MEMORY; - } - - ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res); - if (ret != 1) { - talloc_free(ldb); - return NT_STATUS_INVALID_HANDLE; - } - - expiry = ldb_msg_find_uint(res[0], "expiry", 0); - if (expiry < time(NULL)) { - DEBUG(1,("schannel: attempt to use expired session key for %s\n", computer_name)); - talloc_free(ldb); - return NT_STATUS_INVALID_HANDLE; - } - - val = ldb_msg_find_ldb_val(res[0], "sessionKey"); - if (val == NULL || val->length != 16) { - talloc_free(ldb); - return NT_STATUS_INVALID_HANDLE; - } - - memcpy((*creds)->session_key, val->data, 16); - - val = ldb_msg_find_ldb_val(res[0], "seed"); - if (val == NULL || val->length != 8) { - talloc_free(ldb); - return NT_STATUS_INVALID_HANDLE; - } - - memcpy((*creds)->seed.data, val->data, 8); - - (*creds)->negotiate_flags = ldb_msg_find_int(res[0], "negotiateFlags", 0); - - (*creds)->secure_channel_type = ldb_msg_find_int(res[0], "secureChannelType", 0); - - (*creds)->account_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "accountName", NULL)); - - (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL)); - - (*creds)->domain = talloc_reference(*creds, ldb_msg_find_string(res[0], "flatname", NULL)); - - (*creds)->rid = ldb_msg_find_uint(res[0], "rid", 0); - - talloc_free(ldb); - - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c deleted file mode 100644 index f5a091cd78..0000000000 --- a/source4/libcli/auth/spnego.c +++ /dev/null @@ -1,884 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough 2003 - Copyright (C) Andrew Bartlett 2004 - - 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 "auth/auth.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -enum spnego_state_position { - SPNEGO_SERVER_START, - SPNEGO_CLIENT_START, - SPNEGO_SERVER_TARG, - SPNEGO_CLIENT_TARG, - SPNEGO_FALLBACK, - SPNEGO_DONE -}; - -struct spnego_state { - uint_t ref_count; - enum spnego_message_type expected_packet; - enum spnego_state_position state_position; - struct gensec_security *sub_sec_security; - BOOL no_response_expected; -}; - - -static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state; - - spnego_state = talloc(gensec_security, struct spnego_state); - if (!spnego_state) { - return NT_STATUS_NO_MEMORY; - } - - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; - spnego_state->state_position = SPNEGO_CLIENT_START; - spnego_state->sub_sec_security = NULL; - spnego_state->no_response_expected = False; - - gensec_security->private_data = spnego_state; - return NT_STATUS_OK; -} - -static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state; - - spnego_state = talloc(gensec_security, struct spnego_state); - if (!spnego_state) { - return NT_STATUS_NO_MEMORY; - } - - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; - spnego_state->state_position = SPNEGO_SERVER_START; - spnego_state->sub_sec_security = NULL; - spnego_state->no_response_expected = False; - - gensec_security->private_data = spnego_state; - return NT_STATUS_OK; -} - -/* - wrappers for the spnego_*() functions -*/ -static NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_unseal_packet(spnego_state->sub_sec_security, - mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_check_packet(spnego_state->sub_sec_security, - mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_seal_packet(spnego_state->sub_sec_security, - mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_sign_packet(spnego_state->sub_sec_security, - mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_wrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_wrap: wrong state for wrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_wrap(spnego_state->sub_sec_security, - mem_ctx, in, out); -} - -static NTSTATUS gensec_spnego_unwrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_unwrap(spnego_state->sub_sec_security, - mem_ctx, in, out); -} - -static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return 0; - } - - return gensec_sig_size(spnego_state->sub_sec_security); -} - -static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, - DATA_BLOB *session_key) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - if (!spnego_state->sub_sec_security) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_session_key(spnego_state->sub_sec_security, - session_key); -} - -static NTSTATUS gensec_spnego_session_info(struct gensec_security *gensec_security, - struct auth_session_info **session_info) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - if (!spnego_state->sub_sec_security) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_session_info(spnego_state->sub_sec_security, - session_info); -} - -/** Fallback to another GENSEC mechanism, based on magic strings - * - * This is the 'fallback' case, where we don't get SPNEGO, and have to - * try all the other options (and hope they all have a magic string - * they check) -*/ - -static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec_security, - struct spnego_state *spnego_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - int i; - int num_ops; - const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); - for (i=0; i < num_ops; i++) { - NTSTATUS nt_status; - if (!all_ops[i]->oid) { - continue; - } - if (strcasecmp(GENSEC_OID_SPNEGO,all_ops[i]->oid) == 0) { - continue; - } - - nt_status = gensec_subcontext_start(spnego_state, - gensec_security, - &spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - /* select the sub context */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - all_ops[i]->oid); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - continue; - } - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, in, out); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - spnego_state->state_position = SPNEGO_FALLBACK; - return nt_status; - } - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - } - DEBUG(1, ("Failed to parse SPNEGO request\n")); - return NT_STATUS_INVALID_PARAMETER; - -} - -/* - Parse the netTokenInit from the client, to the server. - - -*/ - -static NTSTATUS gensec_spnego_server_parse_negTokenInit(struct gensec_security *gensec_security, - struct spnego_state *spnego_state, - TALLOC_CTX *out_mem_ctx, - const char **mechType, - const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) -{ - NTSTATUS nt_status; - - if (!mechType || !mechType[0]) { - DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - nt_status = gensec_subcontext_start(spnego_state, - gensec_security, - &spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - /* select the sub context */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechType[0]); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - return nt_status; - } - - if (!unwrapped_in.length) { - return NT_STATUS_INVALID_PARAMETER; - } - - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - unwrapped_in, - unwrapped_out); - - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", - spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - } - return nt_status; -} - -static NTSTATUS gensec_spnego_client_parse_negTokenInit(struct gensec_security *gensec_security, - struct spnego_state *spnego_state, - TALLOC_CTX *out_mem_ctx, - const char **mechType, - const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) -{ - int i; - NTSTATUS nt_status; - DATA_BLOB null_data_blob = data_blob(NULL,0); - - for (i=0; mechType && mechType[i]; i++) { - nt_status = gensec_subcontext_start(spnego_state, - gensec_security, - &spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - break; - } - /* select the sub context */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechType[i]); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - continue; - } - - if (i == 0) { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - unwrapped_in, - unwrapped_out); - } else { - /* only get the helping start blob for the first OID */ - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - unwrapped_out); - } - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", - spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - } - return nt_status; - } - if (!mechType || !mechType[i]) { - DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); - } - return NT_STATUS_INVALID_PARAMETER; -} - -/** create a client negTokenInit - * - * This is the case, where the client is the first one who sends data -*/ - -static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec_security, - struct spnego_state *spnego_state, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - DATA_BLOB null_data_blob = data_blob(NULL,0); - NTSTATUS nt_status; - const char **mechTypes = NULL; - DATA_BLOB unwrapped_out = data_blob(NULL,0); - - mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); - - if (!mechTypes) { - DEBUG(1, ("no GENSEC OID backends available\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - nt_status = gensec_subcontext_start(spnego_state, - gensec_security, - &spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - /* select our preferred mech */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechTypes[0]); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - return nt_status; - } - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, in, &unwrapped_out); - if (NT_STATUS_IS_OK(nt_status) || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - struct spnego_data spnego_out; - spnego_out.type = SPNEGO_NEG_TOKEN_INIT; - spnego_out.negTokenInit.mechTypes = mechTypes; - spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = null_data_blob; - spnego_out.negTokenInit.mechToken = unwrapped_out; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* set next state */ - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_CLIENT_TARG; - - if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->no_response_expected = True; - } - - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - - DEBUG(1, ("Failed to setup SPNEGO negTokenInit request: %s\n", nt_errstr(nt_status))); - return NT_STATUS_INVALID_PARAMETER; -} - - -/** create a client negTokenTarg - * - * This is the case, where the client is the first one who sends data -*/ - -static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec_security, - struct spnego_state *spnego_state, - TALLOC_CTX *out_mem_ctx, - NTSTATUS nt_status, - const DATA_BLOB unwrapped_out, DATA_BLOB *out) -{ - struct spnego_data spnego_out; - DATA_BLOB null_data_blob = data_blob(NULL, 0); - - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - spnego_out.negTokenTarg.supportedMech = NULL; - - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_state->state_position = SPNEGO_SERVER_TARG; - } else if (NT_STATUS_IS_OK(nt_status)) { - if (unwrapped_out.data) { - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - } - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; - spnego_state->state_position = SPNEGO_DONE; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) { - if (spnego_state->sub_sec_security) { - /* we have a mech, but we just didn't get the input parameter */ - spnego_out.negTokenTarg.supportedMech - = spnego_state->sub_sec_security->ops->oid; - } else { - const char **mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); - if (!mechTypes) { - DEBUG(1, ("no GENSEC OID backends available\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - nt_status = gensec_subcontext_start(spnego_state, - gensec_security, - &spnego_state->sub_sec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - /* select our preferred mech */ - nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, - mechTypes[0]); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(spnego_state->sub_sec_security); - spnego_state->sub_sec_security = NULL; - return nt_status; - } - - /* we should be sending the whole list here */ - spnego_out.negTokenTarg.supportedMech = mechTypes[0]; - } - - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_state->state_position = SPNEGO_SERVER_TARG; - nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; - } else { - spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; - DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); - spnego_state->state_position = SPNEGO_DONE; - } - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - - return nt_status; -} - - -static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - DATA_BLOB null_data_blob = data_blob(NULL, 0); - DATA_BLOB unwrapped_out = data_blob(NULL, 0); - struct spnego_data spnego_out; - struct spnego_data spnego; - - ssize_t len; - - *out = data_blob(NULL, 0); - - if (!out_mem_ctx) { - out_mem_ctx = spnego_state; - } - - /* and switch into the state machine */ - - switch (spnego_state->state_position) { - case SPNEGO_FALLBACK: - return gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, in, out); - case SPNEGO_SERVER_START: - { - if (in.length) { - NTSTATUS nt_status; - - len = spnego_read_data(in, &spnego); - if (len == -1) { - return gensec_spnego_server_try_fallback(gensec_security, spnego_state, out_mem_ctx, in, out); - } - /* client sent NegTargetInit, we send NegTokenTarg */ - - /* OK, so it's real SPNEGO, check the packet's the one we expect */ - if (spnego.type != spnego_state->expected_packet) { - DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, - spnego_state->expected_packet)); - dump_data(1, in.data, in.length); - spnego_free_data(&spnego); - return NT_STATUS_INVALID_PARAMETER; - } - - nt_status = gensec_spnego_server_parse_negTokenInit(gensec_security, - spnego_state, - out_mem_ctx, - spnego.negTokenInit.mechTypes, - spnego.negTokenInit.mechToken, - &unwrapped_out); - - nt_status = gensec_spnego_server_negTokenTarg(gensec_security, - spnego_state, - out_mem_ctx, - nt_status, - unwrapped_out, - out); - - spnego_free_data(&spnego); - - return nt_status; - } else { - const char **mechlist = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO); - - spnego_out.type = SPNEGO_NEG_TOKEN_INIT; - spnego_out.negTokenInit.mechTypes = mechlist; - spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC - = data_blob_string_const(talloc_asprintf(out_mem_ctx, "%s$@%s", lp_netbios_name(), lp_realm())); - spnego_out.negTokenInit.mechToken = unwrapped_out; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* set next state */ - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_SERVER_TARG; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - } - - case SPNEGO_CLIENT_START: - { - /* The server offers a list of mechanisms */ - - const char *my_mechs[] = {NULL, NULL}; - NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; - - if (!in.length) { - /* client to produce negTokenInit */ - return gensec_spnego_client_negTokenInit(gensec_security, spnego_state, - out_mem_ctx, in, out); - } - - len = spnego_read_data(in, &spnego); - - if (len == -1) { - DEBUG(1, ("Invalid SPNEGO request:\n")); - dump_data(1, in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; - } - - /* OK, so it's real SPNEGO, check the packet's the one we expect */ - if (spnego.type != spnego_state->expected_packet) { - DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, - spnego_state->expected_packet)); - dump_data(1, in.data, in.length); - spnego_free_data(&spnego); - return NT_STATUS_INVALID_PARAMETER; - } - - if (spnego.negTokenInit.targetPrincipal) { - DEBUG(5, ("Server claims it's principal name is %s (ignored)\n", spnego.negTokenInit.targetPrincipal)); - } - - nt_status = gensec_spnego_client_parse_negTokenInit(gensec_security, - spnego_state, - out_mem_ctx, - spnego.negTokenInit.mechTypes, - spnego.negTokenInit.mechToken, - &unwrapped_out); - - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) { - spnego_free_data(&spnego); - return nt_status; - } - - /* compose reply */ - my_mechs[0] = spnego_state->sub_sec_security->ops->oid; - - spnego_out.type = SPNEGO_NEG_TOKEN_INIT; - spnego_out.negTokenInit.mechTypes = my_mechs; - spnego_out.negTokenInit.reqFlags = 0; - spnego_out.negTokenInit.mechListMIC = null_data_blob; - spnego_out.negTokenInit.mechToken = unwrapped_out; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* set next state */ - spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; - spnego_state->state_position = SPNEGO_CLIENT_TARG; - - if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->no_response_expected = True; - } - - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - case SPNEGO_SERVER_TARG: - { - NTSTATUS nt_status; - if (!in.length) { - return NT_STATUS_INVALID_PARAMETER; - } - - len = spnego_read_data(in, &spnego); - - if (len == -1) { - DEBUG(1, ("Invalid SPNEGO request:\n")); - dump_data(1, in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; - } - - /* OK, so it's real SPNEGO, check the packet's the one we expect */ - if (spnego.type != spnego_state->expected_packet) { - DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, - spnego_state->expected_packet)); - dump_data(1, in.data, in.length); - spnego_free_data(&spnego); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!spnego_state->sub_sec_security) { - DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - - nt_status = gensec_spnego_server_negTokenTarg(gensec_security, - spnego_state, - out_mem_ctx, - nt_status, - unwrapped_out, - out); - - spnego_free_data(&spnego); - - return nt_status; - } - case SPNEGO_CLIENT_TARG: - { - NTSTATUS nt_status; - if (!in.length) { - return NT_STATUS_INVALID_PARAMETER; - } - - len = spnego_read_data(in, &spnego); - - if (len == -1) { - DEBUG(1, ("Invalid SPNEGO request:\n")); - dump_data(1, in.data, in.length); - return NT_STATUS_INVALID_PARAMETER; - } - - /* OK, so it's real SPNEGO, check the packet's the one we expect */ - if (spnego.type != spnego_state->expected_packet) { - DEBUG(1, ("Invalid SPNEGO request: %d, expected %d\n", spnego.type, - spnego_state->expected_packet)); - dump_data(1, in.data, in.length); - spnego_free_data(&spnego); - return NT_STATUS_INVALID_PARAMETER; - } - - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - return NT_STATUS_ACCESS_DENIED; - } - - if (spnego_state->no_response_expected) { - if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - DEBUG(3,("GENSEC SPNEGO: client GENSEC accepted, but server rejected (bad password?)\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } else if (spnego.negTokenTarg.responseToken.length) { - DEBUG(2,("GENSEC SPNEGO: client GENSEC accepted, but server continued negotiation!\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } else { - nt_status = NT_STATUS_OK; - } - } else { - nt_status = gensec_update(spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - - if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->no_response_expected = True; - } - } - - spnego_free_data(&spnego); - - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) - && !NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("SPNEGO(%s) login failed: %s\n", - spnego_state->sub_sec_security->ops->name, - nt_errstr(nt_status))); - return nt_status; - } - - if (unwrapped_out.length) { - /* compose reply */ - spnego_out.type = SPNEGO_NEG_TOKEN_TARG; - spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT; - spnego_out.negTokenTarg.supportedMech = NULL; - spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; - - if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) { - DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - spnego_state->state_position = SPNEGO_CLIENT_TARG; - nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; - } else { - - /* all done - server has accepted, and we agree */ - *out = null_data_blob; - - if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - /* unless of course it did not accept */ - DEBUG(1,("gensec_update ok but not accepted\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } - } - - spnego_state->state_position = SPNEGO_DONE; - - return nt_status; - } - case SPNEGO_DONE: - return NT_STATUS_OK; - } - return NT_STATUS_INVALID_PARAMETER; -} - -static BOOL gensec_spnego_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct spnego_state *spnego_state = gensec_security->private_data; - if (!spnego_state->sub_sec_security) { - return False; - } - - return gensec_have_feature(spnego_state->sub_sec_security, - feature); -} - -static const struct gensec_security_ops gensec_spnego_security_ops = { - .name = "spnego", - .sasl_name = "GSS-SPNEGO", - .auth_type = DCERPC_AUTH_TYPE_SPNEGO, - .oid = GENSEC_OID_SPNEGO, - .client_start = gensec_spnego_client_start, - .server_start = gensec_spnego_server_start, - .update = gensec_spnego_update, - .seal_packet = gensec_spnego_seal_packet, - .sign_packet = gensec_spnego_sign_packet, - .sig_size = gensec_spnego_sig_size, - .check_packet = gensec_spnego_check_packet, - .unseal_packet = gensec_spnego_unseal_packet, - .wrap = gensec_spnego_wrap, - .unwrap = gensec_spnego_unwrap, - .session_key = gensec_spnego_session_key, - .session_info = gensec_spnego_session_info, - .have_feature = gensec_spnego_have_feature, - .enabled = True -}; - -NTSTATUS gensec_spnego_init(void) -{ - NTSTATUS ret; - ret = gensec_register(&gensec_spnego_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_spnego_security_ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h deleted file mode 100644 index 1064370146..0000000000 --- a/source4/libcli/auth/spnego.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough 2003 - - 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. -*/ - -#ifndef SAMBA_SPNEGO_H -#define SAMBA_SPNEGO_H - -#define SPNEGO_DELEG_FLAG 0x01 -#define SPNEGO_MUTUAL_FLAG 0x02 -#define SPNEGO_REPLAY_FLAG 0x04 -#define SPNEGO_SEQUENCE_FLAG 0x08 -#define SPNEGO_ANON_FLAG 0x10 -#define SPNEGO_CONF_FLAG 0x20 -#define SPNEGO_INTEG_FLAG 0x40 -#define SPNEGO_REQ_FLAG 0x80 - -enum spnego_negResult { - SPNEGO_ACCEPT_COMPLETED = 0, - SPNEGO_ACCEPT_INCOMPLETE = 1, - SPNEGO_REJECT = 2, - SPNEGO_NONE_RESULT = 3 -}; - -struct spnego_negTokenInit { - const char **mechTypes; - int reqFlags; - DATA_BLOB mechToken; - DATA_BLOB mechListMIC; - char *targetPrincipal; -}; - -struct spnego_negTokenTarg { - uint8_t negResult; - const char *supportedMech; - DATA_BLOB responseToken; - DATA_BLOB mechListMIC; -}; - -struct spnego_data { - int type; - struct spnego_negTokenInit negTokenInit; - struct spnego_negTokenTarg negTokenTarg; -}; - -enum spnego_message_type { - SPNEGO_NEG_TOKEN_INIT = 0, - SPNEGO_NEG_TOKEN_TARG = 1, -}; - -#endif diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c deleted file mode 100644 index e48c32f0da..0000000000 --- a/source4/libcli/auth/spnego_parse.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough 2003 - - 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 "auth/auth.h" -#include "asn_1.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token) -{ - ZERO_STRUCTP(token); - - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - int i; - uint8_t context; - if (!asn1_peek_uint8(asn1, &context)) { - asn1->has_error = True; - break; - } - - switch (context) { - /* Read mechTypes */ - case ASN1_CONTEXT(0): - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - token->mechTypes = talloc(NULL, const char *); - for (i = 0; !asn1->has_error && - 0 < asn1_tag_remaining(asn1); i++) { - token->mechTypes = talloc_realloc(NULL, - token->mechTypes, - const char *, i+2); - asn1_read_OID(asn1, token->mechTypes + i); - if (token->mechTypes[i]) { - talloc_steal(token->mechTypes, - token->mechTypes[i]); - } - } - token->mechTypes[i] = NULL; - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - break; - /* Read reqFlags */ - case ASN1_CONTEXT(1): - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_Integer(asn1, &token->reqFlags); - token->reqFlags |= SPNEGO_REQ_FLAG; - asn1_end_tag(asn1); - break; - /* Read mechToken */ - case ASN1_CONTEXT(2): - asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, &token->mechToken); - asn1_end_tag(asn1); - break; - /* Read mecListMIC */ - case ASN1_CONTEXT(3): - { - uint8_t type_peek; - asn1_start_tag(asn1, ASN1_CONTEXT(3)); - if (!asn1_peek_uint8(asn1, &type_peek)) { - asn1->has_error = True; - break; - } - if (type_peek == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, - &token->mechListMIC); - } else { - /* RFC 2478 says we have an Octet String here, - but W2k sends something different... */ - char *mechListMIC; - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, &mechListMIC); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - token->targetPrincipal = mechListMIC; - } - asn1_end_tag(asn1); - break; - } - default: - asn1->has_error = True; - break; - } - } - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - - return !asn1->has_error; -} - -static BOOL write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token) -{ - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - - /* Write mechTypes */ - if (token->mechTypes && *token->mechTypes) { - int i; - - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - for (i = 0; token->mechTypes[i]; i++) { - asn1_write_OID(asn1, token->mechTypes[i]); - } - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - } - - /* write reqFlags */ - if (token->reqFlags & SPNEGO_REQ_FLAG) { - int flags = token->reqFlags & ~SPNEGO_REQ_FLAG; - - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_write_Integer(asn1, flags); - asn1_pop_tag(asn1); - } - - /* write mechToken */ - if (token->mechToken.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(2)); - asn1_write_OctetString(asn1, token->mechToken.data, - token->mechToken.length); - asn1_pop_tag(asn1); - } - - /* write mechListMIC */ - if (token->mechListMIC.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(3)); -#if 0 - /* This is what RFC 2478 says ... */ - asn1_write_OctetString(asn1, token->mechListMIC.data, - token->mechListMIC.length); -#else - /* ... but unfortunately this is what Windows - sends/expects */ - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_GENERAL_STRING); - asn1_write(asn1, token->mechListMIC.data, - token->mechListMIC.length); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); -#endif - asn1_pop_tag(asn1); - } - - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - return !asn1->has_error; -} - -static BOOL read_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token) -{ - ZERO_STRUCTP(token); - - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - uint8_t context; - if (!asn1_peek_uint8(asn1, &context)) { - asn1->has_error = True; - break; - } - - switch (context) { - case ASN1_CONTEXT(0): - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_ENUMERATED); - asn1_read_uint8(asn1, &token->negResult); - asn1_end_tag(asn1); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(1): - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, &token->supportedMech); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(2): - asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, &token->responseToken); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(3): - asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, &token->mechListMIC); - asn1_end_tag(asn1); - break; - default: - asn1->has_error = True; - break; - } - } - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - - return !asn1->has_error; -} - -static BOOL write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token) -{ - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - - if (token->negResult != SPNEGO_NONE_RESULT) { - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_write_enumerated(asn1, token->negResult); - asn1_pop_tag(asn1); - } - - if (token->supportedMech) { - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_write_OID(asn1, token->supportedMech); - asn1_pop_tag(asn1); - } - - if (token->responseToken.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(2)); - asn1_write_OctetString(asn1, token->responseToken.data, - token->responseToken.length); - asn1_pop_tag(asn1); - } - - if (token->mechListMIC.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(3)); - asn1_write_OctetString(asn1, token->mechListMIC.data, - token->mechListMIC.length); - asn1_pop_tag(asn1); - } - - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - return !asn1->has_error; -} - -ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) -{ - struct asn1_data asn1; - ssize_t ret = -1; - uint8_t context; - - ZERO_STRUCTP(token); - ZERO_STRUCT(asn1); - - if (data.length == 0) { - return ret; - } - - asn1_load(&asn1, data); - - if (!asn1_peek_uint8(&asn1, &context)) { - asn1.has_error = True; - } else { - switch (context) { - case ASN1_APPLICATION(0): - asn1_start_tag(&asn1, ASN1_APPLICATION(0)); - asn1_check_OID(&asn1, GENSEC_OID_SPNEGO); - if (read_negTokenInit(&asn1, &token->negTokenInit)) { - token->type = SPNEGO_NEG_TOKEN_INIT; - } - asn1_end_tag(&asn1); - break; - case ASN1_CONTEXT(1): - if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { - token->type = SPNEGO_NEG_TOKEN_TARG; - } - break; - default: - asn1.has_error = True; - break; - } - } - - if (!asn1.has_error) ret = asn1.ofs; - asn1_free(&asn1); - - return ret; -} - -ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego) -{ - struct asn1_data asn1; - ssize_t ret = -1; - - ZERO_STRUCT(asn1); - - switch (spnego->type) { - case SPNEGO_NEG_TOKEN_INIT: - asn1_push_tag(&asn1, ASN1_APPLICATION(0)); - asn1_write_OID(&asn1, GENSEC_OID_SPNEGO); - write_negTokenInit(&asn1, &spnego->negTokenInit); - asn1_pop_tag(&asn1); - break; - case SPNEGO_NEG_TOKEN_TARG: - write_negTokenTarg(&asn1, &spnego->negTokenTarg); - break; - default: - asn1.has_error = True; - break; - } - - if (!asn1.has_error) { - *blob = data_blob_talloc(mem_ctx, asn1.data, asn1.length); - ret = asn1.ofs; - } - asn1_free(&asn1); - - return ret; -} - -BOOL spnego_free_data(struct spnego_data *spnego) -{ - BOOL ret = True; - - if (!spnego) goto out; - - switch(spnego->type) { - case SPNEGO_NEG_TOKEN_INIT: - if (spnego->negTokenInit.mechTypes) { - talloc_free(spnego->negTokenInit.mechTypes); - } - data_blob_free(&spnego->negTokenInit.mechToken); - data_blob_free(&spnego->negTokenInit.mechListMIC); - talloc_free(spnego->negTokenInit.targetPrincipal); - break; - case SPNEGO_NEG_TOKEN_TARG: - if (spnego->negTokenTarg.supportedMech) { - talloc_free(discard_const(spnego->negTokenTarg.supportedMech)); - } - data_blob_free(&spnego->negTokenTarg.responseToken); - data_blob_free(&spnego->negTokenTarg.mechListMIC); - break; - default: - ret = False; - break; - } - ZERO_STRUCTP(spnego); -out: - return ret; -} - -- cgit From a47cb58c2f6d34dd98e3dc2dd023a259ff501643 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Apr 2005 04:32:37 +0000 Subject: r6184: the beginnings of the libcli/dgram/ library, and the dgram server. Currently just listens on port 138 and parses the packets (using IDL like the rest of NBT). This allows me to develop the structures and test with real packets (This used to be commit 10d64a525349ff96695ad961a3cfeb5bc7c8844f) --- source4/libcli/dgram/dgramsocket.c | 153 +++++++++++++++++++++++++++++++++++++ source4/libcli/dgram/libdgram.h | 41 ++++++++++ 2 files changed, 194 insertions(+) create mode 100644 source4/libcli/dgram/dgramsocket.c create mode 100644 source4/libcli/dgram/libdgram.h (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c new file mode 100644 index 0000000000..7f179bc3c3 --- /dev/null +++ b/source4/libcli/dgram/dgramsocket.c @@ -0,0 +1,153 @@ +/* + Unix SMB/CIFS implementation. + + low level socket handling for nbt dgram requests (UDP138) + + Copyright (C) Andrew Tridgell 2005 + + 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 "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" + +#define DGRAM_MAX_PACKET_SIZE 2048 + + +/* + handle recv events on a nbt dgram socket +*/ +static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock) +{ + TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); + NTSTATUS status; + const char *src_addr; + int src_port; + DATA_BLOB blob; + size_t nread; + struct nbt_dgram_packet *packet; + + blob = data_blob_talloc(tmp_ctx, NULL, DGRAM_MAX_PACKET_SIZE); + if (blob.data == NULL) { + talloc_free(tmp_ctx); + return; + } + + status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, + &src_addr, &src_port); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + talloc_steal(tmp_ctx, src_addr); + blob.length = nread; + + DEBUG(0,("Received dgram packet of length %d from %s:%d\n", + blob.length, src_addr, src_port)); + + packet = talloc(tmp_ctx, struct nbt_dgram_packet); + if (packet == NULL) { + talloc_free(tmp_ctx); + return; + } + + /* parse the request */ + status = ndr_pull_struct_blob(&blob, packet, packet, + (ndr_pull_flags_fn_t)ndr_pull_nbt_dgram_packet); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Failed to parse incoming NBT DGRAM packet - %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return; + } + + NDR_PRINT_DEBUG(nbt_dgram_packet, packet); + + talloc_free(tmp_ctx); +} + + +/* + handle fd events on a nbt_dgram_socket +*/ +static void dgm_socket_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct nbt_dgram_socket *dgmsock = talloc_get_type(private, + struct nbt_dgram_socket); + if (flags & EVENT_FD_WRITE) { + /* nothing at the moment */ + } else if (flags & EVENT_FD_READ) { + dgm_socket_recv(dgmsock); + } +} + +/* + initialise a nbt_dgram_socket. The event_ctx is optional, if provided + then operations will use that event context +*/ +struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) +{ + struct nbt_dgram_socket *dgmsock; + NTSTATUS status; + + dgmsock = talloc(mem_ctx, struct nbt_dgram_socket); + if (dgmsock == NULL) goto failed; + + if (event_ctx == NULL) { + dgmsock->event_ctx = event_context_init(dgmsock); + } else { + dgmsock->event_ctx = talloc_reference(dgmsock, event_ctx); + } + if (dgmsock->event_ctx == NULL) goto failed; + + status = socket_create("ip", SOCKET_TYPE_DGRAM, &dgmsock->sock, 0); + if (!NT_STATUS_IS_OK(status)) goto failed; + + socket_set_option(dgmsock->sock, "SO_BROADCAST", "1"); + + talloc_steal(dgmsock, dgmsock->sock); + + dgmsock->fde = event_add_fd(dgmsock->event_ctx, dgmsock, + socket_get_fd(dgmsock->sock), 0, + dgm_socket_handler, dgmsock); + + return dgmsock; + +failed: + talloc_free(dgmsock); + return NULL; +} + + +/* + setup a handler for incoming requests +*/ +NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, + void (*handler)(struct nbt_dgram_socket *, + struct nbt_dgram_packet *, + const char *, int ), + void *private) +{ + dgmsock->incoming.handler = handler; + dgmsock->incoming.private = private; + EVENT_FD_READABLE(dgmsock->fde); + return NT_STATUS_OK; +} diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h new file mode 100644 index 0000000000..6ead6dccf0 --- /dev/null +++ b/source4/libcli/dgram/libdgram.h @@ -0,0 +1,41 @@ +/* + Unix SMB/CIFS implementation. + + a raw async NBT DGRAM library + + Copyright (C) Andrew Tridgell 2005 + + 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 "librpc/gen_ndr/ndr_nbt.h" + +/* + context structure for operations on dgram packets +*/ +struct nbt_dgram_socket { + struct socket_context *sock; + struct event_context *event_ctx; + + /* the fd event */ + struct fd_event *fde; + + /* what to do with incoming request packets */ + struct { + void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, + const char *, int ); + void *private; + } incoming; +}; -- cgit From 6db5d09dba3f1f6111b5fcd89cb303c95adec6bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Apr 2005 04:36:00 +0000 Subject: r6185: added LIBCLI_DGRAM to the list of libs to be built as part of LIBCLI (This used to be commit 47e1452da08d06b0b9f15545b3b2b0631f15bac2) --- source4/libcli/config.mk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e6be2ed058..51fb3c7025 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -35,6 +35,11 @@ ADD_OBJ_FILES = \ libcli/nbt/namerelease.o REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS +[SUBSYSTEM::LIBCLI_DGRAM] +ADD_OBJ_FILES = \ + libcli/dgram/dgramsocket.o +REQUIRED_SUBSYSTEMS = LIBCLI_NBT + [SUBSYSTEM::LIBCLI_WINS] ADD_OBJ_FILES = \ libcli/wins/winsrepl.o @@ -51,4 +56,5 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ - LIBCLI_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE + LIBCLI_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ + LIBCLI_DGRAM -- cgit From 769070d502a95439ea7d6e2c6616cfa08fc5d673 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 5 Apr 2005 08:35:02 +0000 Subject: r6209: started added code to support mailslot requests over UDP/138 datagrams. This adds the IDL to parse mailslot packets, plus mailslot dispatch and listener registration code. mailslots are used for UDP/138 browse and netlogon packets (This used to be commit f20e7e5200de736b3451d748ed716be638f93502) --- source4/libcli/config.mk | 4 +- source4/libcli/dgram/dgramsocket.c | 99 ++++++++++++++++++++++++++-- source4/libcli/dgram/libdgram.h | 77 ++++++++++++++++++++++ source4/libcli/dgram/mailslot.c | 132 +++++++++++++++++++++++++++++++++++++ 4 files changed, 305 insertions(+), 7 deletions(-) create mode 100644 source4/libcli/dgram/mailslot.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 51fb3c7025..f90f9907ad 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -37,7 +37,9 @@ REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS [SUBSYSTEM::LIBCLI_DGRAM] ADD_OBJ_FILES = \ - libcli/dgram/dgramsocket.o + libcli/dgram/dgramsocket.o \ + libcli/dgram/mailslot.o +NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI_WINS] diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 7f179bc3c3..33734258a3 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -33,15 +33,16 @@ /* handle recv events on a nbt dgram socket */ -static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock) +static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) { - TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); NTSTATUS status; const char *src_addr; int src_port; DATA_BLOB blob; size_t nread; struct nbt_dgram_packet *packet; + const char *mailslot_name; blob = data_blob_talloc(tmp_ctx, NULL, DGRAM_MAX_PACKET_SIZE); if (blob.data == NULL) { @@ -49,7 +50,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock) return; } - status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, + status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, 0, &src_addr, &src_port); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); @@ -77,12 +78,60 @@ static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock) return; } - NDR_PRINT_DEBUG(nbt_dgram_packet, packet); + /* if this is a mailslot message, then see if we can dispatch it to a handler */ + mailslot_name = dgram_mailslot_name(packet); + if (mailslot_name) { + struct dgram_mailslot_handler *dgmslot; + dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); + if (dgmslot) { + dgmslot->handler(dgmslot, packet, src_addr, src_port); + } else { + DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); + } + } else { + /* dispatch if there is a general handler */ + if (dgmsock->incoming.handler) { + dgmsock->incoming.handler(dgmsock, packet, src_addr, src_port); + } + } talloc_free(tmp_ctx); } +/* + handle send events on a nbt dgram socket +*/ +static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) +{ + struct nbt_dgram_request *req; + NTSTATUS status; + + while ((req = dgmsock->send_queue)) { + size_t len; + + len = req->encoded.length; + status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0, + req->dest_addr, req->dest_port); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(3,("Failed to send datagram of length %u to %s:%d\n", + req->encoded.length, req->dest_addr, req->dest_port)); + DLIST_REMOVE(dgmsock->send_queue, req); + talloc_free(req); + continue; + } + + if (!NT_STATUS_IS_OK(status)) return; + + DLIST_REMOVE(dgmsock->send_queue, req); + talloc_free(req); + } + + EVENT_FD_NOT_WRITEABLE(dgmsock->fde); + return; +} + + /* handle fd events on a nbt_dgram_socket */ @@ -92,7 +141,7 @@ static void dgm_socket_handler(struct event_context *ev, struct fd_event *fde, struct nbt_dgram_socket *dgmsock = talloc_get_type(private, struct nbt_dgram_socket); if (flags & EVENT_FD_WRITE) { - /* nothing at the moment */ + dgm_socket_send(dgmsock); } else if (flags & EVENT_FD_READ) { dgm_socket_recv(dgmsock); } @@ -128,6 +177,10 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, dgmsock->fde = event_add_fd(dgmsock->event_ctx, dgmsock, socket_get_fd(dgmsock->sock), 0, dgm_socket_handler, dgmsock); + + dgmsock->send_queue = NULL; + dgmsock->incoming.handler = NULL; + dgmsock->mailslot_handlers = NULL; return dgmsock; @@ -138,7 +191,7 @@ failed: /* - setup a handler for incoming requests + setup a handler for generic incoming requests */ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, @@ -151,3 +204,37 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, EVENT_FD_READABLE(dgmsock->fde); return NT_STATUS_OK; } + + +/* + queue a datagram for send +*/ +NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *packet, + const char *dest_addr, + int dest_port) +{ + struct nbt_dgram_request *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + req = talloc(dgmsock, struct nbt_dgram_request); + if (req == NULL) goto failed; + + req->dest_addr = talloc_strdup(req, dest_addr); + if (req->dest_addr == NULL) goto failed; + req->dest_port = dest_port; + + status = ndr_push_struct_blob(&req->encoded, req, packet, + (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); + if (!NT_STATUS_IS_OK(status)) goto failed; + + DLIST_ADD_END(dgmsock->send_queue, req, struct nbt_dgram_request *); + + EVENT_FD_WRITEABLE(dgmsock->fde); + + return NT_STATUS_OK; + +failed: + talloc_free(req); + return status; +} diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 6ead6dccf0..866877e341 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -22,6 +22,21 @@ #include "librpc/gen_ndr/ndr_nbt.h" + +/* + a nbt name request +*/ +struct nbt_dgram_request { + struct nbt_dgram_request *next, *prev; + + /* where to send the request */ + const char *dest_addr; + int dest_port; + + /* the encoded request */ + DATA_BLOB encoded; +}; + /* context structure for operations on dgram packets */ @@ -32,6 +47,12 @@ struct nbt_dgram_socket { /* the fd event */ struct fd_event *fde; + /* a queue of outgoing requests */ + struct nbt_dgram_request *send_queue; + + /* a list of mailslot handlers */ + struct dgram_mailslot_handler *mailslot_handlers; + /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, @@ -39,3 +60,59 @@ struct nbt_dgram_socket { void *private; } incoming; }; + + +/* + the mailslot code keeps a list of mailslot handlers. A mailslot + handler is a function that receives incoming packets for a specific + mailslot name. When a caller needs to send a mailslot and wants to + get a reply then it needs to register itself as listening for + incoming packets on the reply mailslot +*/ + +typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, + struct nbt_dgram_packet *, + const char *, int ); + +struct dgram_mailslot_handler { + struct dgram_mailslot_handler *next, *prev; + + struct nbt_dgram_socket *dgmsock; + const char *mailslot_name; + + dgram_mailslot_handler_t handler; + void *private; +}; + + +/* prototypes */ +NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *packet, + const char *dest_addr, + int dest_port); +NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, + void (*handler)(struct nbt_dgram_socket *, + struct nbt_dgram_packet *, + const char *, int ), + void *private); +struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx); + +const char *dgram_mailslot_name(struct nbt_dgram_packet *packet); +struct dgram_mailslot_handler *dgram_mailslot_find(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name); +struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name, + dgram_mailslot_handler_t handler, + void *private); +struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name, + dgram_mailslot_handler_t handler, + void *private); + + + + + + + diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c new file mode 100644 index 0000000000..da9b6cdd20 --- /dev/null +++ b/source4/libcli/dgram/mailslot.c @@ -0,0 +1,132 @@ +/* + Unix SMB/CIFS implementation. + + packet handling for mailslot requests + + Copyright (C) Andrew Tridgell 2005 + + 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 "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" + +/* + destroy a mailslot handler +*/ +static int dgram_mailslot_destructor(void *ptr) +{ + struct dgram_mailslot_handler *dgmslot = + talloc_get_type(ptr, struct dgram_mailslot_handler); + + DLIST_REMOVE(dgmslot->dgmsock->mailslot_handlers, dgmslot); + return 0; +} + +/* + start listening on a mailslot. talloc_free() the handle to stop listening +*/ +struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name, + dgram_mailslot_handler_t handler, + void *private) +{ + struct dgram_mailslot_handler *dgmslot; + + dgmslot = talloc(dgmsock, struct dgram_mailslot_handler); + if (dgmslot == NULL) return NULL; + + dgmslot->dgmsock = dgmsock; + dgmslot->mailslot_name = talloc_strdup(dgmslot, mailslot_name); + if (dgmslot->mailslot_name == NULL) { + talloc_free(dgmslot); + return NULL; + } + dgmslot->handler = handler; + dgmslot->private = private; + + DLIST_ADD(dgmsock->mailslot_handlers, dgmslot); + talloc_set_destructor(dgmslot, dgram_mailslot_destructor); + + return dgmslot; +} + +/* + find the handler for a specific mailslot name +*/ +struct dgram_mailslot_handler *dgram_mailslot_find(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name) +{ + struct dgram_mailslot_handler *h; + for (h=dgmsock->mailslot_handlers;h;h=h->next) { + if (strcasecmp(h->mailslot_name, mailslot_name) == 0) { + return h; + } + } + return NULL; +} + +/* + check that a datagram packet is a valid mailslot request, and return the + mailslot name if it is, otherwise return NULL +*/ +const char *dgram_mailslot_name(struct nbt_dgram_packet *packet) +{ + if (packet->msg_type != DGRAM_DIRECT_UNIQUE && + packet->msg_type != DGRAM_DIRECT_GROUP && + packet->msg_type != DGRAM_BCAST) { + return NULL; + } + if (packet->data.msg.dgram_body_type != DGRAM_SMB) return NULL; + if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL; + if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL; + return packet->data.msg.body.smb.body.trans.mailslot_name; +} + + +/* + create a temporary mailslot handler for a reply mailslot, allocating + a new mailslot name using the given base name and a random integer extension +*/ +struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name, + dgram_mailslot_handler_t handler, + void *private) +{ + char *name; + int i; + struct dgram_mailslot_handler *dgmslot; + + /* try a 100 times at most */ + for (i=0;i<100;i++) { + name = talloc_asprintf(dgmsock, "%s%u", + mailslot_name, + generate_random() % UINT16_MAX); + if (name == NULL) return NULL; + if (dgram_mailslot_find(dgmsock, name)) { + talloc_free(name); + return NULL; + } + dgmslot = dgram_mailslot_listen(dgmsock, name, handler, private); + talloc_free(name); + return dgmslot; + } + DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name)); + return NULL; +} -- cgit From 7c6c366150022d6a745dcf18ed67bd264bc9c55d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Apr 2005 11:17:08 +0000 Subject: r6223: added a bit more datagram infrastructure and the beginnings of a test suite. The NBT-DGRAM test does a UDP/138 netlogon request, to which a windows server sends a reply, but the windows server sends the reply to the wrong port (it always sends to 138), so the test suite doesn't see it. (This used to be commit a7634625dbc944dd8256a822be290010f341a571) --- source4/libcli/config.mk | 3 +- source4/libcli/dgram/libdgram.h | 16 +++++++++-- source4/libcli/dgram/mailslot.c | 61 +++++++++++++++++++++++++++++++++++++++-- source4/libcli/dgram/netlogon.c | 58 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 source4/libcli/dgram/netlogon.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index f90f9907ad..56e923daa2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -38,7 +38,8 @@ REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS [SUBSYSTEM::LIBCLI_DGRAM] ADD_OBJ_FILES = \ libcli/dgram/dgramsocket.o \ - libcli/dgram/mailslot.o + libcli/dgram/mailslot.o \ + libcli/dgram/netlogon.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 866877e341..482fd86980 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -111,8 +111,18 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms void *private); - - - +NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, + enum dgram_msg_type msg_type, + const char *mailslot_name, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + DATA_BLOB *request); + +NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + struct nbt_netlogon_packet *request); diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index da9b6cdd20..89aab9c874 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -115,9 +115,9 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms /* try a 100 times at most */ for (i=0;i<100;i++) { - name = talloc_asprintf(dgmsock, "%s%u", + name = talloc_asprintf(dgmsock, "%s%03u", mailslot_name, - generate_random() % UINT16_MAX); + generate_random() % 1000); if (name == NULL) return NULL; if (dgram_mailslot_find(dgmsock, name)) { talloc_free(name); @@ -130,3 +130,60 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name)); return NULL; } + + +/* + send a mailslot request +*/ +NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, + enum dgram_msg_type msg_type, + const char *mailslot_name, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + DATA_BLOB *request) +{ + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + struct nbt_dgram_packet packet; + struct dgram_message *msg; + struct dgram_smb_packet *smb; + struct smb_trans_body *trans; + NTSTATUS status; + + ZERO_STRUCT(packet); + packet.msg_type = msg_type; + packet.flags = DGRAM_FLAG_FIRST; + packet.dgram_id = generate_random() % UINT16_MAX; + packet.source = socket_get_my_addr(dgmsock->sock, tmp_ctx); + packet.src_port = socket_get_my_port(dgmsock->sock); + + msg = &packet.data.msg; + /* this length calculation is very crude - it should be based on gensize + calls */ + msg->length = 138 + strlen(mailslot_name) + request->length; + msg->offset = 0; + + msg->source_name = *src_name; + msg->dest_name = *dest_name; + msg->dgram_body_type = DGRAM_SMB; + + smb = &msg->body.smb; + smb->smb_command = SMB_TRANSACTION; + + trans = &smb->body.trans; + trans->total_data_count = request->length; + trans->timeout = (uint32_t)-1; + trans->data_count = request->length; + trans->data_offset = 70 + strlen(mailslot_name); + trans->opcode = 1; /* write mail slot */ + trans->priority = 1; + trans->class = 2; + trans->mailslot_name = mailslot_name; + trans->data = *request; + + status = nbt_dgram_send(dgmsock, &packet, dest_address, lp_dgram_port()); + + talloc_free(tmp_ctx); + + return status; +} diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c new file mode 100644 index 0000000000..1f3a3d6c62 --- /dev/null +++ b/source4/libcli/dgram/netlogon.c @@ -0,0 +1,58 @@ +/* + Unix SMB/CIFS implementation. + + handling for netlogon dgram requests + + Copyright (C) Andrew Tridgell 2005 + + 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 "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" + +/* + send a netlogon mailslot request +*/ +NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + struct nbt_netlogon_packet *request) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + + status = ndr_push_struct_blob(&blob, tmp_ctx, request, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + "\\MAILSLOT\\NET\\NETLOGON", + dest_name, dest_address, src_name, &blob); + talloc_free(tmp_ctx); + return status; +} + -- cgit From f83e6ded9d31f819dba5e59e15c703d292716206 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Apr 2005 05:34:13 +0000 Subject: r6245: receive and parse the GETDC response in the NBT-DGRAM test. The test now tries to bind to port 138 if possible, so if you run it as root and smbd/nmbd is not running then it works against windows servers (This used to be commit 52ccdb79bc922be52c24dd393323dbbee83a2aea) --- source4/libcli/dgram/libdgram.h | 6 ++++-- source4/libcli/dgram/mailslot.c | 2 ++ source4/libcli/dgram/netlogon.c | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 482fd86980..0b8157f0c6 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -124,5 +124,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, const char *dest_address, struct nbt_name *src_name, struct nbt_netlogon_packet *request); - - +NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon); diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 89aab9c874..3b7fcdcd81 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -64,6 +64,8 @@ struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dg DLIST_ADD(dgmsock->mailslot_handlers, dgmslot); talloc_set_destructor(dgmslot, dgram_mailslot_destructor); + EVENT_FD_READABLE(dgmsock->fde); + return dgmslot; } diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 1f3a3d6c62..c76264eea4 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -56,3 +56,19 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, return status; } + +/* + parse a netlogon response. The packet must be a valid mailslot packet +*/ +NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon) +{ + DATA_BLOB *data = &dgram->data.msg.body.smb.body.trans.data; + NTSTATUS status; + + status = ndr_pull_struct_blob(data, mem_ctx, netlogon, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); + return status; +} -- cgit From b0ca8ed4559efae38933f49a638e7b51ae8bf0c8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Apr 2005 08:57:09 +0000 Subject: r6247: added the server side code for receiving mailslot requests, and parsing incoming netlogon requests. No replies are sent yet. (This used to be commit 3b34df6a674cd2aeddc354cdadae3f0e1c000d45) --- source4/libcli/dgram/dgramsocket.c | 2 +- source4/libcli/dgram/netlogon.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 33734258a3..a3909df768 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -59,7 +59,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) talloc_steal(tmp_ctx, src_addr); blob.length = nread; - DEBUG(0,("Received dgram packet of length %d from %s:%d\n", + DEBUG(2,("Received dgram packet of length %d from %s:%d\n", blob.length, src_addr, src_port)); packet = talloc(tmp_ctx, struct nbt_dgram_packet); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index c76264eea4..a0218e2cb5 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -50,7 +50,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - "\\MAILSLOT\\NET\\NETLOGON", + NBT_MAILSLOT_NETLOGON, dest_name, dest_address, src_name, &blob); talloc_free(tmp_ctx); return status; -- cgit From ce7eb419307de28b6a674948a70960a39e0c38f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Apr 2005 09:38:16 +0000 Subject: r6248: added parsing of type 10 UAS announce netlogon packets (This used to be commit d7e6e395cedef47dc182094c91f764e248b9b149) --- source4/libcli/dgram/netlogon.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index a0218e2cb5..869e99e2fc 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -70,5 +70,12 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, status = ndr_pull_struct_blob(data, mem_ctx, netlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to parse netlogon packet of length %d\n", + data->length)); +#if 0 + file_save("netlogon.dat", data->data, data->length); +#endif + } return status; } -- cgit From e7dd6a12913464fd752ddb94bd2f553f14007c74 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Apr 2005 23:08:04 +0000 Subject: r6287: sorted out a small but surprisingly tricky dependency problem with the ndr code for handling sids and security descriptors now that we have a sid in the nbt IDL (This used to be commit f8e77fcdeac704aed5e501aa9108f3ed0ab26ca4) --- source4/libcli/security/config.mk | 8 ++++++++ source4/libcli/security/dom_sid.c | 32 -------------------------------- 2 files changed, 8 insertions(+), 32 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index d6896535d6..40987e37e2 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,8 +1,16 @@ +################################# +# Start SUBSYSTEM LIB_SECURITY_NDR_HELPER +[SUBSYSTEM::LIB_SECURITY_NDR_HELPER] +ADD_OBJ_FILES = librpc/ndr/ndr_sec_helper.o +# End SUBSYSTEM LIB_SECURITY_NDR_HELPER +################################# + ################################# # Start SUBSYSTEM LIB_SECURITY_NDR [SUBSYSTEM::LIB_SECURITY_NDR] ADD_OBJ_FILES = librpc/gen_ndr/ndr_security.o NOPROTO = YES +REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR_HELPER # End SUBSYSTEM LIB_SECURITY_NDR ################################# diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 493ecab183..80e481c3e4 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -84,38 +84,6 @@ BOOL dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) return dom_sid_compare(sid1, sid2) == 0; } -/* - convert a dom_sid to a string -*/ -char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) -{ - int i, ofs, maxlen; - uint32_t ia; - char *ret; - - if (!sid) { - return talloc_strdup(mem_ctx, "(NULL SID)"); - } - - maxlen = sid->num_auths * 11 + 25; - ret = talloc_size(mem_ctx, maxlen); - if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); - - ia = (sid->id_auth[5]) + - (sid->id_auth[4] << 8 ) + - (sid->id_auth[3] << 16) + - (sid->id_auth[2] << 24); - - ofs = snprintf(ret, maxlen, "S-%u-%lu", - (uint_t)sid->sid_rev_num, (unsigned long)ia); - - for (i = 0; i < sid->num_auths; i++) { - ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); - } - - return ret; -} - /* convert a string to a dom_sid, returning a talloc'd dom_sid -- cgit From b708e87a63947bc963d17592ac88022b708816c3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Apr 2005 23:09:38 +0000 Subject: r6288: the nbt dgram server now responds to GETDC requests. It works with our test suite, but doesn't yet seem to satisfy a nt4 client. I'm investigating. (This used to be commit 406217262dff5adb5d0cb0028198e08f66cc85f4) --- source4/libcli/dgram/libdgram.h | 6 ++++++ source4/libcli/dgram/mailslot.c | 7 ++++++- source4/libcli/dgram/netlogon.c | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 0b8157f0c6..163cb1e37d 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -116,14 +116,20 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, const char *mailslot_name, struct nbt_name *dest_name, const char *dest_address, + int dest_port, struct nbt_name *src_name, DATA_BLOB *request); NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, const char *dest_address, + int dest_port, struct nbt_name *src_name, struct nbt_netlogon_packet *request); +NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_netlogon_packet *reply); NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 3b7fcdcd81..1035853240 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -142,6 +142,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, const char *mailslot_name, struct nbt_name *dest_name, const char *dest_address, + int dest_port, struct nbt_name *src_name, DATA_BLOB *request) { @@ -152,6 +153,10 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, struct smb_trans_body *trans; NTSTATUS status; + if (dest_port == 0) { + dest_port = lp_dgram_port(); + } + ZERO_STRUCT(packet); packet.msg_type = msg_type; packet.flags = DGRAM_FLAG_FIRST; @@ -183,7 +188,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, trans->mailslot_name = mailslot_name; trans->data = *request; - status = nbt_dgram_send(dgmsock, &packet, dest_address, lp_dgram_port()); + status = nbt_dgram_send(dgmsock, &packet, dest_address, dest_port); talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 869e99e2fc..138cc0d484 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -34,6 +34,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, const char *dest_address, + int dest_port, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -51,7 +52,37 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, NBT_MAILSLOT_NETLOGON, - dest_name, dest_address, src_name, &blob); + dest_name, dest_address, dest_port, + src_name, &blob); + talloc_free(tmp_ctx); + return status; +} + + +/* + send a netlogon mailslot reply +*/ +NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_netlogon_packet *reply) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + + status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + mailslot_name, + &request->data.msg.source_name, + request->source, request->src_port, + &request->data.msg.dest_name, &blob); talloc_free(tmp_ctx); return status; } -- cgit From b6fd09d80504d55be98b167cd12b5507573d32db Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Apr 2005 03:43:17 +0000 Subject: r6320: some minor netlogon datagram fixes - NT4 can now join a Samba4 domain without Samba3 nmbd (This used to be commit 4507bdc339505e91118d403948946f4a98a4f562) --- source4/libcli/dgram/mailslot.c | 4 ++-- source4/libcli/dgram/netlogon.c | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 1035853240..ca9a66a729 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -159,7 +159,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, ZERO_STRUCT(packet); packet.msg_type = msg_type; - packet.flags = DGRAM_FLAG_FIRST; + packet.flags = DGRAM_FLAG_FIRST | DGRAM_NODE_NBDD; packet.dgram_id = generate_random() % UINT16_MAX; packet.source = socket_get_my_addr(dgmsock->sock, tmp_ctx); packet.src_port = socket_get_my_port(dgmsock->sock); @@ -179,7 +179,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, trans = &smb->body.trans; trans->total_data_count = request->length; - trans->timeout = (uint32_t)-1; + trans->timeout = 1000; trans->data_count = request->length; trans->data_offset = 70 + strlen(mailslot_name); trans->opcode = 1; /* write mail slot */ diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 138cc0d484..a030ca73c2 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -70,6 +70,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, NTSTATUS status; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + struct nbt_name myname; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); @@ -78,11 +79,15 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, return status; } + myname.name = lp_netbios_name(); + myname.type = NBT_NAME_CLIENT; + myname.scope = NULL; + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, request->source, request->src_port, - &request->data.msg.dest_name, &blob); + &myname, &blob); talloc_free(tmp_ctx); return status; } -- cgit From f06e39e30866207162656801210d2f574166d4df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Apr 2005 05:07:04 +0000 Subject: r6321: added IDL and test suite for NBT dgram 'sam logon' request (sent by clients when a user tries to login) (This used to be commit 08ded62156b387457bc56b5910e1ddc813b375bd) --- source4/libcli/config.mk | 3 +- source4/libcli/dgram/libdgram.h | 15 ++++++ source4/libcli/dgram/ntlogon.c | 117 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/dgram/ntlogon.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 56e923daa2..def7bd0f27 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -39,7 +39,8 @@ REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS ADD_OBJ_FILES = \ libcli/dgram/dgramsocket.o \ libcli/dgram/mailslot.o \ - libcli/dgram/netlogon.o + libcli/dgram/netlogon.o \ + libcli/dgram/ntlogon.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 163cb1e37d..af278d2ab6 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -134,3 +134,18 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, struct nbt_netlogon_packet *netlogon); + +NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + const char *dest_address, + int dest_port, + struct nbt_name *src_name, + struct nbt_ntlogon_packet *request); +NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_ntlogon_packet *reply); +NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_ntlogon_packet *ntlogon); diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c new file mode 100644 index 0000000000..7f18e8cec6 --- /dev/null +++ b/source4/libcli/dgram/ntlogon.c @@ -0,0 +1,117 @@ +/* + Unix SMB/CIFS implementation. + + handling for ntlogon dgram requests + + Copyright (C) Andrew Tridgell 2005 + + 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 "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" + +/* + send a ntlogon mailslot request +*/ +NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + const char *dest_address, + int dest_port, + struct nbt_name *src_name, + struct nbt_ntlogon_packet *request) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + + status = ndr_push_struct_blob(&blob, tmp_ctx, request, + (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + NBT_MAILSLOT_NTLOGON, + dest_name, dest_address, dest_port, + src_name, &blob); + talloc_free(tmp_ctx); + return status; +} + + +/* + send a ntlogon mailslot reply +*/ +NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_ntlogon_packet *reply) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + struct nbt_name myname; + + status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + myname.name = lp_netbios_name(); + myname.type = NBT_NAME_CLIENT; + myname.scope = NULL; + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + mailslot_name, + &request->data.msg.source_name, + request->source, request->src_port, + &myname, &blob); + talloc_free(tmp_ctx); + return status; +} + + +/* + parse a ntlogon response. The packet must be a valid mailslot packet +*/ +NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_ntlogon_packet *ntlogon) +{ + DATA_BLOB *data = &dgram->data.msg.body.smb.body.trans.data; + NTSTATUS status; + + status = ndr_pull_struct_blob(data, mem_ctx, ntlogon, + (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to parse ntlogon packet of length %d\n", + data->length)); +#if 0 + file_save("ntlogon.dat", data->data, data->length); +#endif + } + return status; +} -- cgit From 63ddff3d7b59fef8c8f2340803b85cde33a49402 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Apr 2005 05:50:02 +0000 Subject: r6323: added server side support for dgram NTLOGON requests. NT4 workstations can now login to a Samba4 domain. (This used to be commit df146d64ebce6b462c08a1f30919390fcf8196cb) --- source4/libcli/dgram/libdgram.h | 1 + source4/libcli/dgram/mailslot.c | 20 +++++++++++++++++++- source4/libcli/dgram/netlogon.c | 8 ++++---- source4/libcli/dgram/ntlogon.c | 8 ++++---- 4 files changed, 28 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index af278d2ab6..b8ca9e2fe5 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -109,6 +109,7 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms const char *mailslot_name, dgram_mailslot_handler_t handler, void *private); +DATA_BLOB dgram_mailslot_data(struct nbt_dgram_packet *dgram); NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index ca9a66a729..d7c0870ded 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -167,7 +167,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, msg = &packet.data.msg; /* this length calculation is very crude - it should be based on gensize calls */ - msg->length = 138 + strlen(mailslot_name) + request->length; + msg->length = 138 + strlen(mailslot_name) + request->length; msg->offset = 0; msg->source_name = *src_name; @@ -194,3 +194,21 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, return status; } + +/* + return the mailslot data portion from a mailslot packet +*/ +DATA_BLOB dgram_mailslot_data(struct nbt_dgram_packet *dgram) +{ + struct smb_trans_body *trans = &dgram->data.msg.body.smb.body.trans; + DATA_BLOB ret = trans->data; + int pad = trans->data_offset - (70 + strlen(trans->mailslot_name)); + + if (pad < 0 || pad > ret.length) { + DEBUG(2,("Badly formatted data in mailslot - pad = %d\n", pad)); + return data_blob(NULL, 0); + } + ret.data += pad; + ret.length -= pad; + return ret; +} diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index a030ca73c2..208117845b 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -101,16 +101,16 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *dgram, struct nbt_netlogon_packet *netlogon) { - DATA_BLOB *data = &dgram->data.msg.body.smb.body.trans.data; + DATA_BLOB data = dgram_mailslot_data(dgram); NTSTATUS status; - status = ndr_pull_struct_blob(data, mem_ctx, netlogon, + status = ndr_pull_struct_blob(&data, mem_ctx, netlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse netlogon packet of length %d\n", - data->length)); + data.length)); #if 0 - file_save("netlogon.dat", data->data, data->length); + file_save("netlogon.dat", data.data, data.length); #endif } return status; diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 7f18e8cec6..1c1f138b1e 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -101,16 +101,16 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *dgram, struct nbt_ntlogon_packet *ntlogon) { - DATA_BLOB *data = &dgram->data.msg.body.smb.body.trans.data; + DATA_BLOB data = dgram_mailslot_data(dgram); NTSTATUS status; - status = ndr_pull_struct_blob(data, mem_ctx, ntlogon, + status = ndr_pull_struct_blob(&data, mem_ctx, ntlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse ntlogon packet of length %d\n", - data->length)); + data.length)); #if 0 - file_save("ntlogon.dat", data->data, data->length); + file_save("ntlogon.dat", data.data, data.length); #endif } return status; -- cgit From 8d0a36366c741d0ae9302f1ac8cc6894033be687 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Apr 2005 02:36:30 +0000 Subject: r6331: added IDL and test suite for the ADS style response to a datagram netlogon query. Note that this response is almost identical to the CLDAP netlogon response, so adding that will now be quite easy. (This used to be commit 1ea4ed4ad1d9336f8288283688fa2d7bebfa533c) --- source4/libcli/nbt/nbtname.c | 206 +++++++++++++++++++++++++++---------------- 1 file changed, 128 insertions(+), 78 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 12b8884e2d..f7d19d11cf 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -32,7 +32,15 @@ #define MAX_COMPONENTS 10 /* - pull one component of a compressed name + print a nbt string +*/ +void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) +{ + return ndr_print_string(ndr, name, s); +} + +/* + pull one component of a nbt_string */ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, uint32_t *offset, uint32_t *max_offset) @@ -79,6 +87,97 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, return NT_STATUS_BAD_NETWORK_NAME; } +/* + pull a nbt_string from the wire +*/ +NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) +{ + NTSTATUS status; + uint32_t offset = ndr->offset; + uint32_t max_offset = offset; + unsigned num_components; + char *name; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + name = NULL; + + /* break up name into a list of components */ + for (num_components=0;num_componentsoffset = max_offset; + + return NT_STATUS_OK; +} + +/* + push a nbt string to the wire +*/ +NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) +{ + int i; + int fulllen; + char *fullname; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + fullname = talloc_strdup(ndr, ""); + NT_STATUS_HAVE_NO_MEMORY(fullname); + + while (*s) { + int len = strcspn(s, "."); + fullname = talloc_asprintf_append(fullname, "%c%*.*s", + (unsigned char)len, + (unsigned char)len, + (unsigned char)len, s); + NT_STATUS_HAVE_NO_MEMORY(fullname); + s += len; + if (*s == '.') s++; + } + + /* see if we can find the fullname in the existing packet - if + so, we can use a NBT name pointer. This allows us to fit + longer names into the packet */ + fulllen = strlen(fullname)+1; + for (i=0;i + fulllen < ndr->offset;i++) { + if (ndr->data[i] == fullname[0] && + memcmp(fullname, &ndr->data[i], fulllen) == 0) { + talloc_free(fullname); + return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i); + } + } + + NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen)); + + talloc_free(fullname); + + return NT_STATUS_OK; +} + + /* decompress a 'compressed' name component */ @@ -151,57 +250,49 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, return cname; } + /* pull a nbt name from the wire */ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) { NTSTATUS status; - uint_t num_components; - uint32_t offset = ndr->offset; - uint32_t max_offset = offset; - uint8_t *components[MAX_COMPONENTS]; - int i; uint8_t *scope; + char *cname; + const char *s; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - /* break up name into a list of components */ - for (num_components=0;num_componentsscope = talloc_strdup(ndr, scope+1); + NT_STATUS_HAVE_NO_MEMORY(r->scope); + } else { + r->scope = NULL; } - ndr->offset = max_offset; + cname = discard_const_p(char, s); /* the first component is limited to 16 bytes in the DOS charset, which is 32 in the 'compressed' form */ - if (strlen(components[0]) > 32) { + if (strlen(cname) > 32) { return NT_STATUS_BAD_NETWORK_NAME; } /* decompress the first component */ - status = decompress_name(components[0], &r->type); + status = decompress_name(cname, &r->type); NT_STATUS_NOT_OK_RETURN(status); - r->name = components[0]; - - /* combine the remaining components into the scope */ - scope = components[1]; - for (i=2;iname = talloc_strdup(ndr, cname); + NT_STATUS_HAVE_NO_MEMORY(r->name); - r->scope = scope; + talloc_free(cname); return NT_STATUS_OK; } @@ -211,69 +302,28 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name */ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name *r) { - uint_t num_components; - uint8_t *components[MAX_COMPONENTS]; - char *dscope=NULL, *p; uint8_t *cname, *fullname; - int i; - int fulllen; + NTSTATUS status; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - if (r->scope) { - dscope = talloc_strdup(ndr, r->scope); - NT_STATUS_HAVE_NO_MEMORY(dscope); - } - cname = compress_name(ndr, r->name, r->type); NT_STATUS_HAVE_NO_MEMORY(cname); - /* form the base components */ - components[0] = cname; - num_components = 1; - - while (dscope && (p=strchr(dscope, '.')) && - num_components < MAX_COMPONENTS) { - *p = 0; - components[num_components] = dscope; - dscope = p+1; - num_components++; - } - if (dscope && num_components < MAX_COMPONENTS) { - components[num_components++] = dscope; - } - if (num_components == MAX_COMPONENTS) { - return NT_STATUS_BAD_NETWORK_NAME; - } - - fullname = talloc_asprintf(ndr, "%c%s", (unsigned char)strlen(cname), cname); - NT_STATUS_HAVE_NO_MEMORY(fullname); - - for (i=1;iscope) { + fullname = talloc_asprintf(ndr, "%s.%s", cname, r->scope); NT_STATUS_HAVE_NO_MEMORY(fullname); + talloc_free(cname); + } else { + fullname = cname; } - - /* see if we can find the fullname in the existing packet - if - so, we can use a NBT name pointer. This allows us to fit - longer names into the packet */ - fulllen = strlen(fullname)+1; - for (i=0;i + fulllen < ndr->offset;i++) { - if (ndr->data[i] == fullname[0] && - memcmp(fullname, &ndr->data[i], fulllen) == 0) { - talloc_free(fullname); - return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i); - } - } - - NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen)); - + + status = ndr_push_nbt_string(ndr, ndr_flags, fullname); talloc_free(fullname); - return NT_STATUS_OK; + return status; } -- cgit From a451bc70e074f8f35f968b3ef1fc3daddb55590c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Apr 2005 05:52:54 +0000 Subject: r6333: removed an extraneous line (pointed out by metze) (This used to be commit 61d65d100d38529966f3f1803f66ed47540dc852) --- source4/libcli/dgram/mailslot.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index d7c0870ded..9f02210646 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -97,7 +97,6 @@ const char *dgram_mailslot_name(struct nbt_dgram_packet *packet) } if (packet->data.msg.dgram_body_type != DGRAM_SMB) return NULL; if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL; - if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL; return packet->data.msg.body.smb.body.trans.mailslot_name; } -- cgit From 8c4e06004cf5e95ea861440ef0ec0b4ddacf4c10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Apr 2005 05:55:32 +0000 Subject: r6335: at debug level 10, save netlogon and ntlogon packets that fail to parse (This used to be commit c29279355c679e821665d028f207ee9ed6f857ef) --- source4/libcli/dgram/netlogon.c | 6 +++--- source4/libcli/dgram/ntlogon.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 208117845b..6e939725d0 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -109,9 +109,9 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse netlogon packet of length %d\n", data.length)); -#if 0 - file_save("netlogon.dat", data.data, data.length); -#endif + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data.data, data.length); + } } return status; } diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 1c1f138b1e..38651a4085 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -109,9 +109,9 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse ntlogon packet of length %d\n", data.length)); -#if 0 - file_save("ntlogon.dat", data.data, data.length); -#endif + if (DEBUGLVL(10)) { + file_save("ntlogon.dat", data.data, data.length); + } } return status; } -- cgit From e284a262942eb8c69d7862cb61bf4542baec6032 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Apr 2005 07:40:23 +0000 Subject: r6338: ADS style GETDC response now works well enough that WinXP can join Samba4 without Samba3 nmbd (This used to be commit f4d07d7d3b6973b503d8c98f177471dd6cebfa92) --- source4/libcli/nbt/nbtname.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index f7d19d11cf..5f344d9c6d 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -144,6 +144,11 @@ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) return NT_STATUS_OK; } + if (s == NULL || *s == 0) { + return ndr_push_bytes(ndr, "", 1); + } + + fullname = talloc_strdup(ndr, ""); NT_STATUS_HAVE_NO_MEMORY(fullname); @@ -162,11 +167,14 @@ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) so, we can use a NBT name pointer. This allows us to fit longer names into the packet */ fulllen = strlen(fullname)+1; - for (i=0;i + fulllen < ndr->offset;i++) { + for (i=0;i + fulllen <= ndr->offset;i++) { if (ndr->data[i] == fullname[0] && memcmp(fullname, &ndr->data[i], fulllen) == 0) { + uint8_t b[2]; talloc_free(fullname); - return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i); + b[0] = 0xC0 | (i>>8); + b[1] = (i&0xFF); + return ndr_push_bytes(ndr, b, 2); } } -- cgit From d9c15b0f280621fca844c0e8482b5e95f4ad2d11 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Apr 2005 13:19:40 +0000 Subject: r6342: fixed a bad union assumption that caused ACLs to fail on 64 bit machines Thanks to lars and agruen for finding this (This used to be commit 2acc06918574b1178eecf3d61026f84f85bb40e1) --- source4/libcli/raw/rawacl.c | 2 +- source4/libcli/raw/rawfileinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 82c69ec706..e168da9d1d 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -40,7 +40,7 @@ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, SSVAL(params, 0, io->query_secdesc.in.fnum); SSVAL(params, 2, 0); /* padding */ - SIVAL(params, 4, io->query_secdesc.in.secinfo_flags); + SIVAL(params, 4, io->query_secdesc.secinfo_flags); nt.in.params.data = params; nt.in.params.length = 8; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 88c2f0d0fc..9f7786429c 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -310,7 +310,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre return NULL; } - SIVAL(tp.in.params.data, 0, fnum); + SSVAL(tp.in.params.data, 0, fnum); SSVAL(tp.in.params.data, 2, info_level); req = smb_raw_trans2_send(tree, &tp); -- cgit From 9779e6d670d19a5dfdc034084b580653d5ca0670 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Fri, 15 Apr 2005 14:45:00 +0000 Subject: r6352: Two new composite calls: - qfsinfo (query file system information) - appendacl (append an ACL to existing file's security descriptor and get new full ACL) The second one also includes an improvement to security descriptor handling which allows to copy security descriptor. Written by Peter Novodvorsky Both functions have corresponding torture tests added. Tested under valgrind and work against Samba 4 and Windows XP. ToDo: document composite call creation process in prog_guide.txt (This used to be commit 441cff62ac75ed16851ce7b8daf9d03eb4c3ec79) --- source4/libcli/composite/appendacl.c | 311 ++++++++++++++++++++++++++ source4/libcli/composite/composite.h | 37 +++ source4/libcli/composite/fsinfo.c | 200 +++++++++++++++++ source4/libcli/config.mk | 4 +- source4/libcli/security/security_descriptor.c | 80 ++++++- 5 files changed, 628 insertions(+), 4 deletions(-) create mode 100644 source4/libcli/composite/appendacl.c create mode 100644 source4/libcli/composite/fsinfo.c (limited to 'source4/libcli') diff --git a/source4/libcli/composite/appendacl.c b/source4/libcli/composite/appendacl.c new file mode 100644 index 0000000000..76702e6bca --- /dev/null +++ b/source4/libcli/composite/appendacl.c @@ -0,0 +1,311 @@ +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum appendacl_stage {APPENDACL_OPENPATH, APPENDACL_GET, + APPENDACL_SET, APPENDACL_GETAGAIN, APPENDACL_CLOSEPATH}; + +static void appendacl_handler(struct smbcli_request *req); + +struct appendacl_state { + enum appendacl_stage stage; + struct smb_composite_appendacl *io; + + union smb_open *io_open; + union smb_setfileinfo *io_setfileinfo; + union smb_fileinfo *io_fileinfo; + + struct smbcli_request *req; +}; + + +static NTSTATUS appendacl_open(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + + status = smb_raw_open_recv(state->req, c, state->io_open); + NT_STATUS_NOT_OK_RETURN(status); + + /* setup structures for getting fileinfo */ + state->io_fileinfo = talloc(c, union smb_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); + + state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; + state->io_fileinfo->query_secdesc.in.fnum = state->io_open->ntcreatex.out.fnum; + state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; + + state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* set the handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_GET; + + talloc_free (state->io_open); + + return NT_STATUS_OK; +} + +static NTSTATUS appendacl_get(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + int i; + NTSTATUS status; + + status = smb_raw_fileinfo_recv(state->req, state->io_fileinfo, state->io_fileinfo); + NT_STATUS_NOT_OK_RETURN(status); + + /* setup structures for setting fileinfo */ + state->io_setfileinfo = talloc(c, union smb_setfileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo); + + state->io_setfileinfo->set_secdesc.level = RAW_SFILEINFO_SEC_DESC; + state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.in.fnum; + + state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL; + state->io_setfileinfo->set_secdesc.in.sd = state->io_fileinfo->query_secdesc.out.sd; + talloc_steal(state->io_setfileinfo, state->io_setfileinfo->set_secdesc.in.sd); + + /* append all aces from io->in.sd->dacl to new security descriptor */ + if (io->in.sd->dacl != NULL) { + for (i = 0; i < io->in.sd->dacl->num_aces; i++) { + security_descriptor_dacl_add(state->io_setfileinfo->set_secdesc.in.sd, + &(io->in.sd->dacl->aces[i])); + } + } + + status = smb_raw_setfileinfo(tree, state->io_setfileinfo); + NT_STATUS_NOT_OK_RETURN(status); + + state->req = smb_raw_setfileinfo_send(tree, state->io_setfileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call handler when done setting new security descriptor on file */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_SET; + + talloc_free (state->io_fileinfo); + + return NT_STATUS_OK; +} + +static NTSTATUS appendacl_set(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + + status = smbcli_request_simple_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + /* setup structures for getting fileinfo */ + state->io_fileinfo = talloc(c, union smb_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); + + + state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; + state->io_fileinfo->query_secdesc.in.fnum = state->io_setfileinfo->set_secdesc.file.fnum; + state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; + + state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* set the handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_GETAGAIN; + + talloc_free (state->io_setfileinfo); + + return NT_STATUS_OK; +} + + +static NTSTATUS appendacl_getagain(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + union smb_close *io_close; + NTSTATUS status; + + status = smb_raw_fileinfo_recv(state->req, c, state->io_fileinfo); + NT_STATUS_NOT_OK_RETURN(status); + + io->out.sd = state->io_fileinfo->query_secdesc.out.sd; + + /* setup structures for close */ + io_close = talloc(c, union smb_close); + NT_STATUS_HAVE_NO_MEMORY(io_close); + + io_close->close.level = RAW_CLOSE_CLOSE; + io_close->close.in.fnum = state->io_fileinfo->query_secdesc.in.fnum; + io_close->close.in.write_time = 0; + + state->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_CLOSEPATH; + + talloc_free (state->io_fileinfo); + + return NT_STATUS_OK; +} + + + +static NTSTATUS appendacl_close(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + NTSTATUS status; + + status = smbcli_request_simple_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + c->state = SMBCLI_REQUEST_DONE; + + return NT_STATUS_OK; +} + +/* + handler for completion of a sub-request in appendacl +*/ +static void appendacl_handler(struct smbcli_request *req) +{ + struct composite_context *c = req->async.private; + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case APPENDACL_OPENPATH: + c->status = appendacl_open(c, state->io); + break; + + case APPENDACL_GET: + c->status = appendacl_get(c, state->io); + break; + + case APPENDACL_SET: + c->status = appendacl_set(c, state->io); + break; + + case APPENDACL_GETAGAIN: + c->status = appendacl_getagain(c, state->io); + break; + + case APPENDACL_CLOSEPATH: + c->status = appendacl_close(c, state->io); + break; + } + + /* We should get here if c->state >= SMBCLI_REQUEST_DONE */ + if (!NT_STATUS_IS_OK(c->status)) { + c->state = SMBCLI_REQUEST_ERROR; + } + + if (c->state >= SMBCLI_REQUEST_DONE && + c->async.fn) { + c->async.fn(c); + } +} + + +/* + composite appendacl call - does an open followed by a number setfileinfo, + after that new acls are read with fileinfo, followed by a close +*/ +struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree, + struct smb_composite_appendacl *io) +{ + struct composite_context *c; + struct appendacl_state *state; + + c = talloc_zero(tree, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct appendacl_state); + if (state == NULL) goto failed; + + state->io = io; + + c->private = state; + c->state = SMBCLI_REQUEST_SEND; + c->event_ctx = tree->session->transport->socket->event.ctx; + + /* setup structures for opening file */ + state->io_open = talloc_zero(c, union smb_open); + if (state->io_open == NULL) goto failed; + + state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + state->io_open->ntcreatex.in.root_fid = 0; + state->io_open->ntcreatex.in.flags = 0; + state->io_open->ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + state->io_open->ntcreatex.in.security_flags = 0; + state->io_open->ntcreatex.in.fname = io->in.fname; + + /* send the open on its way */ + state->req = smb_raw_open_send(tree, state->io_open); + if (state->req == NULL) goto failed; + + /* setup the callback handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_OPENPATH; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + composite appendacl call - recv side +*/ +NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); + state->io->out.sd = security_descriptor_copy (mem_ctx, state->io->out.sd); + } + + talloc_free(c); + return status; +} + + +/* + composite appendacl call - sync interface +*/ +NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_composite_appendacl *io) +{ + struct composite_context *c = smb_composite_appendacl_send(tree, io); + return smb_composite_appendacl_recv(c, mem_ctx); +} + diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 18922127ee..87e7a7b6ad 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -135,3 +135,40 @@ struct smb_composite_sesssetup { uint16_t vuid; } out; }; + +/* + query file system info +*/ +struct smb_composite_fsinfo { + struct { + const char *dest_host; + int port; + const char *called_name; + const char *service; + const char *service_type; + struct cli_credentials *credentials; + const char *workgroup; + enum smb_fsinfo_level level; + } in; + + struct { + union smb_fsinfo *fsinfo; + } out; +}; + +/* + composite call for appending new acl to the file's security descriptor and get + new full acl +*/ + +struct smb_composite_appendacl { + struct { + const char *fname; + + const struct security_descriptor *sd; + } in; + + struct { + struct security_descriptor *sd; + } out; +}; diff --git a/source4/libcli/composite/fsinfo.c b/source4/libcli/composite/fsinfo.c new file mode 100644 index 0000000000..1ad8a18149 --- /dev/null +++ b/source4/libcli/composite/fsinfo.c @@ -0,0 +1,200 @@ +/* + a composite API for quering file system information +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY}; + + +static void fsinfo_raw_handler(struct smbcli_request *req); +static void fsinfo_composite_handler(struct composite_context *c); +static void fsinfo_state_handler(struct composite_context *c); + +struct fsinfo_state { + enum fsinfo_stage stage; + struct composite_context *creq; + struct smb_composite_fsinfo *io; + struct smb_composite_connect *connect; + union smb_fsinfo *fsinfo; + struct smbcli_tree *tree; + struct smbcli_request *req; +}; + +static NTSTATUS fsinfo_connect(struct composite_context *c, + struct smb_composite_fsinfo *io) +{ + NTSTATUS status; + struct fsinfo_state *state; + state = talloc_get_type(c->private, struct fsinfo_state); + + status = smb_composite_connect_recv(state->creq, c); + NT_STATUS_NOT_OK_RETURN(status); + + state->fsinfo = talloc(state, union smb_fsinfo); + NT_STATUS_HAVE_NO_MEMORY(state->fsinfo); + + state->fsinfo->generic.level = io->in.level; + + state->req = smb_raw_fsinfo_send(state->connect->out.tree, + state, + state->fsinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + state->req->async.private = c; + state->req->async.fn = fsinfo_raw_handler; + + state->stage = FSINFO_QUERY; + c->event_ctx = talloc_reference(c, state->req->session->transport->socket->event.ctx); + + return NT_STATUS_OK; +} + +static NTSTATUS fsinfo_query(struct composite_context *c, + struct smb_composite_fsinfo *io) +{ + NTSTATUS status; + struct fsinfo_state *state; + state = talloc_get_type(c->private, struct fsinfo_state); + + status = smb_raw_fsinfo_recv(state->req, state, state->fsinfo); + NT_STATUS_NOT_OK_RETURN(status); + + state->io->out.fsinfo = state->fsinfo; + + c->state = SMBCLI_REQUEST_DONE; + + if (c->async.fn) + c->async.fn(c); + + return NT_STATUS_OK; + +} + +/* + handler for completion of a sub-request in fsinfo +*/ +static void fsinfo_state_handler(struct composite_context *req) +{ + struct fsinfo_state *state = talloc_get_type(req->private, struct fsinfo_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case FSINFO_CONNECT: + req->status = fsinfo_connect(req, state->io); + break; + + case FSINFO_QUERY: + req->status = fsinfo_query(req, state->io); + break; + } + + if (!NT_STATUS_IS_OK(req->status)) { + req->state = SMBCLI_REQUEST_ERROR; + } + + if (req->state >= SMBCLI_REQUEST_DONE && req->async.fn) { + req->async.fn(req); + } +} + +/* + As raw and composite handlers take different requests, we need to handlers + to adapt both for the same state machine in fsinfo_state_handler() +*/ +static void fsinfo_raw_handler(struct smbcli_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + return fsinfo_state_handler(c); +} + +static void fsinfo_composite_handler(struct composite_context *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + return fsinfo_state_handler(c); +} + +/* + composite fsinfo call - connects to a tree and queries a file system information +*/ +struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, + struct smb_composite_fsinfo *io) +{ + struct composite_context *c; + struct fsinfo_state *state; + + c = talloc_zero(tree, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct fsinfo_state); + if (state == NULL) goto failed; + + state->io = io; + + state->connect = talloc(state, struct smb_composite_connect); + + if (state->connect == NULL) goto failed; + + state->connect->in.dest_host = io->in.dest_host; + state->connect->in.port = io->in.port; + state->connect->in.called_name = io->in.called_name; + state->connect->in.service = io->in.service; + state->connect->in.service_type = io->in.service_type; + state->connect->in.credentials = io->in.credentials; + state->connect->in.workgroup = io->in.workgroup; + + c->state = SMBCLI_REQUEST_SEND; + state->stage = FSINFO_CONNECT; + c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); + c->private = state; + + state->creq = smb_composite_connect_send(state->connect, c->event_ctx); + + if (state->creq == NULL) goto failed; + + state->creq->async.private = c; + state->creq->async.fn = fsinfo_composite_handler; + + return c; +failed: + talloc_free(c); + return NULL; +} + +/* + composite fsinfo call - recv side +*/ +NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct fsinfo_state *state = talloc_get_type(c->private, struct fsinfo_state); + talloc_steal(mem_ctx, state->io->out.fsinfo); + } + + talloc_free(c); + return status; +} + + +/* + composite fsinfo call - sync interface +*/ +NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_composite_fsinfo *io) +{ + struct composite_context *c = smb_composite_fsinfo_send(tree, io); + return smb_composite_fsinfo_recv(c, mem_ctx); +} + diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index def7bd0f27..816bff4ca4 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -22,7 +22,9 @@ ADD_OBJ_FILES = \ libcli/composite/savefile.o \ libcli/composite/connect.o \ libcli/composite/sesssetup.o \ - libcli/composite/fetchfile.o + libcli/composite/fetchfile.o \ + libcli/composite/appendacl.o \ + libcli/composite/fsinfo.o REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE_BASE [SUBSYSTEM::LIBCLI_NBT] diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 77d296235a..54c4bcb6cb 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -50,6 +50,46 @@ struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx) return sd; } +static struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx, + const struct security_acl *oacl) +{ + struct security_acl *nacl; + int i; + + nacl = talloc (mem_ctx, struct security_acl); + if (nacl == NULL) { + return NULL; + } + + nacl->aces = talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces); + if ((nacl->aces == NULL) && (oacl->num_aces > 0)) { + goto failed; + } + + /* remapping array in trustee dom_sid from old acl to new acl */ + + for (i = 0; i < oacl->num_aces; i++) { + nacl->aces[i].trustee.sub_auths = + talloc_memdup(nacl->aces, nacl->aces[i].trustee.sub_auths, + sizeof(uint32_t) * nacl->aces[i].trustee.num_auths); + + if ((nacl->aces[i].trustee.sub_auths == NULL) && (nacl->aces[i].trustee.num_auths > 0)) { + goto failed; + } + } + + nacl->revision = oacl->revision; + nacl->size = oacl->size; + nacl->num_aces = oacl->num_aces; + + return nacl; + + failed: + talloc_free (nacl); + return NULL; + +} + /* talloc and copy a security descriptor */ @@ -58,11 +98,45 @@ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, { struct security_descriptor *nsd; - /* FIXME */ - DEBUG(1, ("security_descriptor_copy(): sorry unimplemented yet\n")); - nsd = NULL; + nsd = talloc_zero(mem_ctx, struct security_descriptor); + if (!nsd) { + return NULL; + } + + if (osd->owner_sid) { + nsd->owner_sid = dom_sid_dup(nsd, osd->owner_sid); + if (nsd->owner_sid == NULL) { + goto failed; + } + } + + if (osd->group_sid) { + nsd->group_sid = dom_sid_dup(nsd, osd->group_sid); + if (nsd->group_sid == NULL) { + goto failed; + } + } + + if (osd->sacl) { + nsd->sacl = security_acl_dup(nsd, osd->sacl); + if (nsd->sacl == NULL) { + goto failed; + } + } + + if (osd->dacl) { + nsd->dacl = security_acl_dup(nsd, osd->dacl); + if (nsd->dacl == NULL) { + goto failed; + } + } return nsd; + + failed: + talloc_free(nsd); + + return NULL; } /* -- cgit From 874cd2db86e7feb82eedd2b436c5c301d3cbe5fa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Apr 2005 06:33:20 +0000 Subject: r6460: Push the client credentials into NTLMSSP, allowing logins of the form user@REALM for the first time. Fix the build for smbencrypt.c Andrew Bartlett (This used to be commit 5a6a57cd93e22e612bfbb8a8f7bc29269a9a3ac6) --- source4/libcli/auth/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index f2b6eb00d7..3a4a724789 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -24,7 +24,7 @@ #include "includes.h" #include "system/time.h" -#include "auth/auth.h" +#include "auth/ntlmssp/ntlmssp.h" #include "lib/crypto/crypto.h" #include "pstring.h" -- cgit From 0501a440bedde5e867e461d266aafe666be53e54 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Apr 2005 08:26:53 +0000 Subject: r6462: Move the arcfour sbox state into it's own structure, and allocate it with talloc() for the NTLMSSP system. Andrew Bartlett (This used to be commit 7a93ac49c28d433ccf0f077294f473fe728b9995) --- source4/libcli/util/smbdes.c | 48 ++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index 016bd59501..d214d4cfe4 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "lib/crypto/crypto.h" /* NOTES: @@ -365,51 +366,46 @@ void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int } /* initialise the arcfour sbox with key */ -void arcfour_init(uint8_t s_box[258], const DATA_BLOB *key) +void arcfour_init(struct arcfour_state *state, const DATA_BLOB *key) { int ind; uint8_t j = 0; - for (ind = 0; ind < 256; ind++) { - s_box[ind] = (uint8_t)ind; + for (ind = 0; ind < sizeof(state->sbox); ind++) { + state->sbox[ind] = (uint8_t)ind; } - for (ind = 0; ind < 256; ind++) { + for (ind = 0; ind < sizeof(state->sbox); ind++) { uint8_t tc; - j += (s_box[ind] + key->data[ind%key->length]); + j += (state->sbox[ind] + key->data[ind%key->length]); - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; + tc = state->sbox[ind]; + state->sbox[ind] = state->sbox[j]; + state->sbox[j] = tc; } - s_box[256] = 0; /* i */ - s_box[257] = 0; /* j */ - + state->index_i = 0; + state->index_j = 0; } /* crypt the data with arcfour */ -void arcfour_crypt_sbox(uint8_t s_box[258], uint8_t *data, int len) +void arcfour_crypt_sbox(struct arcfour_state *state, uint8_t *data, int len) { - uint8_t index_i = s_box[256]; - uint8_t index_j = s_box[257]; int ind; for (ind = 0; ind < len; ind++) { uint8_t tc; uint8_t t; - index_i++; - index_j += s_box[index_i]; + state->index_i++; + state->index_j += state->sbox[state->index_i]; - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; + tc = state->sbox[state->index_i]; + state->sbox[state->index_i] = state->sbox[state->index_j]; + state->sbox[state->index_j] = tc; - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; + t = state->sbox[state->index_i] + state->sbox[state->index_j]; + data[ind] = data[ind] ^ state->sbox[t]; } - s_box[256] = index_i; - s_box[257] = index_j; } /* @@ -417,9 +413,9 @@ void arcfour_crypt_sbox(uint8_t s_box[258], uint8_t *data, int len) */ void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) { - uint8_t s_box[258]; - arcfour_init(s_box, key); - arcfour_crypt_sbox(s_box, data, len); + struct arcfour_state state; + arcfour_init(&state, key); + arcfour_crypt_sbox(&state, data, len); } /* -- cgit From aefd5df1999683cdb8da680fdc32f349841ad217 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 4 May 2005 19:12:04 +0000 Subject: r6614: Basic approach to monitoring messages for composite functions. rafal (This used to be commit 47a7a6c3fcfd1ab159a6baa71cd5c7984334fddb) --- source4/libcli/composite/composite.h | 3 +++ source4/libcli/composite/monitor.h | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 source4/libcli/composite/monitor.h (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 87e7a7b6ad..be7fbd9972 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -48,6 +48,9 @@ struct composite_context { void (*fn)(struct composite_context *); void *private; } async; + + /* information about the progress */ + void (*monitor_fn)(struct monitor_msg *); }; diff --git a/source4/libcli/composite/monitor.h b/source4/libcli/composite/monitor.h new file mode 100644 index 0000000000..cdcf298818 --- /dev/null +++ b/source4/libcli/composite/monitor.h @@ -0,0 +1,50 @@ +/* + Unix SMB/CIFS implementation. + + Definitions of composite function monitoring messages. + + Copyright (C) Rafal Szczesniak 2005 + + 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. +*/ + +/* + * Monitor structure definition. Composite function monitoring allows client + * application to be notified on function progress. This enables eg. gui + * client to display progress bars, status messages, etc. + */ + +enum monitor_type { + rpc_open_user, + rpc_query_user, + rpc_close_user +}; + +struct monitor_msg { + enum monitor_type type; + union monitor_data { + struct rpc_open_user { + uint32_t rid, access_mask; + } rpc_open_user; + + struct rpc_query_user { + uint16_t level; + } rpc_query_user; + + struct rpc_close_user { + uint32_t rid; + } rpc_close_user; + } data; +}; -- cgit From f6c0bee79125e779ab0036a77506e2f688c4872f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 May 2005 01:57:47 +0000 Subject: r6689: minor ldap client library work - added support for binary encoded search filters - fixed some const handling - changed the message type to an enum, to help debugging (This used to be commit d5353b63428698d1ce95c50e2626f1841fa637e3) --- source4/libcli/ldap/ldap.c | 79 ++++++++++++++++++++++++++++++++++------------ source4/libcli/ldap/ldap.h | 8 ++--- 2 files changed, 63 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2962f7eef4..37c3266b97 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -106,6 +106,40 @@ static const char *match_brace(const char *s) static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, const char **s); +/* + decode a RFC2254 binary string representation of a buffer. + Used in LDAP filters. +*/ +static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +{ + int i, j; + struct ldap_val ret; + int slen = strlen(str); + + ret.data = talloc_size(mem_ctx, slen); + ret.length = 0; + if (ret.data == NULL) return ret; + + for (i=j=0;i ::= */ @@ -139,8 +173,7 @@ static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, ret->operation = LDAP_OP_SIMPLE; ret->u.simple.attr = l; - ret->u.simple.value.data = val; - ret->u.simple.value.length = val?strlen(val):0; + ret->u.simple.value = ldap_binary_decode(ret, val); return ret; } @@ -696,9 +729,12 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - char **filter) + const char **filterp) { uint8_t filter_tag, tag_desc; + char *filter = NULL; + + *filterp = NULL; if (!asn1_peek_uint8(data, &filter_tag)) return False; @@ -715,22 +751,21 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_CONTEXT(0)); - *filter = talloc_strdup(mem_ctx, "(&"); - if (*filter == NULL) + filter = talloc_strdup(mem_ctx, "(&"); + if (filter == NULL) return False; while (asn1_tag_remaining(data) > 0) { - char *subfilter; + const char *subfilter; if (!ldap_decode_filter(mem_ctx, data, &subfilter)) return False; - *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, - subfilter); - if (*filter == NULL) + filter = talloc_asprintf_append(filter, "%s", subfilter); + if (filter == NULL) return False; } asn1_end_tag(data); - *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + filter = talloc_asprintf(mem_ctx, "%s)", filter); break; } case 1: { @@ -740,23 +775,22 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_CONTEXT(1)); - *filter = talloc_strdup(mem_ctx, "(|"); - if (*filter == NULL) + filter = talloc_strdup(mem_ctx, "(|"); + if (filter == NULL) return False; while (asn1_tag_remaining(data) > 0) { - char *subfilter; + const char *subfilter; if (!ldap_decode_filter(mem_ctx, data, &subfilter)) return False; - *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, - subfilter); - if (*filter == NULL) + filter = talloc_asprintf_append(filter, "%s", subfilter); + if (filter == NULL) return False; } asn1_end_tag(data); - *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + filter = talloc_asprintf(mem_ctx, "%s)", filter); break; } case 3: { @@ -770,7 +804,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value == NULL)) return False; - *filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); + filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); break; } case 7: { @@ -787,7 +821,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, return False; asn1_read(data, attr_name, attr_len); attr_name[attr_len] = '\0'; - *filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); + filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); SAFE_FREE(attr_name); asn1_end_tag(data); break; @@ -795,8 +829,11 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, default: return False; } - if (*filter == NULL) + if (filter == NULL) return False; + + *filterp = filter; + return True; } @@ -1260,3 +1297,5 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, return (*host != NULL); } + + diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 710c022a3c..50031fd60c 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -149,7 +149,7 @@ struct ldap_SearchRequest { uint32_t timelimit; uint32_t sizelimit; BOOL attributesonly; - char *filter; + const char *filter; int num_attributes; const char **attributes; }; @@ -251,9 +251,9 @@ struct ldap_Control { struct ldap_message { TALLOC_CTX *mem_ctx; - uint32_t messageid; - uint8_t type; - union ldap_Request r; + uint32_t messageid; + enum ldap_request_tag type; + union ldap_Request r; int num_controls; struct ldap_Control *controls; }; -- cgit From c8177de955ca1aa8683ef73b0e5a0018fbca2707 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 May 2005 01:59:00 +0000 Subject: r6691: fixed a comment (This used to be commit a0fa871c3fda9fce7da0b110ed313c930a677a80) --- source4/libcli/dgram/libdgram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index b8ca9e2fe5..b9dfe84996 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -24,7 +24,7 @@ /* - a nbt name request + a datagram name request */ struct nbt_dgram_request { struct nbt_dgram_request *next, *prev; -- cgit From 489a6b5591c37a8977426d9ca7fd07978e5e5614 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 May 2005 01:59:33 +0000 Subject: r6692: used idr_get_new_random() in the nbt client library (This used to be commit a3f64357af75587a855cfedb58ce2583658c7d04) --- source4/libcli/nbt/nbtsocket.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1d8cf36ea4..481327cc85 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -367,19 +367,10 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, /* we select a random transaction id unless the user supplied one */ if (request->name_trn_id == 0) { - request->name_trn_id = generate_random() % UINT16_MAX; - } - - /* choose the next available transaction id >= the one asked for. - The strange 2nd call is to try to make the ids less guessable - and less likely to collide. It's not possible to make NBT secure - to ID guessing, but this at least makes accidential collisions - less likely */ - id = idr_get_new_above(req->nbtsock->idr, req, - request->name_trn_id, UINT16_MAX); - if (id == -1) { - id = idr_get_new_above(req->nbtsock->idr, req, - 1+(generate_random()%(UINT16_MAX/2)), + id = idr_get_new_random(req->nbtsock->idr, req, UINT16_MAX); + } else { + if (idr_find(req->nbtsock->idr, request->name_trn_id)) goto failed; + id = idr_get_new_above(req->nbtsock->idr, req, request->name_trn_id, UINT16_MAX); } if (id == -1) goto failed; -- cgit From 0ac02ed7c344a7462d5d797b46e89e9d4a6937de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 May 2005 02:01:25 +0000 Subject: r6693: first version of cldap client library, with async interface (This used to be commit cbeffe830b2d3aee2ba346034548fa273a08f409) --- source4/libcli/cldap/cldap.c | 473 +++++++++++++++++++++++++++++++++++++++++++ source4/libcli/cldap/cldap.h | 140 +++++++++++++ source4/libcli/config.mk | 6 + 3 files changed, 619 insertions(+) create mode 100644 source4/libcli/cldap/cldap.c create mode 100644 source4/libcli/cldap/cldap.h (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c new file mode 100644 index 0000000000..7caf5a0810 --- /dev/null +++ b/source4/libcli/cldap/cldap.c @@ -0,0 +1,473 @@ +/* + Unix SMB/CIFS implementation. + + cldap client library + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +/* + see RFC1798 for details of CLDAP + + basic properties + - carried over UDP on port 389 + - request and response matched by message ID + - request consists of only a single searchRequest element + - response can be in one of two forms + - a single searchResponse, followed by a searchResult + - a single searchResult +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/ldap/ldap.h" +#include "libcli/cldap/cldap.h" +#include "lib/socket/socket.h" +#include "include/asn_1.h" + +#define CLDAP_MAX_PACKET_SIZE 2048 +const unsigned CLDAP_PORT = 389; + +/* + destroy a pending request +*/ +static int cldap_request_destructor(void *ptr) +{ + struct cldap_request *req = talloc_get_type(ptr, struct cldap_request); + if (req->state == CLDAP_REQUEST_SEND) { + DLIST_REMOVE(req->cldap->send_queue, req); + } + if (req->message_id != 0) { + idr_remove(req->cldap->idr, req->message_id); + req->message_id = 0; + } + return 0; +} + +/* + handle recv events on a cldap socket +*/ +static void cldap_socket_recv(struct cldap_socket *cldap) +{ + TALLOC_CTX *tmp_ctx = talloc_new(cldap); + NTSTATUS status; + const char *src_addr; + int src_port; + DATA_BLOB blob; + size_t nread; + struct asn1_data asn1; + struct ldap_message ldap_msg; + struct cldap_request *req; + + blob = data_blob_talloc(tmp_ctx, NULL, CLDAP_MAX_PACKET_SIZE); + if (blob.data == NULL) { + talloc_free(tmp_ctx); + return; + } + + status = socket_recvfrom(cldap->sock, blob.data, blob.length, &nread, 0, + &src_addr, &src_port); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + talloc_steal(tmp_ctx, src_addr); + blob.length = nread; + + DEBUG(2,("Received cldap packet of length %d from %s:%d\n", + blob.length, src_addr, src_port)); + + if (!asn1_load(&asn1, blob)) { + DEBUG(2,("Failed to setup for asn.1 decode\n")); + talloc_free(tmp_ctx); + return; + } + talloc_steal(tmp_ctx, asn1.data); + + ZERO_STRUCT(ldap_msg); + ldap_msg.mem_ctx = tmp_ctx; + + /* this initial decode is used to find the message id */ + if (!ldap_decode(&asn1, &ldap_msg)) { + DEBUG(2,("Failed to decode ldap message\n")); + talloc_free(tmp_ctx); + return; + } + + /* find the pending request */ + req = idr_find(cldap->idr, ldap_msg.messageid); + if (req == NULL) { + DEBUG(2,("Mismatched cldap reply %u from %s:%d\n", + ldap_msg.messageid, src_addr, src_port)); + talloc_free(tmp_ctx); + return; + } + + req->asn1 = asn1; + talloc_steal(req, asn1.data); + req->asn1.ofs = 0; + + req->state = CLDAP_REQUEST_DONE; + talloc_free(req->te); + + talloc_free(tmp_ctx); + + if (req->async.fn) { + req->async.fn(req); + } +} + +/* + handle request timeouts +*/ +static void cldap_request_timeout(struct event_context *event_ctx, + struct timed_event *te, struct timeval t, + void *private) +{ + struct cldap_request *req = talloc_get_type(private, struct cldap_request); + + /* possibly try again */ + if (req->num_retries != 0) { + size_t len = req->encoded.length; + + req->num_retries--; + + socket_sendto(req->cldap->sock, &req->encoded, &len, 0, + req->dest_addr, req->dest_port); + + req->te = event_add_timed(req->cldap->event_ctx, req, + timeval_current_ofs(req->timeout, 0), + cldap_request_timeout, req); + return; + } + + req->state = CLDAP_REQUEST_TIMEOUT; + if (req->async.fn) { + req->async.fn(req); + } +} + +/* + handle send events on a cldap socket +*/ +static void cldap_socket_send(struct cldap_socket *cldap) +{ + struct cldap_request *req; + NTSTATUS status; + + while ((req = cldap->send_queue)) { + size_t len; + + len = req->encoded.length; + status = socket_sendto(cldap->sock, &req->encoded, &len, 0, + req->dest_addr, req->dest_port); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(3,("Failed to send cldap request of length %u to %s:%d\n", + req->encoded.length, req->dest_addr, req->dest_port)); + DLIST_REMOVE(cldap->send_queue, req); + talloc_free(req); + continue; + } + + if (!NT_STATUS_IS_OK(status)) return; + + DLIST_REMOVE(cldap->send_queue, req); + + req->state = CLDAP_REQUEST_WAIT; + + req->te = event_add_timed(cldap->event_ctx, req, + timeval_current_ofs(req->timeout, 0), + cldap_request_timeout, req); + + EVENT_FD_READABLE(cldap->fde); + } + + EVENT_FD_NOT_WRITEABLE(cldap->fde); + return; +} + + +/* + handle fd events on a cldap_socket +*/ +static void cldap_socket_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct cldap_socket *cldap = talloc_get_type(private, struct cldap_socket); + if (flags & EVENT_FD_WRITE) { + cldap_socket_send(cldap); + } else if (flags & EVENT_FD_READ) { + cldap_socket_recv(cldap); + } +} + +/* + initialise a cldap_socket. The event_ctx is optional, if provided + then operations will use that event context +*/ +struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) +{ + struct cldap_socket *cldap; + NTSTATUS status; + + cldap = talloc(mem_ctx, struct cldap_socket); + if (cldap == NULL) goto failed; + + if (event_ctx == NULL) { + cldap->event_ctx = event_context_init(cldap); + } else { + cldap->event_ctx = talloc_reference(cldap, event_ctx); + } + if (cldap->event_ctx == NULL) goto failed; + + cldap->idr = idr_init(cldap); + if (cldap->idr == NULL) goto failed; + + status = socket_create("ip", SOCKET_TYPE_DGRAM, &cldap->sock, 0); + if (!NT_STATUS_IS_OK(status)) goto failed; + + talloc_steal(cldap, cldap->sock); + + cldap->fde = event_add_fd(cldap->event_ctx, cldap, + socket_get_fd(cldap->sock), 0, + cldap_socket_handler, cldap); + + cldap->send_queue = NULL; + + return cldap; + +failed: + talloc_free(cldap); + return NULL; +} + + +/* + queue a cldap request for send +*/ +struct cldap_request *cldap_search_send(struct cldap_socket *cldap, + struct cldap_search *io) +{ + struct ldap_message msg; + struct cldap_request *req; + struct ldap_SearchRequest *search; + + req = talloc_zero(cldap, struct cldap_request); + if (req == NULL) goto failed; + + req->cldap = cldap; + req->state = CLDAP_REQUEST_SEND; + req->timeout = io->in.timeout; + req->num_retries = io->in.retries; + + req->dest_addr = talloc_strdup(req, io->in.dest_address); + if (req->dest_addr == NULL) goto failed; + req->dest_port = CLDAP_PORT; + + req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); + if (req->message_id == -1) goto failed; + + talloc_set_destructor(req, cldap_request_destructor); + + msg.mem_ctx = cldap; + msg.messageid = req->message_id; + msg.type = LDAP_TAG_SearchRequest; + msg.num_controls = 0; + msg.controls = NULL; + search = &msg.r.SearchRequest; + + search->basedn = ""; + search->scope = LDAP_SEARCH_SCOPE_BASE; + search->deref = LDAP_DEREFERENCE_NEVER; + search->timelimit = 0; + search->sizelimit = 0; + search->attributesonly = False; + search->num_attributes = str_list_length(io->in.attributes); + search->attributes = io->in.attributes; + search->filter = io->in.filter; + + if (!ldap_encode(&msg, &req->encoded)) { + DEBUG(0,("Failed to encode cldap message to %s:%d\n", + req->dest_addr, req->dest_port)); + goto failed; + } + talloc_steal(req, req->encoded.data); + + DLIST_ADD_END(cldap->send_queue, req, struct cldap_request *); + + EVENT_FD_WRITEABLE(cldap->fde); + + return req; + +failed: + talloc_free(req); + return NULL; +} + +/* + receive a cldap reply +*/ +NTSTATUS cldap_search_recv(struct cldap_request *req, + TALLOC_CTX *mem_ctx, + struct cldap_search *io) +{ + struct ldap_message ldap_msg; + + if (req == NULL) { + return NT_STATUS_NO_MEMORY; + } + + while (req->state < CLDAP_REQUEST_DONE) { + if (event_loop_once(req->cldap->event_ctx) != 0) { + talloc_free(req); + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + } + + if (req->state == CLDAP_REQUEST_TIMEOUT) { + talloc_free(req); + return NT_STATUS_IO_TIMEOUT; + } + + ZERO_STRUCT(ldap_msg); + ldap_msg.mem_ctx = mem_ctx; + + if (!ldap_decode(&req->asn1, &ldap_msg)) { + talloc_free(req); + return NT_STATUS_INVALID_PARAMETER; + } + + ZERO_STRUCT(io->out); + + /* the first possible form has a search result in first place */ + if (ldap_msg.type == LDAP_TAG_SearchResultEntry) { + io->out.response = talloc(mem_ctx, struct ldap_SearchResEntry); + NT_STATUS_HAVE_NO_MEMORY(io->out.response); + *io->out.response = ldap_msg.r.SearchResultEntry; + + /* decode the 2nd part */ + if (!ldap_decode(&req->asn1, &ldap_msg)) { + talloc_free(req); + return NT_STATUS_INVALID_PARAMETER; + } + } + + if (ldap_msg.type != LDAP_TAG_SearchResultDone) { + talloc_free(req); + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + io->out.result = talloc(mem_ctx, struct ldap_Result); + NT_STATUS_HAVE_NO_MEMORY(io->out.result); + *io->out.result = ldap_msg.r.SearchResultDone; + + talloc_free(req); + return NT_STATUS_OK; +} + + +/* + synchronous cldap search +*/ +NTSTATUS cldap_search(struct cldap_socket *cldap, + TALLOC_CTX *mem_ctx, + struct cldap_search *io) +{ + struct cldap_request *req = cldap_search_send(cldap, io); + return cldap_search_recv(req, mem_ctx, io); +} + + +/* + queue a cldap netlogon for send +*/ +struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, + struct cldap_netlogon *io) +{ + struct cldap_search search; + char *filter; + struct cldap_request *req; + const char *attr[] = { "NetLogon", NULL }; + + filter = talloc_asprintf(cldap, + "(&(DnsDomain=%s)(Host=%s)(NtVer=\\%02X\\00\\00\\00))", + io->in.realm, io->in.host, io->in.version); + if (filter == NULL) return NULL; + + search.in.dest_address = io->in.dest_address; + search.in.filter = filter; + search.in.attributes = attr; + search.in.timeout = 2; + search.in.retries = 2; + + req = cldap_search_send(cldap, &search); + + talloc_free(filter); + + return req; +} + + +/* + receive a cldap netlogon reply +*/ +NTSTATUS cldap_netlogon_recv(struct cldap_request *req, + TALLOC_CTX *mem_ctx, + struct cldap_netlogon *io) +{ + NTSTATUS status; + struct cldap_search search; + DATA_BLOB *data; + + status = cldap_search_recv(req, mem_ctx, &search); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (search.out.response == NULL) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + if (search.out.response->num_attributes != 1 || + strcasecmp(search.out.response->attributes[0].name, "netlogon") != 0 || + search.out.response->attributes[0].num_values != 1 || + search.out.response->attributes[0].values->length < 2) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + data = search.out.response->attributes[0].values; + + status = ndr_pull_struct_blob_all(data, mem_ctx, &io->out.netlogon, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", + SVAL(data->data, 0))); + dump_data(10, data->data, data->length); + } + + return status; +} + +/* + sync cldap netlogon search +*/ +NTSTATUS cldap_netlogon(struct cldap_socket *cldap, + TALLOC_CTX *mem_ctx, struct cldap_netlogon *io) +{ + struct cldap_request *req = cldap_netlogon_send(cldap, io); + return cldap_netlogon_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h new file mode 100644 index 0000000000..5ed7df15c7 --- /dev/null +++ b/source4/libcli/cldap/cldap.h @@ -0,0 +1,140 @@ +/* + Unix SMB/CIFS implementation. + + a async CLDAP library + + Copyright (C) Andrew Tridgell 2005 + + 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 "asn_1.h" +#include "librpc/gen_ndr/ndr_nbt.h" + +enum cldap_request_state {CLDAP_REQUEST_SEND, + CLDAP_REQUEST_WAIT, + CLDAP_REQUEST_DONE, + CLDAP_REQUEST_TIMEOUT}; + +/* + a cldap request packet +*/ +struct cldap_request { + struct cldap_request *next, *prev; + + struct cldap_socket *cldap; + + enum cldap_request_state state; + + /* where to send the request */ + const char *dest_addr; + int dest_port; + + /* timeout between retries (seconds) */ + int timeout; + int num_retries; + + /* the ldap message_id */ + int message_id; + + struct timed_event *te; + + /* the encoded request */ + DATA_BLOB encoded; + + /* the reply data */ + struct asn1_data asn1; + + /* information on what to do on completion */ + struct { + void (*fn)(struct cldap_request *); + void *private; + } async; +}; + +/* + context structure for operations on cldap packets +*/ +struct cldap_socket { + struct socket_context *sock; + struct event_context *event_ctx; + + /* the fd event */ + struct fd_event *fde; + + /* a queue of outgoing requests */ + struct cldap_request *send_queue; + + /* mapping from message_id to pending request */ + struct idr_context *idr; + + /* what to do with incoming request packets */ + struct { + void (*handler)(struct cldap_socket *, struct ldap_message *, + const char *, int ); + void *private; + } incoming; +}; + + +/* + a general cldap search request +*/ +struct cldap_search { + struct { + const char *dest_address; + const char *filter; + const char **attributes; + int timeout; + int retries; + } in; + struct { + struct ldap_SearchResEntry *response; + struct ldap_Result *result; + } out; +}; + +struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx); +struct cldap_request *cldap_search_send(struct cldap_socket *cldap, + struct cldap_search *io); +NTSTATUS cldap_search_recv(struct cldap_request *req, TALLOC_CTX *mem_ctx, + struct cldap_search *io); +NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, + struct cldap_search *io); + + +/* + a netlogon cldap request +*/ +struct cldap_netlogon { + struct { + const char *dest_address; + const char *realm; + const char *host; + uint8_t version; + } in; + struct { + struct nbt_cldap_netlogon netlogon; + } out; +}; + +struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, + struct cldap_netlogon *io); +NTSTATUS cldap_netlogon_recv(struct cldap_request *req, + TALLOC_CTX *mem_ctx, + struct cldap_netlogon *io); +NTSTATUS cldap_netlogon(struct cldap_socket *cldap, + TALLOC_CTX *mem_ctx, struct cldap_netlogon *io); diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 816bff4ca4..834aa01dac 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -46,6 +46,12 @@ ADD_OBJ_FILES = \ NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT +[SUBSYSTEM::LIBCLI_CLDAP] +ADD_OBJ_FILES = \ + libcli/cldap/cldap.o +NOPROTO=YES +REQUIRED_SUBSYSTEMS = LIBCLI_LDAP + [SUBSYSTEM::LIBCLI_WINS] ADD_OBJ_FILES = \ libcli/wins/winsrepl.o -- cgit From 493cab3dbc8ae3587f334eaf297646f7051e7781 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 May 2005 09:50:29 +0000 Subject: r6699: Windows clients seem to ask for CIFS/, ie in upper case, so match it. Andrew Bartlett (This used to be commit 6d7f1daaf2a521864994e06b013c36287f27a129) --- source4/libcli/composite/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index ab46c198ef..3c59f19781 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -285,7 +285,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, return NULL; } - status = gensec_set_target_service(session->gensec, "cifs"); + status = gensec_set_target_service(session->gensec, "CIFS"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC target service: %s\n", nt_errstr(status))); -- cgit From 1cf8396db450b5844f95d02e59075d46b514f53e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 May 2005 10:07:18 +0000 Subject: r6702: Revert -r 6699, as I think this is a win2k v win2k3 issue. Andrew Bartlett (This used to be commit 77b67da5b8187951ba8c25af85bbf716cf5b3561) --- source4/libcli/composite/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 3c59f19781..ab46c198ef 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -285,7 +285,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, return NULL; } - status = gensec_set_target_service(session->gensec, "CIFS"); + status = gensec_set_target_service(session->gensec, "cifs"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC target service: %s\n", nt_errstr(status))); -- cgit From 5cbfca296739980c1d03fe23c275195ade0bb6b6 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 10 May 2005 12:45:48 +0000 Subject: r6708: Another type of monitor message. rafal (This used to be commit f7aaa0bfcae7fd4518256a703ad237693ff0c295) --- source4/libcli/composite/monitor.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/monitor.h b/source4/libcli/composite/monitor.h index cdcf298818..729f37204f 100644 --- a/source4/libcli/composite/monitor.h +++ b/source4/libcli/composite/monitor.h @@ -27,6 +27,7 @@ */ enum monitor_type { + rpc_create_user, rpc_open_user, rpc_query_user, rpc_close_user @@ -35,6 +36,10 @@ enum monitor_type { struct monitor_msg { enum monitor_type type; union monitor_data { + struct rpc_create_user { + uint32_t rid; + } rpc_create_user; + struct rpc_open_user { uint32_t rid, access_mask; } rpc_open_user; -- cgit From 2f2fc84a7c6724f6eab39bf301be70ba5bec15cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 May 2005 23:33:56 +0000 Subject: r6720: added support for the remaining 2 types of CLDAP netlogon response. To work around the fact that the type of the returned data is not encoded in the packet, this required adding ndr_pull_union_blob() which allows us to pull a blob into a union with a specified switch value, in this case the switch value comes from the calling NtVer field. (This used to be commit bd27e626c27be72913d1a1569ee6e2e2711df84e) --- source4/libcli/cldap/cldap.c | 5 +++-- source4/libcli/cldap/cldap.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 7caf5a0810..a28afc6877 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -451,8 +451,9 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - status = ndr_pull_struct_blob_all(data, mem_ctx, &io->out.netlogon, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + status = ndr_pull_union_blob(data, mem_ctx, &io->out.netlogon, + io->in.version & 0xF, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", SVAL(data->data, 0))); diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 5ed7df15c7..a8bba7edbe 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -127,7 +127,7 @@ struct cldap_netlogon { uint8_t version; } in; struct { - struct nbt_cldap_netlogon netlogon; + union nbt_cldap_netlogon netlogon; } out; }; -- cgit From a8c26fa4ace4dbb2e514669560143d68879a99bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 11 May 2005 04:48:30 +0000 Subject: r6724: added "cldap port" smb.conf parameter (This used to be commit 04af0e7c5de467a24b965ce1de2fb07621133164) --- source4/libcli/cldap/cldap.c | 26 ++++++++++++++++++++++---- source4/libcli/cldap/cldap.h | 4 ++++ 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index a28afc6877..75ce0a67db 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -41,7 +41,6 @@ #include "include/asn_1.h" #define CLDAP_MAX_PACKET_SIZE 2048 -const unsigned CLDAP_PORT = 389; /* destroy a pending request @@ -112,8 +111,12 @@ static void cldap_socket_recv(struct cldap_socket *cldap) /* find the pending request */ req = idr_find(cldap->idr, ldap_msg.messageid); if (req == NULL) { - DEBUG(2,("Mismatched cldap reply %u from %s:%d\n", - ldap_msg.messageid, src_addr, src_port)); + if (cldap->incoming.handler) { + cldap->incoming.handler(cldap, &ldap_msg, src_addr, src_port); + } else { + DEBUG(2,("Mismatched cldap reply %u from %s:%d\n", + ldap_msg.messageid, src_addr, src_port)); + } talloc_free(tmp_ctx); return; } @@ -249,6 +252,7 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, cldap_socket_handler, cldap); cldap->send_queue = NULL; + cldap->incoming.handler = NULL; return cldap; @@ -258,6 +262,20 @@ failed: } +/* + setup a handler for incoming requests +*/ +NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, + void (*handler)(struct cldap_socket *, struct ldap_message *, + const char *, int ), + void *private) +{ + cldap->incoming.handler = handler; + cldap->incoming.private = private; + EVENT_FD_READABLE(cldap->fde); + return NT_STATUS_OK; +} + /* queue a cldap request for send */ @@ -278,7 +296,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->dest_addr = talloc_strdup(req, io->in.dest_address); if (req->dest_addr == NULL) goto failed; - req->dest_port = CLDAP_PORT; + req->dest_port = lp_cldap_port(); req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); if (req->message_id == -1) goto failed; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index a8bba7edbe..8a678b4539 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -108,6 +108,10 @@ struct cldap_search { struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); +NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, + void (*handler)(struct cldap_socket *, struct ldap_message *, + const char *, int ), + void *private); struct cldap_request *cldap_search_send(struct cldap_socket *cldap, struct cldap_search *io); NTSTATUS cldap_search_recv(struct cldap_request *req, TALLOC_CTX *mem_ctx, -- cgit From 49304e965f87d00b7ba5d66fe929611d3ad2ebef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 11 May 2005 05:59:46 +0000 Subject: r6726: support binary search elements in ldap_decode() (This used to be commit 2b36f1dfdd6cf3ab89f63b541ae4cd905fb03c8d) --- source4/libcli/ldap/ldap.c | 48 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 37c3266b97..1a4f323ebf 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -140,6 +140,39 @@ static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) } +/* + encode a blob as a RFC2254 binary string, escaping any + non-printable or '\' characters +*/ +static const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) +{ + int i; + char *ret; + int len = blob.length; + for (i=0;i ::= */ @@ -765,7 +798,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, } asn1_end_tag(data); - filter = talloc_asprintf(mem_ctx, "%s)", filter); + filter = talloc_asprintf_append(filter, ")"); break; } case 1: { @@ -790,21 +823,24 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); - filter = talloc_asprintf(mem_ctx, "%s)", filter); + filter = talloc_asprintf_append(filter, ")"); break; } case 3: { /* equalityMatch */ - const char *attrib, *value; + const char *attrib; + DATA_BLOB value; if (tag_desc != 0xa0) /* context compound */ return False; asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString_talloc(mem_ctx, data, &value); + asn1_read_OctetString(data, &value); asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value == NULL)) + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) return False; - filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); + filter = talloc_asprintf(mem_ctx, "(%s=%s)", + attrib, ldap_binary_encode(mem_ctx, value)); + data_blob_free(&value); break; } case 7: { -- cgit From 2542d54e9384302c6c9a7b2b2bf4be07b6d95f9c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 May 2005 14:38:13 +0000 Subject: r6732: - move sasl send recv code to the ldap lib - support 'modrdn' ldif metze (This used to be commit b6a1734699953964fcde6fe6ea7048496492eb33) --- source4/libcli/ldap/ldap_client.c | 131 +++++++++++++++++++++++++++++++++++++- source4/libcli/ldap/ldap_ldif.c | 58 +++++++++++++++++ 2 files changed, 188 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 71b57e116e..8867344de3 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -548,9 +548,138 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, return NULL; } +/* + Write data to a fd +*/ +static ssize_t write_data(int fd, char *buffer, size_t N) +{ + size_t total=0; + ssize_t ret; + + while (total < N) { + ret = sys_write(fd,buffer + total,N - total); + + if (ret == -1) { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + + return (ssize_t)total; +} + + +/* + Read data from the client, reading exactly N bytes +*/ +static ssize_t read_data(int fd, char *buffer, size_t N) +{ + ssize_t ret; + size_t total=0; + + while (total < N) { + + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", + (int)(N - total), strerror(errno) )); + return 0; + } + + if (ret == -1) { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", + (int)(N - total), strerror(errno) )); + return -1; + } + total += ret; + } + + return (ssize_t)total; +} + +static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, struct ldap_message *req) +{ + NTSTATUS status; + DATA_BLOB request; + BOOL result; + DATA_BLOB wrapped; + int len; + char length[4]; + struct asn1_data asn1; + struct ldap_message *rep; + + req->messageid = conn->next_msgid++; + + if (!ldap_encode(req, &request)) + return NULL; + + status = gensec_wrap(conn->gensec, + req->mem_ctx, + &request, + &wrapped); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status))); + return NULL; + } + + RSIVAL(length, 0, wrapped.length); + + result = (write_data(conn->sock, length, 4) == 4); + if (!result) + return NULL; + + result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length); + if (!result) + return NULL; + + wrapped = data_blob(NULL, 0x4000); + data_blob_clear(&wrapped); + + result = (read_data(conn->sock, length, 4) == 4); + if (!result) + return NULL; + + len = RIVAL(length,0); + + result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len); + if (!result) + return NULL; + + wrapped.length = len; + + status = gensec_unwrap(conn->gensec, + req->mem_ctx, + &wrapped, + &request); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status))); + return NULL; + } + + rep = new_ldap_message(req->mem_ctx); + + asn1_load(&asn1, request); + if (!ldap_decode(&asn1, rep)) { + return NULL; + } + + return rep; +} + struct ldap_message *ldap_transaction(struct ldap_connection *conn, struct ldap_message *request) { + if ((request->type != LDAP_TAG_BindRequest) && conn->gensec && + (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || + gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { + return ldap_transaction_sasl(conn, request); + } + if (!ldap_send_msg(conn, request, NULL)) return False; @@ -624,7 +753,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) return result; } - gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index e5e5cdd6df..c36106e116 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -305,6 +305,53 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) return True; } +static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) +{ + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + const char *attr_name; + struct ldap_val value; + + r->newrdn = NULL; + r->deleteolddn = False; + r->newsuperior = NULL; + + if (next_attr(chunk, &attr_name, &value) != 0) { + return False; + } + + if (!strequal(attr_name, "newrdn")) { + return False; + } + + r->newrdn = value.data; + + if (next_attr(chunk, &attr_name, &value) != 0) { + return False; + } + + if (!strequal(attr_name, "deleteoldrdn")) { + return False; + } + + if (value.data && (((char *)value.data)[0] != '0')) { + r->deleteolddn = True; + } + + if (next_attr(chunk, &attr_name, &value) != 0) { + /* newsuperior is optional */ + return True; + } + + if (!strequal(attr_name, "newsuperior")) { + return False; + } + + r->newsuperior = value.data; + + return True; +} + + /* read from a LDIF source, creating a ldap_message */ @@ -381,6 +428,17 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void return msg; } + if (strequal(value.data, "modrdn")) { + msg->type = LDAP_TAG_ModifyDNRequest; + + msg->r.ModifyDNRequest.dn = dn; + + if (!fill_modrdn(msg, &s)) + goto failed; + + return msg; + } + DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); failed: -- cgit From ea6943ec79729800c520daed8d4128f1d4530a93 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 May 2005 08:25:35 +0000 Subject: r6744: added support for reply packets in libcli/cldap/ (This used to be commit 992858e1b91c3ff05077afa8a7abe155198597d4) --- source4/libcli/cldap/cldap.c | 166 +++++++++++++++++++++++++++++++++++++++++-- source4/libcli/cldap/cldap.h | 25 +++++++ 2 files changed, 184 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 75ce0a67db..2f4d1e73a9 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -51,7 +51,7 @@ static int cldap_request_destructor(void *ptr) if (req->state == CLDAP_REQUEST_SEND) { DLIST_REMOVE(req->cldap->send_queue, req); } - if (req->message_id != 0) { + if (!req->is_reply && req->message_id != 0) { idr_remove(req->cldap->idr, req->message_id); req->message_id = 0; } @@ -191,13 +191,17 @@ static void cldap_socket_send(struct cldap_socket *cldap) DLIST_REMOVE(cldap->send_queue, req); - req->state = CLDAP_REQUEST_WAIT; + if (req->is_reply) { + talloc_free(req); + } else { + req->state = CLDAP_REQUEST_WAIT; - req->te = event_add_timed(cldap->event_ctx, req, - timeval_current_ofs(req->timeout, 0), - cldap_request_timeout, req); + req->te = event_add_timed(cldap->event_ctx, req, + timeval_current_ofs(req->timeout, 0), + cldap_request_timeout, req); - EVENT_FD_READABLE(cldap->fde); + EVENT_FD_READABLE(cldap->fde); + } } EVENT_FD_NOT_WRITEABLE(cldap->fde); @@ -293,6 +297,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->state = CLDAP_REQUEST_SEND; req->timeout = io->in.timeout; req->num_retries = io->in.retries; + req->is_reply = False; req->dest_addr = talloc_strdup(req, io->in.dest_address); if (req->dest_addr == NULL) goto failed; @@ -303,7 +308,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, talloc_set_destructor(req, cldap_request_destructor); - msg.mem_ctx = cldap; + msg.mem_ctx = req; msg.messageid = req->message_id; msg.type = LDAP_TAG_SearchRequest; msg.num_controls = 0; @@ -338,6 +343,78 @@ failed: return NULL; } + +/* + queue a cldap reply for send +*/ +NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) +{ + struct ldap_message msg; + struct cldap_request *req; + DATA_BLOB blob1, blob2; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + req = talloc_zero(cldap, struct cldap_request); + if (req == NULL) goto failed; + + req->cldap = cldap; + req->state = CLDAP_REQUEST_SEND; + req->is_reply = True; + + req->dest_addr = talloc_strdup(req, io->dest_address); + if (req->dest_addr == NULL) goto failed; + req->dest_port = io->dest_port; + + talloc_set_destructor(req, cldap_request_destructor); + + msg.mem_ctx = req; + msg.messageid = io->messageid; + msg.num_controls = 0; + msg.controls = NULL; + + if (io->response) { + msg.type = LDAP_TAG_SearchResultEntry; + msg.r.SearchResultEntry = *io->response; + + if (!ldap_encode(&msg, &blob1)) { + DEBUG(0,("Failed to encode cldap message to %s:%d\n", + req->dest_addr, req->dest_port)); + status = NT_STATUS_INVALID_PARAMETER; + goto failed; + } + talloc_steal(req, blob1.data); + } else { + blob1 = data_blob(NULL, 0); + } + + msg.type = LDAP_TAG_SearchResultDone; + msg.r.SearchResultDone = *io->result; + + if (!ldap_encode(&msg, &blob2)) { + DEBUG(0,("Failed to encode cldap message to %s:%d\n", + req->dest_addr, req->dest_port)); + status = NT_STATUS_INVALID_PARAMETER; + goto failed; + } + talloc_steal(req, blob2.data); + + req->encoded = data_blob_talloc(req, NULL, blob1.length + blob2.length); + if (req->encoded.data == NULL) goto failed; + + memcpy(req->encoded.data, blob1.data, blob1.length); + memcpy(req->encoded.data+blob1.length, blob2.data, blob2.length); + + DLIST_ADD_END(cldap->send_queue, req, struct cldap_request *); + + EVENT_FD_WRITEABLE(cldap->fde); + + return NT_STATUS_OK; + +failed: + talloc_free(req); + return status; +} + /* receive a cldap reply */ @@ -490,3 +567,78 @@ NTSTATUS cldap_netlogon(struct cldap_socket *cldap, struct cldap_request *req = cldap_netlogon_send(cldap, io); return cldap_netlogon_recv(req, mem_ctx, io); } + + +/* + send an empty reply (used on any error, so the client doesn't keep waiting + or send the bad request again) +*/ +NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, + uint32_t message_id, + const char *src_address, int src_port) +{ + NTSTATUS status; + struct cldap_reply reply; + struct ldap_Result result; + + reply.messageid = message_id; + reply.dest_address = src_address; + reply.dest_port = src_port; + reply.response = NULL; + reply.result = &result; + + ZERO_STRUCT(result); + + status = cldap_reply_send(cldap, &reply); + + return status; +} + + +/* + send a netlogon reply +*/ +NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, + uint32_t message_id, + const char *src_address, int src_port, + uint32_t version, + union nbt_cldap_netlogon *netlogon) +{ + NTSTATUS status; + struct cldap_reply reply; + struct ldap_SearchResEntry response; + struct ldap_Result result; + TALLOC_CTX *tmp_ctx = talloc_new(cldap); + DATA_BLOB blob; + + status = ndr_push_union_blob(&blob, tmp_ctx, netlogon, version & 0xF, + (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + reply.messageid = message_id; + reply.dest_address = src_address; + reply.dest_port = src_port; + reply.response = &response; + reply.result = &result; + + ZERO_STRUCT(result); + + response.dn = ""; + response.num_attributes = 1; + response.attributes = talloc(tmp_ctx, struct ldap_attribute); + NT_STATUS_HAVE_NO_MEMORY(response.attributes); + response.attributes->name = "netlogon"; + response.attributes->num_values = 1; + response.attributes->values = &blob; + + status = cldap_reply_send(cldap, &reply); + + talloc_free(tmp_ctx); + + return status; +} + + diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 8a678b4539..fbdaada8c9 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -46,6 +46,8 @@ struct cldap_request { int timeout; int num_retries; + BOOL is_reply; + /* the ldap message_id */ int message_id; @@ -120,6 +122,19 @@ NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, struct cldap_search *io); +/* + a general cldap reply +*/ +struct cldap_reply { + uint32_t messageid; + const char *dest_address; + int dest_port; + struct ldap_SearchResEntry *response; + struct ldap_Result *result; +}; + +NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io); + /* a netlogon cldap request */ @@ -142,3 +157,13 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, struct cldap_netlogon *io); NTSTATUS cldap_netlogon(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, struct cldap_netlogon *io); + + +NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, + uint32_t message_id, + const char *src_address, int src_port); +NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, + uint32_t message_id, + const char *src_address, int src_port, + uint32_t version, + union nbt_cldap_netlogon *netlogon); -- cgit From c956f4f98205c376062c4d634fd4ba4fb41031e4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 May 2005 08:26:26 +0000 Subject: r6745: - escape spaces in binary ldap blobs - expose the ldap filter string parsing outside of ldap.c (This used to be commit b644ff6fe164fbe359c47e4d34f5ad490ff61d5b) --- source4/libcli/ldap/ldap.c | 16 +++++++++++++--- source4/libcli/ldap/ldap.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1a4f323ebf..9a8a7bb589 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -150,7 +150,7 @@ static const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) char *ret; int len = blob.length; for (i=0;i ::= '(' ')' */ static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s) + const char **s) { char *l, *s2; const char *p, *p2; @@ -1335,3 +1335,13 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, } + +/* + externally callable version of filter string parsing - used in the + cldap server +*/ +struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, + const char *s) +{ + return ldap_parse_filter(mem_ctx, &s); +} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 50031fd60c..63d79628a9 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -323,6 +323,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); +struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, + const char *s); /* The following definitions come from libcli/ldap/ldap_client.c */ -- cgit From 4029df5e602760a0a0f8851e9f7bb28e1434f4f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 13 May 2005 06:07:53 +0000 Subject: r6763: added functions in libcli/ldap/ to binary encode some NDR structures into ldap friendly filter strings (This used to be commit 8890dd3ac331cffe83226a356c52df89c917c2b0) --- source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 5 ++- source4/libcli/ldap/ldap.h | 7 ++++ source4/libcli/ldap/ldap_ndr.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 source4/libcli/ldap/ldap_ndr.c (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 87bfdfdbba..888590ec5e 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -3,7 +3,8 @@ [SUBSYSTEM::LIBCLI_LDAP] ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ - libcli/ldap/ldap_ldif.o + libcli/ldap/ldap_ldif.o \ + libcli/ldap/ldap_ndr.o NOPROTO=YES # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 9a8a7bb589..cc7f1a10bc 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -144,7 +144,7 @@ static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) encode a blob as a RFC2254 binary string, escaping any non-printable or '\' characters */ -static const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) +const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) { int i; char *ret; @@ -1345,3 +1345,6 @@ struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, { return ldap_parse_filter(mem_ctx, &s); } + + + diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 63d79628a9..8d4294cf76 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -325,6 +325,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, const char *s); +const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -378,4 +379,10 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, int *num_mods); struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); +/* The following definitions come from libcli/ldap/ldap_ndr.c */ + +const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); +const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); +const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); + #endif diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c new file mode 100644 index 0000000000..45d9b2729e --- /dev/null +++ b/source4/libcli/ldap/ldap_ndr.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS mplementation. + + wrap/unwrap NDR encoded elements for ldap calls + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/ldap/ldap.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* + encode a NDR uint32 as a ldap filter element +*/ +const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) +{ + uint8_t buf[4]; + DATA_BLOB blob; + SIVAL(buf, 0, value); + blob.data = buf; + blob.length = 4; + return ldap_binary_encode(mem_ctx, blob); +} + +/* + encode a NDR dom_sid as a ldap filter element +*/ +const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) +{ + DATA_BLOB blob; + NTSTATUS status; + const char *ret; + status = ndr_push_struct_blob(&blob, mem_ctx, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + ret = ldap_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} + + +/* + encode a NDR GUID as a ldap filter element +*/ +const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +{ + DATA_BLOB blob; + NTSTATUS status; + const char *ret; + status = ndr_push_struct_blob(&blob, mem_ctx, guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + ret = ldap_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} -- cgit From 06869ce014ffa249fb117df1d4d7182a1de24c5a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 13 May 2005 06:08:49 +0000 Subject: r6764: added support for DomainGuid, DomainSid, AAC, and User attributes in cldap netlogon queries (This used to be commit 7c1d0f449d3922a309fc86e5d9cb1e962a39805d) --- source4/libcli/cldap/cldap.c | 42 +++++++++++++++++++++++++++++++++++------- source4/libcli/cldap/cldap.h | 6 +++++- 2 files changed, 40 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 2f4d1e73a9..ed416532a2 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -489,6 +489,7 @@ NTSTATUS cldap_search(struct cldap_socket *cldap, } + /* queue a cldap netlogon for send */ @@ -499,11 +500,36 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, char *filter; struct cldap_request *req; const char *attr[] = { "NetLogon", NULL }; + TALLOC_CTX *tmp_ctx = talloc_new(cldap); - filter = talloc_asprintf(cldap, - "(&(DnsDomain=%s)(Host=%s)(NtVer=\\%02X\\00\\00\\00))", - io->in.realm, io->in.host, io->in.version); - if (filter == NULL) return NULL; + filter = talloc_asprintf(tmp_ctx, + "(&(DnsDomain=%s)(Host=%s)(NtVer=%s)", + io->in.realm, io->in.host, + ldap_encode_ndr_uint32(tmp_ctx, io->in.version)); + if (filter == NULL) goto failed; + if (io->in.user) { + filter = talloc_asprintf_append(filter, "(User=%s)", io->in.user); + } + if (io->in.acct_control != -1) { + filter = talloc_asprintf_append(filter, "(AAC=%s)", + ldap_encode_ndr_uint32(tmp_ctx, io->in.acct_control)); + } + if (io->in.domain_sid) { + struct dom_sid *sid = dom_sid_parse_talloc(tmp_ctx, io->in.domain_sid); + if (sid == NULL) goto failed; + filter = talloc_asprintf_append(filter, "(domainSid=%s)", + ldap_encode_ndr_dom_sid(tmp_ctx, sid)); + } + if (io->in.domain_guid) { + struct GUID guid; + NTSTATUS status; + status = GUID_from_string(io->in.domain_guid, &guid); + if (!NT_STATUS_IS_OK(status)) goto failed; + filter = talloc_asprintf_append(filter, "(DomainGuid=%s)", + ldap_encode_ndr_GUID(tmp_ctx, &guid)); + } + filter = talloc_asprintf_append(filter, ")"); + if (filter == NULL) goto failed; search.in.dest_address = io->in.dest_address; search.in.filter = filter; @@ -513,9 +539,11 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, req = cldap_search_send(cldap, &search); - talloc_free(filter); - + talloc_free(tmp_ctx); return req; +failed: + talloc_free(tmp_ctx); + return NULL; } @@ -535,7 +563,7 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, return status; } if (search.out.response == NULL) { - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + return NT_STATUS_NOT_FOUND; } if (search.out.response->num_attributes != 1 || diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index fbdaada8c9..632dbd1f65 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -143,7 +143,11 @@ struct cldap_netlogon { const char *dest_address; const char *realm; const char *host; - uint8_t version; + const char *user; + const char *domain_guid; + const char *domain_sid; + int acct_control; + uint32_t version; } in; struct { union nbt_cldap_netlogon netlogon; -- cgit From 6f36f7cd25b9576fbfdbced0525a5a077b1ccdb4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 13 May 2005 06:28:22 +0000 Subject: r6766: some more cldap tests ... my best guess now is that w2k3 converts the & in the cldap query to an | for the ldap search. at least it behaves roughly like that. (This used to be commit 1d6ab9aaefee71e3d0f87c1afae8ccdbae1f0e04) --- source4/libcli/cldap/cldap.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index ed416532a2..b52b2f53f0 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -502,23 +502,32 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, const char *attr[] = { "NetLogon", NULL }; TALLOC_CTX *tmp_ctx = talloc_new(cldap); - filter = talloc_asprintf(tmp_ctx, - "(&(DnsDomain=%s)(Host=%s)(NtVer=%s)", - io->in.realm, io->in.host, + filter = talloc_asprintf(tmp_ctx, "(&(NtVer=%s)", ldap_encode_ndr_uint32(tmp_ctx, io->in.version)); if (filter == NULL) goto failed; if (io->in.user) { filter = talloc_asprintf_append(filter, "(User=%s)", io->in.user); + if (filter == NULL) goto failed; + } + if (io->in.host) { + filter = talloc_asprintf_append(filter, "(Host=%s)", io->in.host); + if (filter == NULL) goto failed; + } + if (io->in.realm) { + filter = talloc_asprintf_append(filter, "(DnsDomain=%s)", io->in.realm); + if (filter == NULL) goto failed; } if (io->in.acct_control != -1) { filter = talloc_asprintf_append(filter, "(AAC=%s)", ldap_encode_ndr_uint32(tmp_ctx, io->in.acct_control)); + if (filter == NULL) goto failed; } if (io->in.domain_sid) { struct dom_sid *sid = dom_sid_parse_talloc(tmp_ctx, io->in.domain_sid); if (sid == NULL) goto failed; filter = talloc_asprintf_append(filter, "(domainSid=%s)", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); + if (filter == NULL) goto failed; } if (io->in.domain_guid) { struct GUID guid; @@ -527,6 +536,7 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, if (!NT_STATUS_IS_OK(status)) goto failed; filter = talloc_asprintf_append(filter, "(DomainGuid=%s)", ldap_encode_ndr_GUID(tmp_ctx, &guid)); + if (filter == NULL) goto failed; } filter = talloc_asprintf_append(filter, ")"); if (filter == NULL) goto failed; -- cgit From 9469051d5bcdd6a91b688d20bc91bb3cb2ba094d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 16 May 2005 11:17:57 +0000 Subject: r6817: - fixed empty ldap search elements in filters - added support for guids in cldap netlogon searches. the cldap server now passes the LDAP-CLDAP torture test (This used to be commit eb7979d9def389942fa1c54693d2dfcb8828f544) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap.h | 2 ++ source4/libcli/ldap/ldap_ndr.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index cc7f1a10bc..0c6a466f27 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -110,7 +110,7 @@ static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, decode a RFC2254 binary string representation of a buffer. Used in LDAP filters. */ -static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) { int i, j; struct ldap_val ret; diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 8d4294cf76..54a96d9672 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -326,6 +326,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); +struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -384,5 +385,6 @@ struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid); #endif diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 45d9b2729e..2db85d8f09 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -74,3 +74,19 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) data_blob_free(&blob); return ret; } + +/* + decode a NDR GUID from a ldap filter element +*/ +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid) +{ + DATA_BLOB blob; + NTSTATUS status; + + blob.data = val.data; + blob.length = val.length; + status = ndr_pull_struct_blob(&blob, mem_ctx, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(val.data); + return status; +} -- cgit From e73d051e20f18ab981f540a7178900ac3f3c45fd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 17 May 2005 00:51:13 +0000 Subject: r6839: Add support for building subsystems as shared libraries. This can be done by setting: OUTPUT_TYPE = SHARED_LIBRARY in the [SUBSYSTEM::...] section belonging to a subsystem. The idea is to allow multiple values to OUTPUT_TYPE simultaneously (e.g. OUTPUT_TYPE = SHARED_LIBRARY, STATIC_LIBRARY, OBJLIST ) (This used to be commit b9d0ae93ba86fec0115f58e7940b2a6c908bc809) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 834aa01dac..acf61dc2d3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -35,7 +35,7 @@ ADD_OBJ_FILES = \ libcli/nbt/nameregister.o \ libcli/nbt/namerefresh.o \ libcli/nbt/namerelease.o -REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS +REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS [SUBSYSTEM::LIBCLI_DGRAM] ADD_OBJ_FILES = \ -- cgit From cd8cb33d3a897f0a1d84f75e9de09b70cca95536 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 17 May 2005 07:15:12 +0000 Subject: r6851: Typo in comment. (This used to be commit e1864a7ac91b6bdd49c0cee26b592dc6d963e35d) --- source4/libcli/auth/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 0c013ce0ef..0c2e5f9d14 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,5 +1,5 @@ ################################# -# Start SUBSYSTEM GENSEC +# Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] ADD_OBJ_FILES = libcli/auth/credentials.o \ libcli/auth/session.o \ -- cgit From 3c6a91069a92eb0180de3d32bd7c94f99314d32c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 22 May 2005 08:15:10 +0000 Subject: r6929: LIBCLI_NBT depends on LIB_SECURITY_NDR for various security descriptor utilities. (This used to be commit 9b319fc56f08edaf30b1ee671a3448ba10562c62) --- source4/libcli/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index acf61dc2d3..617c8184ab 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -35,7 +35,8 @@ ADD_OBJ_FILES = \ libcli/nbt/nameregister.o \ libcli/nbt/namerefresh.o \ libcli/nbt/namerelease.o -REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS +REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS \ + LIB_SECURITY_NDR [SUBSYSTEM::LIBCLI_DGRAM] ADD_OBJ_FILES = \ -- cgit From e4d5dde7c8012f8585019d417a854399943fe0d8 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 22 May 2005 09:43:20 +0000 Subject: r6930: Use NBT_NAME_CLIENT instead of the number 0. (This used to be commit e6b53ce177d7fea7440656a7bba3dd96fb82e9f3) --- source4/libcli/wins/winsrepl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c index bf3593bdf8..7a3ce72b91 100644 --- a/source4/libcli/wins/winsrepl.c +++ b/source4/libcli/wins/winsrepl.c @@ -603,7 +603,7 @@ static NTSTATUS wrepl_extract_name(struct nbt_name *name, if (len < 17) { name->name = talloc_strndup(mem_ctx, namebuf, len); - name->type = 0; + name->type = NBT_NAME_CLIENT; name->scope = NULL; return NT_STATUS_OK; } -- cgit From 2b7fe67f4d02f861c9a4bfe823e648f0a995e613 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 22 May 2005 10:23:01 +0000 Subject: r6933: Add a couple of helper functions for creating nbt names. (This used to be commit b896daf11c3efb1b3ca939575da9dab82b395777) --- source4/libcli/composite/connect.c | 8 ++------ source4/libcli/dgram/netlogon.c | 4 +--- source4/libcli/dgram/ntlogon.c | 4 +--- source4/libcli/resolve/resolve.c | 23 +++++++++++++++++++++++ source4/libcli/wins/winsrepl.c | 4 +--- 5 files changed, 28 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 0da71df992..526eee8cb8 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -213,9 +213,7 @@ static NTSTATUS connect_socket(struct composite_context *c, state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); - calling.name = cli_credentials_get_workstation(io->in.credentials); - calling.type = NBT_NAME_CLIENT; - calling.scope = NULL; + make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials)); nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); @@ -349,9 +347,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec c->event_ctx = talloc_reference(c, state->sock->event.ctx); c->private = state; - name.name = io->in.dest_host; - name.type = NBT_NAME_SERVER; - name.scope = NULL; + make_nbt_name_server(&name, io->in.dest_host); state->creq = resolve_name_send(&name, c->event_ctx); if (state->creq == NULL) goto failed; diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 6e939725d0..9d3a0dbed9 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -79,9 +79,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, return status; } - myname.name = lp_netbios_name(); - myname.type = NBT_NAME_CLIENT; - myname.scope = NULL; + make_nbt_name_client(&myname, lp_netbios_name()); status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 38651a4085..e4a24b0591 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -79,9 +79,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, return status; } - myname.name = lp_netbios_name(); - myname.type = NBT_NAME_CLIENT; - myname.scope = NULL; + make_nbt_name_client(&myname, lp_netbios_name()); status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 82268dc953..a3bbd60920 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -181,3 +181,26 @@ NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **r struct composite_context *c = resolve_name_send(name, NULL); return resolve_name_recv(c, mem_ctx, reply_addr); } + +/* Initialise a struct nbt_name with a NULL scope */ + +void make_nbt_name(struct nbt_name *nbt, const char *name, int type) +{ + nbt->name = name; + nbt->scope = NULL; + nbt->type = type; +} + +/* Initialise a struct nbt_name with a NBT_NAME_CLIENT (0x00) name */ + +void make_nbt_name_client(struct nbt_name *nbt, const char *name) +{ + make_nbt_name(nbt, name, NBT_NAME_CLIENT); +} + +/* Initialise a struct nbt_name with a NBT_NAME_SERVER (0x20) name */ + +void make_nbt_name_server(struct nbt_name *nbt, const char *name) +{ + make_nbt_name(nbt, name, NBT_NAME_SERVER); +} diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c index 7a3ce72b91..65b713202f 100644 --- a/source4/libcli/wins/winsrepl.c +++ b/source4/libcli/wins/winsrepl.c @@ -602,9 +602,7 @@ static NTSTATUS wrepl_extract_name(struct nbt_name *name, } if (len < 17) { - name->name = talloc_strndup(mem_ctx, namebuf, len); - name->type = NBT_NAME_CLIENT; - name->scope = NULL; + make_nbt_name_client(name, talloc_strndup(mem_ctx, namebuf, len)); return NT_STATUS_OK; } -- cgit From 9b8c012392b6810786267a2a744540fba3878f05 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 27 May 2005 07:38:41 +0000 Subject: r7010: Merge libcli/libsmb.mk into libcli/config.mk (This used to be commit d7d48adce9628ee7a0d2f8ac3504745aaeb912b9) --- source4/libcli/config.mk | 10 ++++++++++ source4/libcli/libsmb.mk | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 source4/libcli/libsmb.mk (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 617c8184ab..82796f4246 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -71,3 +71,13 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM + +[SUBSYSTEM::LIBSMB] +REQUIRED_SUBSYSTEMS = LIBCLI SOCKET +ADD_OBJ_FILES = libcli/clireadwrite.o \ + libcli/cliconnect.o \ + libcli/clifile.o \ + libcli/clilist.o \ + libcli/clitrans2.o \ + libcli/climessage.o \ + libcli/clideltree.o diff --git a/source4/libcli/libsmb.mk b/source4/libcli/libsmb.mk deleted file mode 100644 index 5f314dfca1..0000000000 --- a/source4/libcli/libsmb.mk +++ /dev/null @@ -1,9 +0,0 @@ -[SUBSYSTEM::LIBSMB] -REQUIRED_SUBSYSTEMS = LIBCLI SOCKET -ADD_OBJ_FILES = libcli/clireadwrite.o \ - libcli/cliconnect.o \ - libcli/clifile.o \ - libcli/clilist.o \ - libcli/clitrans2.o \ - libcli/climessage.o \ - libcli/clideltree.o -- cgit From 665480ffed385abb74bc44b6f376547a6d465db9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Jun 2005 13:31:27 +0000 Subject: r7229: use socket_pending() to get rid of the max packet size limits in the nbt and dgram layers (This used to be commit 2a9efbdae638a655999e07a7c3da97fd20dc056c) --- source4/libcli/dgram/dgramsocket.c | 12 ++++++++---- source4/libcli/nbt/nbtsocket.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index a3909df768..88eed5c10b 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -27,8 +27,6 @@ #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" -#define DGRAM_MAX_PACKET_SIZE 2048 - /* handle recv events on a nbt dgram socket @@ -40,11 +38,17 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) const char *src_addr; int src_port; DATA_BLOB blob; - size_t nread; + size_t nread, dsize; struct nbt_dgram_packet *packet; const char *mailslot_name; - blob = data_blob_talloc(tmp_ctx, NULL, DGRAM_MAX_PACKET_SIZE); + status = socket_pending(dgmsock->sock, &dsize); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + blob = data_blob_talloc(tmp_ctx, NULL, dsize); if (blob.data == NULL) { talloc_free(tmp_ctx); return; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 481327cc85..f600afb79f 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -26,7 +26,6 @@ #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" -#define NBT_MAX_PACKET_SIZE 2048 #define NBT_MAX_REPLIES 1000 /* @@ -157,11 +156,17 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) const char *src_addr; int src_port; DATA_BLOB blob; - size_t nread; + size_t nread, dsize; struct nbt_name_packet *packet; struct nbt_name_request *req; - blob = data_blob_talloc(tmp_ctx, NULL, NBT_MAX_PACKET_SIZE); + status = socket_pending(nbtsock->sock, &dsize); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + blob = data_blob_talloc(tmp_ctx, NULL, dsize); if (blob.data == NULL) { talloc_free(tmp_ctx); return; -- cgit From 4be9b65d770c891e821ba35fa6a2d146a4d50e5a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Jun 2005 13:37:23 +0000 Subject: r7230: use socket_pending() to get rid of the max packet size limits in the cldap code (This used to be commit 9da5379048784524eee213d8609f1d96f0058e39) --- source4/libcli/cldap/cldap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index b52b2f53f0..a96906cf4c 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -40,8 +40,6 @@ #include "lib/socket/socket.h" #include "include/asn_1.h" -#define CLDAP_MAX_PACKET_SIZE 2048 - /* destroy a pending request */ @@ -68,12 +66,18 @@ static void cldap_socket_recv(struct cldap_socket *cldap) const char *src_addr; int src_port; DATA_BLOB blob; - size_t nread; + size_t nread, dsize; struct asn1_data asn1; struct ldap_message ldap_msg; struct cldap_request *req; - blob = data_blob_talloc(tmp_ctx, NULL, CLDAP_MAX_PACKET_SIZE); + status = socket_pending(cldap->sock, &dsize); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + blob = data_blob_talloc(tmp_ctx, NULL, dsize); if (blob.data == NULL) { talloc_free(tmp_ctx); return; -- cgit From 7c9d76d30c0f89f926744941ba3e0e6dbb24975c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Jun 2005 22:09:18 +0000 Subject: r7377: Integrate browse service stuff more nicely Add notes on mailslots Add TODO list for pidl, including some plans on switching over to using [string] attributes for pidl. (This used to be commit fca195ce072bacb0543625aec7f4bce814e278eb) --- source4/libcli/config.mk | 3 +- source4/libcli/dgram/browse.c | 98 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/dgram/mailslot.c | 16 ++++++- 3 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 source4/libcli/dgram/browse.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 82796f4246..11e54498cf 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -43,7 +43,8 @@ ADD_OBJ_FILES = \ libcli/dgram/dgramsocket.o \ libcli/dgram/mailslot.o \ libcli/dgram/netlogon.o \ - libcli/dgram/ntlogon.o + libcli/dgram/ntlogon.o \ + libcli/dgram/browse.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c new file mode 100644 index 0000000000..d7707b7ec8 --- /dev/null +++ b/source4/libcli/dgram/browse.c @@ -0,0 +1,98 @@ +/* + Unix SMB/CIFS implementation. + + handling for browsing dgram requests + + Copyright (C) Jelmer Vernooij 2005 + Heavily based on ntlogon.c + + 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 "lib/events/events.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" + +NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, const char *dest_address, int dest_port, + struct nbt_name *src_name, struct nbt_browse_packet *request) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + + status = ndr_push_struct_blob(&blob, tmp_ctx, request, + (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + NBT_MAILSLOT_BROWSE, + dest_name, dest_address, dest_port, + src_name, &blob); + talloc_free(tmp_ctx); + return status; +} + +NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, const char *mailslot_name, + struct nbt_browse_packet *reply) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + struct nbt_name myname; + + status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + make_nbt_name_client(&myname, lp_netbios_name()); + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + mailslot_name, + &request->data.msg.source_name, + request->source, request->src_port, + &myname, &blob); + talloc_free(tmp_ctx); + return status; +} + +NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, + struct nbt_browse_packet *pkt) +{ + DATA_BLOB data = dgram_mailslot_data(dgram); + NTSTATUS status; + + status = ndr_pull_struct_blob(&data, mem_ctx, pkt, + (ndr_pull_flags_fn_t)ndr_pull_nbt_browse_packet); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to parse browse packet of length %d\n", + data.length)); + if (DEBUGLVL(10)) { + file_save("browse.dat", data.data, data.length); + } + } + return status; +} diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 9f02210646..14e7e49fc1 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -1,8 +1,8 @@ /* Unix SMB/CIFS implementation. - packet handling for mailslot requests - + packet handling for mailslot requests. + Copyright (C) Andrew Tridgell 2005 This program is free software; you can redistribute it and/or modify @@ -20,6 +20,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + This implements "Class 2 mailslots", i.e. the communication mechanism + used for all mailslot packets smaller then 425 bytes. + + "Class 1 mailslots" (which use SMB) are used for messages larger + then 426 bytes and are supported on some systems. These are not implemented + in Samba4 yet, as there don't appear to be any core services that use + them. + + 425 and 426-byte sized messages are not supported at all. +*/ + #include "includes.h" #include "lib/events/events.h" #include "dlinklist.h" -- cgit From 09753bf20a2d5c7c0b101e05f2178ca1d2e52283 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jun 2005 08:45:01 +0000 Subject: r7430: Next step in AIX build (This used to be commit 43e1bd870d9d7ca67e0ce1d2d1a1589aad41d770) --- source4/libcli/composite/connect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 526eee8cb8..9e33a2f7db 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -308,7 +308,7 @@ static void request_handler(struct smbcli_request *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - return state_handler(c); + state_handler(c); } /* @@ -318,7 +318,7 @@ static void composite_handler(struct composite_context *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - return state_handler(c); + state_handler(c); } /* -- cgit From 35314f2427d82c819903087d04e3cd7915b32b36 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jun 2005 09:46:46 +0000 Subject: r7433: Another little AIX one... (This used to be commit c1ccaa0cc9de9c8f781162674bc73ca0ff88fedd) --- source4/libcli/composite/fetchfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c index fb9226985e..c9e8321db2 100644 --- a/source4/libcli/composite/fetchfile.c +++ b/source4/libcli/composite/fetchfile.c @@ -117,7 +117,7 @@ static void fetchfile_composite_handler(struct composite_context *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - return fetchfile_state_handler(c); + fetchfile_state_handler(c); } struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, -- cgit From 46c231f1c8ce0f67c13f5545f080636c9e252364 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jun 2005 10:33:20 +0000 Subject: r7435: Another little step, sorry for the spam... :-) (This used to be commit 96d9b7fc988405a0d771b778e95a9f60b1efe514) --- source4/libcli/composite/fsinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/fsinfo.c b/source4/libcli/composite/fsinfo.c index 1ad8a18149..e0accbb6a6 100644 --- a/source4/libcli/composite/fsinfo.c +++ b/source4/libcli/composite/fsinfo.c @@ -111,14 +111,14 @@ static void fsinfo_raw_handler(struct smbcli_request *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - return fsinfo_state_handler(c); + fsinfo_state_handler(c); } static void fsinfo_composite_handler(struct composite_context *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - return fsinfo_state_handler(c); + fsinfo_state_handler(c); } /* -- cgit From c96492a9dce25a1881e854ac7861a0b258ee1ae1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jun 2005 13:13:15 +0000 Subject: r7436: As far as I see it, these are the last two "real" ones for Samba4 on AIX to build. The remaining patch (not now) is to convert the javascript stuff not to use // style comments. Volker (This used to be commit 29f7e430ac4ae43f6844f021be73bf391610ef73) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 5f344d9c6d..0fc679def3 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -36,7 +36,7 @@ */ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) { - return ndr_print_string(ndr, name, s); + ndr_print_string(ndr, name, s); } /* -- cgit From 302b4db004c51700dac7714d88ca27cdafe9612f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Jun 2005 07:49:00 +0000 Subject: r7455: Remove some talloc contexts that aren't used. (This used to be commit b0ad51f2ce6c3646d664773aaa32fe55172ad88b) --- source4/libcli/cliconnect.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 53a97da168..ace9389ae8 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -67,14 +67,10 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, { struct smb_composite_sesssetup setup; NTSTATUS status; - TALLOC_CTX *mem_ctx; cli->session = smbcli_session_init(cli->transport, cli, True); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; - mem_ctx = talloc_init("smbcli_session_setup"); - if (!mem_ctx) return NT_STATUS_NO_MEMORY; - setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.credentials = credentials; @@ -84,8 +80,6 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, cli->session->vuid = setup.out.vuid; - talloc_free(mem_ctx); - return status; } @@ -144,9 +138,6 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, { struct smbcli_tree *tree; NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("smbcli_full_connection"); *ret_cli = NULL; @@ -164,8 +155,6 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, (*ret_cli)->transport = tree->session->transport; done: - talloc_free(mem_ctx); - return status; } -- cgit From 6412e8eeae6b4abfb65514b00c49419a7cb97b1a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 11 Jun 2005 03:35:28 +0000 Subject: r7482: Rename smbcli_send_tconX() to smbcli_tconX() so as not to get it confused with an async function. (This used to be commit 340ad67cada15329051c205c5b094ad641718c72) --- source4/libcli/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index ace9389ae8..a866e26970 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -84,8 +84,8 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, } /* wrapper around smb_tree_connect() */ -NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename, - const char *devtype, const char *password) +NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, + const char *devtype, const char *password) { union smb_tcon tcon; TALLOC_CTX *mem_ctx; -- cgit From 07b0d86121cf78e0f7407364240d8eb76bde8d80 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Jun 2005 03:53:39 +0000 Subject: r7483: ensure we try reading from a socket if epoll says we can, and don't just do the write. This is needed because the write could return -1/EAGAIN for dgram sockets, if the socket buffer is nearly full. The epoll loop then goes on forever. This was causing some failures in 'make test' (This used to be commit b7fefe76a2d3c288611868f41d65af4e13ac460b) --- source4/libcli/cldap/cldap.c | 3 ++- source4/libcli/dgram/dgramsocket.c | 3 ++- source4/libcli/nbt/nbtsocket.c | 3 ++- source4/libcli/wins/winsrepl.c | 1 - 4 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index a96906cf4c..41d5f1a06e 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -222,7 +222,8 @@ static void cldap_socket_handler(struct event_context *ev, struct fd_event *fde, struct cldap_socket *cldap = talloc_get_type(private, struct cldap_socket); if (flags & EVENT_FD_WRITE) { cldap_socket_send(cldap); - } else if (flags & EVENT_FD_READ) { + } + if (flags & EVENT_FD_READ) { cldap_socket_recv(cldap); } } diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 88eed5c10b..aff9d2e182 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -146,7 +146,8 @@ static void dgm_socket_handler(struct event_context *ev, struct fd_event *fde, struct nbt_dgram_socket); if (flags & EVENT_FD_WRITE) { dgm_socket_send(dgmsock); - } else if (flags & EVENT_FD_READ) { + } + if (flags & EVENT_FD_READ) { dgm_socket_recv(dgmsock); } } diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index f600afb79f..0401e68af8 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -292,7 +292,8 @@ static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *f struct nbt_name_socket); if (flags & EVENT_FD_WRITE) { nbt_name_socket_send(nbtsock); - } else if (flags & EVENT_FD_READ) { + } + if (flags & EVENT_FD_READ) { nbt_name_socket_recv(nbtsock); } } diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c index 65b713202f..732b597c53 100644 --- a/source4/libcli/wins/winsrepl.c +++ b/source4/libcli/wins/winsrepl.c @@ -200,7 +200,6 @@ static void wrepl_handler(struct event_context *ev, struct fd_event *fde, struct wrepl_socket); if (flags & EVENT_FD_WRITE) { wrepl_handler_send(wrepl_socket); - return; } if (flags & EVENT_FD_READ) { wrepl_handler_recv(wrepl_socket); -- cgit From 816f4f7c4afa1022075fb36563fadf4820f37afd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Jun 2005 06:06:29 +0000 Subject: r7519: rip the copy of the ldap expression parser out of libcli/ldap/ and use the original one in lib/ldb/ instead. Having two copies of this code is silly. (This used to be commit 0e9f18c44858b692c724c004f362de9e3dc15db5) --- source4/libcli/ldap/ldap.c | 392 ++-------------------------------------- source4/libcli/ldap/ldap.h | 38 +--- source4/libcli/ldap/ldap_ldif.c | 12 +- source4/libcli/ldap/ldap_ndr.c | 22 ++- 4 files changed, 43 insertions(+), 421 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0c6a466f27..f383d08074 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -28,350 +28,11 @@ #include "asn_1.h" #include "libcli/ldap/ldap.h" -/**************************************************************************** - * - * LDAP filter parser -- main routine is ldap_parse_filter - * - * Shamelessly stolen and adapted from ldb. - * - ***************************************************************************/ - -/* - return next token element. Caller frees -*/ -static char *ldap_parse_lex(TALLOC_CTX *mem_ctx, const char **s, - const char *sep) -{ - const char *p = *s; - char *ret; - - while (isspace(*p)) { - p++; - } - *s = p; - - if (*p == 0) { - return NULL; - } - - if (strchr(sep, *p)) { - (*s) = p+1; - ret = talloc_strndup(mem_ctx, p, 1); - if (!ret) { - errno = ENOMEM; - } - return ret; - } - - while (*p && (isalnum(*p) || !strchr(sep, *p))) { - p++; - } - - if (p == *s) { - return NULL; - } - - ret = talloc_strndup(mem_ctx, *s, p - *s); - if (!ret) { - errno = ENOMEM; - } - - *s = p; - - return ret; -} - - -/* - find a matching close brace in a string -*/ -static const char *match_brace(const char *s) -{ - unsigned int count = 0; - while (*s && (count != 0 || *s != ')')) { - if (*s == '(') { - count++; - } - if (*s == ')') { - count--; - } - s++; - } - if (! *s) { - return NULL; - } - return s; -} - -static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s); - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) -{ - int i, j; - struct ldap_val ret; - int slen = strlen(str); - - ret.data = talloc_size(mem_ctx, slen); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;i ::= -*/ -static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, - const char *s) -{ - char *eq, *val, *l; - struct ldap_parse_tree *ret; - - l = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); - if (!l) { - return NULL; - } - - if (strchr("()&|=", *l)) - return NULL; - - eq = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); - if (!eq || strcmp(eq, "=") != 0) - return NULL; - - val = ldap_parse_lex(mem_ctx, &s, ")"); - if (val && strchr("()&|", *val)) - return NULL; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDAP_OP_SIMPLE; - ret->u.simple.attr = l; - ret->u.simple.value = ldap_binary_decode(ret, val); - - return ret; -} - - -/* - parse a filterlist - ::= '&' - ::= '|' - ::= | -*/ -static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, - enum ldap_parse_op op, - const char *s) -{ - struct ldap_parse_tree *ret, *next; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(mem_ctx, struct ldap_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - return NULL; - } - - ret->u.list.elements[0] = ldap_parse_filter(mem_ctx, &s); - if (!ret->u.list.elements[0]) { - return NULL; - } - - while (isspace(*s)) s++; - - while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { - struct ldap_parse_tree **e; - e = talloc_realloc(ret, - ret->u.list.elements, - struct ldap_parse_tree *, - ret->u.list.num_elements+1); - if (!e) { - errno = ENOMEM; - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace(*s)) s++; - } - - return ret; -} - - -/* - ::= '!' -*/ -static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s) -{ - struct ldap_parse_tree *ret; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDAP_OP_NOT; - ret->u.not.child = ldap_parse_filter(mem_ctx, &s); - if (!ret->u.not.child) - return NULL; - - return ret; -} - -/* - parse a filtercomp - ::= | | | -*/ -static struct ldap_parse_tree *ldap_parse_filtercomp(TALLOC_CTX *mem_ctx, - const char *s) -{ - while (isspace(*s)) s++; - - switch (*s) { - case '&': - return ldap_parse_filterlist(mem_ctx, LDAP_OP_AND, s+1); - - case '|': - return ldap_parse_filterlist(mem_ctx, LDAP_OP_OR, s+1); - - case '!': - return ldap_parse_not(mem_ctx, s+1); - - case '(': - case ')': - return NULL; - } - - return ldap_parse_simple(mem_ctx, s); -} - - -/* - ::= '(' ')' -*/ -static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s) -{ - char *l, *s2; - const char *p, *p2; - struct ldap_parse_tree *ret; - - l = ldap_parse_lex(mem_ctx, s, LDAP_ALL_SEP); - if (!l) { - return NULL; - } - - if (strcmp(l, "(") != 0) { - return NULL; - } - - p = match_brace(*s); - if (!p) { - return NULL; - } - p2 = p + 1; - - s2 = talloc_strndup(mem_ctx, *s, p - *s); - if (!s2) { - errno = ENOMEM; - return NULL; - } - - ret = ldap_parse_filtercomp(mem_ctx, s2); - - *s = p2; - - return ret; -} - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= | -*/ -static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char *s) -{ - while (isspace(*s)) s++; - - if (*s == '(') { - return ldap_parse_filter(mem_ctx, &s); - } - - return ldap_parse_simple(mem_ctx, s); -} - -static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tree) +static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { switch (tree->operation) { - case LDAP_OP_SIMPLE: { + case LDB_OP_SIMPLE: { if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -392,7 +53,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tre break; } - case LDAP_OP_AND: { + case LDB_OP_AND: { int i; asn1_push_tag(data, 0xa0); @@ -403,7 +64,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tre break; } - case LDAP_OP_OR: { + case LDB_OP_OR: { int i; asn1_push_tag(data, 0xa1); @@ -481,9 +142,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - if (r->SASL.secblob.length > 0) { - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); - } + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); asn1_pop_tag(&data); break; } @@ -493,6 +152,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; + struct ldb_parse_tree *tree; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); @@ -501,22 +161,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - { - TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); - struct ldap_parse_tree *tree; - - if (mem_ctx == NULL) - return False; + tree = ldb_parse_tree(NULL, r->filter); - tree = ldap_parse_tree(mem_ctx, r->filter); - - if (tree == NULL) - return False; + if (tree == NULL) + return False; - ldap_push_filter(&data, tree); + ldap_push_filter(&data, tree); - talloc_free(mem_ctx); - } + talloc_free(tree); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -830,6 +482,8 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* equalityMatch */ const char *attrib; DATA_BLOB value; + struct ldb_val val; + if (tag_desc != 0xa0) /* context compound */ return False; asn1_start_tag(data, ASN1_CONTEXT(3)); @@ -838,8 +492,10 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) return False; + val.data = value.data; + val.length = value.length; filter = talloc_asprintf(mem_ctx, "(%s=%s)", - attrib, ldap_binary_encode(mem_ctx, value)); + attrib, ldb_binary_encode(mem_ctx, val)); data_blob_free(&value); break; } @@ -881,7 +537,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldap_val value; + struct ldb_val value; asn1_read_OctetString(data, &blob); value.data = blob.data; value.length = blob.length; @@ -1334,17 +990,3 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, return (*host != NULL); } - - -/* - externally callable version of filter string parsing - used in the - cldap server -*/ -struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, - const char *s) -{ - return ldap_parse_filter(mem_ctx, &s); -} - - - diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 54a96d9672..12d30a2610 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -22,6 +22,9 @@ #ifndef _SMB_LDAP_H #define _SMB_LDAP_H +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_parse.h" + enum ldap_request_tag { LDAP_TAG_BindRequest = 0, LDAP_TAG_BindResponse = 1, @@ -288,33 +291,6 @@ struct ldap_connection { struct gensec_security *gensec; }; -/* Hmm. A blob might be more appropriate here :-) */ - -struct ldap_val { - unsigned int length; - void *data; -}; - -enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; - -struct ldap_parse_tree { - enum ldap_parse_op operation; - union { - struct { - char *attr; - struct ldap_val value; - } simple; - struct { - unsigned int num_elements; - struct ldap_parse_tree **elements; - } list; - struct { - struct ldap_parse_tree *child; - } not; - } u; -}; - -#define LDAP_ALL_SEP "()&|=!" #define LDAP_CONNECTION_TIMEOUT 10000 /* The following definitions come from libcli/ldap/ldap.c */ @@ -323,10 +299,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); -struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, - const char *s); -const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); -struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -368,7 +340,7 @@ NTSTATUS ldap2nterror(int ldaperror); /* The following definitions come from libcli/ldap/ldap_ldif.c */ -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldap_attribute *attrib); BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldap_attribute *attrib, @@ -385,6 +357,6 @@ struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); #endif diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index c36106e116..2489a97748 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -104,7 +104,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, } /* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldap_val *value) +static int next_attr(char **s, const char **attr, struct ldb_val *value) { char *p; int base64_encoded = 0; @@ -157,7 +157,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) return 0; } -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldap_attribute *attrib) { attrib->values = talloc_realloc(mem_ctx, @@ -195,7 +195,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) { struct ldap_AddRequest *r = &msg->r.AddRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->num_attributes = 0; r->attributes = NULL; @@ -251,7 +251,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->num_mods = 0; r->mods = NULL; @@ -309,7 +309,7 @@ static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->newrdn = NULL; r->deleteolddn = False; @@ -362,7 +362,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void const char *attr=NULL; const char *dn; char *chunk=NULL, *s; - struct ldap_val value; + struct ldb_val value; value.data = NULL; diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 2db85d8f09..720022c6c2 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -25,17 +25,25 @@ #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" +struct ldb_val ldb_blob(DATA_BLOB blob) +{ + struct ldb_val val; + val.data = blob.data; + val.length = blob.length; + return val; +} + /* encode a NDR uint32 as a ldap filter element */ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) { uint8_t buf[4]; - DATA_BLOB blob; + struct ldb_val val; SIVAL(buf, 0, value); - blob.data = buf; - blob.length = 4; - return ldap_binary_encode(mem_ctx, blob); + val.data = buf; + val.length = 4; + return ldb_binary_encode(mem_ctx, val); } /* @@ -51,7 +59,7 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldap_binary_encode(mem_ctx, blob); + ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); data_blob_free(&blob); return ret; } @@ -70,7 +78,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldap_binary_encode(mem_ctx, blob); + ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); data_blob_free(&blob); return ret; } @@ -78,7 +86,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) /* decode a NDR GUID from a ldap filter element */ -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid) +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) { DATA_BLOB blob; NTSTATUS status; -- cgit From 8fd5825a890db4f08966e4b262b03fb7868cc4c2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Jun 2005 07:36:52 +0000 Subject: r7524: make the ldap ASN.1 filter parse code go via a struct ldb_parse_tree. This also fixes the error handling. next step will be to pass the parse tree straight into ldb, avoiding the string encoding completely. (This used to be commit 235cf625e20767c8d5d30c5955ae45e1fdf88bf2) --- source4/libcli/ldap/ldap.c | 184 ++++++++++++++++++++++++++------------------- 1 file changed, 107 insertions(+), 77 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index f383d08074..2718dd7e34 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -413,122 +413,152 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - const char **filterp) +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) { uint8_t filter_tag, tag_desc; - char *filter = NULL; - - *filterp = NULL; + struct ldb_parse_tree *ret; - if (!asn1_peek_uint8(data, &filter_tag)) - return False; + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } tag_desc = filter_tag; filter_tag &= 0x1f; /* strip off the asn1 stuff */ tag_desc &= 0xe0; - switch(filter_tag) { - case 0: { - /* AND of one or more filters */ - if (tag_desc != 0xa0) /* context compount */ - return False; - - asn1_start_tag(data, ASN1_CONTEXT(0)); + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; - filter = talloc_strdup(mem_ctx, "(&"); - if (filter == NULL) - return False; - - while (asn1_tag_remaining(data) > 0) { - const char *subfilter; - if (!ldap_decode_filter(mem_ctx, data, &subfilter)) - return False; - filter = talloc_asprintf_append(filter, "%s", subfilter); - if (filter == NULL) - return False; + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (tag_desc != 0xa0) { + /* context compount */ + goto failed; } - asn1_end_tag(data); - - filter = talloc_asprintf_append(filter, ")"); - break; - } - case 1: { - /* OR of one or more filters */ - if (tag_desc != 0xa0) /* context compount */ - return False; - asn1_start_tag(data, ASN1_CONTEXT(1)); - - filter = talloc_strdup(mem_ctx, "(|"); - if (filter == NULL) - return False; + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } while (asn1_tag_remaining(data) > 0) { - const char *subfilter; - if (!ldap_decode_filter(mem_ctx, data, &subfilter)) - return False; - filter = talloc_asprintf_append(filter, "%s", subfilter); - if (filter == NULL) - return False; + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; } - - asn1_end_tag(data); - - filter = talloc_asprintf_append(filter, ")"); break; - } + case 3: { /* equalityMatch */ const char *attrib; DATA_BLOB value; - struct ldb_val val; - if (tag_desc != 0xa0) /* context compound */ - return False; + ret->operation = LDB_OP_SIMPLE; + + if (tag_desc != 0xa0) { + /* context compound */ + goto failed; + } + asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); asn1_read_OctetString(data, &value); asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) - return False; - val.data = value.data; - val.length = value.length; - filter = talloc_asprintf(mem_ctx, "(%s=%s)", - attrib, ldb_binary_encode(mem_ctx, val)); - data_blob_free(&value); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + ret->u.simple.attr = talloc_steal(ret, attrib); + ret->u.simple.value.data = talloc_steal(ret, value.data); + ret->u.simple.value.length = value.length; break; } case 7: { /* Normal presence, "attribute=*" */ int attr_len; - char *attr_name; - if (tag_desc != 0x80) /* context simple */ - return False; - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) - return False; + if (tag_desc != 0x80) { + /* context simple */ + goto failed; + } + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + goto failed; + } + + ret->operation = LDB_OP_SIMPLE; + attr_len = asn1_tag_remaining(data); - attr_name = malloc(attr_len+1); - if (attr_name == NULL) - return False; - asn1_read(data, attr_name, attr_len); - attr_name[attr_len] = '\0'; - filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); - SAFE_FREE(attr_name); - asn1_end_tag(data); + + ret->u.simple.attr = talloc_size(ret, attr_len+1); + if (ret->u.simple.attr == NULL) { + goto failed; + } + if (!asn1_read(data, ret->u.simple.attr, attr_len)) { + goto failed; + } + ret->u.simple.attr[attr_len] = 0; + ret->u.simple.value.data = talloc_strdup(ret, "*"); + if (ret->u.simple.value.data == NULL) { + goto failed; + } + ret->u.simple.value.length = 1; + if (!asn1_end_tag(data)) { + goto failed; + } break; } default: - return False; + DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); + goto failed; } - if (filter == NULL) - return False; + + return ret; - *filterp = filter; +failed: + talloc_free(ret); + DEBUG(0,("Failed to parse ASN.1 LDAP filter\n")); + return NULL; +} + + +static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, + const char **filterp) +{ + struct ldb_parse_tree *tree; + tree = ldap_decode_filter_tree(mem_ctx, data); + if (tree == NULL) { + return False; + } + *filterp = ldb_filter_from_tree(mem_ctx, tree); + talloc_free(tree); + if (*filterp == NULL) { + return False; + } return True; } + + static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { -- cgit From 4b0e5bd75373ffa2d847706a71fd0349dfa15e71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Jun 2005 09:10:17 +0000 Subject: r7527: - added a ldb_search_bytree() interface, which takes a ldb_parse_tree instead of a search expression. This allows our ldap server to pass its ASN.1 parsed search expressions straight to ldb, instead of going via strings. - updated all the ldb modules code to handle the new interface - got rid of the separate ldb_parse.h now that the ldb_parse structures are exposed externally - moved to C99 structure initialisation in ldb - switched ldap server to using ldb_search_bytree() (This used to be commit 96620ab2ee5d440bbbc51c1bc0cad9977770f897) --- source4/libcli/cldap/cldap.c | 5 ++++- source4/libcli/ldap/ldap.c | 41 +++++++++-------------------------------- source4/libcli/ldap/ldap.h | 3 +-- source4/libcli/util/asn1.c | 4 +++- 4 files changed, 17 insertions(+), 36 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 41d5f1a06e..71326caa37 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -328,7 +328,10 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, search->attributesonly = False; search->num_attributes = str_list_length(io->in.attributes); search->attributes = io->in.attributes; - search->filter = io->in.filter; + search->tree = ldb_parse_tree(req, io->in.filter); + if (search->tree == NULL) { + goto failed; + } if (!ldap_encode(&msg, &req->encoded)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2718dd7e34..0d310b4eed 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -152,7 +152,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - struct ldb_parse_tree *tree; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); @@ -161,14 +160,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - tree = ldb_parse_tree(NULL, r->filter); - - if (tree == NULL) - return False; - - ldap_push_filter(&data, tree); - - talloc_free(tree); + ldap_push_filter(&data, r->tree); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -176,7 +168,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) strlen(r->attributes[i])); } asn1_pop_tag(&data); - asn1_pop_tag(&data); break; } @@ -413,6 +404,10 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, struct asn1_data *data) { @@ -540,25 +535,6 @@ failed: } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - const char **filterp) -{ - struct ldb_parse_tree *tree; - - tree = ldap_decode_filter_tree(mem_ctx, data); - if (tree == NULL) { - return False; - } - *filterp = ldb_filter_from_tree(mem_ctx, tree); - talloc_free(tree); - if (*filterp == NULL) { - return False; - } - return True; -} - - - static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { @@ -674,9 +650,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_Integer(data, &r->timelimit); asn1_read_BOOLEAN(data, &r->attributesonly); - /* Maybe create a TALLOC_CTX for the filter? This can waste - * quite a bit of memory recursing down. */ - ldap_decode_filter(msg->mem_ctx, data, &r->filter); + r->tree = ldap_decode_filter_tree(msg->mem_ctx, data); + if (r->tree == NULL) { + return False; + } asn1_start_tag(data, ASN1_SEQUENCE(0)); diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 12d30a2610..a44c249e7a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -23,7 +23,6 @@ #define _SMB_LDAP_H #include "lib/ldb/include/ldb.h" -#include "lib/ldb/include/ldb_parse.h" enum ldap_request_tag { LDAP_TAG_BindRequest = 0, @@ -152,7 +151,7 @@ struct ldap_SearchRequest { uint32_t timelimit; uint32_t sizelimit; BOOL attributesonly; - const char *filter; + struct ldb_parse_tree *tree; int num_attributes; const char **attributes; }; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 1124cc1701..dff31f6411 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -509,9 +509,11 @@ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) data->has_error = True; return False; } - *blob = data_blob(NULL, len); + *blob = data_blob(NULL, len+1); asn1_read(data, blob->data, len); asn1_end_tag(data); + blob->length--; + blob->data[len] = 0; if (data->has_error) { data_blob_free(blob); -- cgit From 9d6b3e62c2dd27c7e8f72d6887888f686d868981 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Jun 2005 03:52:27 +0000 Subject: r7566: added support for LDAPString types in the asn.1 library (This used to be commit 1a81d28456261ad77181fd12c0b4a9df6aa6a47d) --- source4/libcli/util/asn1.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index dff31f6411..510ffa37cf 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -214,11 +214,18 @@ BOOL asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length return !data->has_error; } +/* write a LDAP string */ +BOOL asn1_write_LDAPString(struct asn1_data *data, const char *s) +{ + asn1_write(data, s, strlen(s)); + return !data->has_error; +} + /* write a general string */ BOOL asn1_write_GeneralString(struct asn1_data *data, const char *s) { asn1_push_tag(data, ASN1_GENERAL_STRING); - asn1_write(data, s, strlen(s)); + asn1_write_LDAPString(data, s); asn1_pop_tag(data); return !data->has_error; } @@ -477,11 +484,10 @@ BOOL asn1_check_OID(struct asn1_data *data, const char *OID) return True; } -/* read a GeneralString from a ASN1 buffer */ -BOOL asn1_read_GeneralString(struct asn1_data *data, char **s) +/* read a LDAPString from a ASN1 buffer */ +BOOL asn1_read_LDAPString(struct asn1_data *data, char **s) { int len; - if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; len = asn1_tag_remaining(data); if (len < 0) { data->has_error = True; @@ -494,10 +500,19 @@ BOOL asn1_read_GeneralString(struct asn1_data *data, char **s) } asn1_read(data, *s, len); (*s)[len] = 0; - asn1_end_tag(data); return !data->has_error; } + +/* read a GeneralString from a ASN1 buffer */ +BOOL asn1_read_GeneralString(struct asn1_data *data, char **s) +{ + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; + if (!asn1_read_LDAPString(data, s)) return False; + return asn1_end_tag(data); +} + + /* read a octet string blob */ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) { -- cgit From 6426f2a39ab42e164e29265b6d04cec9dca92eca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Jun 2005 03:53:35 +0000 Subject: r7567: added wire parsing of NOT and extended ldap search requests. This allows us to parse and handle the complex queries we are getting from w2k, such as (|(|(&(!(groupType:1.2.840.113556.1.4.803=1))(groupType:1.2.840.113556.1.4.803=2147483648)(groupType:1.2.840.113556.1.4.804=6))(samAccountType=805306368))(samAccountType=805306369)) (This used to be commit 041bce591306a0fb26bd31fe371e30021ea5c0c1) --- source4/libcli/ldap/ldap.c | 134 ++++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 37 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0d310b4eed..048a60317a 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -31,8 +31,10 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { + int i; + switch (tree->operation) { - case LDB_OP_SIMPLE: { + case LDB_OP_SIMPLE: if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -43,7 +45,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree return !data->has_error; } - /* Equality is all we currently do... */ + /* equality test */ asn1_push_tag(data, 0xa3); asn1_write_OctetString(data, tree->u.simple.attr, strlen(tree->u.simple.attr)); @@ -51,29 +53,51 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree tree->u.simple.value.length); asn1_pop_tag(data); break; - } - - case LDB_OP_AND: { - int i; - asn1_push_tag(data, 0xa0); - for (i=0; iu.list.num_elements; i++) { - ldap_push_filter(data, tree->u.list.elements[i]); + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, 0xa9); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, 1); + asn1_write_OctetString(data, tree->u.extended.rule_id, + strlen(tree->u.extended.rule_id)); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, 2); + asn1_write_OctetString(data, tree->u.extended.attr, + strlen(tree->u.extended.attr)); + asn1_pop_tag(data); + } + asn1_push_tag(data, 3); + asn1_write_OctetString(data, tree->u.extended.value.data, + tree->u.extended.value.length); + asn1_pop_tag(data); + if (tree->u.extended.dnAttributes) { + asn1_push_tag(data, 4); + asn1_write_BOOLEAN(data, True); + asn1_pop_tag(data); } asn1_pop_tag(data); break; - } - - case LDB_OP_OR: { - int i; + - asn1_push_tag(data, 0xa1); + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, 0xa0 | (tree->operation==LDB_OP_AND?0:1)); for (i=0; iu.list.num_elements; i++) { ldap_push_filter(data, tree->u.list.elements[i]); } asn1_pop_tag(data); break; - } + default: return False; } @@ -464,25 +488,34 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } break; - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } - ret->operation = LDB_OP_SIMPLE; + ret->operation = LDB_OP_NOT; + ret->u.not.child = ldap_decode_filter_tree(ret, data); - if (tag_desc != 0xa0) { - /* context compound */ + if (!asn1_end_tag(data)) { goto failed; } + break; - asn1_start_tag(data, ASN1_CONTEXT(3)); + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); asn1_read_OctetString(data, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; } + + ret->operation = LDB_OP_SIMPLE; ret->u.simple.attr = talloc_steal(ret, attrib); ret->u.simple.value.data = talloc_steal(ret, value.data); ret->u.simple.value.length = value.length; @@ -490,37 +523,64 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } case 7: { /* Normal presence, "attribute=*" */ - int attr_len; - if (tag_desc != 0x80) { - /* context simple */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { goto failed; } - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + if (!asn1_read_LDAPString(data, &attr)) { goto failed; } ret->operation = LDB_OP_SIMPLE; - - attr_len = asn1_tag_remaining(data); - - ret->u.simple.attr = talloc_size(ret, attr_len+1); - if (ret->u.simple.attr == NULL) { + ret->u.simple.attr = talloc_steal(ret, attr); + ret->u.simple.value.data = talloc_strdup(ret, "*"); + if (ret->u.simple.value.data == NULL) { goto failed; } - if (!asn1_read(data, ret->u.simple.attr, attr_len)) { + ret->u.simple.value.length = 1; + if (!asn1_end_tag(data)) { goto failed; } - ret->u.simple.attr[attr_len] = 0; - ret->u.simple.value.data = talloc_strdup(ret, "*"); - if (ret->u.simple.value.data == NULL) { + break; + } + case 9: { + char *oid, *attr, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - ret->u.simple.value.length = 1; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, &oid); + asn1_end_tag(data); + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, &attr); + asn1_end_tag(data); + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, &value); + asn1_end_tag(data); + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + if ((data->has_error) || (oid == NULL) || (value == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EXTENDED; + ret->u.extended.attr = talloc_steal(ret, attr); + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + if (!asn1_end_tag(data)) { goto failed; } break; } + default: DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); goto failed; -- cgit From 26d35d90a2a2e98b12ab866d330cbd9c0e220cef Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 Jun 2005 06:50:12 +0000 Subject: r7569: Fix typo in comments. (This used to be commit 64fb327ccf80d2d501ae559a6c4336a066191df0) --- source4/libcli/raw/clisession.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 3156624589..130959e776 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -231,7 +231,7 @@ NTSTATUS smb_raw_session_setup(struct smbcli_session *session, TALLOC_CTX *mem_c /**************************************************************************** - Send a uloggoff (async send) + Send a ulogoff (async send) *****************************************************************************/ struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session) { @@ -251,7 +251,7 @@ struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session) } /**************************************************************************** - Send a uloggoff (sync interface) + Send a ulogoff (sync interface) *****************************************************************************/ NTSTATUS smb_raw_ulogoff(struct smbcli_session *session) { -- cgit From c0947b0d7f809f5139fbfcdbd618ed7b0a77d2be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 00:27:51 +0000 Subject: r7593: simplified the memory management in the ldap code. Having a mem_ctx element in a structure is not necessary any more. (This used to be commit 912d0427f52eac811b27bf7e385b0642f7dc7f53) --- source4/libcli/cldap/cldap.c | 75 +++++++++++++++++++++------------------ source4/libcli/ldap/ldap.c | 72 ++++++++++++++++++------------------- source4/libcli/ldap/ldap.h | 2 -- source4/libcli/ldap/ldap_client.c | 34 ++++++------------ source4/libcli/ldap/ldap_ldif.c | 16 ++++----- 5 files changed, 95 insertions(+), 104 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 71326caa37..1674031c99 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -68,7 +68,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) DATA_BLOB blob; size_t nread, dsize; struct asn1_data asn1; - struct ldap_message ldap_msg; + struct ldap_message *ldap_msg; struct cldap_request *req; status = socket_pending(cldap->sock, &dsize); @@ -102,24 +102,27 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } talloc_steal(tmp_ctx, asn1.data); - ZERO_STRUCT(ldap_msg); - ldap_msg.mem_ctx = tmp_ctx; + ldap_msg = talloc(tmp_ctx, struct ldap_message); + if (ldap_msg == NULL) { + talloc_free(tmp_ctx); + return; + } /* this initial decode is used to find the message id */ - if (!ldap_decode(&asn1, &ldap_msg)) { + if (!ldap_decode(&asn1, ldap_msg)) { DEBUG(2,("Failed to decode ldap message\n")); talloc_free(tmp_ctx); return; } /* find the pending request */ - req = idr_find(cldap->idr, ldap_msg.messageid); + req = idr_find(cldap->idr, ldap_msg->messageid); if (req == NULL) { if (cldap->incoming.handler) { - cldap->incoming.handler(cldap, &ldap_msg, src_addr, src_port); + cldap->incoming.handler(cldap, ldap_msg, src_addr, src_port); } else { DEBUG(2,("Mismatched cldap reply %u from %s:%d\n", - ldap_msg.messageid, src_addr, src_port)); + ldap_msg->messageid, src_addr, src_port)); } talloc_free(tmp_ctx); return; @@ -291,7 +294,7 @@ NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, struct cldap_request *cldap_search_send(struct cldap_socket *cldap, struct cldap_search *io) { - struct ldap_message msg; + struct ldap_message *msg; struct cldap_request *req; struct ldap_SearchRequest *search; @@ -313,12 +316,13 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, talloc_set_destructor(req, cldap_request_destructor); - msg.mem_ctx = req; - msg.messageid = req->message_id; - msg.type = LDAP_TAG_SearchRequest; - msg.num_controls = 0; - msg.controls = NULL; - search = &msg.r.SearchRequest; + msg = talloc(req, struct ldap_message); + if (msg == NULL) goto failed; + msg->messageid = req->message_id; + msg->type = LDAP_TAG_SearchRequest; + msg->num_controls = 0; + msg->controls = NULL; + search = &msg->r.SearchRequest; search->basedn = ""; search->scope = LDAP_SEARCH_SCOPE_BASE; @@ -333,7 +337,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, goto failed; } - if (!ldap_encode(&msg, &req->encoded)) { + if (!ldap_encode(msg, &req->encoded)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest_addr, req->dest_port)); goto failed; @@ -357,7 +361,7 @@ failed: */ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) { - struct ldap_message msg; + struct ldap_message *msg; struct cldap_request *req; DATA_BLOB blob1, blob2; NTSTATUS status = NT_STATUS_NO_MEMORY; @@ -375,16 +379,17 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) talloc_set_destructor(req, cldap_request_destructor); - msg.mem_ctx = req; - msg.messageid = io->messageid; - msg.num_controls = 0; - msg.controls = NULL; + msg = talloc(req, struct ldap_message); + if (msg == NULL) goto failed; + msg->messageid = io->messageid; + msg->num_controls = 0; + msg->controls = NULL; if (io->response) { - msg.type = LDAP_TAG_SearchResultEntry; - msg.r.SearchResultEntry = *io->response; + msg->type = LDAP_TAG_SearchResultEntry; + msg->r.SearchResultEntry = *io->response; - if (!ldap_encode(&msg, &blob1)) { + if (!ldap_encode(msg, &blob1)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest_addr, req->dest_port)); status = NT_STATUS_INVALID_PARAMETER; @@ -395,10 +400,10 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) blob1 = data_blob(NULL, 0); } - msg.type = LDAP_TAG_SearchResultDone; - msg.r.SearchResultDone = *io->result; + msg->type = LDAP_TAG_SearchResultDone; + msg->r.SearchResultDone = *io->result; - if (!ldap_encode(&msg, &blob2)) { + if (!ldap_encode(msg, &blob2)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest_addr, req->dest_port)); status = NT_STATUS_INVALID_PARAMETER; @@ -430,7 +435,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, TALLOC_CTX *mem_ctx, struct cldap_search *io) { - struct ldap_message ldap_msg; + struct ldap_message *ldap_msg; if (req == NULL) { return NT_STATUS_NO_MEMORY; @@ -448,10 +453,10 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, return NT_STATUS_IO_TIMEOUT; } - ZERO_STRUCT(ldap_msg); - ldap_msg.mem_ctx = mem_ctx; + ldap_msg = talloc(mem_ctx, struct ldap_message); + NT_STATUS_HAVE_NO_MEMORY(ldap_msg); - if (!ldap_decode(&req->asn1, &ldap_msg)) { + if (!ldap_decode(&req->asn1, ldap_msg)) { talloc_free(req); return NT_STATUS_INVALID_PARAMETER; } @@ -459,26 +464,26 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, ZERO_STRUCT(io->out); /* the first possible form has a search result in first place */ - if (ldap_msg.type == LDAP_TAG_SearchResultEntry) { + if (ldap_msg->type == LDAP_TAG_SearchResultEntry) { io->out.response = talloc(mem_ctx, struct ldap_SearchResEntry); NT_STATUS_HAVE_NO_MEMORY(io->out.response); - *io->out.response = ldap_msg.r.SearchResultEntry; + *io->out.response = ldap_msg->r.SearchResultEntry; /* decode the 2nd part */ - if (!ldap_decode(&req->asn1, &ldap_msg)) { + if (!ldap_decode(&req->asn1, ldap_msg)) { talloc_free(req); return NT_STATUS_INVALID_PARAMETER; } } - if (ldap_msg.type != LDAP_TAG_SearchResultDone) { + if (ldap_msg->type != LDAP_TAG_SearchResultDone) { talloc_free(req); return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } io->out.result = talloc(mem_ctx, struct ldap_Result); NT_STATUS_HAVE_NO_MEMORY(io->out.result); - *io->out.result = ldap_msg.r.SearchResultDone; + *io->out.result = ldap_msg->r.SearchResultDone; talloc_free(req); return NT_STATUS_OK; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 048a60317a..0ac17c39bd 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -647,7 +647,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_BindRequest; asn1_start_tag(data, tag); asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { int pwlen; r->creds.password = ""; @@ -655,7 +655,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen != 0) { - char *pw = talloc_size(msg->mem_ctx, pwlen+1); + char *pw = talloc_size(msg, pwlen+1); asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -664,10 +664,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ asn1_start_tag(data, ASN1_CONTEXT(3)); r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->creds.SASL.mechanism); + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); asn1_read_OctetString(data, &r->creds.SASL.secblob); if (r->creds.SASL.secblob.data) { - talloc_steal(msg->mem_ctx, r->creds.SASL.secblob.data); + talloc_steal(msg, r->creds.SASL.secblob.data); } asn1_end_tag(data); } @@ -679,11 +679,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, &r->response); + ldap_decode_response(msg, data, &r->response); if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + r->SASL.secblob = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { r->SASL.secblob = data_blob(NULL, 0); @@ -703,14 +703,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_SearchRequest *r = &msg->r.SearchRequest; msg->type = LDAP_TAG_SearchRequest; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn); + asn1_read_OctetString_talloc(msg, data, &r->basedn); asn1_read_enumerated(data, (int *)&(r->scope)); asn1_read_enumerated(data, (int *)&(r->deref)); asn1_read_Integer(data, &r->sizelimit); asn1_read_Integer(data, &r->timelimit); asn1_read_BOOLEAN(data, &r->attributesonly); - r->tree = ldap_decode_filter_tree(msg->mem_ctx, data); + r->tree = ldap_decode_filter_tree(msg, data); if (r->tree == NULL) { return False; } @@ -722,10 +722,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) while (asn1_tag_remaining(data) > 0) { const char *attr; - if (!asn1_read_OctetString_talloc(msg->mem_ctx, data, + if (!asn1_read_OctetString_talloc(msg, data, &attr)) return False; - if (!add_string_to_array(msg->mem_ctx, attr, + if (!add_string_to_array(msg, attr, &r->attributes, &r->num_attributes)) return False; @@ -742,8 +742,8 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->attributes = NULL; r->num_attributes = 0; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); - ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, &r->num_attributes); asn1_end_tag(data); break; @@ -753,7 +753,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.SearchResultDone; msg->type = LDAP_TAG_SearchResultDone; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -762,7 +762,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_SearchResRef *r = &msg->r.SearchResultReference; msg->type = LDAP_TAG_SearchResultReference; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->referral); + asn1_read_OctetString_talloc(msg, data, &r->referral); asn1_end_tag(data); break; } @@ -771,7 +771,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; msg->type = LDAP_TAG_ModifyRequest; asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); asn1_start_tag(data, ASN1_SEQUENCE(0)); r->num_mods = 0; @@ -784,9 +784,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_enumerated(data, &v); mod.type = v; - ldap_decode_attrib(msg->mem_ctx, data, &mod.attrib); + ldap_decode_attrib(msg, data, &mod.attrib); asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, + if (!add_mod_to_array_talloc(msg, &mod, &r->mods, &r->num_mods)) break; } @@ -800,7 +800,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.ModifyResponse; msg->type = LDAP_TAG_ModifyResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -809,11 +809,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_AddRequest *r = &msg->r.AddRequest; msg->type = LDAP_TAG_AddRequest; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); r->attributes = NULL; r->num_attributes = 0; - ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + ldap_decode_attribs(msg, data, &r->attributes, &r->num_attributes); asn1_end_tag(data); @@ -824,7 +824,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.AddResponse; msg->type = LDAP_TAG_AddResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -837,7 +837,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); - dn = talloc_size(msg->mem_ctx, len+1); + dn = talloc_size(msg, len+1); if (dn == NULL) break; asn1_read(data, dn, len); @@ -851,7 +851,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.DelResponse; msg->type = LDAP_TAG_DelResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -861,8 +861,8 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_ModifyDNRequest; asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->newrdn); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); asn1_read_BOOLEAN(data, &r->deleteolddn); r->newsuperior = NULL; if (asn1_tag_remaining(data) > 0) { @@ -870,7 +870,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); - newsup = talloc_size(msg->mem_ctx, len+1); + newsup = talloc_size(msg, len+1); if (newsup == NULL) break; asn1_read(data, newsup, len); @@ -886,7 +886,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.ModifyDNResponse; msg->type = LDAP_TAG_ModifyDNResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -896,12 +896,12 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_CompareRequest; asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->attribute); + asn1_read_OctetString_talloc(msg, data, &r->attribute); asn1_read_OctetString(data, &r->value); if (r->value.data) { - talloc_steal(msg->mem_ctx, r->value.data); + talloc_steal(msg, r->value.data); } asn1_end_tag(data); asn1_end_tag(data); @@ -912,7 +912,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.CompareResponse; msg->type = LDAP_TAG_CompareResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -935,7 +935,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { return False; } - r->oid = blob2string_talloc(msg->mem_ctx, tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); data_blob_free(&tmp_blob); if (!r->oid) { return False; @@ -943,7 +943,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + r->value = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { r->value = data_blob(NULL, 0); @@ -957,7 +957,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; msg->type = LDAP_TAG_ExtendedResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, &r->response); + ldap_decode_response(msg, data, &r->response); /* I have to come across an operation that actually sends * something back to really see what's going on. The currently * needed pwdchange does not send anything back. */ @@ -983,7 +983,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { asn1_start_tag(data, ASN1_SEQUENCE(0)); - ctrl = talloc_realloc(msg->mem_ctx, ctrl, struct ldap_Control, i+1); + ctrl = talloc_realloc(msg, ctrl, struct ldap_Control, i+1); if (!ctrl) { return False; } @@ -1000,7 +1000,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { asn1_read_OctetString(data, &ctrl[i].value); if (ctrl[i].value.data) { - talloc_steal(msg->mem_ctx, ctrl[i].value.data); + talloc_steal(msg, ctrl[i].value.data); } } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index a44c249e7a..f0f43e65fc 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -252,7 +252,6 @@ struct ldap_Control { }; struct ldap_message { - TALLOC_CTX *mem_ctx; uint32_t messageid; enum ldap_request_tag type; union ldap_Request r; @@ -267,7 +266,6 @@ struct ldap_queue_entry { }; struct ldap_connection { - TALLOC_CTX *mem_ctx; int sock; int next_msgid; char *host; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8867344de3..6ff8db85a5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -312,9 +312,9 @@ static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *con res->type = LDAP_TAG_BindRequest; res->r.BindRequest.version = 3; - res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); + res->r.BindRequest.dn = talloc_strdup(res, dn); res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); + res->r.BindRequest.creds.password = talloc_strdup(res, pw); return res; } @@ -332,7 +332,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, res->r.BindRequest.version = 3; res->r.BindRequest.dn = ""; res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; - res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism); res->r.BindRequest.creds.SASL.secblob = *secblob; return res; @@ -348,7 +348,6 @@ static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) return NULL; } - result->mem_ctx = result; result->next_msgid = 1; result->outstanding = NULL; result->searchid = 0; @@ -372,8 +371,8 @@ struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) return NULL; } - ret = ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, - &conn->port, &conn->ldaps); + ret = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); if (!ret) { talloc_free(conn); return NULL; @@ -398,17 +397,7 @@ struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { - struct ldap_message *result; - - result = talloc(mem_ctx, struct ldap_message); - - if (!result) { - return NULL; - } - - result->mem_ctx = result; - - return result; + return talloc(mem_ctx, struct ldap_message); } BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, @@ -619,7 +608,7 @@ static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, return NULL; status = gensec_wrap(conn->gensec, - req->mem_ctx, + req, &request, &wrapped); if (!NT_STATUS_IS_OK(status)) { @@ -653,7 +642,7 @@ static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, wrapped.length = len; status = gensec_unwrap(conn->gensec, - req->mem_ctx, + req, &wrapped, &request); if (!NT_STATUS_IS_OK(status)) { @@ -661,7 +650,7 @@ static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, return NULL; } - rep = new_ldap_message(req->mem_ctx); + rep = new_ldap_message(req); asn1_load(&asn1, request); if (!ldap_decode(&asn1, rep)) { @@ -776,7 +765,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) goto done; } - status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); + status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", nt_errstr(status))); @@ -828,8 +817,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) } done: - if (mem_ctx) - talloc_free(mem_ctx); + talloc_free(mem_ctx); return result; } diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 2489a97748..0e0885c1cc 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -212,7 +212,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc(msg->mem_ctx, + r->attributes = talloc_realloc(msg, r->attributes, struct ldap_attribute, r->num_attributes+1); @@ -222,11 +222,11 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) attrib = &(r->attributes[r->num_attributes]); r->num_attributes += 1; ZERO_STRUCTP(attrib); - attrib->name = talloc_strdup(msg->mem_ctx, + attrib->name = talloc_strdup(msg, attr_name); } - if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) + if (!add_value_to_attrib(msg, &value, attrib)) return False; } return True; @@ -261,7 +261,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) struct ldap_mod mod; mod.type = LDAP_MODIFY_NONE; - mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); + mod.attrib.name = talloc_strdup(msg, value.data); if (strequal(attr_name, "add")) mod.type = LDAP_MODIFY_ADD; @@ -290,14 +290,14 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) mod.attrib.name)); return False; } - if (!add_value_to_attrib(msg->mem_ctx, &value, + if (!add_value_to_attrib(msg, &value, &mod.attrib)) { DEBUG(3, ("Could not add value\n")); return False; } } - if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, + if (!add_mod_to_array_talloc(msg, &mod, &r->mods, &r->num_mods)) return False; } @@ -370,7 +370,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void if (msg == NULL) return NULL; - chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); + chunk = next_chunk(msg, fgetc_fn, private_data); if (!chunk) { goto failed; } @@ -388,7 +388,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void goto failed; } - dn = talloc_strdup(msg->mem_ctx, value.data); + dn = talloc_strdup(msg, value.data); if (next_attr(&s, &attr, &value) != 0) { goto failed; -- cgit From 3e92471d4cfa169b97da73752b6eb6d1ea8cb466 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 01:02:53 +0000 Subject: r7596: next step in ldap cleanup. I'm aiming to get rid of the cut&pasted ldif parsing code in libcli/ldap/ldap_ldif.c, and instead use the ldb ldif code. To do that I have changed the ldap code to use 'struct ldb_message_element' instead of 'struct ldap_attribute'. They are essentially the same structure anyway, so by making them really the same it will be much easier to use the ldb code in libcli/ldap/ I have also made 'struct ldb_val' the same as a DATA_BLOB, which will simplify data handling in quite a few places (I haven't yet removed all the code that maps between these two, that will come later) (This used to be commit 87fc3073392236221a3a6b933284e9e477c24ae5) --- source4/libcli/cldap/cldap.c | 2 +- source4/libcli/ldap/ldap.c | 12 ++++++------ source4/libcli/ldap/ldap.h | 18 ++++++------------ source4/libcli/ldap/ldap_ldif.c | 12 ++++++------ 4 files changed, 19 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 1674031c99..79cdff2437 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -679,7 +679,7 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, response.dn = ""; response.num_attributes = 1; - response.attributes = talloc(tmp_ctx, struct ldap_attribute); + response.attributes = talloc(tmp_ctx, struct ldb_message_element); NT_STATUS_HAVE_NO_MEMORY(response.attributes); response.attributes->name = "netlogon"; response.attributes->num_values = 1; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0ac17c39bd..1a3ab6e0a5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -201,7 +201,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { - struct ldap_attribute *attr = &r->attributes[i]; + struct ldb_message_element *attr = &r->attributes[i]; asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, attr->name, strlen(attr->name)); @@ -232,7 +232,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_mods; i++) { - struct ldap_attribute *attrib = &r->mods[i].attrib; + struct ldb_message_element *attrib = &r->mods[i].attrib; asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_enumerated(&data, r->mods[i].type); asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -268,7 +268,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { - struct ldap_attribute *attrib = &r->attributes[i]; + struct ldb_message_element *attrib = &r->attributes[i]; asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, attrib->name, strlen(attrib->name)); @@ -596,7 +596,7 @@ failed: static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldap_attribute *attrib) + struct ldb_message_element *attrib) { asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); @@ -616,12 +616,12 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, } static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldap_attribute **attributes, + struct ldb_message_element **attributes, int *num_attributes) { asn1_start_tag(data, ASN1_SEQUENCE(0)); while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldap_attribute attrib; + struct ldb_message_element attrib; ZERO_STRUCT(attrib); ldap_decode_attrib(mem_ctx, data, &attrib); add_attrib_to_array_talloc(mem_ctx, &attrib, diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index f0f43e65fc..577df1fc3d 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -101,12 +101,6 @@ struct ldap_Result { const char *referral; }; -struct ldap_attribute { - const char *name; - int num_values; - DATA_BLOB *values; -}; - struct ldap_BindRequest { int version; const char *dn; @@ -159,7 +153,7 @@ struct ldap_SearchRequest { struct ldap_SearchResEntry { const char *dn; int num_attributes; - struct ldap_attribute *attributes; + struct ldb_message_element *attributes; }; struct ldap_SearchResRef { @@ -175,7 +169,7 @@ enum ldap_modify_type { struct ldap_mod { enum ldap_modify_type type; - struct ldap_attribute attrib; + struct ldb_message_element attrib; }; struct ldap_ModifyRequest { @@ -187,7 +181,7 @@ struct ldap_ModifyRequest { struct ldap_AddRequest { const char *dn; int num_attributes; - struct ldap_attribute *attributes; + struct ldb_message_element *attributes; }; struct ldap_DelRequest { @@ -338,10 +332,10 @@ NTSTATUS ldap2nterror(int ldaperror); /* The following definitions come from libcli/ldap/ldap_ldif.c */ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldap_attribute *attrib); + struct ldb_message_element *attrib); BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldap_attribute *attrib, - struct ldap_attribute **attribs, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, int *num_attribs); BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod *mod, diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 0e0885c1cc..594640179e 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -158,7 +158,7 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value) } BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldap_attribute *attrib) + struct ldb_message_element *attrib) { attrib->values = talloc_realloc(mem_ctx, attrib->values, @@ -174,13 +174,13 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, } BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldap_attribute *attrib, - struct ldap_attribute **attribs, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, int *num_attribs) { *attribs = talloc_realloc(mem_ctx, *attribs, - struct ldap_attribute, + struct ldb_message_element, *num_attribs+1); if (*attribs == NULL) @@ -202,7 +202,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) while (next_attr(chunk, &attr_name, &value) == 0) { int i; - struct ldap_attribute *attrib = NULL; + struct ldb_message_element *attrib = NULL; for (i=0; inum_attributes; i++) { if (strequal(r->attributes[i].name, attr_name)) { @@ -214,7 +214,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) if (attrib == NULL) { r->attributes = talloc_realloc(msg, r->attributes, - struct ldap_attribute, + struct ldb_message_element, r->num_attributes+1); if (r->attributes == NULL) return False; -- cgit From 49bc2672f8c2d75ce35f1ef537057fd05d4689e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 01:12:31 +0000 Subject: r7598: take advantage of struct data_blob and struct ldb_val being the same structure in a couple of places (This used to be commit bcd4671acae2be51958cbae23a0ab2dd2b194a5e) --- source4/libcli/ldap/ldap.c | 5 +---- source4/libcli/ldap/ldap_ndr.c | 12 ++---------- 2 files changed, 3 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1a3ab6e0a5..bce3da94ae 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -603,11 +603,8 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldb_val value; asn1_read_OctetString(data, &blob); - value.data = blob.data; - value.length = blob.length; - add_value_to_attrib(mem_ctx, &value, attrib); + add_value_to_attrib(mem_ctx, &blob, attrib); data_blob_free(&blob); } asn1_end_tag(data); diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 720022c6c2..88ca1ece77 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -25,14 +25,6 @@ #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" -struct ldb_val ldb_blob(DATA_BLOB blob) -{ - struct ldb_val val; - val.data = blob.data; - val.length = blob.length; - return val; -} - /* encode a NDR uint32 as a ldap filter element */ @@ -59,7 +51,7 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); + ret = ldb_binary_encode(mem_ctx, blob); data_blob_free(&blob); return ret; } @@ -78,7 +70,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); + ret = ldb_binary_encode(mem_ctx, blob); data_blob_free(&blob); return ret; } -- cgit From ec4a99ffe89656c4ef89e21109c4136d491952d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 01:22:30 +0000 Subject: r7599: it turns out we were not using the ldif code in libcli/ldap/ at all, so best to just remove it. If we need it again, then it will be easy to just use a wrapper around the ldb code. (This used to be commit b316e1c2d3e4dc09c321ec72b40d78ffb855e101) --- source4/libcli/ldap/ldap_ldif.c | 393 ---------------------------------------- 1 file changed, 393 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 594640179e..55e902ecad 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -27,136 +27,6 @@ #include "system/iconv.h" #include "libcli/ldap/ldap.h" -/**************************************************************************** - * - * LDIF parser - * - * Shamelessly stolen and adapted from ldb. - * - ***************************************************************************/ - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(TALLOC_CTX *mem_ctx, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); - if (!c2) { - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && - chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && - chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && - (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - -/* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldb_val *value) -{ - char *p; - int base64_encoded = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - *attr = *s; - - while (isspace(*p)) { - p++; - } - - value->data = p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - DATA_BLOB blob = base64_decode_data_blob(value->data); - memcpy(value->data, blob.data, blob.length); - value->length = blob.length; - ((char *)value->data)[value->length] = '\0'; - } - - return 0; -} - BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldb_message_element *attrib) { @@ -191,47 +61,6 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, return True; } -static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) -{ - struct ldap_AddRequest *r = &msg->r.AddRequest; - const char *attr_name; - struct ldb_val value; - - r->num_attributes = 0; - r->attributes = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - int i; - struct ldb_message_element *attrib = NULL; - - for (i=0; inum_attributes; i++) { - if (strequal(r->attributes[i].name, attr_name)) { - attrib = &r->attributes[i]; - break; - } - } - - if (attrib == NULL) { - r->attributes = talloc_realloc(msg, - r->attributes, - struct ldb_message_element, - r->num_attributes+1); - if (r->attributes == NULL) - return False; - - attrib = &(r->attributes[r->num_attributes]); - r->num_attributes += 1; - ZERO_STRUCTP(attrib); - attrib->name = talloc_strdup(msg, - attr_name); - } - - if (!add_value_to_attrib(msg, &value, attrib)) - return False; - } - return True; -} - BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod *mod, struct ldap_mod **mods, @@ -247,225 +76,3 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, return True; } -static BOOL fill_mods(struct ldap_message *msg, char **chunk) -{ - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - const char *attr_name; - struct ldb_val value; - - r->num_mods = 0; - r->mods = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - - struct ldap_mod mod; - mod.type = LDAP_MODIFY_NONE; - - mod.attrib.name = talloc_strdup(msg, value.data); - - if (strequal(attr_name, "add")) - mod.type = LDAP_MODIFY_ADD; - - if (strequal(attr_name, "delete")) - mod.type = LDAP_MODIFY_DELETE; - - if (strequal(attr_name, "replace")) - mod.type = LDAP_MODIFY_REPLACE; - - if (mod.type == LDAP_MODIFY_NONE) { - DEBUG(2, ("ldif modification type %s unsupported\n", - attr_name)); - return False; - } - - mod.attrib.num_values = 0; - mod.attrib.values = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - if (strequal(attr_name, "-")) - break; - if (!strequal(attr_name, mod.attrib.name)) { - DEBUG(3, ("attrib name %s does not " - "match %s\n", attr_name, - mod.attrib.name)); - return False; - } - if (!add_value_to_attrib(msg, &value, - &mod.attrib)) { - DEBUG(3, ("Could not add value\n")); - return False; - } - } - - if (!add_mod_to_array_talloc(msg, &mod, &r->mods, - &r->num_mods)) - return False; - } - - return True; -} - -static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) -{ - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - const char *attr_name; - struct ldb_val value; - - r->newrdn = NULL; - r->deleteolddn = False; - r->newsuperior = NULL; - - if (next_attr(chunk, &attr_name, &value) != 0) { - return False; - } - - if (!strequal(attr_name, "newrdn")) { - return False; - } - - r->newrdn = value.data; - - if (next_attr(chunk, &attr_name, &value) != 0) { - return False; - } - - if (!strequal(attr_name, "deleteoldrdn")) { - return False; - } - - if (value.data && (((char *)value.data)[0] != '0')) { - r->deleteolddn = True; - } - - if (next_attr(chunk, &attr_name, &value) != 0) { - /* newsuperior is optional */ - return True; - } - - if (!strequal(attr_name, "newsuperior")) { - return False; - } - - r->newsuperior = value.data; - - return True; -} - - -/* - read from a LDIF source, creating a ldap_message -*/ -static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *), - void *private_data) -{ - struct ldap_message *msg; - const char *attr=NULL; - const char *dn; - char *chunk=NULL, *s; - struct ldb_val value; - - value.data = NULL; - - msg = new_ldap_message(mem_ctx); - if (msg == NULL) - return NULL; - - chunk = next_chunk(msg, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - - s = chunk; - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (!strequal(attr, "dn")) { - DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", - attr)); - goto failed; - } - - dn = talloc_strdup(msg, value.data); - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - if (!strequal(attr, "changetype")) { - DEBUG(5, ("Error: Second line of ldif must be a changetype " - "not '%s'\n", attr)); - goto failed; - } - - if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; - return msg; - } - - if (strequal(value.data, "add")) { - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = dn; - - if (!fill_add_attributes(msg, &s)) - goto failed; - - return msg; - } - - if (strequal(value.data, "modify")) { - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = dn; - - if (!fill_mods(msg, &s)) - goto failed; - - return msg; - } - - if (strequal(value.data, "modrdn")) { - msg->type = LDAP_TAG_ModifyDNRequest; - - msg->r.ModifyDNRequest.dn = dn; - - if (!fill_modrdn(msg, &s)) - goto failed; - - return msg; - } - - DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); - -failed: - talloc_free(msg); - return NULL; -} - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s) -{ - struct ldif_read_string_state state; - state.s = s; - return ldif_read(mem_ctx, fgetc_string, &state); -} - -- cgit From bab977dad76e9204278c7afe0bb905cda064f488 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 05:39:40 +0000 Subject: r7626: a new ldap client library. Main features are: - hooked into events system, so requests can be truly async and won't interfere with other processing happening at the same time - uses NTSTATUS codes for errors (previously errors were mostly ignored). In a similar fashion to the DOS error handling, I have reserved a range of the NTSTATUS code 32 bit space for LDAP error codes, so a function can return a LDAP error code in a NTSTATUS - much cleaner packet handling (This used to be commit 2e3c660b2fc20e046d82bf1cc296422b6e7dfad0) --- source4/libcli/ldap/config.mk | 4 +- source4/libcli/ldap/ldap.c | 40 -- source4/libcli/ldap/ldap.h | 97 --- source4/libcli/ldap/ldap_bind.c | 250 ++++++++ source4/libcli/ldap/ldap_client.c | 1275 ++++++++++++------------------------- source4/libcli/ldap/ldap_client.h | 86 +++ source4/libcli/ldap/ldap_ldif.c | 78 --- source4/libcli/ldap/ldap_msg.c | 84 +++ source4/libcli/util/nterr.c | 11 +- 9 files changed, 850 insertions(+), 1075 deletions(-) create mode 100644 source4/libcli/ldap/ldap_bind.c create mode 100644 source4/libcli/ldap/ldap_client.h delete mode 100644 source4/libcli/ldap/ldap_ldif.c create mode 100644 source4/libcli/ldap/ldap_msg.c (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 888590ec5e..ca33581043 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -3,8 +3,8 @@ [SUBSYSTEM::LIBCLI_LDAP] ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ - libcli/ldap/ldap_ldif.o \ + libcli/ldap/ldap_bind.o \ + libcli/ldap/ldap_msg.o \ libcli/ldap/ldap_ndr.o -NOPROTO=YES # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index bce3da94ae..c642fc3e4b 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1013,44 +1013,4 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) return ((!data->has_error) && (data->nesting == NULL)); } -BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16_t *port, BOOL *ldaps) -{ - int tmp_port = 0; - char protocol[11]; - char tmp_host[255]; - const char *p = url; - int ret; - - /* skip leading "URL:" (if any) */ - if (strncasecmp( p, "URL:", 4) == 0) { - p += 4; - } - - /* Paranoia check */ - SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); - - ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); - if (ret < 2) { - return False; - } - - if (strequal(protocol, "ldap")) { - *port = 389; - *ldaps = False; - } else if (strequal(protocol, "ldaps")) { - *port = 636; - *ldaps = True; - } else { - DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); - return False; - } - - if (tmp_port != 0) - *port = tmp_port; - - *host = talloc_strdup(mem_ctx, tmp_host); - - return (*host != NULL); -} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 577df1fc3d..072070f723 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -253,101 +253,4 @@ struct ldap_message { struct ldap_Control *controls; }; -struct ldap_queue_entry { - struct ldap_queue_entry *next, *prev; - int msgid; - struct ldap_message *msg; -}; - -struct ldap_connection { - int sock; - int next_msgid; - char *host; - uint16_t port; - BOOL ldaps; - - const char *auth_dn; - const char *simple_pw; - - /* Current outstanding search entry */ - int searchid; - - /* List for incoming search entries */ - struct ldap_queue_entry *search_entries; - - /* Outstanding LDAP requests that have not yet been replied to */ - struct ldap_queue_entry *outstanding; - - /* Let's support SASL */ - struct gensec_security *gensec; -}; - -#define LDAP_CONNECTION_TIMEOUT 10000 - -/* The following definitions come from libcli/ldap/ldap.c */ - -BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); -BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); -BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16_t *port, BOOL *ldaps); - -/* The following definitions come from libcli/ldap/ldap_client.c */ - -struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url); -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime); -BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime); -struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, - const struct timeval *endtime); -struct ldap_message *ldap_transaction(struct ldap_connection *conn, - struct ldap_message *request); -int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password); -int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds); -struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, - const char *userdn, const char *password); -struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, - struct cli_credentials *creds); -BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, - const struct timeval *endtime); -BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime); -struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, - const struct timeval *endtime); -void ldap_endsearchent(struct ldap_connection *conn, - const struct timeval *endtime); -struct ldap_message *ldap_searchone(struct ldap_connection *conn, - struct ldap_message *msg, - const struct timeval *endtime); -BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, - DATA_BLOB *value); -BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, - TALLOC_CTX *mem_ctx, char **value); -BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, - int *value); -int ldap_error(struct ldap_connection *conn); -NTSTATUS ldap2nterror(int ldaperror); - -/* The following definitions come from libcli/ldap/ldap_ldif.c */ - -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib); -BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs); -BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods); -struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); - -/* The following definitions come from libcli/ldap/ldap_ndr.c */ - -const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); -const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); -const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); - #endif diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c new file mode 100644 index 0000000000..11a6997fb2 --- /dev/null +++ b/source4/libcli/ldap/ldap_bind.c @@ -0,0 +1,250 @@ +/* + Unix SMB/CIFS mplementation. + + LDAP bind calls + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Volker Lendecke 2004 + + 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 "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" +#include "auth/auth.h" + +static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, + const char *dn, const char *pw) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = talloc_strdup(res, dn); + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + res->r.BindRequest.creds.password = talloc_strdup(res, pw); + + return res; +} + + +/* + perform a simple username/password bind +*/ +NTSTATUS ldap_bind_simple(struct ldap_connection *conn, + const char *userdn, const char *password) +{ + struct ldap_request *req; + struct ldap_message *msg; + const char *dn, *pw; + NTSTATUS status; + + if (conn == NULL) { + return NT_STATUS_INVALID_CONNECTION; + } + + if (userdn) { + dn = userdn; + } else { + if (conn->auth_dn) { + dn = conn->auth_dn; + } else { + dn = ""; + } + } + + if (password) { + pw = password; + } else { + if (conn->simple_pw) { + pw = conn->simple_pw; + } else { + pw = ""; + } + } + + msg = new_ldap_simple_bind_msg(conn, dn, pw); + NT_STATUS_HAVE_NO_MEMORY(msg); + + /* send the request */ + req = ldap_request_send(conn, msg); + talloc_free(msg); + NT_STATUS_HAVE_NO_MEMORY(req); + + /* wait for replies */ + status = ldap_request_wait(req); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return status; + } + + /* check its a valid reply */ + msg = req->replies[0]; + if (msg->type != LDAP_TAG_BindResponse) { + talloc_free(req); + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + status = ldap_check_response(conn, &msg->r.BindResponse.response); + + talloc_free(req); + + return status; +} + + +static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, + const char *sasl_mechanism, + DATA_BLOB *secblob) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = ""; + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism); + res->r.BindRequest.creds.SASL.secblob = *secblob; + + return res; +} + + +/* + perform a sasl bind using the given credentials +*/ +NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) +{ + NTSTATUS status; + TALLOC_CTX *tmp_ctx = NULL; + DATA_BLOB input = data_blob(NULL, 0); + DATA_BLOB output = data_blob(NULL, 0); + + status = gensec_client_start(conn, &conn->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); + goto failed; + } + + gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + + status = gensec_set_credentials(conn->gensec, creds); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC creds: %s\n", + nt_errstr(status))); + goto failed; + } + + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto failed; + } + + status = gensec_set_target_service(conn->gensec, "ldap"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", + nt_errstr(status))); + goto failed; + } + + status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto failed; + } + + tmp_ctx = talloc_new(conn); + if (tmp_ctx == NULL) goto failed; + + status = gensec_update(conn->gensec, tmp_ctx, input, &output); + + while (1) { + struct ldap_message *response; + struct ldap_message *msg; + struct ldap_request *req; + int result = LDAP_OTHER; + + if (NT_STATUS_IS_OK(status) && output.length == 0) { + break; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(status)) { + break; + } + + msg = new_ldap_sasl_bind_msg(tmp_ctx, "GSS-SPNEGO", &output); + if (msg == NULL) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + + req = ldap_request_send(conn, msg); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + talloc_steal(tmp_ctx, req); + + status = ldap_result_n(req, 0, &response); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + if (response->type != LDAP_TAG_BindResponse) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + goto failed; + } + + result = response->r.BindResponse.response.resultcode; + + if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + break; + } + + status = gensec_update(conn->gensec, tmp_ctx, + response->r.BindResponse.SASL.secblob, + &output); + } + + if (NT_STATUS_IS_OK(status) && + (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || + gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { + conn->enable_wrap = True; + } + + talloc_free(tmp_ctx); + return status; + +failed: + talloc_free(tmp_ctx); + talloc_free(conn->gensec); + conn->gensec = NULL; + return status; +} diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6ff8db85a5..f3a7f104d4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -24,1024 +24,587 @@ */ #include "includes.h" -#include "system/network.h" -#include "system/filesys.h" -#include "auth/auth.h" #include "asn_1.h" #include "dlinklist.h" +#include "lib/events/events.h" +#include "lib/socket/socket.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" - -/**************************************************************************** - Check the timeout. -****************************************************************************/ -static BOOL timeout_until(struct timeval *timeout, - const struct timeval *endtime) -{ - struct timeval now; - - GetTimeOfDay(&now); - - if ((now.tv_sec > endtime->tv_sec) || - ((now.tv_sec == endtime->tv_sec) && - (now.tv_usec > endtime->tv_usec))) - return False; - - timeout->tv_sec = endtime->tv_sec - now.tv_sec; - timeout->tv_usec = endtime->tv_usec - now.tv_usec; - return True; -} - - -/**************************************************************************** - Read data from the client, reading exactly N bytes, with timeout. -****************************************************************************/ -static ssize_t read_data_until(int fd,char *buffer,size_t N, - const struct timeval *endtime) +/* + create a new ldap_connection stucture. The event context is optional +*/ +struct ldap_connection *ldap_new_connection(TALLOC_CTX *mem_ctx, + struct event_context *ev) { - ssize_t ret; - size_t total=0; - - while (total < N) { - - if (endtime != NULL) { - fd_set r_fds; - struct timeval timeout; - int res; - - FD_ZERO(&r_fds); - FD_SET(fd, &r_fds); - - if (!timeout_until(&timeout, endtime)) - return -1; - - res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout); - if (res <= 0) - return -1; - } - - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); - return 0; - } + struct ldap_connection *conn; - if (ret == -1) { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); - return -1; - } - total += ret; + conn = talloc_zero(mem_ctx, struct ldap_connection); + if (conn == NULL) { + return NULL; } - return (ssize_t)total; -} - -/**************************************************************************** - Write data to a fd with timeout. -****************************************************************************/ -static ssize_t write_data_until(int fd,char *buffer,size_t N, - const struct timeval *endtime) -{ - size_t total=0; - ssize_t ret; - - while (total < N) { - - if (endtime != NULL) { - fd_set w_fds; - struct timeval timeout; - int res; - - FD_ZERO(&w_fds); - FD_SET(fd, &w_fds); - - if (!timeout_until(&timeout, endtime)) - return -1; - - res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout); - if (res <= 0) - return -1; - } - - ret = sys_write(fd,buffer + total,N - total); - - if (ret == -1) { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); - return -1; + if (ev == NULL) { + ev = event_context_init(conn); + if (ev == NULL) { + talloc_free(conn); + return NULL; } - if (ret == 0) - return total; - - total += ret; } - return (ssize_t)total; -} + conn->next_messageid = 1; + conn->event.event_ctx = ev; + /* set a reasonable request timeout */ + conn->timeout = 60; -static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data, - const struct timeval *endtime) -{ - if (read_data_until(sock, result, 1, endtime) != 1) - return False; - - return asn1_write(data, result, 1); + return conn; } -/* Read a complete ASN sequence (ie LDAP result) from a socket */ -static BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, - const struct timeval *endtime) -{ - uint8_t b; - size_t len; - char *buf; - - ZERO_STRUCTP(data); - - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - if (b != 0x30) { - data->has_error = True; - return False; - } +/* + the connection is dead +*/ +static void ldap_connection_dead(struct ldap_connection *conn) +{ + struct ldap_request *req; - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - - if (b & 0x80) { - int n = b & 0x7f; - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - len = b; - while (n > 1) { - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - len = (len<<8) | b; - n--; + while (conn->pending) { + req = conn->pending; + DLIST_REMOVE(req->conn->pending, req); + req->state = LDAP_REQUEST_DONE; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } + + while (conn->send_queue) { + req = conn->send_queue; + DLIST_REMOVE(req->conn->send_queue, req); + req->state = LDAP_REQUEST_DONE; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); } - } else { - len = b; } - buf = talloc_size(NULL, len); - if (buf == NULL) - return False; - - if (read_data_until(sock, buf, len, endtime) != len) - return False; - - if (!asn1_write(data, buf, len)) - return False; - - talloc_free(buf); - - data->ofs = 0; - - return True; + talloc_free(conn->sock); + conn->sock = NULL; } - -/**************************************************************************** - create an outgoing socket. timeout is in milliseconds. - **************************************************************************/ -static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeout) -{ - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout) / connect_loop; - - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } - - if (type != SOCK_STREAM) return(res); - - memset((char *)&sock_out,'\0',sizeof(sock_out)); - sock_out.sin_addr.s_addr = addr->addr; - - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; - - /* set it non-blocking */ - set_blocking(res,False); - - DEBUG(3,("Connecting to %s at port %d\n", sys_inet_ntoa(*addr),port)); - - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && loops--) { - msleep(connect_loop); - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n", sys_inet_ntoa(*addr),port)); - close(res); - return -1; - } - -#ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } -#endif - - if (ret < 0) { - DEBUG(2,("error connecting to %s:%d (%s)\n", - sys_inet_ntoa(*addr),port,strerror(errno))); - close(res); - return -1; - } - - /* set it blocking again */ - set_blocking(res,True); - - return res; -} - -#if 0 -static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn, - const char *base, - enum ldap_scope scope, - char *filter, - int num_attributes, - const char **attributes) +/* + match up with a pending message, adding to the replies list +*/ +static void ldap_match_message(struct ldap_connection *conn, struct ldap_message *msg) { - struct ldap_message *res; + struct ldap_request *req; - res = new_ldap_message(conn); - if (!res) { - return NULL; + for (req=conn->pending; req; req=req->next) { + if (req->messageid == msg->messageid) break; } - - res->type = LDAP_TAG_SearchRequest; - res->r.SearchRequest.basedn = base; - res->r.SearchRequest.scope = scope; - res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - res->r.SearchRequest.timelimit = 0; - res->r.SearchRequest.sizelimit = 0; - res->r.SearchRequest.attributesonly = False; - res->r.SearchRequest.filter = filter; - res->r.SearchRequest.num_attributes = num_attributes; - res->r.SearchRequest.attributes = attributes; - - return res; -} -#endif - -static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, const char *dn, const char *pw) -{ - struct ldap_message *res; - - res = new_ldap_message(conn); - if (!res) { - return NULL; + if (req == NULL) { + DEBUG(0,("ldap: no matching message id for %u\n", + msg->messageid)); + talloc_free(msg); + return; } - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = talloc_strdup(res, dn); - res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - res->r.BindRequest.creds.password = talloc_strdup(res, pw); - - return res; -} - -static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, const char *sasl_mechanism, DATA_BLOB *secblob) -{ - struct ldap_message *res; - - res = new_ldap_message(conn); - if (!res) { - return NULL; + /* add to the list of replies received */ + talloc_steal(req, msg); + req->replies = talloc_realloc(req, req->replies, + struct ldap_message *, req->num_replies+1); + if (req->replies == NULL) { + req->status = NT_STATUS_NO_MEMORY; + req->state = LDAP_REQUEST_DONE; + DLIST_REMOVE(conn->pending, req); + if (req->async.fn) { + req->async.fn(req); + } + return; } - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = ""; - res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; - res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism); - res->r.BindRequest.creds.SASL.secblob = *secblob; - - return res; -} - -static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) -{ - struct ldap_connection *result; + req->replies[req->num_replies] = talloc_steal(req->replies, msg); + req->num_replies++; - result = talloc(mem_ctx, struct ldap_connection); - - if (!result) { - return NULL; + if (msg->type != LDAP_TAG_SearchResultEntry) { + /* currently only search results expect multiple + replies */ + req->state = LDAP_REQUEST_DONE; + DLIST_REMOVE(conn->pending, req); } - result->next_msgid = 1; - result->outstanding = NULL; - result->searchid = 0; - result->search_entries = NULL; - result->auth_dn = NULL; - result->simple_pw = NULL; - result->gensec = NULL; - - return result; + if (req->async.fn) { + req->async.fn(req); + } } -struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) +/* + try and decode/process plain data +*/ +static void ldap_try_decode_plain(struct ldap_connection *conn) { - struct hostent *hp; - struct ipv4_addr ip; - struct ldap_connection *conn; - BOOL ret; + struct asn1_data asn1; - conn = new_ldap_connection(mem_ctx); - if (!conn) { - return NULL; + if (!asn1_load(&asn1, conn->partial)) { + ldap_connection_dead(conn); + return; } - ret = ldap_parse_basic_url(conn, url, &conn->host, - &conn->port, &conn->ldaps); - if (!ret) { - talloc_free(conn); - return NULL; - } + /* try and decode - this will fail if we don't have a full packet yet */ + while (asn1.ofs < asn1.length) { + struct ldap_message *msg = talloc(conn, struct ldap_message); + if (msg == NULL) { + ldap_connection_dead(conn); + return; + } - hp = sys_gethostbyname(conn->host); - if (!hp || !hp->h_addr) { - talloc_free(conn); - return NULL; + if (ldap_decode(&asn1, msg)) { + ldap_match_message(conn, msg); + } else { + talloc_free(msg); + break; + } } - memcpy((char *)&ip, (char *)hp->h_addr, 4); - - conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); - if (conn->sock < 0) { - talloc_free(conn); - return NULL; + /* keep any remaining data in conn->partial */ + data_blob_free(&conn->partial); + if (asn1.ofs != conn->partial.length) { + conn->partial = data_blob_talloc(conn, + asn1.data + asn1.ofs, + asn1.length - asn1.ofs); } - - return conn; -} - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc(mem_ctx, struct ldap_message); -} - -BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - DATA_BLOB request; - BOOL result; - struct ldap_queue_entry *entry; - - msg->messageid = conn->next_msgid++; - - if (!ldap_encode(msg, &request)) - return False; - - result = (write_data_until(conn->sock, request.data, request.length, - endtime) == request.length); - - data_blob_free(&request); - - if (!result) - return result; - - /* abandon and unbind don't expect results */ - - if ((msg->type == LDAP_TAG_AbandonRequest) || - (msg->type == LDAP_TAG_UnbindRequest)) - return True; - - entry = malloc_p(struct ldap_queue_entry); - - if (entry == NULL) - return False; - - entry->msgid = msg->messageid; - entry->msg = NULL; - DLIST_ADD(conn->outstanding, entry); - - return True; -} - -BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - struct asn1_data data; - BOOL result; - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return False; - - result = ldap_decode(&data, msg); - - asn1_free(&data); - return result; + asn1_free(&asn1); } -static struct ldap_message *recv_from_queue(struct ldap_connection *conn, - int msgid) +/* + try and decode/process wrapped data +*/ +static void ldap_try_decode_wrapped(struct ldap_connection *conn) { - struct ldap_queue_entry *e; + uint32_t len; - for (e = conn->outstanding; e != NULL; e = e->next) { + /* keep decoding while we have a full wrapped packet */ + while (conn->partial.length >= 4 && + (len=RIVAL(conn->partial.data, 0)) <= conn->partial.length-4) { + DATA_BLOB wrapped, unwrapped; + struct asn1_data asn1; + struct ldap_message *msg = talloc(conn, struct ldap_message); + NTSTATUS status; - if (e->msgid == msgid) { - struct ldap_message *result = e->msg; - DLIST_REMOVE(conn->outstanding, e); - SAFE_FREE(e); - return result; + if (msg == NULL) { + ldap_connection_dead(conn); + return; } - } - return NULL; -} - -static void add_search_entry(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e = malloc_p(struct ldap_queue_entry); - - if (e == NULL) - return; + wrapped.data = conn->partial.data+4; + wrapped.length = len; - e->msg = msg; - DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); - return; -} - -static void fill_outstanding_request(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e; - - for (e = conn->outstanding; e != NULL; e = e->next) { - if (e->msgid == msg->messageid) { - e->msg = msg; + status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); + if (!NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); return; } - } - - /* This reply has not been expected, destroy the incoming msg */ - talloc_free(msg); - return; -} - -struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) -{ - struct ldap_message *result = recv_from_queue(conn, msgid); - - if (result != NULL) - return result; - while (True) { - struct asn1_data data; - BOOL res; - - result = new_ldap_message(conn); - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return NULL; - - res = ldap_decode(&data, result); - asn1_free(&data); - - if (!res) - return NULL; + if (!asn1_load(&asn1, unwrapped)) { + ldap_connection_dead(conn); + return; + } - if (result->messageid == msgid) - return result; + if (ldap_decode(&asn1, msg)) { + ldap_match_message(conn, msg); + } else { + talloc_free(msg); + } + + asn1_free(&asn1); - if (result->type == LDAP_TAG_SearchResultEntry) { - add_search_entry(conn, result); + if (conn->partial.length == len + 4) { + data_blob_free(&conn->partial); } else { - fill_outstanding_request(conn, result); + memmove(conn->partial.data, conn->partial.data+len+4, + conn->partial.length - (len+4)); + conn->partial.length -= len + 4; } } - - return NULL; } + /* - Write data to a fd + handle ldap recv events */ -static ssize_t write_data(int fd, char *buffer, size_t N) +static void ldap_recv_handler(struct ldap_connection *conn) { - size_t total=0; - ssize_t ret; + NTSTATUS status; + size_t npending=0, nread; - while (total < N) { - ret = sys_write(fd,buffer + total,N - total); + /* work out how much data is pending */ + status = socket_pending(conn->sock, &npending); + if (!NT_STATUS_IS_OK(status) || npending == 0) { + DEBUG(0,("ldap_recv_handler - pending=%d - %s\n", + (int)npending, nt_errstr(status))); + return; + } - if (ret == -1) { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); - return -1; - } - if (ret == 0) - return total; + conn->partial.data = talloc_realloc_size(conn, conn->partial.data, + conn->partial.length + npending); + if (conn->partial.data == NULL) { + ldap_connection_dead(conn); + return; + } - total += ret; + /* receive the pending data */ + status = socket_recv(conn->sock, conn->partial.data + conn->partial.length, + npending, &nread, 0); + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + return; } + if (!NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); + return; + } + conn->partial.length += nread; - return (ssize_t)total; + /* see if we can decode what we have */ + if (conn->enable_wrap) { + ldap_try_decode_wrapped(conn); + } else { + ldap_try_decode_plain(conn); + } } /* - Read data from the client, reading exactly N bytes + handle ldap send events */ -static ssize_t read_data(int fd, char *buffer, size_t N) +static void ldap_send_handler(struct ldap_connection *conn) { - ssize_t ret; - size_t total=0; - - while (total < N) { + while (conn->send_queue) { + struct ldap_request *req = conn->send_queue; + size_t nsent; + NTSTATUS status; - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", - (int)(N - total), strerror(errno) )); - return 0; + status = socket_send(conn->sock, &req->data, &nsent, 0); + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + break; } - - if (ret == -1) { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", - (int)(N - total), strerror(errno) )); - return -1; + if (!NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); + return; } - total += ret; - } - - return (ssize_t)total; -} - -static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, struct ldap_message *req) -{ - NTSTATUS status; - DATA_BLOB request; - BOOL result; - DATA_BLOB wrapped; - int len; - char length[4]; - struct asn1_data asn1; - struct ldap_message *rep; - - req->messageid = conn->next_msgid++; - - if (!ldap_encode(req, &request)) - return NULL; - - status = gensec_wrap(conn->gensec, - req, - &request, - &wrapped); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status))); - return NULL; - } - - RSIVAL(length, 0, wrapped.length); - result = (write_data(conn->sock, length, 4) == 4); - if (!result) - return NULL; - - result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length); - if (!result) - return NULL; - - wrapped = data_blob(NULL, 0x4000); - data_blob_clear(&wrapped); - - result = (read_data(conn->sock, length, 4) == 4); - if (!result) - return NULL; - - len = RIVAL(length,0); - - result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len); - if (!result) - return NULL; - - wrapped.length = len; - - status = gensec_unwrap(conn->gensec, - req, - &wrapped, - &request); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status))); - return NULL; + req->data.data += nsent; + req->data.length -= nsent; + if (req->data.length == 0) { + req->state = LDAP_REQUEST_PENDING; + DLIST_REMOVE(conn->send_queue, req); + + /* some types of requests don't expect a reply */ + if (req->type == LDAP_TAG_AbandonRequest || + req->type == LDAP_TAG_UnbindRequest) { + req->status = NT_STATUS_OK; + req->state = LDAP_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + } else { + DLIST_ADD(conn->pending, req); + } + } } - - rep = new_ldap_message(req); - - asn1_load(&asn1, request); - if (!ldap_decode(&asn1, rep)) { - return NULL; + if (conn->send_queue == NULL) { + EVENT_FD_NOT_WRITEABLE(conn->event.fde); } - - return rep; } -struct ldap_message *ldap_transaction(struct ldap_connection *conn, - struct ldap_message *request) + +/* + handle ldap socket events +*/ +static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) { - if ((request->type != LDAP_TAG_BindRequest) && conn->gensec && - (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || - gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { - return ldap_transaction_sasl(conn, request); + struct ldap_connection *conn = talloc_get_type(private, struct ldap_connection); + if (flags & EVENT_FD_WRITE) { + ldap_send_handler(conn); + if (conn->sock == NULL) return; + } + if (flags & EVENT_FD_READ) { + ldap_recv_handler(conn); } - - if (!ldap_send_msg(conn, request, NULL)) - return False; - - return ldap_receive(conn, request->messageid, NULL); } -int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) +/* + parse a ldap URL +*/ +static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, + char **host, uint16_t *port, BOOL *ldaps) { - struct ldap_message *response; - struct ldap_message *msg; - const char *dn, *pw; - int result = LDAP_OTHER; + int tmp_port = 0; + char protocol[11]; + char tmp_host[255]; + const char *p = url; + int ret; - if (conn == NULL) - return result; + /* skip leading "URL:" (if any) */ + if (strncasecmp(p, "URL:", 4) == 0) { + p += 4; + } - if (userdn) { - dn = userdn; - } else { - if (conn->auth_dn) { - dn = conn->auth_dn; - } else { - dn = ""; - } + /* Paranoia check */ + SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); + + ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + if (ret < 2) { + return NT_STATUS_INVALID_PARAMETER; } - if (password) { - pw = password; + if (strequal(protocol, "ldap")) { + *port = 389; + *ldaps = False; + } else if (strequal(protocol, "ldaps")) { + *port = 636; + *ldaps = True; } else { - if (conn->simple_pw) { - pw = conn->simple_pw; - } else { - pw = ""; - } + DEBUG(0, ("unrecognised ldap protocol (%s)!\n", protocol)); + return NT_STATUS_PROTOCOL_UNREACHABLE; } - msg = new_ldap_simple_bind_msg(conn, dn, pw); - if (!msg) - return result; + if (tmp_port != 0) + *port = tmp_port; - response = ldap_transaction(conn, msg); - if (!response) { - talloc_free(msg); - return result; - } - - result = response->r.BindResponse.response.resultcode; - - talloc_free(msg); - talloc_free(response); + *host = talloc_strdup(mem_ctx, tmp_host); + NT_STATUS_HAVE_NO_MEMORY(*host); - return result; + return NT_STATUS_OK; } -int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) +/* + connect to a ldap server +*/ +NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) { NTSTATUS status; - TALLOC_CTX *mem_ctx = NULL; - struct ldap_message *response; - struct ldap_message *msg; - DATA_BLOB input = data_blob(NULL, 0); - DATA_BLOB output = data_blob(NULL, 0); - int result = LDAP_OTHER; - if (conn == NULL) - return result; + status = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); + NT_STATUS_NOT_OK_RETURN(status); - status = gensec_client_start(conn, &conn->gensec); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); - return result; - } - - gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); - - status = gensec_set_credentials(conn->gensec, creds); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC creds: %s\n", - nt_errstr(status))); - goto done; - } + status = socket_create("ipv4", SOCKET_TYPE_STREAM, &conn->sock, 0); + NT_STATUS_NOT_OK_RETURN(status); - status = gensec_set_target_hostname(conn->gensec, conn->host); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto done; - } + talloc_steal(conn, conn->sock); - status = gensec_set_target_service(conn->gensec, "ldap"); + /* connect in a event friendly way */ + status = socket_connect_ev(conn->sock, NULL, 0, conn->host, conn->port, 0, + conn->event.event_ctx); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target service: %s\n", - nt_errstr(status))); - goto done; + talloc_free(conn->sock); + return status; } - status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", - nt_errstr(status))); - goto done; + /* setup a handler for events on this socket */ + conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, + socket_get_fd(conn->sock), + EVENT_FD_READ, ldap_io_handler, conn); + if (conn->event.fde == NULL) { + talloc_free(conn->sock); + return NT_STATUS_INTERNAL_ERROR; } - mem_ctx = talloc_init("ldap_bind_sasl"); - if (!mem_ctx) - goto done; - - status = gensec_update(conn->gensec, mem_ctx, - input, - &output); - - while(1) { - if (NT_STATUS_IS_OK(status) && output.length == 0) { - break; - } - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - break; - } - - msg = new_ldap_sasl_bind_msg(conn, "GSS-SPNEGO", &output); - if (!msg) - goto done; - - response = ldap_transaction(conn, msg); - talloc_free(msg); - - if (!response) { - goto done; - } - - result = response->r.BindResponse.response.resultcode; - - if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { - break; - } - - if (!NT_STATUS_IS_OK(status)) { - status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.secblob, - &output); - } else { - output.length = 0; - } - - talloc_free(response); - } - -done: - talloc_free(mem_ctx); - - return result; + return NT_STATUS_OK; } -struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, - const char *userdn, const char *password) +/* destroy an open ldap request */ +static int ldap_request_destructor(void *ptr) { - struct ldap_connection *conn; - int result; - - conn =ldap_connect(mem_ctx, url); - if (!conn) { - return NULL; + struct ldap_request *req = talloc_get_type(ptr, struct ldap_request); + if (req->state == LDAP_REQUEST_SEND) { + DLIST_REMOVE(req->conn->send_queue, req); } - - result = ldap_bind_simple(conn, userdn, password); - if (result != LDAP_SUCCESS) { - talloc_free(conn); - return NULL; + if (req->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(req->conn->pending, req); } - - return conn; + return 0; } -struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, - const char *url, - struct cli_credentials *creds) +/* + called on timeout of a ldap request +*/ +static void ldap_request_timeout(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) { - struct ldap_connection *conn; - int result; - - conn =ldap_connect(mem_ctx, url); - if (!conn) { - return NULL; + struct ldap_request *req = talloc_get_type(private, struct ldap_request); + req->status = NT_STATUS_IO_TIMEOUT; + if (req->state == LDAP_REQUEST_SEND) { + DLIST_REMOVE(req->conn->send_queue, req); } - - result = ldap_bind_sasl(conn, creds); - if (result != LDAP_SUCCESS) { - talloc_free(conn); - return NULL; + if (req->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(req->conn->pending, req); + } + req->state = LDAP_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); } - - return conn; } -BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) +/* + send a ldap message - async interface +*/ +struct ldap_request *ldap_request_send(struct ldap_connection *conn, + struct ldap_message *msg) { - struct ldap_message *msg = new_ldap_message(conn); - BOOL result; + struct ldap_request *req; - if (msg == NULL) - return False; + if (conn->sock == NULL) { + return NULL; + } - msg->type = LDAP_TAG_AbandonRequest; - msg->r.AbandonRequest.messageid = msgid; + req = talloc_zero(conn, struct ldap_request); + if (req == NULL) goto failed; - result = ldap_send_msg(conn, msg, endtime); - talloc_free(msg); - return result; -} + req->state = LDAP_REQUEST_SEND; + req->conn = conn; + req->messageid = conn->next_messageid++; + req->type = msg->type; + if (req->messageid == -1) { + goto failed; + } -BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - if ((conn->searchid != 0) && - (!ldap_abandon_message(conn, conn->searchid, endtime))) - return False; + talloc_set_destructor(req, ldap_request_destructor); - conn->searchid = conn->next_msgid; - return ldap_send_msg(conn, msg, endtime); -} + msg->messageid = req->messageid; -struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_message *result; + if (!ldap_encode(msg, &req->data)) { + goto failed; + } - if (conn->search_entries != NULL) { - struct ldap_queue_entry *e = conn->search_entries; + /* possibly encrypt/sign the request */ + if (conn->enable_wrap) { + DATA_BLOB wrapped; + NTSTATUS status; - result = e->msg; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - return result; + status = gensec_wrap(conn->gensec, req, &req->data, &wrapped); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + data_blob_free(&req->data); + req->data = data_blob_talloc(req, NULL, wrapped.length + 4); + if (req->data.data == NULL) { + goto failed; + } + RSIVAL(req->data.data, 0, wrapped.length); + memcpy(req->data.data+4, wrapped.data, wrapped.length); + data_blob_free(&wrapped); } - result = ldap_receive(conn, conn->searchid, endtime); - if (!result) { - return NULL; + + if (conn->send_queue == NULL) { + EVENT_FD_WRITEABLE(conn->event.fde); } + DLIST_ADD_END(conn->send_queue, req, struct ldap_request *); - if (result->type == LDAP_TAG_SearchResultEntry) - return result; + /* put a timeout on the request */ + event_add_timed(conn->event.event_ctx, req, + timeval_current_ofs(conn->timeout, 0), + ldap_request_timeout, req); - if (result->type == LDAP_TAG_SearchResultDone) { - /* TODO: Handle Paged Results */ - talloc_free(result); - return NULL; - } + return req; - /* TODO: Handle Search References here */ +failed: + talloc_free(req); return NULL; } -void ldap_endsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_queue_entry *e; - - e = conn->search_entries; - while (e != NULL) { - struct ldap_queue_entry *next = e->next; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - e = next; +/* + wait for a request to complete + note that this does not destroy the request +*/ +NTSTATUS ldap_request_wait(struct ldap_request *req) +{ + while (req->state != LDAP_REQUEST_DONE) { + if (event_loop_once(req->conn->event.event_ctx) != 0) { + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + break; + } } + return req->status; } -struct ldap_message *ldap_searchone(struct ldap_connection *conn, - struct ldap_message *msg, - const struct timeval *endtime) -{ - struct ldap_message *res1, *res2 = NULL; - if (!ldap_setsearchent(conn, msg, endtime)) - return NULL; - - res1 = ldap_getsearchent(conn, endtime); - - if (res1 != NULL) - res2 = ldap_getsearchent(conn, endtime); - - ldap_endsearchent(conn, endtime); - - if (res1 == NULL) - return NULL; - if (res2 != NULL) { - /* More than one entry */ - talloc_free(res1); - talloc_free(res2); - return NULL; +/* + used to setup the status code from a ldap response +*/ +NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) +{ + if (r->resultcode == LDAP_SUCCESS) { + return NT_STATUS_OK; } - return res1; + if (conn->last_error) { + talloc_free(conn->last_error); + } + conn->last_error = talloc_asprintf(conn, "LDAP error %u - %s <%s> <%s>", + r->resultcode, + r->dn, r->errormessage, r->referral); + + return NT_STATUS_LDAP(r->resultcode); } -BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, - DATA_BLOB *value) +/* + return error string representing the last error +*/ +const char *ldap_errstr(struct ldap_connection *conn, NTSTATUS status) { - int i; - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - - if (msg->type != LDAP_TAG_SearchResultEntry) - return False; - - for (i=0; inum_attributes; i++) { - if (strequal(attr, r->attributes[i].name)) { - if (r->attributes[i].num_values != 1) - return False; - - *value = r->attributes[i].values[0]; - return True; - } + if (NT_STATUS_IS_LDAP(status) && conn->last_error != NULL) { + return conn->last_error; } - return False; + return nt_errstr(status); } -BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, - TALLOC_CTX *mem_ctx, char **value) -{ - DATA_BLOB blob; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - *value = talloc_size(mem_ctx, blob.length+1); - - if (*value == NULL) - return False; - memcpy(*value, blob.data, blob.length); - (*value)[blob.length] = '\0'; - return True; -} - -BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, - int *value) +/* + return the Nth result message, waiting if necessary +*/ +NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg) { - DATA_BLOB blob; - char *val; - int errno_save; - BOOL res; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - val = malloc(blob.length+1); - if (val == NULL) - return False; + *msg = NULL; - memcpy(val, blob.data, blob.length); - val[blob.length] = '\0'; - - errno_save = errno; - errno = 0; - - *value = strtol(val, NULL, 10); + while (req->state != LDAP_REQUEST_DONE && n >= req->num_replies) { + if (event_loop_once(req->conn->event.event_ctx) != 0) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + } - res = (errno == 0); + if (n < req->num_replies) { + *msg = req->replies[n]; + return NT_STATUS_OK; + } - free(val); - errno = errno_save; + if (!NT_STATUS_IS_OK(req->status)) { + return req->status; + } - return res; + return NT_STATUS_NO_MORE_ENTRIES; } -int ldap_error(struct ldap_connection *conn) -{ - return 0; -} -NTSTATUS ldap2nterror(int ldaperror) +/* + return a single result message, checking if it is of the expected LDAP type +*/ +NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type) { - return NT_STATUS_OK; + NTSTATUS status; + status = ldap_result_n(req, 0, msg); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if ((*msg)->type != type) { + *msg = NULL; + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + return status; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h new file mode 100644 index 0000000000..719c3639c1 --- /dev/null +++ b/source4/libcli/ldap/ldap_client.h @@ -0,0 +1,86 @@ +/* + Unix SMB/CIFS Implementation. + + ldap client side header + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + + +enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE}; + +/* this is the handle that the caller gets when an async ldap message + is sent */ +struct ldap_request { + struct ldap_request *next, *prev; + struct ldap_connection *conn; + + enum ldap_request_tag type; + int messageid; + enum ldap_request_state state; + + int num_replies; + struct ldap_message **replies; + + NTSTATUS status; + DATA_BLOB data; + struct { + void (*fn)(struct ldap_request *); + void *private; + } async; +}; + + +/* main context for a ldap client connection */ +struct ldap_connection { + struct socket_context *sock; + char *host; + uint16_t port; + BOOL ldaps; + + const char *auth_dn; + const char *simple_pw; + + /* next message id to assign */ + unsigned next_messageid; + + /* outgoing send queue */ + struct ldap_request *send_queue; + + /* Outstanding LDAP requests that have not yet been replied to */ + struct ldap_request *pending; + + /* Let's support SASL */ + struct gensec_security *gensec; + + /* set if we are wrapping requests */ + BOOL enable_wrap; + + /* partially received packet */ + DATA_BLOB partial; + + /* the default timeout for messages */ + int timeout; + + /* last error message */ + char *last_error; + + struct { + struct event_context *event_ctx; + struct fd_event *fde; + } event; +}; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c deleted file mode 100644 index 55e902ecad..0000000000 --- a/source4/libcli/ldap/ldap_ldif.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 - - 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 "system/iconv.h" -#include "libcli/ldap/ldap.h" - -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return False; - - attrib->values[attrib->num_values] = - data_blob_talloc(mem_ctx, value->data, value->length); - attrib->num_values += 1; - return True; -} - -BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return False; - - (*attribs)[*num_attribs] = *attrib; - *num_attribs += 1; - return True; -} - -BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return False; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return True; -} - diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c new file mode 100644 index 0000000000..5ac44a5226 --- /dev/null +++ b/source4/libcli/ldap/ldap_msg.c @@ -0,0 +1,84 @@ +/* + Unix SMB/CIFS mplementation. + + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Volker Lendecke 2004 + + 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 "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" + + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + return talloc(mem_ctx, struct ldap_message); +} + + +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return False; + + attrib->values[attrib->num_values] = + data_blob_talloc(mem_ctx, value->data, value->length); + attrib->num_values += 1; + return True; +} + +BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return False; + + (*attribs)[*num_attribs] = *attrib; + *num_attribs += 1; + return True; +} + +BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return False; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return True; +} + diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index d727cfe2a9..eca47572e3 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -648,7 +648,7 @@ static const nt_err_code_struct nt_err_desc[] = *****************************************************************************/ const char *nt_errstr(NTSTATUS nt_code) { - static pstring msg; + static fstring msg; int idx = 0; while (nt_errs[idx].nt_errstr != NULL) { @@ -659,7 +659,14 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } - slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); + if (NT_STATUS_IS_DOS(nt_code)) { + slprintf(msg, sizeof(msg), "DOS code %u:%u", + NT_STATUS_DOS_CLASS(nt_code), NT_STATUS_DOS_CODE(nt_code)); + } else if (NT_STATUS_IS_LDAP(nt_code)) { + slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); + } else { + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); + } return msg; } -- cgit From af237084ecd4f9928c6c282b9c5c73598d5c73d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 11:36:09 +0000 Subject: r7633: this patch started as an attempt to make the dcerpc code use a given event_context for the socket_connect() call, so that when things that use dcerpc are running alongside anything else it doesn't block the whole process during a connect. Then of course I needed to change any code that created a dcerpc connection (such as the auth code) to also take an event context, and anything that called that and so on .... thus the size of the patch. There were 3 places where I punted: - abartlet wanted me to add a gensec_set_event_context() call instead of adding it to the gensec init calls. Andrew, my apologies for not doing this. I didn't do it as adding a new parameter allowed me to catch all the callers with the compiler. Now that its done, we could go back and use gensec_set_event_context() - the ejs code calls auth initialisation, which means it should pass in the event context from the web server. I punted on that. Needs fixing. - I used a NULL event context in dcom_get_pipe(). This is equivalent to what we did already, but should be fixed to use a callers event context. Jelmer, can you think of a clean way to do that? I also cleaned up a couple of things: - libnet_context_destroy() makes no sense. I removed it. - removed some unused vars in various places (This used to be commit 3a3025485bdb8f600ab528c0b4b4eef0c65e3fc9) --- source4/libcli/cliconnect.c | 5 +++-- source4/libcli/composite/connect.c | 5 +++-- source4/libcli/composite/sesssetup.c | 2 +- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/raw/clitree.c | 5 +++-- source4/libcli/util/clilsa.c | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index a866e26970..0009151429 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -134,7 +134,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, const char *host, const char *sharename, const char *devtype, - struct cli_credentials *credentials) + struct cli_credentials *credentials, + struct event_context *ev) { struct smbcli_tree *tree; NTSTATUS status; @@ -143,7 +144,7 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, status = smbcli_tree_full_connection(parent_ctx, &tree, host, 0, sharename, devtype, - credentials); + credentials, ev); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 9e33a2f7db..fb439172d0 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -382,8 +382,9 @@ NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem /* sync version of smb_composite_connect */ -NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx) +NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, + struct event_context *ev) { - struct composite_context *c = smb_composite_connect_send(io, NULL); + struct composite_context *c = smb_composite_connect_send(io, ev); return smb_composite_connect_recv(c, mem_ctx); } diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index ab46c198ef..2736d91262 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -263,7 +263,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, smbcli_temp_set_signing(session->transport); - status = gensec_client_start(session, &session->gensec); + status = gensec_client_start(session, &session->gensec, c->event_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); return NULL; diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 11a6997fb2..ea97798261 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -144,7 +144,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr DATA_BLOB input = data_blob(NULL, 0); DATA_BLOB output = data_blob(NULL, 0); - status = gensec_client_start(conn, &conn->gensec); + status = gensec_client_start(conn, &conn->gensec, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 87c2dbba7c..76cb1a43fe 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -166,7 +166,8 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_tree **ret_tree, const char *dest_host, int port, const char *service, const char *service_type, - struct cli_credentials *credentials) + struct cli_credentials *credentials, + struct event_context *ev) { struct smb_composite_connect io; NTSTATUS status; @@ -179,7 +180,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.credentials = credentials; io.in.workgroup = lp_workgroup(); - status = smb_composite_connect(&io, parent_ctx); + status = smb_composite_connect(&io, parent_ctx, ev); if (NT_STATUS_IS_OK(status)) { *ret_tree = io.out.tree; } diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 0c0c64c0b4..ad2006756b 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -76,7 +76,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } lsa->ipc_tree->tid = tcon.tconx.out.tid; - lsa->pipe = dcerpc_pipe_init(lsa); + lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx); if (lsa->pipe == NULL) { talloc_free(lsa); return NT_STATUS_NO_MEMORY; -- cgit From d13e788f20743989ff0d76b13262793027dc66bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 23:19:03 +0000 Subject: r7654: - add a timeout to all smb requests (default 60 seconds) - add a request destructor, to make it safe to destroy a pending request with talloc_free() (This used to be commit 72c6988767249caa585f37fec4c0afbf41557ec2) --- source4/libcli/raw/clitransport.c | 46 +++++++++++++++++++++++++++++++++++++++ source4/libcli/raw/libcliraw.h | 4 ++++ 2 files changed, 50 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 05833b2f9a..999795b81e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -79,6 +79,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->options.use_spnego = lp_use_spnego(); transport->options.max_xmit = lp_max_xmit(); transport->options.max_mux = lp_maxmux(); + transport->options.request_timeout = SMB_REQUEST_TIMEOUT; transport->negotiate.max_xmit = transport->options.max_xmit; @@ -580,6 +581,42 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) return True; } +/* + handle timeouts of individual smb requests +*/ +static void smbcli_timeout_handler(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct smbcli_request *req = talloc_get_type(private, struct smbcli_request); + + if (req->state == SMBCLI_REQUEST_SEND) { + DLIST_REMOVE(req->transport->pending_send, req); + } + if (req->state == SMBCLI_REQUEST_RECV) { + DLIST_REMOVE(req->transport->pending_recv, req); + } + req->status = NT_STATUS_IO_TIMEOUT; + req->state = SMBCLI_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + destroy a request +*/ +static int smbcli_request_destructor(void *ptr) +{ + struct smbcli_request *req = talloc_get_type(ptr, struct smbcli_request); + if (req->state == SMBCLI_REQUEST_SEND) { + DLIST_REMOVE(req->transport->pending_send, req); + } + if (req->state == SMBCLI_REQUEST_RECV) { + DLIST_REMOVE(req->transport->pending_recv, req); + } + return 0; +} /* @@ -600,4 +637,13 @@ void smbcli_transport_send(struct smbcli_request *req) /* make sure we look for write events */ smbcli_transport_write_enable(req->transport); + + /* add a timeout */ + if (req->transport->options.request_timeout) { + event_add_timed(req->transport->socket->event.ctx, req, + timeval_current_ofs(req->transport->options.request_timeout, 0), + smbcli_timeout_handler, req); + } + + talloc_set_destructor(req, smbcli_request_destructor); } diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index d7414a237e..2794a22da2 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -28,6 +28,9 @@ struct smbcli_request; /* forward declare */ struct smbcli_session; /* forward declare */ struct smbcli_transport; /* forward declare */ +/* default timeout for all smb requests */ +#define SMB_REQUEST_TIMEOUT 60 + /* context that will be and has been negotiated between the client and server */ struct smbcli_negotiate { /* @@ -88,6 +91,7 @@ struct smbcli_options { uint_t use_spnego:1; uint32_t max_xmit; uint16_t max_mux; + int request_timeout; }; /* this is the context for the client transport layer */ -- cgit From ab1e121b76a953f89592df8ec471603715b57dfc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Jun 2005 02:45:40 +0000 Subject: r7665: - added a ildap_*() interface to our internal ldap library. This interface is very similar to the traditional ldap interface, and will be used as part of a ldb backend based on the current ldb_ldap backend - fixed some allocation issues in ldb_msg.c (This used to be commit b34a29dcf26f68a2f47380a6c74a4095fdfd2fbe) --- source4/libcli/ldap/config.mk | 4 +- source4/libcli/ldap/ldap.h | 1 + source4/libcli/ldap/ldap_client.c | 25 +++++ source4/libcli/ldap/ldap_ildap.c | 209 ++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_msg.c | 4 +- 5 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 source4/libcli/ldap/ldap_ildap.c (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index ca33581043..210fb112d3 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -5,6 +5,8 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ libcli/ldap/ldap_bind.o \ libcli/ldap/ldap_msg.o \ - libcli/ldap/ldap_ndr.o + libcli/ldap/ldap_ndr.o \ + libcli/ldap/ldap_ildap.o +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBBASIC LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 072070f723..4f2dbc0787 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -217,6 +217,7 @@ struct ldap_ExtendedResponse { }; union ldap_Request { + struct ldap_Result GeneralResult; struct ldap_BindRequest BindRequest; struct ldap_BindResponse BindResponse; struct ldap_UnbindRequest UnbindRequest; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f3a7f104d4..7ad45f4eea 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -573,6 +573,8 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms { *msg = NULL; + NT_STATUS_HAVE_NO_MEMORY(req); + while (req->state != LDAP_REQUEST_DONE && n >= req->num_replies) { if (event_loop_once(req->conn->event.event_ctx) != 0) { return NT_STATUS_UNEXPECTED_NETWORK_ERROR; @@ -608,3 +610,26 @@ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, in } return status; } + +/* + a simple ldap transaction, for single result requests that only need a status code + this relies on single valued requests having the response type == request type + 1 +*/ +NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg) +{ + struct ldap_request *req = ldap_request_send(conn, msg); + struct ldap_message *res; + NTSTATUS status; + status = ldap_result_n(req, 0, &res); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return status; + } + if (res->type != msg->type + 1) { + talloc_free(req); + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + status = ldap_check_response(conn, &res->r.GeneralResult); + talloc_free(req); + return status; +} diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c new file mode 100644 index 0000000000..cfcb79f64f --- /dev/null +++ b/source4/libcli/ldap/ldap_ildap.c @@ -0,0 +1,209 @@ +/* + Unix SMB/CIFS mplementation. + + ildap api - an api similar to the traditional ldap api + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" + +/* + delete a record + */ +NTSTATUS ildap_delete(struct ldap_connection *conn, const char *dn) +{ + struct ldap_message *msg; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + +/* + add a record + */ +NTSTATUS ildap_add(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) +{ + struct ldap_message *msg; + int n, i; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + for (n=0;mods[n];n++) /* noop */ ; + + msg->type = LDAP_TAG_AddRequest; + msg->r.AddRequest.dn = dn; + msg->r.AddRequest.num_attributes = n; + msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); + if (msg->r.AddRequest.attributes == NULL) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + for (i=0;ir.AddRequest.attributes[i] = mods[i]->attrib; + } + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + + +/* + modify a record + */ +NTSTATUS ildap_modify(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) +{ + struct ldap_message *msg; + int n, i; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + for (n=0;mods[n];n++) /* noop */ ; + + msg->type = LDAP_TAG_ModifyRequest; + msg->r.ModifyRequest.dn = dn; + msg->r.ModifyRequest.num_mods = n; + msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); + if (msg->r.ModifyRequest.mods == NULL) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + for (i=0;ir.ModifyRequest.mods[i] = *mods[i]; + } + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + + +/* + rename a record + */ +NTSTATUS ildap_rename(struct ldap_connection *conn, const char *dn, const char *newrdn, + const char *parentdn, BOOL deleteolddn) +{ + struct ldap_message *msg; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + msg->type = LDAP_TAG_ModifyDNRequest; + msg->r.ModifyDNRequest.dn = dn; + msg->r.ModifyDNRequest.newrdn = newrdn; + msg->r.ModifyDNRequest.deleteolddn = deleteolddn; + msg->r.ModifyDNRequest.newsuperior = parentdn; + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + + +/* + count the returned search entries +*/ +int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) +{ + int i; + for (i=0;res && res[i];i++) /* noop */ ; + return i; +} + + +/* + perform a ldap search +*/ +NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, + int scope, const char *expression, + const char * const *attrs, BOOL attributesonly, + struct ldap_message ***results) +{ + struct ldap_message *msg; + int n, i; + NTSTATUS status; + struct ldap_request *req; + + *results = NULL; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + for (n=0;attrs && attrs[n];n++) /* noop */ ; + + msg->type = LDAP_TAG_SearchRequest; + msg->r.SearchRequest.basedn = basedn; + msg->r.SearchRequest.scope = scope; + msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + msg->r.SearchRequest.timelimit = 0; + msg->r.SearchRequest.sizelimit = 0; + msg->r.SearchRequest.attributesonly = attributesonly; + msg->r.SearchRequest.tree = ldb_parse_tree(msg, expression); + msg->r.SearchRequest.num_attributes = n; + msg->r.SearchRequest.attributes = attrs; + + req = ldap_request_send(conn, msg); + talloc_steal(msg, req); + + for (i=n=0;True;i++) { + struct ldap_message *res; + status = ldap_result_n(req, i, &res); + if (!NT_STATUS_IS_OK(status)) break; + if (res->type != LDAP_TAG_SearchResultEntry) continue; + + (*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2); + if (*results == NULL) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + (*results)[n] = talloc_steal(*results, res); + (*results)[n+1] = NULL; + n++; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { + status = NT_STATUS_OK; + } + + return status; +} diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 5ac44a5226..901c42a62a 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -44,7 +44,7 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, return False; attrib->values[attrib->num_values] = - data_blob_talloc(mem_ctx, value->data, value->length); + data_blob_talloc(attrib->values, value->data, value->length); attrib->num_values += 1; return True; } @@ -63,6 +63,8 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, return False; (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); *num_attribs += 1; return True; } -- cgit From fca7031da9962c27cfa82a52a50b6fc23aa494de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jun 2005 07:18:30 +0000 Subject: r7679: update the documentation of security_description_create() metze (This used to be commit 6ad7ffab043c3b510f4dff052973a054e5a75779) --- source4/libcli/security/security_descriptor.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 54c4bcb6cb..d1978fd795 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -287,7 +287,10 @@ BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, /* create a security descriptor using string SIDs. This is used by the torture code to allow the easy creation of complex ACLs - This is a varargs function. The list of ACEs ends with a NULL sid. + This is a varargs function. The list of DACL ACEs ends with a NULL sid. + + Each ACE contains a set of 4 parameters: + SID, ACCESS_TYPE, MASK, FLAGS a typical call would be: @@ -299,7 +302,7 @@ BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, SEC_FILE_ALL, SEC_ACE_FLAG_OBJECT_INHERIT, NULL); - that would create a sd with one ACE + that would create a sd with one DACL ACE */ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, const char *owner_sid, -- cgit From ee57c76a687c72ac7e8dc7c135ab53baa7a42776 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 00:02:36 +0000 Subject: r7704: - fixed open_nbt_connection() to return NULL when the connection failed - got rid of smbcli_shutdown() and use talloc_free() instead. (This used to be commit 1011b1bf51d420d6702ef448c894ea8ebeafa284) --- source4/libcli/cliconnect.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 0009151429..489aea82dd 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -183,14 +183,6 @@ struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) return cli; } -/**************************************************************************** - Shutdown a client structure. -****************************************************************************/ -void smbcli_shutdown(struct smbcli_state *cli) -{ - talloc_free(cli); -} - /* parse a //server/share type UNC name */ -- cgit From 777b4b021456f5bd8bbadfe97532efc13286e581 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 00:30:49 +0000 Subject: r7705: prevent SIGPIPE. this is what causes BASE-NEGNOWAIT to sometimes fail (This used to be commit 0163d7fe99caee54c6c2bd614e4f076fd00a6176) --- source4/libcli/raw/clisocket.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 7cb7040131..d6007ec8ba 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -63,6 +63,9 @@ struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx, return NULL; } + /* ensure we don't get SIGPIPE */ + BlockSignals(True,SIGPIPE); + return sock; } -- cgit From 56b79e945f1e28d1ba7296e44a9802c140b942ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 07:54:14 +0000 Subject: r7713: fixed error display in ildap_search() (This used to be commit abc9f4bd89d0eda655f7de01db49cbbb64682bf4) --- source4/libcli/ldap/ldap_ildap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index cfcb79f64f..541797c25c 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -189,6 +189,12 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, struct ldap_message *res; status = ldap_result_n(req, i, &res); if (!NT_STATUS_IS_OK(status)) break; + + if (res->type == LDAP_TAG_SearchResultDone) { + status = ldap_check_response(conn, &res->r.GeneralResult); + break; + } + if (res->type != LDAP_TAG_SearchResultEntry) continue; (*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2); -- cgit From 90cf33953dcfab988162f9ee53cdc0eb6ff87c28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 09:01:51 +0000 Subject: r7715: ensure we don't print null strings in ldap_errstr() (This used to be commit dc419fc89973c2d7fa333df389b75cb218e8a848) --- source4/libcli/ldap/ldap_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7ad45f4eea..e392002a19 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -549,7 +549,9 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r } conn->last_error = talloc_asprintf(conn, "LDAP error %u - %s <%s> <%s>", r->resultcode, - r->dn, r->errormessage, r->referral); + r->dn?r->dn:"(NULL)", + r->errormessage?r->errormessage:"", + r->referral?r->referral:""); return NT_STATUS_LDAP(r->resultcode); } -- cgit From 1e99722d020f38eaad7fe2010f43c23586a19410 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 09:08:08 +0000 Subject: r7716: a single wrapped ldap blob can contain multiple ldap messages (This used to be commit de5f265b6c586335965a6de844c203206261cc3b) --- source4/libcli/ldap/ldap_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index e392002a19..bc70cd56aa 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -213,12 +213,12 @@ static void ldap_try_decode_wrapped(struct ldap_connection *conn) return; } - if (ldap_decode(&asn1, msg)) { + while (ldap_decode(&asn1, msg)) { ldap_match_message(conn, msg); - } else { - talloc_free(msg); + msg = talloc(conn, struct ldap_message); } + talloc_free(msg); asn1_free(&asn1); if (conn->partial.length == len + 4) { -- cgit From ca91a8a6919b9bc1b6016310c6b30447723b08d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 09:09:27 +0000 Subject: r7717: fixed some typos (This used to be commit fc8feee56034fe165359c804d111f80e5b3ebb65) --- source4/libcli/ldap/ldap_bind.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index ea97798261..7e4fa10fe4 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -154,28 +154,28 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC creds: %s\n", + DEBUG(1, ("Failed to set GENSEC creds: %s\n", nt_errstr(status))); goto failed; } status = gensec_set_target_hostname(conn->gensec, conn->host); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", nt_errstr(status))); goto failed; } status = gensec_set_target_service(conn->gensec, "ldap"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target service: %s\n", + DEBUG(1, ("Failed to set GENSEC target service: %s\n", nt_errstr(status))); goto failed; } status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + DEBUG(1, ("Failed to set GENSEC client SPNEGO mechanism: %s\n", nt_errstr(status))); goto failed; } -- cgit From b4eee348c4d36e67ba83651c250366e84e7125dd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 10:38:06 +0000 Subject: r7720: - simplify the asn1 decode of ldap_search() a lot, taking advantage of the fact that the ldap data structures now use ldb_message_element. - fixed null termination of elements in ildap (This used to be commit 09060994c1ed12073ae6e1131d7074db8fdc523c) --- source4/libcli/ldap/ldap.c | 4 +++- source4/libcli/ldap/ldap_msg.c | 5 +++-- source4/libcli/util/asn1.c | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c642fc3e4b..83858b1768 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -98,6 +98,9 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; + case LDB_OP_NOT: + #warning "OP_NOT missing" + default: return False; } @@ -605,7 +608,6 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, DATA_BLOB blob; asn1_read_OctetString(data, &blob); add_value_to_attrib(mem_ctx, &blob, attrib); - data_blob_free(&blob); } asn1_end_tag(data); asn1_end_tag(data); diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 901c42a62a..9b531f3138 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -43,8 +43,9 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, if (attrib->values == NULL) return False; - attrib->values[attrib->num_values] = - data_blob_talloc(attrib->values, value->data, value->length); + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; attrib->num_values += 1; return True; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 510ffa37cf..92f9a8c389 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -576,7 +576,6 @@ BOOL asn1_read_Integer(struct asn1_data *data, int *i) if (!asn1_start_tag(data, ASN1_INTEGER)) return False; if (!asn1_read_implicit_Integer(data, i)) return False; return asn1_end_tag(data); - } /* read an interger */ -- cgit From 91a79f2b24b62d9b78ecb52ff593672acc6f971a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 12:44:36 +0000 Subject: r7722: when we get a zero read, the connection is dead (This used to be commit 060323530454edf21b217550b373513e5860146c) --- source4/libcli/ldap/ldap_client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index bc70cd56aa..f2b09e89e3 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -243,8 +243,7 @@ static void ldap_recv_handler(struct ldap_connection *conn) /* work out how much data is pending */ status = socket_pending(conn->sock, &npending); if (!NT_STATUS_IS_OK(status) || npending == 0) { - DEBUG(0,("ldap_recv_handler - pending=%d - %s\n", - (int)npending, nt_errstr(status))); + ldap_connection_dead(conn); return; } -- cgit From 2a0a0f2551b03e4792cab37455b094d21819dc87 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 12:45:28 +0000 Subject: r7723: - fix a mismatched asn1 push/pop on bind - add error checking to ldap_encode() - fixed the asn1 codes for extended search - use asn1 context macros (This used to be commit 25d500b6e559b9a530ae65a21046cfde0f8c41af) --- source4/libcli/ldap/ldap.c | 55 ++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 83858b1768..81e659d3e8 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -38,7 +38,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ - asn1_push_tag(data, 0x87); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); asn1_write(data, tree->u.simple.attr, strlen(tree->u.simple.attr)); asn1_pop_tag(data); @@ -46,7 +46,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree } /* equality test */ - asn1_push_tag(data, 0xa3); + asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, tree->u.simple.attr, strlen(tree->u.simple.attr)); asn1_write_OctetString(data, tree->u.simple.value.data, @@ -63,37 +63,34 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree dnAttributes [4] BOOLEAN DEFAULT FALSE } */ - asn1_push_tag(data, 0xa9); + asn1_push_tag(data, ASN1_CONTEXT(9)); if (tree->u.extended.rule_id) { - asn1_push_tag(data, 1); - asn1_write_OctetString(data, tree->u.extended.rule_id, - strlen(tree->u.extended.rule_id)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); asn1_pop_tag(data); } if (tree->u.extended.attr) { - asn1_push_tag(data, 2); - asn1_write_OctetString(data, tree->u.extended.attr, - strlen(tree->u.extended.attr)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); asn1_pop_tag(data); } - asn1_push_tag(data, 3); - asn1_write_OctetString(data, tree->u.extended.value.data, - tree->u.extended.value.length); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_LDAPString(data, tree->u.extended.value.data); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); asn1_pop_tag(data); - if (tree->u.extended.dnAttributes) { - asn1_push_tag(data, 4); - asn1_write_BOOLEAN(data, True); - asn1_pop_tag(data); - } asn1_pop_tag(data); break; case LDB_OP_AND: case LDB_OP_OR: - asn1_push_tag(data, 0xa0 | (tree->operation==LDB_OP_AND?0:1)); + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); for (i=0; iu.list.num_elements; i++) { - ldap_push_filter(data, tree->u.list.elements[i]); + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return False; + } } asn1_pop_tag(data); break; @@ -161,7 +158,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) return False; } - asn1_pop_tag(&data); asn1_pop_tag(&data); break; } @@ -187,7 +183,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - ldap_push_filter(&data, r->tree); + if (!ldap_push_filter(&data, r->tree)) { + return False; + } asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -389,6 +387,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } asn1_pop_tag(&data); + + if (data.has_error) { + asn1_free(&data); + return False; + } + *result = data_blob(data.data, data.length); asn1_free(&data); return True; @@ -438,16 +442,14 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, struct asn1_data *data) { - uint8_t filter_tag, tag_desc; + uint8_t filter_tag; struct ldb_parse_tree *ret; if (!asn1_peek_uint8(data, &filter_tag)) { return NULL; } - tag_desc = filter_tag; filter_tag &= 0x1f; /* strip off the asn1 stuff */ - tag_desc &= 0xe0; ret = talloc(mem_ctx, struct ldb_parse_tree); if (ret == NULL) return NULL; @@ -460,11 +462,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->u.list.num_elements = 0; ret->u.list.elements = NULL; - if (tag_desc != 0xa0) { - /* context compount */ - goto failed; - } - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } -- cgit From be19641f30f9a13a38dd08216e1fd22aaaffa9bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 12:48:42 +0000 Subject: r7724: added encoding of LDB_OP_NOT search components (This used to be commit 82b1feeafea57ca1b8d7bf79f777eebcc703769c) --- source4/libcli/ldap/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 81e659d3e8..2514e10117 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -96,7 +96,12 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree break; case LDB_OP_NOT: - #warning "OP_NOT missing" + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.not.child)) { + return False; + } + asn1_pop_tag(data); + break; default: return False; -- cgit From e2bb0d0ba75265101cefd7325d705a7bf63ec585 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 13:15:09 +0000 Subject: r7725: fixed a bug with partial asn1 frames in the ldap client (This used to be commit 0f22306a9c61c1b00aeb0f3bf7e875d9b7b4606d) --- source4/libcli/ldap/ldap_client.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f2b09e89e3..41764b9a37 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -156,6 +156,8 @@ static void ldap_try_decode_plain(struct ldap_connection *conn) /* try and decode - this will fail if we don't have a full packet yet */ while (asn1.ofs < asn1.length) { struct ldap_message *msg = talloc(conn, struct ldap_message); + off_t saved_ofs = asn1.ofs; + if (msg == NULL) { ldap_connection_dead(conn); return; @@ -164,6 +166,7 @@ static void ldap_try_decode_plain(struct ldap_connection *conn) if (ldap_decode(&asn1, msg)) { ldap_match_message(conn, msg); } else { + asn1.ofs = saved_ofs; talloc_free(msg); break; } -- cgit From d52ce8ff0c0546b681f3787728f739c1bb6a71e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 18 Jun 2005 20:32:21 +0000 Subject: r7731: change debug level to not spam the build-farm smbd log metze (This used to be commit 3a1ed83fd0714fa46055c8fe5b039986909f9a45) --- source4/libcli/auth/session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index fda0aab055..b32e1d724d 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -191,7 +191,7 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT sess_crypt_blob(&out, blob, session_key, False); if (IVAL(out.data, 4) != 1) { - DEBUG(0,("Unexpected revision number %d in session crypted secret (BLOB)\n", + DEBUG(2,("Unexpected revision number %d in session crypted secret (BLOB)\n", IVAL(out.data, 4))); return NT_STATUS_UNKNOWN_REVISION; } -- cgit From b773ca709abf1468859110a849e193362d4a2641 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Sat, 18 Jun 2005 22:32:14 +0000 Subject: r7735: Extend resolve_name function so that it's possible to pass resolve methods explicitly or NULL for defaults saved in smb.conf. rafal (This used to be commit 121cf5ec3e075a6e37df52caad9fbc8bf7d59339) --- source4/libcli/resolve/resolve.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index a3bbd60920..0b7c359ca1 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -39,10 +39,11 @@ static const struct resolve_method { const char *name; struct composite_context *(*send_fn)(struct nbt_name *, struct event_context *); NTSTATUS (*recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); + } methods[] = { - { "bcast", resolve_name_bcast_send, resolve_name_bcast_recv }, - { "wins", resolve_name_wins_send, resolve_name_wins_recv }, - { "host", resolve_name_host_send, resolve_name_host_recv } + { "bcast", resolve_name_bcast_send, resolve_name_bcast_recv }, + { "wins", resolve_name_wins_send, resolve_name_wins_recv }, + { "host", resolve_name_host_send, resolve_name_host_recv } }; @@ -115,7 +116,8 @@ static struct composite_context *setup_next_method(struct composite_context *c) /* general name resolution - async send */ -struct composite_context *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx) +struct composite_context *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx, + const char **methods) { struct composite_context *c; struct resolve_state *state; @@ -130,9 +132,15 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ status = nbt_name_dup(state, name, &state->name); if (!NT_STATUS_IS_OK(status)) goto failed; - state->methods = lp_name_resolve_order(); - if (state->methods == NULL) { - return NULL; + /* use default methods from config file if not passed explicitly */ + if (methods == NULL) { + state->methods = lp_name_resolve_order(); + if (state->methods == NULL) { + return NULL; + } + + } else { + state->methods = methods; } c->state = SMBCLI_REQUEST_SEND; @@ -178,7 +186,7 @@ NTSTATUS resolve_name_recv(struct composite_context *c, */ NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct composite_context *c = resolve_name_send(name, NULL); + struct composite_context *c = resolve_name_send(name, NULL, NULL); return resolve_name_recv(c, mem_ctx, reply_addr); } -- cgit From 7a8315bddcada6bca07b9d36775d4c1a5b0f9e88 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Sat, 18 Jun 2005 22:33:07 +0000 Subject: r7736: Propagate change in resolve_name function. Let's use default methods in this case. rafal (This used to be commit b0bae584a4936845732d68aa7d2ccce4411dd1d7) --- source4/libcli/composite/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index fb439172d0..84023f6e3b 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -349,7 +349,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx); + state->creq = resolve_name_send(&name, c->event_ctx, NULL); if (state->creq == NULL) goto failed; state->creq->async.private = c; -- cgit From 68853a1c7be11ffaaef4ad2e3f78a97f0b401b68 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 07:21:18 +0000 Subject: r7746: - added TLS support to our ldap server - this involved changing the buffer handling in the ldap server quite a lot, as it didn't handle partial packets at all - removed completely bogus asn1_object_length() function. You can't do that with BER/DER (This used to be commit fed6f4cc6ceaf83aacb581499aeaf6af4ee8ddd2) --- source4/libcli/util/asn1.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 92f9a8c389..10afd74273 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -387,26 +387,6 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) } -/* Get the length to be expected in buf */ -BOOL asn1_object_length(uint8_t *buf, size_t buf_length, - uint8_t tag, size_t *result) -{ - struct asn1_data data; - - /* Fake the asn1_load to avoid the memdup, this is just to be able to - * re-use the length-reading in asn1_start_tag */ - ZERO_STRUCT(data); - data.data = buf; - data.length = buf_length; - if (!asn1_start_tag(&data, tag)) - return False; - *result = asn1_tag_remaining(&data)+data.ofs; - /* We can't use asn1_end_tag here, as we did not consume the complete - * tag, so asn1_end_tag would flag an error and not free nesting */ - talloc_free(data.nesting); - return True; -} - /* stop reading a tag */ BOOL asn1_end_tag(struct asn1_data *data) { -- cgit From c7496c6cdb7bdcdd483868c21457350f567ec054 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 09:31:34 +0000 Subject: r7747: - simplified the ldap server buffer handling - got rid of the special cases for sasl buffers - added a tls_socket_pending() call to determine how much data is waiting on a tls connection - removed the attempt at async handling of ldap calls. The buffers/sockets are all async, but the calls themselves are sync. (This used to be commit 73cb4aad229d08e17e22d5792580bd43a61b142a) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 41764b9a37..c9915ae140 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -174,7 +174,7 @@ static void ldap_try_decode_plain(struct ldap_connection *conn) /* keep any remaining data in conn->partial */ data_blob_free(&conn->partial); - if (asn1.ofs != conn->partial.length) { + if (asn1.ofs != asn1.length) { conn->partial = data_blob_talloc(conn, asn1.data + asn1.ofs, asn1.length - asn1.ofs); -- cgit From 7267cb3312f148be8cd00eb76b8e137cd4b2a314 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 10:37:45 +0000 Subject: r7749: some bug fixes from testing with socket:testnonblock - fixed some infinite loops in asn1.c - ensure asn1 callers know if an error is end of buffer or bad data - handle npending 0 in ldap server (This used to be commit f22c3b84c8912ccd36e676a782b58f1841be8875) --- source4/libcli/ldap/ldap.c | 5 +++-- source4/libcli/util/asn1.c | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2514e10117..d7a230a77f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -501,7 +501,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->operation = LDB_OP_NOT; ret->u.not.child = ldap_decode_filter_tree(ret, data); - + if (ret->u.not.child == NULL) { + goto failed; + } if (!asn1_end_tag(data)) { goto failed; } @@ -595,7 +597,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, failed: talloc_free(ret); - DEBUG(0,("Failed to parse ASN.1 LDAP filter\n")); return NULL; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 10afd74273..2a4c75d939 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -299,8 +299,12 @@ BOOL asn1_peek(struct asn1_data *data, void *p, int len) if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) return False; - if (data->ofs + len > data->length) + if (data->ofs + len > data->length) { + /* we need to mark the buffer as consumed, so the caller knows + this was an out of data error, and not a decode error */ + data->ofs = data->length; return False; + } memcpy(p, data->data + data->ofs, len); return True; @@ -437,7 +441,7 @@ BOOL asn1_read_OID(struct asn1_data *data, const char **OID) do { asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); - } while (!data->has_error && b & 0x80); + } while (!data->has_error && (b & 0x80)); tmp_oid = talloc_asprintf_append(tmp_oid, " %u", v); } @@ -540,7 +544,7 @@ BOOL asn1_read_implicit_Integer(struct asn1_data *data, int *i) uint8_t b; *i = 0; - while (asn1_tag_remaining(data)>0) { + while (!data->has_error && asn1_tag_remaining(data)>0) { if (!asn1_read_uint8(data, &b)) return False; *i = (*i << 8) + b; } @@ -564,7 +568,7 @@ BOOL asn1_read_enumerated(struct asn1_data *data, int *v) *v = 0; if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; - while (asn1_tag_remaining(data)>0) { + while (!data->has_error && asn1_tag_remaining(data)>0) { uint8_t b; asn1_read_uint8(data, &b); *v = (*v << 8) + b; -- cgit From e578c33c2c8bc23a9a78259613f33b65d7d1668f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 19 Jun 2005 13:26:32 +0000 Subject: r7757: Add NTLMv2 support to the NT1 Session setup (ie, not SPNEGO/NTLMSSP) Session Setup code. Add a mem_ctx argument to a few of the NTLMv2 support functions, and add smb.conf options to control client NTLMv2 behaviour. Andrew Bartlett (This used to be commit 3f35cdb218a3dae08a05e77452ca9f73716ceb28) --- source4/libcli/auth/smbencrypt.c | 35 ++++++++------ source4/libcli/composite/sesssetup.c | 90 +++++++++++++++++++++++------------- 2 files changed, 80 insertions(+), 45 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 3a4a724789..a9a7bb9903 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -324,7 +324,8 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO return response; } -static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], +static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, + const uint8_t ntlm_v2_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob) { @@ -332,7 +333,8 @@ static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], DATA_BLOB ntlmv2_client_data; DATA_BLOB final_response; - TALLOC_CTX *mem_ctx = talloc_init("NTLMv2_generate_response internal context"); + TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0, + "NTLMv2_generate_response internal context"); if (!mem_ctx) { return data_blob(NULL, 0); @@ -346,7 +348,7 @@ static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + final_response = data_blob(out_mem_ctx, sizeof(ntlmv2_response) + ntlmv2_client_data.length); memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); @@ -358,12 +360,13 @@ static DATA_BLOB NTLMv2_generate_response(const uint8_t ntlm_v2_hash[16], return final_response; } -static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], +static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, + const uint8_t ntlm_v2_hash[16], const DATA_BLOB *server_chal) { uint8_t lmv2_response[16]; - DATA_BLOB lmv2_client_data = data_blob(NULL, 8); - DATA_BLOB final_response = data_blob(NULL, 24); + DATA_BLOB lmv2_client_data = data_blob(mem_ctx, 8); + DATA_BLOB final_response = data_blob(mem_ctx, 24); /* LMv2 */ /* client-supplied random data */ @@ -383,7 +386,8 @@ static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16], return final_response; } -BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t nt_hash[16], +BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, + const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, @@ -400,10 +404,11 @@ BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t n } if (nt_response) { - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, + *nt_response = NTLMv2_generate_response(mem_ctx, + ntlm_v2_hash, server_chal, names_blob); if (user_session_key) { - *user_session_key = data_blob(NULL, 16); + *user_session_key = data_blob(mem_ctx, 16); /* The NTLMv2 calculations also provide a session key, for signing etc later */ /* use only the first 16 bytes of nt_response for session key */ @@ -414,9 +419,10 @@ BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t n /* LMv2 */ if (lm_response) { - *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); + *lm_response = LMv2_generate_response(mem_ctx, + ntlm_v2_hash, server_chal); if (lm_session_key) { - *lm_session_key = data_blob(NULL, 16); + *lm_session_key = data_blob(mem_ctx, 16); /* The NTLMv2 calculations also provide a session key, for signing etc later */ /* use only the first 16 bytes of lm_response for session key */ @@ -427,7 +433,9 @@ BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uint8_t n return True; } -BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, +BOOL SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, + const char *user, const char *domain, + const char *password, const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, @@ -436,7 +444,8 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password uint8_t nt_hash[16]; E_md4hash(password, nt_hash); - return SMBNTLMv2encrypt_hash(user, domain, nt_hash, server_chal, names_blob, + return SMBNTLMv2encrypt_hash(mem_ctx, + user, domain, nt_hash, server_chal, names_blob, lm_response, nt_response, lm_session_key, user_session_key); } diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 2736d91262..2a75fb4e20 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -25,7 +25,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "auth/auth.h" - +#include "version.h" struct sesssetup_state { union smb_sesssetup setup; @@ -50,10 +50,10 @@ static DATA_BLOB lanman_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB ch form an encrypted NT password from a plaintext password and the server supplied challenge */ -static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge) +static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const struct samr_Password *nt_hash, DATA_BLOB challenge) { DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBNTencrypt(pass, challenge.data, blob.data); + SMBOWFencrypt(nt_hash->hash, challenge.data, blob.data); return blob; } @@ -68,26 +68,6 @@ static void set_user_session_key(struct smbcli_session *session, session_key->length); } -/* - setup signing for a NT1 style session setup -*/ -static void use_nt1_session_keys(struct smbcli_session *session, - const char *password, const DATA_BLOB *nt_response) -{ - struct smbcli_transport *transport = session->transport; - uint8_t nt_hash[16]; - DATA_BLOB session_key = data_blob_talloc(session, NULL, 16); - - E_md4hash(password, nt_hash); - SMBsesskeygen_ntv1(nt_hash, session_key.data); - - smbcli_transport_simple_set_signing(transport, session_key, *nt_response); - - set_user_session_key(session, &session_key); - data_blob_free(&session_key); -} - - /* handler for completion of a smbcli_request sub-request */ @@ -169,6 +149,7 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, struct smb_composite_sesssetup *io) { struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); + const struct samr_Password *nt_hash = cli_credentials_get_nt_hash(io->in.credentials, state); const char *password = cli_credentials_get_password(io->in.credentials); state->setup.nt1.level = RAW_SESSSETUP_NT1; @@ -178,7 +159,7 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, state->setup.nt1.in.sesskey = io->in.sesskey; state->setup.nt1.in.capabilities = io->in.capabilities; state->setup.nt1.in.os = "Unix"; - state->setup.nt1.in.lanman = "Samba"; + state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials); state->setup.nt1.in.domain = cli_credentials_get_domain(io->in.credentials); @@ -187,14 +168,59 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, state->setup.nt1.in.password2 = data_blob(NULL, 0); } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - state->setup.nt1.in.password1 = lanman_blob(state, password, - session->transport->negotiate.secblob); - state->setup.nt1.in.password2 = nt_blob(state, password, - session->transport->negotiate.secblob); - use_nt1_session_keys(session, password, &state->setup.nt1.in.password2); - } else { + DATA_BLOB session_key; + /* TODO: NTLMv2 in the client session setup */ + if (lp_client_ntlmv2_auth()) { + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_netbios_name(), lp_workgroup()); + DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key; + + /* TODO - test with various domain cases, and without domain */ + if (!SMBNTLMv2encrypt_hash(state, + state->setup.nt1.in.user, state->setup.nt1.in.domain, + nt_hash->hash, &session->transport->negotiate.secblob, + &names_blob, + &lmv2_response, &ntlmv2_response, + &lmv2_session_key, &session_key)) { + data_blob_free(&names_blob); + return NULL; + } + data_blob_free(&names_blob); + state->setup.nt1.in.password1 = lmv2_response; + state->setup.nt1.in.password2 = ntlmv2_response; + + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&lmv2_session_key); + data_blob_free(&session_key); + } else { + + state->setup.nt1.in.password2 = nt_blob(state, nt_hash, + session->transport->negotiate.secblob); + if (lp_client_lanman_auth()) { + state->setup.nt1.in.password1 = lanman_blob(state, password, + session->transport->negotiate.secblob); + } else { + /* if not sending the LM password, send the NT password twice */ + state->setup.nt1.in.password1 = state->setup.nt1.in.password2; + } + + session_key = data_blob_talloc(session, NULL, 16); + SMBsesskeygen_ntv1(nt_hash->hash, session_key.data); + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&session_key); + } + + } else if (lp_client_plaintext_auth()) { state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); + } else { + /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ + return NULL; } return smb_raw_session_setup_send(session, &state->setup); @@ -219,7 +245,7 @@ static struct smbcli_request *session_setup_old(struct composite_context *c, state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); state->setup.old.in.user = cli_credentials_get_username(io->in.credentials); state->setup.old.in.os = "Unix"; - state->setup.old.in.lanman = "Samba"; + state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); if (!password) { state->setup.old.in.password = data_blob(NULL, 0); @@ -256,7 +282,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, state->setup.spnego.in.sesskey = io->in.sesskey; state->setup.spnego.in.capabilities = io->in.capabilities; state->setup.spnego.in.os = "Unix"; - state->setup.spnego.in.lanman = "Samba"; + state->setup.spnego.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); state->setup.spnego.in.workgroup = io->in.workgroup; state->setup.spnego.out.vuid = session->vuid; -- cgit From a40d966ff592436be7014c8a83144c0a5901c1fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 22:29:40 +0000 Subject: r7763: fixed some circular dependencies (This used to be commit 3bdf89b0f7521ca39d48dc4c32fe96971d4d60fd) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 210fb112d3..93665c5152 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -7,6 +7,6 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_msg.o \ libcli/ldap/ldap_ndr.o \ libcli/ldap/ldap_ildap.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBBASIC LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 5eccf719fba324e9f1ce4a5b425b29a25125d4f1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Jun 2005 01:17:29 +0000 Subject: r7770: added ldaps support to our ldap client library (This used to be commit 8f5c2e8682795258a6361b9516a38a8fabdef150) --- source4/libcli/ldap/config.mk | 2 +- source4/libcli/ldap/ldap_client.c | 25 +++++++++++++++++-------- source4/libcli/ldap/ldap_client.h | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 93665c5152..a92e733493 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -7,6 +7,6 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_msg.o \ libcli/ldap/ldap_ndr.o \ libcli/ldap/ldap_ildap.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR LIBTLS # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c9915ae140..32bd6656d6 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -28,6 +28,7 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" +#include "lib/tls/tls.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" @@ -90,8 +91,8 @@ static void ldap_connection_dead(struct ldap_connection *conn) } } - talloc_free(conn->sock); - conn->sock = NULL; + talloc_free(conn->tls); + conn->tls = NULL; } @@ -244,7 +245,7 @@ static void ldap_recv_handler(struct ldap_connection *conn) size_t npending=0, nread; /* work out how much data is pending */ - status = socket_pending(conn->sock, &npending); + status = tls_socket_pending(conn->tls, &npending); if (!NT_STATUS_IS_OK(status) || npending == 0) { ldap_connection_dead(conn); return; @@ -258,8 +259,8 @@ static void ldap_recv_handler(struct ldap_connection *conn) } /* receive the pending data */ - status = socket_recv(conn->sock, conn->partial.data + conn->partial.length, - npending, &nread, 0); + status = tls_socket_recv(conn->tls, conn->partial.data + conn->partial.length, + npending, &nread); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { return; } @@ -288,7 +289,7 @@ static void ldap_send_handler(struct ldap_connection *conn) size_t nsent; NTSTATUS status; - status = socket_send(conn->sock, &req->data, &nsent, 0); + status = tls_socket_send(conn->tls, &req->data, &nsent); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { break; } @@ -331,7 +332,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, struct ldap_connection *conn = talloc_get_type(private, struct ldap_connection); if (flags & EVENT_FD_WRITE) { ldap_send_handler(conn); - if (conn->sock == NULL) return; + if (conn->tls == NULL) return; } if (flags & EVENT_FD_READ) { ldap_recv_handler(conn); @@ -416,6 +417,14 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) return NT_STATUS_INTERNAL_ERROR; } + conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); + if (conn->tls == NULL) { + talloc_free(conn->sock); + return NT_STATUS_INTERNAL_ERROR; + } + talloc_steal(conn, conn->tls); + talloc_steal(conn->tls, conn->sock); + return NT_STATUS_OK; } @@ -460,7 +469,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, { struct ldap_request *req; - if (conn->sock == NULL) { + if (conn->tls == NULL) { return NULL; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 719c3639c1..b61f765b40 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -47,6 +47,7 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { + struct tls_context *tls; struct socket_context *sock; char *host; uint16_t port; -- cgit From bec00581247c9062ea0acce6037ef75ab188548c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Jun 2005 13:42:47 +0000 Subject: r7810: don't give errors when the ldap server sends us reference replies (This used to be commit f2b2d2626f5eb4fbd7d7c5cdcde486d00fc19447) --- source4/libcli/ldap/ldap_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 32bd6656d6..a8463f7872 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -130,7 +130,8 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message req->replies[req->num_replies] = talloc_steal(req->replies, msg); req->num_replies++; - if (msg->type != LDAP_TAG_SearchResultEntry) { + if (msg->type != LDAP_TAG_SearchResultEntry && + msg->type != LDAP_TAG_SearchResultReference) { /* currently only search results expect multiple replies */ req->state = LDAP_REQUEST_DONE; -- cgit From 338bc0f58aef55f4b5820b97b234d2507d1ea236 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 21 Jun 2005 20:18:08 +0000 Subject: r7813: Make async request independent from config file routines. rafal (This used to be commit 84315cdf0d535ed0fe43bfc7cc4c83bc405c2cfb) --- source4/libcli/resolve/resolve.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 0b7c359ca1..b87f9abe89 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -132,16 +132,8 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ status = nbt_name_dup(state, name, &state->name); if (!NT_STATUS_IS_OK(status)) goto failed; - /* use default methods from config file if not passed explicitly */ - if (methods == NULL) { - state->methods = lp_name_resolve_order(); - if (state->methods == NULL) { - return NULL; - } - - } else { - state->methods = methods; - } + if (methods == NULL) goto failed; + state->methods = methods; c->state = SMBCLI_REQUEST_SEND; c->private = state; @@ -186,7 +178,7 @@ NTSTATUS resolve_name_recv(struct composite_context *c, */ NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct composite_context *c = resolve_name_send(name, NULL, NULL); + struct composite_context *c = resolve_name_send(name, NULL, lp_name_resolve_order()); return resolve_name_recv(c, mem_ctx, reply_addr); } -- cgit From 49417aaed7a9e2cc841cad2f418f7f84765cce36 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 21 Jun 2005 20:19:17 +0000 Subject: r7814: Propagate the change in resolve_name_send function. (This used to be commit 7abd634701e2f07ad0497cdbb41467b8911369c7) --- source4/libcli/composite/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 84023f6e3b..b1d2eb2847 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -349,7 +349,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx, NULL); + state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); if (state->creq == NULL) goto failed; state->creq->async.private = c; -- cgit From acd04c9281252f4fe47c7127da13ea25be703c7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Jun 2005 00:03:47 +0000 Subject: r7855: fixed a typo (This used to be commit a1155651e722e28496be02b729c950afae5db9a9) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 7e4fa10fe4..e70a56779b 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -234,7 +234,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } if (NT_STATUS_IS_OK(status) && - (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || + (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL) || gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { conn->enable_wrap = True; } -- cgit From 21d6a163a30d2eac0e048c8ebc02cb48213ac543 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Jun 2005 00:04:26 +0000 Subject: r7856: fixed warning of 'methods' shadowed variable (This used to be commit c435843c66a5dcc003d157374529c3c5ac733e36) --- source4/libcli/resolve/resolve.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index b87f9abe89..3607400155 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -40,7 +40,7 @@ static const struct resolve_method { struct composite_context *(*send_fn)(struct nbt_name *, struct event_context *); NTSTATUS (*recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); -} methods[] = { +} resolve_methods[] = { { "bcast", resolve_name_bcast_send, resolve_name_bcast_recv }, { "wins", resolve_name_wins_send, resolve_name_wins_recv }, { "host", resolve_name_host_send, resolve_name_host_recv } @@ -54,9 +54,9 @@ static const struct resolve_method *find_method(const char *name) { int i; if (name == NULL) return NULL; - for (i=0;i Date: Fri, 24 Jun 2005 00:18:20 +0000 Subject: r7860: switch our ldb storage format to use a NDR encoded objectSid. This is quite a large change as we had lots of code that assumed that objectSid was a string in S- format. metze and simo tried to convince me to use NDR format months ago, but I didn't listen, so its fair that I have the pain of fixing all the code now :-) This builds on the ldb_register_samba_handlers() and ldif handlers code I did earlier this week. There are still three parts of this conversion I have not finished: - the ltdb index records need to use the string form of the objectSid (to keep the DNs sane). Until that it done I have disabled indexing on objectSid, which is a big performance hit, but allows us to pass all our tests while I rejig the indexing system to use a externally supplied conversion function - I haven't yet put in place the code that allows client to use the "S-xxx-yyy" form for objectSid in ldap search expressions. w2k3 supports this, presumably by looking for the "S-" prefix to determine what type of objectSid form is being used by the client. I have been working on ways to handle this, but am not happy with them yet so they aren't part of this patch - I need to change pidl to generate push functions that take a "const void *" instead of a "void*" for the data pointer. That will fix the couple of new warnings this code generates. Luckily it many places the conversion to NDR formatted records actually simplified the code, as it means we no longer need as many calls to dom_sid_parse_talloc(). In some places it got more complex, but not many. (This used to be commit d40bc2fa8ddd43560315688eebdbe98bdd02756c) --- source4/libcli/ldap/ldap_ndr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 88ca1ece77..f490b9983d 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -41,7 +41,7 @@ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) /* encode a NDR dom_sid as a ldap filter element */ -const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) +const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { DATA_BLOB blob; NTSTATUS status; -- cgit From 152a6a00c31f52d14a63bfc977ac54713c56c9cd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Jun 2005 01:18:56 +0000 Subject: r7865: changed pidl to take a "const void *" instead of a "void *" for the structure in ndr_push_*() and ndr_print_*(). The push and print functions really should not modify the structure. metze, to make this work I had to change your spoolss hand marshaller. Can you please check it is OK? I think that the IN and OUT sides of that function are not ever called on the same structure, so I think that attempt at remembering the value by assigning to r->in._offered was not doing anything anyway, but please correct me if I have misunderstood it. If you really do need to remember something on those structures I'd suggest the ndr_token_store() and ndr_token_retrieve() functions, which are used by pidl for just this sort of thing. (This used to be commit eee528be97fa43ca53bdc5652b4d29a0a2caf563) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 0fc679def3..c2fb062025 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -308,7 +308,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name /* push a nbt name to the wire */ -NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name *r) +NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) { uint8_t *cname, *fullname; NTSTATUS status; -- cgit From d6c1ad5c174f3b914927396cf3ec595543289109 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Jun 2005 07:02:39 +0000 Subject: r7941: fixed handling of ASN.1 objects bigger than 64k (This used to be commit f88a6018821163a52bdf384142c7d16f5011ab4e) --- source4/libcli/util/asn1.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 2a4c75d939..6ca2221b1a 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -87,7 +87,16 @@ BOOL asn1_pop_tag(struct asn1_data *data) /* yes, this is ugly. We don't know in advance how many bytes the length of a tag will take, so we assumed 1 byte. If we were wrong then we need to correct our mistake */ - if (len > 255) { + if (len > 0xFFFF) { + data->data[nesting->start] = 0x83; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); + data->data[nesting->start+1] = (len>>16) & 0xFF; + data->data[nesting->start+2] = (len>>8) & 0xFF; + data->data[nesting->start+3] = len&0xff; + } else if (len > 255) { data->data[nesting->start] = 0x82; if (!asn1_write_uint8(data, 0)) return False; if (!asn1_write_uint8(data, 0)) return False; -- cgit From 025e03de549efa47979199adf80b6eef4c8f926b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jun 2005 00:57:15 +0000 Subject: r7970: This SMB signing code (merged from 3.0) turned out to be bogus. Andrew Bartlett (This used to be commit 817160ec1a85724c8bf482f128ea687396de0888) --- source4/libcli/raw/smb_signing.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 4204f3b4dc..14dfc64737 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -118,15 +118,7 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_ /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); - - /* NB. When making and verifying SMB signatures, Windows apparently - zero-pads the key to 128 bits if it isn't long enough. - From Nalin Dahyabhai */ MD5Update(&md5_ctx, mac_key->data, mac_key->length); - if (mac_key->length < sizeof(key_buf)) { - memset(key_buf, 0, sizeof(key_buf)); - MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - mac_key->length); - } MD5Update(&md5_ctx, out->buffer + NBT_HDR_SIZE, out->size - NBT_HDR_SIZE); -- cgit From c58c7c416412fd2ae90427f500b2d94996c36c48 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Jun 2005 01:26:52 +0000 Subject: r8002: favor addresses on our local interfaces in NBT name resolution if possible. This is needed because w2k3 will return bogus IPs in its name resolution replies when it has an unplugged network interface. (This used to be commit 2fafc230520fb5bbe9f763de94aaba87b56f5411) --- source4/libcli/resolve/nbtlist.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index d5b01e06d9..0026c6fceb 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -66,8 +66,21 @@ static void nbtlist_handler(struct nbt_name_request *req) c->state = SMBCLI_REQUEST_ERROR; c->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; } else { + struct nbt_name_query *q = &state->io_queries[i]; c->state = SMBCLI_REQUEST_DONE; - state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addrs[0]); + /* favor a local address if possible */ + state->reply_addr = NULL; + for (i=0;iout.num_addrs;i++) { + if (iface_is_local(q->out.reply_addrs[i])) { + state->reply_addr = talloc_steal(state, + q->out.reply_addrs[i]); + break; + } + } + if (state->reply_addr == NULL) { + state->reply_addr = talloc_steal(state, + q->out.reply_addrs[0]); + } } } -- cgit From 1050a54a3bb125af401f27cf0eb5a0ab51b085ea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Jun 2005 01:34:53 +0000 Subject: r8003: ensure that we don't try to send a trans request with more than 64k data or params (This used to be commit b4f2d17ace6a609ec87da103a89e36edee8903f9) --- source4/libcli/raw/rawtrans.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 118ac5e3fd..b523232bc0 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -216,6 +216,14 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, size_t namelen = 0; uint16_t data_disp, data_length, max_data; + if (parms->in.params.length > UINT16_MAX || + parms->in.data.length > UINT16_MAX) { + DEBUG(3,("Attempt to send invalid trans2 request (params %u, data %u)\n", + parms->in.params.length, parms->in.data.length)); + return NULL; + } + + if (command == SMBtrans) padding = 1; else -- cgit From e0d521ca79314b7c27512565262f614f67e20e64 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 01:23:38 +0000 Subject: r8104: - added support for our client library to not negotiate nt status codes, controlled with 'nt status support' option. - make nt_errstr() display nice strings for dos status codes encoded using NT_STATUS_DOS() - no longer map between dos and nt status codes in the client library, instead return using NT_STATUS_DOS() - fixed the RAW-CONTEXT test to look for NT_STATUS_DOS(ERRSRV, ERRbaduid) instead of NT_STATUS_INVALID_HANDLE (This used to be commit ff5549e87ffae9f062394f30d8fd1ae95b614735) --- source4/libcli/raw/clitransport.c | 21 ++++++++++++++------- source4/libcli/raw/libcliraw.h | 6 +----- source4/libcli/raw/rawnegotiate.c | 6 +++++- source4/libcli/util/clierror.c | 33 ++------------------------------- source4/libcli/util/nterr.c | 19 ++++++++++--------- 5 files changed, 32 insertions(+), 53 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 999795b81e..51a718b10b 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -476,15 +476,22 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) req->flags2 = SVAL(req->in.hdr, HDR_FLG2); if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) { - transport->error.etype = ETYPE_DOS; - transport->error.e.dos.eclass = CVAL(req->in.hdr,HDR_RCLS); - transport->error.e.dos.ecode = SVAL(req->in.hdr,HDR_ERR); - req->status = dos_to_ntstatus(transport->error.e.dos.eclass, - transport->error.e.dos.ecode); + int class = CVAL(req->in.hdr,HDR_RCLS); + int code = SVAL(req->in.hdr,HDR_ERR); + if (class == 0 && code == 0) { + transport->error.e.nt_status = NT_STATUS_OK; + } else { + transport->error.e.nt_status = NT_STATUS_DOS(class, code); + } } else { - transport->error.etype = ETYPE_NT; transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS)); - req->status = transport->error.e.nt_status; + } + + req->status = transport->error.e.nt_status; + if (NT_STATUS_IS_OK(req->status)) { + transport->error.etype = ETYPE_NONE; + } else { + transport->error.etype = ETYPE_SMB; } if (!smbcli_request_check_sign_mac(req)) { diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 2794a22da2..bb13210e74 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -124,12 +124,8 @@ struct smbcli_transport { /* the error fields from the last message */ struct { - enum {ETYPE_NONE, ETYPE_DOS, ETYPE_NT, ETYPE_SOCKET, ETYPE_NBT} etype; + enum {ETYPE_NONE, ETYPE_SMB, ETYPE_SOCKET, ETYPE_NBT} etype; union { - struct { - uint8_t eclass; - uint16_t ecode; - } dos; NTSTATUS nt_status; enum {SOCKET_READ_TIMEOUT, SOCKET_READ_EOF, diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index d2d6b66d59..07b9dd572a 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -174,10 +174,14 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) } /* a way to force ascii SMB */ - if (!lp_unicode() || getenv("SMBCLI_FORCE_ASCII")) { + if (!lp_unicode()) { transport->negotiate.capabilities &= ~CAP_UNICODE; } + if (!lp_nt_status_support()) { + transport->negotiate.capabilities &= ~CAP_STATUS32; + } + failed: return smbcli_request_destroy(req); } diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index 1c82958ce2..52607b1a47 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -29,11 +29,7 @@ const char *smbcli_errstr(struct smbcli_tree *tree) { switch (tree->session->transport->error.etype) { - case ETYPE_DOS: - return dos_errstr( - tree->session->transport->error.e.dos.eclass, - tree->session->transport->error.e.dos.ecode); - case ETYPE_NT: + case ETYPE_SMB: return nt_errstr(tree->session->transport->error.e.nt_status); case ETYPE_SOCKET: @@ -53,13 +49,9 @@ const char *smbcli_errstr(struct smbcli_tree *tree) NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) { switch (tree->session->transport->error.etype) { - case ETYPE_NT: + case ETYPE_SMB: return tree->session->transport->error.e.nt_status; - case ETYPE_DOS: - return dos_to_ntstatus( - tree->session->transport->error.e.dos.eclass, - tree->session->transport->error.e.dos.ecode); case ETYPE_SOCKET: return NT_STATUS_UNSUCCESSFUL; @@ -74,29 +66,8 @@ NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) } -/* Return the DOS error from the last packet - an error class and an error - code. */ -void smbcli_dos_error(struct smbcli_state *cli, uint8_t *eclass, uint32_t *ecode) -{ - if (cli->transport->error.etype == ETYPE_DOS) { - ntstatus_to_dos(cli->transport->error.e.nt_status, - eclass, ecode); - return; - } - - if (eclass) *eclass = cli->transport->error.e.dos.eclass; - if (ecode) *ecode = cli->transport->error.e.dos.ecode; -} - - /* Return true if the last packet was an error */ BOOL smbcli_is_error(struct smbcli_tree *tree) { return NT_STATUS_IS_ERR(smbcli_nt_error(tree)); } - -/* Return true if the last error was a DOS error */ -BOOL smbcli_is_dos_error(struct smbcli_tree *tree) -{ - return tree->session->transport->error.etype == ETYPE_DOS; -} diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index eca47572e3..a5ba1305e4 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -648,9 +648,17 @@ static const nt_err_code_struct nt_err_desc[] = *****************************************************************************/ const char *nt_errstr(NTSTATUS nt_code) { - static fstring msg; + static char msg[40]; int idx = 0; + if (NT_STATUS_IS_DOS(nt_code)) { + return dos_errstr(NT_STATUS_DOS_CLASS(nt_code), + NT_STATUS_DOS_CODE(nt_code)); + } else if (NT_STATUS_IS_LDAP(nt_code)) { + slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); + return msg; + } + while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) { @@ -659,14 +667,7 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } - if (NT_STATUS_IS_DOS(nt_code)) { - slprintf(msg, sizeof(msg), "DOS code %u:%u", - NT_STATUS_DOS_CLASS(nt_code), NT_STATUS_DOS_CODE(nt_code)); - } else if (NT_STATUS_IS_LDAP(nt_code)) { - slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); - } else { - slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); - } + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); return msg; } -- cgit From b3383236a27655227fd20b10252e156aac8e61c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 01:45:52 +0000 Subject: r8106: the use of a static string for dos error codes was causing problems in the torture code. To fix this, get rid of dos_errstr() and instead move the strings into the nt_errstr() table, using cpp to generate the strings (This used to be commit 3136ad9634f0a5ab46e4f83e093df87fdd36484d) --- source4/libcli/config.mk | 1 - source4/libcli/util/nterr.c | 125 +++++++++++++++++++++++++++++- source4/libcli/util/smberr.c | 181 ------------------------------------------- 3 files changed, 121 insertions(+), 186 deletions(-) delete mode 100644 source4/libcli/util/smberr.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 11e54498cf..7779adabaf 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -1,6 +1,5 @@ [SUBSYSTEM::LIBCLI_UTILS] ADD_OBJ_FILES = libcli/util/asn1.o \ - libcli/util/smberr.o \ libcli/util/doserr.o \ libcli/util/errormap.o \ libcli/util/clierror.o \ diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index a5ba1305e4..9bef2cf35c 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -29,6 +29,8 @@ typedef struct NTSTATUS nt_errcode; } nt_err_code_struct; +#define DOS_CODE(class, code) { #class ":" #code, NT_STATUS_DOS(class, code) } + static const nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, @@ -541,6 +543,124 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, + + DOS_CODE(ERRDOS, ERRsuccess), + DOS_CODE(ERRDOS, ERRbadfunc), + DOS_CODE(ERRDOS, ERRbadfile), + DOS_CODE(ERRDOS, ERRbadpath), + DOS_CODE(ERRDOS, ERRnofids), + DOS_CODE(ERRDOS, ERRnoaccess), + DOS_CODE(ERRDOS, ERRbadfid), + DOS_CODE(ERRDOS, ERRbadmcb), + DOS_CODE(ERRDOS, ERRnomem), + DOS_CODE(ERRDOS, ERRbadmem), + DOS_CODE(ERRDOS, ERRbadenv), + DOS_CODE(ERRDOS, ERRbadaccess), + DOS_CODE(ERRDOS, ERRbaddata), + DOS_CODE(ERRDOS, ERRres), + DOS_CODE(ERRDOS, ERRbaddrive), + DOS_CODE(ERRDOS, ERRremcd), + DOS_CODE(ERRDOS, ERRdiffdevice), + DOS_CODE(ERRDOS, ERRnofiles), + DOS_CODE(ERRDOS, ERRgeneral), + DOS_CODE(ERRDOS, ERRbadshare), + DOS_CODE(ERRDOS, ERRlock), + DOS_CODE(ERRDOS, ERRunsup), + DOS_CODE(ERRDOS, ERRnetnamedel), + DOS_CODE(ERRDOS, ERRnosuchshare), + DOS_CODE(ERRDOS, ERRfilexists), + DOS_CODE(ERRDOS, ERRinvalidparam), + DOS_CODE(ERRDOS, ERRcannotopen), + DOS_CODE(ERRDOS, ERRinsufficientbuffer), + DOS_CODE(ERRDOS, ERRinvalidname), + DOS_CODE(ERRDOS, ERRunknownlevel), + DOS_CODE(ERRDOS, ERRnotlocked), + DOS_CODE(ERRDOS, ERRrename), + DOS_CODE(ERRDOS, ERRbadpipe), + DOS_CODE(ERRDOS, ERRpipebusy), + DOS_CODE(ERRDOS, ERRpipeclosing), + DOS_CODE(ERRDOS, ERRnotconnected), + DOS_CODE(ERRDOS, ERRmoredata), + DOS_CODE(ERRDOS, ERRnomoreitems), + DOS_CODE(ERRDOS, ERRbaddirectory), + DOS_CODE(ERRDOS, ERReasnotsupported), + DOS_CODE(ERRDOS, ERRlogonfailure), + DOS_CODE(ERRDOS, ERRbuftoosmall), + DOS_CODE(ERRDOS, ERRunknownipc), + DOS_CODE(ERRDOS, ERRnosuchprintjob), + DOS_CODE(ERRDOS, ERRinvgroup), + DOS_CODE(ERRDOS, ERRnoipc), + DOS_CODE(ERRDOS, ERRdriveralreadyinstalled), + DOS_CODE(ERRDOS, ERRunknownprinterport), + DOS_CODE(ERRDOS, ERRunknownprinterdriver), + DOS_CODE(ERRDOS, ERRunknownprintprocessor), + DOS_CODE(ERRDOS, ERRinvalidseparatorfile), + DOS_CODE(ERRDOS, ERRinvalidjobpriority), + DOS_CODE(ERRDOS, ERRinvalidprintername), + DOS_CODE(ERRDOS, ERRprinteralreadyexists), + DOS_CODE(ERRDOS, ERRinvalidprintercommand), + DOS_CODE(ERRDOS, ERRinvaliddatatype), + DOS_CODE(ERRDOS, ERRinvalidenvironment), + DOS_CODE(ERRDOS, ERRunknownprintmonitor), + DOS_CODE(ERRDOS, ERRprinterdriverinuse), + DOS_CODE(ERRDOS, ERRspoolfilenotfound), + DOS_CODE(ERRDOS, ERRnostartdoc), + DOS_CODE(ERRDOS, ERRnoaddjob), + DOS_CODE(ERRDOS, ERRprintprocessoralreadyinstalled), + DOS_CODE(ERRDOS, ERRprintmonitoralreadyinstalled), + DOS_CODE(ERRDOS, ERRinvalidprintmonitor), + DOS_CODE(ERRDOS, ERRprintmonitorinuse), + DOS_CODE(ERRDOS, ERRprinterhasjobsqueued), + + DOS_CODE(ERRSRV, ERRerror), + DOS_CODE(ERRSRV, ERRbadpw), + DOS_CODE(ERRSRV, ERRbadtype), + DOS_CODE(ERRSRV, ERRaccess), + DOS_CODE(ERRSRV, ERRinvnid), + DOS_CODE(ERRSRV, ERRinvnetname), + DOS_CODE(ERRSRV, ERRinvdevice), + DOS_CODE(ERRSRV, ERRqfull), + DOS_CODE(ERRSRV, ERRqtoobig), + DOS_CODE(ERRSRV, ERRinvpfid), + DOS_CODE(ERRSRV, ERRsmbcmd), + DOS_CODE(ERRSRV, ERRsrverror), + DOS_CODE(ERRSRV, ERRfilespecs), + DOS_CODE(ERRSRV, ERRbadlink), + DOS_CODE(ERRSRV, ERRbadpermits), + DOS_CODE(ERRSRV, ERRbadpid), + DOS_CODE(ERRSRV, ERRsetattrmode), + DOS_CODE(ERRSRV, ERRpaused), + DOS_CODE(ERRSRV, ERRmsgoff), + DOS_CODE(ERRSRV, ERRnoroom), + DOS_CODE(ERRSRV, ERRrmuns), + DOS_CODE(ERRSRV, ERRtimeout), + DOS_CODE(ERRSRV, ERRnoresource), + DOS_CODE(ERRSRV, ERRtoomanyuids), + DOS_CODE(ERRSRV, ERRbaduid), + DOS_CODE(ERRSRV, ERRuseMPX), + DOS_CODE(ERRSRV, ERRuseSTD), + DOS_CODE(ERRSRV, ERRcontMPX), + DOS_CODE(ERRSRV, ERRnosupport), + DOS_CODE(ERRSRV, ERRunknownsmb), + + DOS_CODE(ERRHRD, ERRnowrite), + DOS_CODE(ERRHRD, ERRbadunit), + DOS_CODE(ERRHRD, ERRnotready), + DOS_CODE(ERRHRD, ERRbadcmd), + DOS_CODE(ERRHRD, ERRdata), + DOS_CODE(ERRHRD, ERRbadreq), + DOS_CODE(ERRHRD, ERRseek), + DOS_CODE(ERRHRD, ERRbadmedia), + DOS_CODE(ERRHRD, ERRbadsector), + DOS_CODE(ERRHRD, ERRnopaper), + DOS_CODE(ERRHRD, ERRwrite), + DOS_CODE(ERRHRD, ERRread), + DOS_CODE(ERRHRD, ERRgeneral), + DOS_CODE(ERRHRD, ERRwrongdisk), + DOS_CODE(ERRHRD, ERRFCBunavail), + DOS_CODE(ERRHRD, ERRsharebufexc), + DOS_CODE(ERRHRD, ERRdiskfull), + { NULL, NT_STATUS(0) } }; @@ -651,10 +771,7 @@ const char *nt_errstr(NTSTATUS nt_code) static char msg[40]; int idx = 0; - if (NT_STATUS_IS_DOS(nt_code)) { - return dos_errstr(NT_STATUS_DOS_CLASS(nt_code), - NT_STATUS_DOS_CODE(nt_code)); - } else if (NT_STATUS_IS_LDAP(nt_code)) { + if (NT_STATUS_IS_LDAP(nt_code)) { slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); return msg; } diff --git a/source4/libcli/util/smberr.c b/source4/libcli/util/smberr.c deleted file mode 100644 index 87cc601b8d..0000000000 --- a/source4/libcli/util/smberr.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) Andrew Tridgell 1998-2003 - - 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" - -/* - error code stuff - put together by Merik Karman - merik@blackadder.dsh.oz.au -*/ - -struct err_code_struct { - const char *name; - int code; - const char *message; -}; - -/* Dos Error Messages */ -static const struct err_code_struct dos_msgs[] = { - {"ERRbadfunc",ERRbadfunc,"Invalid function."}, - {"ERRbadfile",ERRbadfile,"File not found."}, - {"ERRbadpath",ERRbadpath,"Directory invalid."}, - {"ERRnofids",ERRnofids,"No file descriptors available"}, - {"ERRnoaccess",ERRnoaccess,"Access denied."}, - {"ERRbadfid",ERRbadfid,"Invalid file handle."}, - {"ERRbadmcb",ERRbadmcb,"Memory control blocks destroyed."}, - {"ERRnomem",ERRnomem,"Insufficient server memory to perform the requested function."}, - {"ERRbadmem",ERRbadmem,"Invalid memory block address."}, - {"ERRbadenv",ERRbadenv,"Invalid environment."}, - {"ERRbadformat",11,"Invalid format."}, - {"ERRbadaccess",ERRbadaccess,"Invalid open mode."}, - {"ERRbaddata",ERRbaddata,"Invalid data."}, - {"ERRres",ERRres,"reserved."}, - {"ERRbaddrive",ERRbaddrive,"Invalid drive specified."}, - {"ERRremcd",ERRremcd,"A Delete Directory request attempted to remove the server's current directory."}, - {"ERRdiffdevice",ERRdiffdevice,"Not same device."}, - {"ERRnofiles",ERRnofiles,"A File Search command can find no more files matching the specified criteria."}, - {"ERRbadshare",ERRbadshare,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, - {"ERRlock",ERRlock,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRunsup", ERRunsup, "The operation is unsupported"}, - {"ERRnosuchshare", ERRnosuchshare, "You specified an invalid share name"}, - {"ERRfilexists",ERRfilexists,"The file named in a Create Directory, Make New File or Link request already exists."}, - {"ERRinvalidname",ERRinvalidname, "Invalid name"}, - {"ERRbadpipe",ERRbadpipe,"Pipe invalid."}, - {"ERRpipebusy",ERRpipebusy,"All instances of the requested pipe are busy."}, - {"ERRpipeclosing",ERRpipeclosing,"Pipe close in progress."}, - {"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."}, - {"ERRmoredata",ERRmoredata,"There is more data to be returned."}, - {"ERRinvgroup",ERRinvgroup,"Invalid workgroup (try the -W option)"}, - {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, - {"ERRdiskfull",ERRdiskfull,"Disk full"}, - {"ERRgeneral",ERRgeneral, "General failure"}, - {"ERRunknownlevel",ERRunknownlevel, "Unknown info level"}, - {NULL,-1,NULL}}; - -/* Server Error Messages */ -static const struct err_code_struct server_msgs[] = { - {"ERRerror",1,"Non-specific error code."}, - {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, - {"ERRbadtype",3,"reserved."}, - {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, - {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, - {"ERRinvnetname",6,"Invalid network name in tree connect."}, - {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, - {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, - {"ERRqtoobig",50,"Print queue full -- no space."}, - {"ERRqeof",51,"EOF on print queue dump."}, - {"ERRinvpfid",52,"Invalid print file FID."}, - {"ERRsmbcmd",64,"The server did not recognize the command received."}, - {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, - {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, - {"ERRreserved",68,"reserved."}, - {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, - {"ERRreserved",70,"reserved."}, - {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, - {"ERRpaused",81,"Server is paused."}, - {"ERRmsgoff",82,"Not receiving messages."}, - {"ERRnoroom",83,"No room to buffer message."}, - {"ERRrmuns",87,"Too many remote user names."}, - {"ERRtimeout",88,"Operation timed out."}, - {"ERRnoresource",89,"No resources currently available for request."}, - {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, - {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, - {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, - {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, - {"ERRcontmpx",252,"Continue in MPX mode."}, - {"ERRreserved",253,"reserved."}, - {"ERRreserved",254,"reserved."}, - {"ERRnosupport",0xFFFF,"Function not supported."}, - {NULL,-1,NULL}}; - -/* Hard Error Messages */ -static const struct err_code_struct hard_msgs[] = { - {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, - {"ERRbadunit",20,"Unknown unit."}, - {"ERRnotready",21,"Drive not ready."}, - {"ERRbadcmd",22,"Unknown command."}, - {"ERRdata",23,"Data error (CRC)."}, - {"ERRbadreq",24,"Bad request structure length."}, - {"ERRseek",25 ,"Seek error."}, - {"ERRbadmedia",26,"Unknown media type."}, - {"ERRbadsector",27,"Sector not found."}, - {"ERRnopaper",28,"Printer out of paper."}, - {"ERRwrite",29,"Write fault."}, - {"ERRread",30,"Read fault."}, - {"ERRgeneral",31,"General failure."}, - {"ERRbadshare",32,"An open conflicts with an existing open."}, - {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, - {"ERRFCBUnavail",35,"No FCBs are available to process request."}, - {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, - {NULL,-1,NULL}}; - - -static const struct { - uint8_t class; - const char *class_name; - const struct err_code_struct *err_msgs; -} err_classes[] = { - {0,"SUCCESS",NULL}, - {0x01,"ERRDOS",dos_msgs}, - {0x02,"ERRSRV",server_msgs}, - {0x03,"ERRHRD",hard_msgs}, - {0x04,"ERRXOS",NULL}, - {0xE1,"ERRRMX1",NULL}, - {0xE2,"ERRRMX2",NULL}, - {0xE3,"ERRRMX3",NULL}, - {0xFF,"ERRCMD",NULL}, - {-1,NULL,NULL}}; - - -/* return a dos error string given a error class and error code */ -const char *dos_errstr(uint8_t class, uint16_t code) -{ - static char *msg; - int i, j; - const struct err_code_struct *err_msgs; - - if (msg) { - free(msg); - msg = NULL; - } - - for (i=0;err_classes[i].class_name;i++) { - if (class == err_classes[i].class) break; - } - if (!err_classes[i].class_name) { - asprintf(&msg, "Unknown DOS error %d:%d\n", class, code); - return msg; - } - - err_msgs = err_classes[i].err_msgs; - - for (j=0;err_msgs && err_msgs[j].name;j++) { - if (err_msgs[j].code == code) { - asprintf(&msg, "%s:%s (%s)\n", - err_classes[i].class_name, - err_msgs[j].name, - err_msgs[j].message); - return msg; - } - } - - asprintf(&msg, "Unknown DOS error %s:%d\n", err_classes[i].class_name, code); - return msg; -} -- cgit From 950f6624842628b770bf58424f3b2ab9a7036263 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 02:54:32 +0000 Subject: r8111: fixed the client library to work against w2k3 with nt status codes disabled. The main change is to turn off spnego, which cannot work at all without nt status codes (w2k3 gives a ERRHRD:ERRgeneral error when you try) I also modified NT_STATUS_EQUAL() to allow for nt->dos code equality, but only when nt status codes are disabled in smb.conf. That keeps all the existing torture code working, while still allowing us to correctly catch the cases where forced dos error codes are needed The dos->ntstatus mapping table has been removed completely, as it doesn't really make sense, is impossible to get right, and with the new dos status handling isn't needed. When matching a nt status code to a dos status code it makes far more sense to map from the nt code to the dos code and compare, rather than the reverse, as the nt->dos mapping is what windows has to do internally, so there really is a valid mapping table. (This used to be commit f21274e07b361ef40fdc0fe23e96f1c9c63a091c) --- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/util/errormap.c | 300 ++++---------------------------------- 2 files changed, 31 insertions(+), 271 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 51a718b10b..f286eff0ea 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -76,7 +76,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->socket = talloc_reference(transport, sock); } transport->negotiate.protocol = PROTOCOL_NT1; - transport->options.use_spnego = lp_use_spnego(); + transport->options.use_spnego = lp_use_spnego() && lp_nt_status_support(); transport->options.max_xmit = lp_max_xmit(); transport->options.max_mux = lp_maxmux(); transport->options.request_timeout = SMB_REQUEST_TIMEOUT; diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index b99ab3d2fe..76400c98a3 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -117,7 +117,7 @@ static const struct { {ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, - {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, @@ -612,262 +612,6 @@ static const struct { }; -/* dos -> nt status error map */ -static const struct { - uint8_t dos_class; - uint32_t dos_code; - NTSTATUS ntstatus; -} dos_to_ntstatus_map[] = { - {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, - {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, - {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, - {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, - {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, - {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, - {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, - {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, - {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, - {ERRDOS, ERRbaddata, NT_STATUS_DATA_ERROR}, - {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, - {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, - {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, - {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, - {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, - {ERRDOS, 23, NT_STATUS_DATA_ERROR}, - {ERRDOS, 24, NT_STATUS_DATA_ERROR}, - {ERRDOS, 26, NT_STATUS_DISK_CORRUPT_ERROR}, - {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, - {ERRDOS, 28, NT_STATUS(0x8000000e)}, - {ERRDOS, 31, NT_STATUS_UNSUCCESSFUL}, - {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, - {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, - {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, - {ERRDOS, 38, NT_STATUS_END_OF_FILE}, - {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, - {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, - {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, - {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, - {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, - {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, - {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, - {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, - {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, - {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, - {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, - {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, - {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, - {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, - {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, - {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, - {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, - {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, - {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, - {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, - {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, - {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD}, - {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, - {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, - {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, - {ERRDOS, 111, STATUS_MORE_ENTRIES}, - {ERRDOS, 112, NT_STATUS_DISK_FULL}, - {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, - {ERRDOS, 122, NT_STATUS_BUFFER_TOO_SMALL}, - {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, - {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, - {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, - {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, - {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, - {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, - {ERRDOS, 170, NT_STATUS(0x80000011)}, - {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, - {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, - {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, - {ERRDOS, 203, NT_STATUS(0xc0000100)}, - {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_INFO_CLASS}, - {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, - {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, - {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, - {ERRDOS, ERRmoredata, NT_STATUS_MORE_PROCESSING_REQUIRED}, - {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, - {ERRDOS, 254, NT_STATUS(0x80000013)}, - {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, - {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, - {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, - {ERRDOS, 275, NT_STATUS_EA_TOO_LARGE}, - {ERRDOS, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRDOS, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRDOS, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, - {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, - {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, - {ERRDOS, 299, NT_STATUS(0x8000000d)}, - {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, - {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, - {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, - {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, - {ERRDOS, 535, NT_STATUS_PIPE_CONNECTED}, - {ERRDOS, 536, NT_STATUS_PIPE_LISTENING}, - {ERRDOS, 995, NT_STATUS_CANCELLED}, - {ERRDOS, 997, NT_STATUS(0x00000103)}, - {ERRDOS, 998, NT_STATUS_ACCESS_VIOLATION}, - {ERRDOS, 999, NT_STATUS_IN_PAGE_ERROR}, - {ERRDOS, 1001, NT_STATUS_BAD_INITIAL_STACK}, - {ERRDOS, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, - {ERRDOS, 1006, NT_STATUS_FILE_INVALID}, - {ERRDOS, 1007, NT_STATUS_FULLSCREEN_MODE}, - {ERRDOS, 1008, NT_STATUS_NO_TOKEN}, - {ERRDOS, 1009, NT_STATUS_REGISTRY_CORRUPT}, - {ERRDOS, 1016, NT_STATUS_REGISTRY_IO_FAILED}, - {ERRDOS, 1017, NT_STATUS_NOT_REGISTRY_FILE}, - {ERRDOS, 1018, NT_STATUS_KEY_DELETED}, - {ERRDOS, 1019, NT_STATUS_NO_LOG_SPACE}, - {ERRDOS, 1020, NT_STATUS_KEY_HAS_CHILDREN}, - {ERRDOS, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, - {ERRDOS, 1022, NT_STATUS(0x0000010c)}, - {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, - {ERRSRV, ERRbadtype, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRSRV, ERRaccess, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRSRV, ERRinvnid, NT_STATUS_NETWORK_NAME_DELETED}, - {ERRSRV, ERRinvnetname, NT_STATUS_BAD_NETWORK_NAME}, - {ERRSRV, ERRinvdevice, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRSRV, ERRqfull, NT_STATUS_PRINT_QUEUE_FULL}, - {ERRSRV, ERRqtoobig, NT_STATUS_NO_SPOOL_SPACE}, - {ERRSRV, ERRinvpfid, NT_STATUS_PRINT_CANCELLED}, - {ERRSRV, ERRsmbcmd, NT_STATUS_NOT_IMPLEMENTED}, - {ERRSRV, ERRbadpermits, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRSRV, ERRpaused, NT_STATUS_SHARING_PAUSED}, - {ERRSRV, ERRmsgoff, NT_STATUS_REQUEST_NOT_ACCEPTED}, - {ERRSRV, ERRnoroom, NT_STATUS_DISK_FULL}, - {ERRSRV, ERRnoresource, NT_STATUS_REQUEST_NOT_ACCEPTED}, - {ERRSRV, ERRtoomanyuids, NT_STATUS_TOO_MANY_SESSIONS}, - {ERRSRV, ERRbaduid, NT_STATUS_INVALID_HANDLE}, - {ERRSRV, 123, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRSRV, 206, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRHRD, 1, NT_STATUS_NOT_IMPLEMENTED}, - {ERRHRD, 2, NT_STATUS_NO_SUCH_DEVICE}, - {ERRHRD, 3, NT_STATUS_OBJECT_PATH_NOT_FOUND}, - {ERRHRD, 4, NT_STATUS_TOO_MANY_OPENED_FILES}, - {ERRHRD, 5, NT_STATUS_INVALID_LOCK_SEQUENCE}, - {ERRHRD, 6, NT_STATUS_INVALID_HANDLE}, - {ERRHRD, 8, NT_STATUS_INSUFFICIENT_RESOURCES}, - {ERRHRD, 12, NT_STATUS_INVALID_LOCK_SEQUENCE}, - {ERRHRD, 13, NT_STATUS_DATA_ERROR}, - {ERRHRD, 14, NT_STATUS_SECTION_NOT_EXTENDED}, - {ERRHRD, 16, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRHRD, 17, NT_STATUS_NOT_SAME_DEVICE}, - {ERRHRD, 18, NT_STATUS(0x80000006)}, - {ERRHRD, ERRnowrite, NT_STATUS_MEDIA_WRITE_PROTECTED}, - {ERRHRD, ERRnotready, NT_STATUS_NO_MEDIA_IN_DEVICE}, - {ERRHRD, ERRbadcmd, NT_STATUS_INVALID_DEVICE_STATE}, - {ERRHRD, ERRdata, NT_STATUS_DATA_ERROR}, - {ERRHRD, ERRbadreq, NT_STATUS_DATA_ERROR}, - {ERRHRD, ERRbadmedia, NT_STATUS_DISK_CORRUPT_ERROR}, - {ERRHRD, ERRbadsector, NT_STATUS_NONEXISTENT_SECTOR}, - {ERRHRD, ERRnopaper, NT_STATUS(0x8000000e)}, - {ERRHRD, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, - {ERRHRD, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, - {ERRHRD, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, - {ERRHRD, ERRwrongdisk, NT_STATUS_WRONG_VOLUME}, - {ERRHRD, 38, NT_STATUS_END_OF_FILE}, - {ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL}, - {ERRHRD, 50, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, - {ERRHRD, 51, NT_STATUS_REMOTE_NOT_LISTENING}, - {ERRHRD, 52, NT_STATUS_DUPLICATE_NAME}, - {ERRHRD, 53, NT_STATUS_BAD_NETWORK_PATH}, - {ERRHRD, 54, NT_STATUS_NETWORK_BUSY}, - {ERRHRD, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, - {ERRHRD, 56, NT_STATUS_TOO_MANY_COMMANDS}, - {ERRHRD, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, - {ERRHRD, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, - {ERRHRD, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, - {ERRHRD, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, - {ERRHRD, 61, NT_STATUS_PRINT_QUEUE_FULL}, - {ERRHRD, 62, NT_STATUS_NO_SPOOL_SPACE}, - {ERRHRD, 63, NT_STATUS_PRINT_CANCELLED}, - {ERRHRD, 64, NT_STATUS_NETWORK_NAME_DELETED}, - {ERRHRD, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRHRD, 66, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRHRD, 67, NT_STATUS_BAD_NETWORK_NAME}, - {ERRHRD, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, - {ERRHRD, 69, NT_STATUS_TOO_MANY_SESSIONS}, - {ERRHRD, 70, NT_STATUS_SHARING_PAUSED}, - {ERRHRD, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, - {ERRHRD, 72, NT_STATUS_REDIRECTOR_PAUSED}, - {ERRHRD, 80, NT_STATUS_OBJECT_NAME_COLLISION}, - {ERRHRD, 86, NT_STATUS_WRONG_PASSWORD}, - {ERRHRD, 87, NT_STATUS_INVALID_INFO_CLASS}, - {ERRHRD, 88, NT_STATUS_NET_WRITE_FAULT}, - {ERRHRD, 109, NT_STATUS_PIPE_BROKEN}, - {ERRHRD, 111, STATUS_MORE_ENTRIES}, - {ERRHRD, 112, NT_STATUS_DISK_FULL}, - {ERRHRD, 121, NT_STATUS_IO_TIMEOUT}, - {ERRHRD, 122, NT_STATUS_BUFFER_TOO_SMALL}, - {ERRHRD, 123, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRHRD, 124, NT_STATUS_INVALID_LEVEL}, - {ERRHRD, 126, NT_STATUS_DLL_NOT_FOUND}, - {ERRHRD, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, - {ERRHRD, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRHRD, 154, NT_STATUS_INVALID_VOLUME_LABEL}, - {ERRHRD, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, - {ERRHRD, 158, NT_STATUS_NOT_LOCKED}, - {ERRHRD, 161, NT_STATUS_OBJECT_PATH_INVALID}, - {ERRHRD, 170, NT_STATUS(0x80000011)}, - {ERRHRD, 182, NT_STATUS_ORDINAL_NOT_FOUND}, - {ERRHRD, 183, NT_STATUS_OBJECT_NAME_COLLISION}, - {ERRHRD, 193, NT_STATUS_BAD_INITIAL_PC}, - {ERRHRD, 203, NT_STATUS(0xc0000100)}, - {ERRHRD, 206, NT_STATUS_NAME_TOO_LONG}, - {ERRHRD, 230, NT_STATUS_INVALID_INFO_CLASS}, - {ERRHRD, 231, NT_STATUS_INSTANCE_NOT_AVAILABLE}, - {ERRHRD, 232, NT_STATUS_PIPE_CLOSING}, - {ERRHRD, 233, NT_STATUS_PIPE_DISCONNECTED}, - {ERRHRD, 234, STATUS_MORE_ENTRIES}, - {ERRHRD, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, - {ERRHRD, 254, NT_STATUS(0x80000013)}, - {ERRHRD, 255, NT_STATUS_EA_TOO_LARGE}, - {ERRHRD, 259, NT_STATUS_GUIDS_EXHAUSTED}, - {ERRHRD, 267, NT_STATUS_NOT_A_DIRECTORY}, - {ERRHRD, 275, NT_STATUS_EA_TOO_LARGE}, - {ERRHRD, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRHRD, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRHRD, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRHRD, 282, NT_STATUS_EAS_NOT_SUPPORTED}, - {ERRHRD, 288, NT_STATUS_MUTANT_NOT_OWNED}, - {ERRHRD, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, - {ERRHRD, 299, NT_STATUS(0x8000000d)}, - {ERRHRD, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, - {ERRHRD, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, - {ERRHRD, 487, NT_STATUS_CONFLICTING_ADDRESSES}, - {ERRHRD, 534, NT_STATUS_INTEGER_OVERFLOW}, - {ERRHRD, 535, NT_STATUS_PIPE_CONNECTED}, - {ERRHRD, 536, NT_STATUS_PIPE_LISTENING}, - {ERRHRD, 995, NT_STATUS_CANCELLED}, - {ERRHRD, 997, NT_STATUS(0x00000103)}, - {ERRHRD, 998, NT_STATUS_ACCESS_VIOLATION}, - {ERRHRD, 999, NT_STATUS_IN_PAGE_ERROR}, - {ERRHRD, 1001, NT_STATUS_BAD_INITIAL_STACK}, - {ERRHRD, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, - {ERRHRD, 1006, NT_STATUS_FILE_INVALID}, - {ERRHRD, 1007, NT_STATUS_FULLSCREEN_MODE}, - {ERRHRD, 1008, NT_STATUS_NO_TOKEN}, - {ERRHRD, 1009, NT_STATUS_REGISTRY_CORRUPT}, - {ERRHRD, 1016, NT_STATUS_REGISTRY_IO_FAILED}, - {ERRHRD, 1017, NT_STATUS_NOT_REGISTRY_FILE}, - {ERRHRD, 1018, NT_STATUS_KEY_DELETED}, - {ERRHRD, 1019, NT_STATUS_NO_LOG_SPACE}, - {ERRHRD, 1020, NT_STATUS_KEY_HAS_CHILDREN}, - {ERRHRD, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, - {ERRHRD, 1022, NT_STATUS(0x0000010c)}, -}; - /* errmap NTSTATUS->Win32 */ static const struct { NTSTATUS ntstatus; @@ -1410,22 +1154,38 @@ static const struct { {NT_STATUS_OK, WERR_OK}}; -/***************************************************************************** -convert a dos eclas/ecode to a NT status32 code - *****************************************************************************/ -NTSTATUS dos_to_ntstatus(uint8_t eclass, uint32_t ecode) +/* + check if a DOS encoded NTSTATUS code maps to the given NTSTATUS code +*/ +BOOL ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2) { - int i; - if (eclass == 0 && ecode == 0) return NT_STATUS_OK; - for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) { - if (eclass == dos_to_ntstatus_map[i].dos_class && - ecode == dos_to_ntstatus_map[i].dos_code) { - return dos_to_ntstatus_map[i].ntstatus; - } + /* when we negotiate nt status support, we don't want to consider + the mapping of dos codes, as we want to catch the cases where + a forced dos code is needed + */ + if (lp_nt_status_support()) { + return NT_STATUS_V(status1) == NT_STATUS_V(status2); } - return NT_STATUS_UNSUCCESSFUL; -} + /* otherwise check if the mapping comes out right. Note that it is important + that we do the mapping only from ntstatus -> dos and not from dos -> ntstatus, + as that is the mapping that servers must do */ + if (!NT_STATUS_IS_DOS(status1) && NT_STATUS_IS_DOS(status2)) { + uint8_t eclass; + uint32_t ecode; + ntstatus_to_dos(status1, &eclass, &ecode); + return eclass == NT_STATUS_DOS_CLASS(status2) && + ecode == NT_STATUS_DOS_CODE(status2); + } + if (NT_STATUS_IS_DOS(status1) && !NT_STATUS_IS_DOS(status2)) { + uint8_t eclass; + uint32_t ecode; + ntstatus_to_dos(status2, &eclass, &ecode); + return eclass == NT_STATUS_DOS_CLASS(status1) && + ecode == NT_STATUS_DOS_CODE(status1); + } + return NT_STATUS_V(status1) == NT_STATUS_V(status2); +} /***************************************************************************** convert a NT status code to a dos class/code -- cgit From 934831686c2bde9bdd9fbb050ac10341b32c83fa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 05:01:22 +0000 Subject: r8115: added support for 2 more dos error codes found during testing (This used to be commit 97cb70571377e3b4e5eb0b7ca516e4af349fdfea) --- source4/libcli/util/nterr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 9bef2cf35c..65de6a72b4 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -575,6 +575,8 @@ static const nt_err_code_struct nt_errs[] = DOS_CODE(ERRDOS, ERRinvalidname), DOS_CODE(ERRDOS, ERRunknownlevel), DOS_CODE(ERRDOS, ERRnotlocked), + DOS_CODE(ERRDOS, ERRcancelviolation), + DOS_CODE(ERRDOS, ERRnoatomiclocks), DOS_CODE(ERRDOS, ERRrename), DOS_CODE(ERRDOS, ERRbadpipe), DOS_CODE(ERRDOS, ERRpipebusy), -- cgit From 65ae28dfa714d1f4b1006093f65ec3f9d904ebb9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 05:55:32 +0000 Subject: r8125: fixed an error code mapping based on the updated torture tests (This used to be commit a3b8a00d7f67da5bc1187ce271a8df1601411dbc) --- source4/libcli/util/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 76400c98a3..808f5427c6 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -66,7 +66,7 @@ static const struct { {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, - {ERRDOS, ERRnofiles, NT_STATUS_NO_SUCH_FILE}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, {ERRDOS, 38, NT_STATUS_END_OF_FILE}, {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, -- cgit From cf601f71aad8e5007e8ec8ac9b455ccd7bda4432 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Jul 2005 10:26:25 +0000 Subject: r8134: remove unused var metze (This used to be commit f308b72b19ab1e0e2f5a732bd1bc13082a634a9c) --- source4/libcli/raw/smb_signing.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 14dfc64737..df63c33cb9 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -104,7 +104,6 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_ { uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; - uint8_t key_buf[16]; /* * Firstly put the sequence number into the first 4 bytes. -- cgit From 3de3d6a02dfb790af21f6c848a202064922ea780 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Jul 2005 03:13:17 +0000 Subject: r8174: Check DOS error codes in torture chkpath test. Jeremy. (This used to be commit ff58ecad044dc7a3cdb4c010ea5cc1ea5e2e4b3b) --- source4/libcli/util/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 65de6a72b4..b7e3bcabde 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -575,6 +575,7 @@ static const nt_err_code_struct nt_errs[] = DOS_CODE(ERRDOS, ERRinvalidname), DOS_CODE(ERRDOS, ERRunknownlevel), DOS_CODE(ERRDOS, ERRnotlocked), + DOS_CODE(ERRDOS, ERRinvalidpath), DOS_CODE(ERRDOS, ERRcancelviolation), DOS_CODE(ERRDOS, ERRnoatomiclocks), DOS_CODE(ERRDOS, ERRrename), -- cgit From e296c8de6e57a321116f01135c5c6fcf215245a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Jul 2005 19:49:35 +0000 Subject: r8212: fix pushing of nbt_string's: - we now use an ndr_token_list, for the nbt string label pointer offsets this avoids to scan the whole buffer - we need to check for already send string on a per component basis not only for the fullname e.g. w2k3 response this in the CLDAP netlogon replies forest: w2k3.vmnet1.vm.base dns_name: sub1. pdc_dns_name: w2k3-104. and this will be interpreted like forest: w2k3.vmnet1.vm.base dns_name: sub1.w2k3.vmnet1.vm.base pdc_dns_name: w2k3-104.w2k3.vmnet1.vm.base metze (This used to be commit d18303a0e27643285ffaf100eeddea2f9555c9db) --- source4/libcli/nbt/nbtname.c | 84 ++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 35 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index c2fb062025..205567a55b 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -136,53 +136,67 @@ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s */ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) { - int i; - int fulllen; - char *fullname; - if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - if (s == NULL || *s == 0) { - return ndr_push_bytes(ndr, "", 1); - } + while (s && *s) { + NTSTATUS status; + char *compname; + size_t complen; + uint32_t offset; + + /* see if we have pushed the remaing string allready, + * if so we use a label pointer to this string + */ + status = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, False); + if (NT_STATUS_IS_OK(status)) { + uint8_t b[2]; + + if (offset > 0x3FFF) { + return ndr_push_error(ndr, NDR_ERR_STRING, + "offset for nbt string label pointer %u[%08X] > 0x00003FFF", + offset, offset); + } + b[0] = 0xC0 | (offset>>8); + b[1] = (offset & 0xFF); - fullname = talloc_strdup(ndr, ""); - NT_STATUS_HAVE_NO_MEMORY(fullname); + return ndr_push_bytes(ndr, b, 2); + } - while (*s) { - int len = strcspn(s, "."); - fullname = talloc_asprintf_append(fullname, "%c%*.*s", - (unsigned char)len, - (unsigned char)len, - (unsigned char)len, s); - NT_STATUS_HAVE_NO_MEMORY(fullname); - s += len; - if (*s == '.') s++; - } + complen = strcspn(s, "."); - /* see if we can find the fullname in the existing packet - if - so, we can use a NBT name pointer. This allows us to fit - longer names into the packet */ - fulllen = strlen(fullname)+1; - for (i=0;i + fulllen <= ndr->offset;i++) { - if (ndr->data[i] == fullname[0] && - memcmp(fullname, &ndr->data[i], fulllen) == 0) { - uint8_t b[2]; - talloc_free(fullname); - b[0] = 0xC0 | (i>>8); - b[1] = (i&0xFF); - return ndr_push_bytes(ndr, b, 2); + /* we need to make sure the length fits into 6 bytes */ + if (complen >= 0x3F) { + return ndr_push_error(ndr, NDR_ERR_STRING, + "component length %u[%08X] > 0x00003F", + complen, complen); } - } - NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen)); + compname = talloc_asprintf(ndr, "%c%*.*s", + (unsigned char)complen, + (unsigned char)complen, + (unsigned char)complen, s); + NT_STATUS_HAVE_NO_MEMORY(compname); - talloc_free(fullname); + /* remember the current componemt + the rest of the string + * so it can be reused later + */ + NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset)); - return NT_STATUS_OK; + /* push just this component into the blob */ + NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1)); + talloc_free(compname); + + s += complen; + if (*s == '.') s++; + } + + /* if we reach the end of the string and have pushed the last component + * without using a label pointer, we need to terminate the string + */ + return ndr_push_bytes(ndr, (const uint8_t *)"", 1); } -- cgit From bde98850be7d7868c59597012e3366cf14fd0169 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Jul 2005 01:53:57 +0000 Subject: r8247: remove the free of fullname in nbtname.c for now. Metze, the ndr_token_store() code is storing temporary pointers into this string in the token list, which means we are referring to freed memory when we scan the token list. A better key might be a pointer into the ndr buffer? (This used to be commit 6a4e8cc991613773a65545eb308cf4ead75844e8) --- source4/libcli/nbt/nbtname.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 205567a55b..b59c24e7cf 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -343,8 +343,12 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt } status = ndr_push_nbt_string(ndr, ndr_flags, fullname); +#if 0 + /* this free conflicts with the use of pointers into strings + in the ndr_token_store() calls above. Metze, can you look + at this? */ talloc_free(fullname); - +#endif return status; } -- cgit From 61edb97bdfabf1ab313fbec5f47f5e6c8a79da1a Mon Sep 17 00:00:00 2001 From: Love Hörnquist Åstrand Date: Tue, 12 Jul 2005 22:22:59 +0000 Subject: r8394: Make sure the argument to ctype is*(3) macros are unsigned char as required by ISO C99. (This used to be commit 56fd21c806e816cf4c3d23881f26474f858b45e2) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index b59c24e7cf..36ffdc9af6 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -429,7 +429,7 @@ static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) int i, len; char *ret; const char *valid_chars = "_-.$@ "; -#define NBT_CHAR_ALLOW(c) (isalnum(c) || strchr(valid_chars, c)) +#define NBT_CHAR_ALLOW(c) (isalnum((unsigned char)c) || strchr(valid_chars, c)) for (len=i=0;s[i];i++,len++) { if (!NBT_CHAR_ALLOW(s[i])) { -- cgit From 562498c5260108c17add1e1a392644d188ff5c79 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Jul 2005 03:01:26 +0000 Subject: r8407: fixed a bug left over from our old socket code. Thanks to lha for giving me a login on a netbsd machine to see this (This used to be commit 4e66f682e4f1c31bbe9441a13af2c245db31433d) --- source4/libcli/raw/clisocket.c | 31 ++++++---------------- source4/libcli/raw/clitransport.c | 56 +++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 46 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index d6007ec8ba..b325fa473e 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -273,48 +273,33 @@ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) /**************************************************************************** Write to socket. Return amount written. ****************************************************************************/ -ssize_t smbcli_sock_write(struct smbcli_socket *sock, const uint8_t *data, size_t len) +NTSTATUS smbcli_sock_write(struct smbcli_socket *sock, const uint8_t *data, + size_t len, size_t *nsent) { - NTSTATUS status; DATA_BLOB blob; - size_t nsent; if (sock->sock == NULL) { - errno = EIO; - return -1; + return NT_STATUS_CONNECTION_DISCONNECTED; } blob.data = discard_const(data); blob.length = len; - status = socket_send(sock->sock, &blob, &nsent, 0); - if (NT_STATUS_IS_ERR(status)) { - return -1; - } - - return nsent; + return socket_send(sock->sock, &blob, nsent, 0); } /**************************************************************************** Read from socket. return amount read ****************************************************************************/ -ssize_t smbcli_sock_read(struct smbcli_socket *sock, uint8_t *data, size_t len) +NTSTATUS smbcli_sock_read(struct smbcli_socket *sock, uint8_t *data, + size_t len, size_t *nread) { - NTSTATUS status; - size_t nread; - if (sock->sock == NULL) { - errno = EIO; - return -1; - } - - status = socket_recv(sock->sock, data, len, &nread, 0); - if (NT_STATUS_IS_ERR(status)) { - return -1; + return NT_STATUS_CONNECTION_DISCONNECTED; } - return nread; + return socket_recv(sock->sock, data, len, nread, 0); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index f286eff0ea..d70d333039 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -346,17 +346,19 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport) { while (transport->pending_send) { struct smbcli_request *req = transport->pending_send; - ssize_t ret; - ret = smbcli_sock_write(transport->socket, req->out.buffer, req->out.size); - if (ret == -1) { - if (errno == EAGAIN || errno == EINTR) { - return; - } + NTSTATUS status; + size_t nwritten; + + status = smbcli_sock_write(transport->socket, req->out.buffer, + req->out.size, &nwritten); + if (NT_STATUS_IS_ERR(status)) { smbcli_transport_dead(transport); + } + if (!NT_STATUS_IS_OK(status)) { return; } - req->out.buffer += ret; - req->out.size -= ret; + req->out.buffer += nwritten; + req->out.size -= nwritten; if (req->out.size == 0) { DLIST_REMOVE(transport->pending_send, req); if (req->one_way_request) { @@ -529,17 +531,21 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) 4 byte header, which tells us how much more is coming. Then we read the rest */ if (transport->recv_buffer.received < NBT_HDR_SIZE) { - ssize_t ret; - ret = smbcli_sock_read(transport->socket, - transport->recv_buffer.header + - transport->recv_buffer.received, - NBT_HDR_SIZE - transport->recv_buffer.received); - if (ret == -1) { + NTSTATUS status; + size_t nread; + status = smbcli_sock_read(transport->socket, + transport->recv_buffer.header + + transport->recv_buffer.received, + NBT_HDR_SIZE - transport->recv_buffer.received, + &nread); + if (NT_STATUS_IS_ERR(status)) { smbcli_transport_dead(transport); + } + if (!NT_STATUS_IS_OK(status)) { return; } - transport->recv_buffer.received += ret; + transport->recv_buffer.received += nread; if (transport->recv_buffer.received == NBT_HDR_SIZE) { /* we've got a full header */ @@ -555,17 +561,21 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) } if (transport->recv_buffer.received < transport->recv_buffer.req_size) { - ssize_t ret; - ret = smbcli_sock_read(transport->socket, - transport->recv_buffer.buffer + - transport->recv_buffer.received, - transport->recv_buffer.req_size - - transport->recv_buffer.received); - if (ret == -1) { + NTSTATUS status; + size_t nread; + status = smbcli_sock_read(transport->socket, + transport->recv_buffer.buffer + + transport->recv_buffer.received, + transport->recv_buffer.req_size - + transport->recv_buffer.received, + &nread); + if (NT_STATUS_IS_ERR(status)) { smbcli_transport_dead(transport); + } + if (!NT_STATUS_IS_OK(status)) { return; } - transport->recv_buffer.received += ret; + transport->recv_buffer.received += nread; } if (transport->recv_buffer.received != 0 && -- cgit From 52bef30fd48393fa7b24ade7622c758373bd6dbe Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 13 Jul 2005 05:55:28 +0000 Subject: r8414: Some C++ friendlyness fixes - 'not' is apparently a keyword in C++. (This used to be commit bcfb3a45e4a5962fe763f8071d4458f4bd11605b) --- source4/libcli/ldap/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index d7a230a77f..5a45e6524e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -97,7 +97,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree case LDB_OP_NOT: asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.not.child)) { + if (!ldap_push_filter(data, tree->u.isnot.child)) { return False; } asn1_pop_tag(data); @@ -500,8 +500,8 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } ret->operation = LDB_OP_NOT; - ret->u.not.child = ldap_decode_filter_tree(ret, data); - if (ret->u.not.child == NULL) { + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { goto failed; } if (!asn1_end_tag(data)) { -- cgit From e835621799647ee70630b389fb53d15b15d68355 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Jul 2005 09:20:52 +0000 Subject: r8520: fixed a pile of warnings from the build farm gcc -Wall output on S390. This is an attempt to avoid the panic we're seeing in the automatic builds. The main fixes are: - assumptions that sizeof(size_t) == sizeof(int), mostly in printf formats - use of NULL format statements to perform dn searches. - assumption that sizeof() returns an int (This used to be commit a58ea6b3854973b694d2b1e22323ed7eb00e3a3f) --- source4/libcli/auth/session.c | 2 +- source4/libcli/cldap/cldap.c | 4 ++-- source4/libcli/dgram/browse.c | 2 +- source4/libcli/dgram/dgramsocket.c | 4 ++-- source4/libcli/dgram/netlogon.c | 2 +- source4/libcli/dgram/ntlogon.c | 2 +- source4/libcli/nbt/nbtname.c | 2 +- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/raw/rawfileinfo.c | 4 ++-- source4/libcli/raw/rawfsinfo.c | 4 ++-- source4/libcli/raw/rawsearch.c | 4 ++-- source4/libcli/raw/rawtrans.c | 2 +- source4/libcli/wins/winsrepl.c | 6 +++--- 13 files changed, 20 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index b32e1d724d..22146cbfb3 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -179,7 +179,7 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT if (blob->length < 8) { DEBUG(0, ("Unexpected length %d in session crypted secret (BLOB)\n", - blob->length)); + (int)blob->length)); return NT_STATUS_INVALID_PARAMETER; } diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 79cdff2437..4ffa40d134 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -93,7 +93,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) blob.length = nread; DEBUG(2,("Received cldap packet of length %d from %s:%d\n", - blob.length, src_addr, src_port)); + (int)blob.length, src_addr, src_port)); if (!asn1_load(&asn1, blob)) { DEBUG(2,("Failed to setup for asn.1 decode\n")); @@ -188,7 +188,7 @@ static void cldap_socket_send(struct cldap_socket *cldap) req->dest_addr, req->dest_port); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send cldap request of length %u to %s:%d\n", - req->encoded.length, req->dest_addr, req->dest_port)); + (unsigned)req->encoded.length, req->dest_addr, req->dest_port)); DLIST_REMOVE(cldap->send_queue, req); talloc_free(req); continue; diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index d7707b7ec8..a304db9c9d 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -89,7 +89,7 @@ NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, (ndr_pull_flags_fn_t)ndr_pull_nbt_browse_packet); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse browse packet of length %d\n", - data.length)); + (int)data.length)); if (DEBUGLVL(10)) { file_save("browse.dat", data.data, data.length); } diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index aff9d2e182..e66e5ed52e 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -64,7 +64,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) blob.length = nread; DEBUG(2,("Received dgram packet of length %d from %s:%d\n", - blob.length, src_addr, src_port)); + (int)blob.length, src_addr, src_port)); packet = talloc(tmp_ctx, struct nbt_dgram_packet); if (packet == NULL) { @@ -119,7 +119,7 @@ static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) req->dest_addr, req->dest_port); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send datagram of length %u to %s:%d\n", - req->encoded.length, req->dest_addr, req->dest_port)); + (unsigned)req->encoded.length, req->dest_addr, req->dest_port)); DLIST_REMOVE(dgmsock->send_queue, req); talloc_free(req); continue; diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 9d3a0dbed9..dda77689de 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -106,7 +106,7 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse netlogon packet of length %d\n", - data.length)); + (int)data.length)); if (DEBUGLVL(10)) { file_save("netlogon.dat", data.data, data.length); } diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index e4a24b0591..03d1266af0 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -106,7 +106,7 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to parse ntlogon packet of length %d\n", - data.length)); + (int)data.length)); if (DEBUGLVL(10)) { file_save("ntlogon.dat", data.data, data.length); } diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 36ffdc9af6..d7f0b1b077 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -171,7 +171,7 @@ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) if (complen >= 0x3F) { return ndr_push_error(ndr, NDR_ERR_STRING, "component length %u[%08X] > 0x00003F", - complen, complen); + (unsigned)complen, (unsigned)complen); } compname = talloc_asprintf(ndr, "%c%*.*s", diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 0401e68af8..f40ec84e77 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -199,7 +199,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) if (DEBUGLVL(10)) { DEBUG(10,("Received nbt packet of length %d from %s:%d\n", - blob.length, src_addr, src_port)); + (int)blob.length, src_addr, src_port)); NDR_PRINT_DEBUG(nbt_name_packet, packet); } diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 9f7786429c..ede4391824 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -25,12 +25,12 @@ /* local macros to make the code more readable */ #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \ DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected min of %d\n", \ - blob->length, parms->generic.level, (size))); \ + (int)blob->length, parms->generic.level, (size))); \ return NT_STATUS_INFO_LENGTH_MISMATCH; \ } #define FINFO_CHECK_SIZE(size) if (blob->length != (size)) { \ DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected %d\n", \ - blob->length, parms->generic.level, (size))); \ + (int)blob->length, parms->generic.level, (size))); \ return NT_STATUS_INFO_LENGTH_MISMATCH; \ } diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index fd99c4aeb9..3daa1c0f53 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -115,13 +115,13 @@ static NTSTATUS smb_raw_qfsinfo_blob_recv(struct smbcli_request *req, /* local macros to make the code more readable */ #define QFS_CHECK_MIN_SIZE(size) if (blob.length < (size)) { \ DEBUG(1,("Unexpected QFS reply size %d for level %u - expected min of %d\n", \ - blob.length, fsinfo->generic.level, (size))); \ + (int)blob.length, fsinfo->generic.level, (size))); \ status = NT_STATUS_INFO_LENGTH_MISMATCH; \ goto failed; \ } #define QFS_CHECK_SIZE(size) if (blob.length != (size)) { \ DEBUG(1,("Unexpected QFS reply size %d for level %u - expected %d\n", \ - blob.length, fsinfo->generic.level, (size))); \ + (int)blob.length, fsinfo->generic.level, (size))); \ status = NT_STATUS_INFO_LENGTH_MISMATCH; \ goto failed; \ } diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 90715ca8e2..a9b49c07a4 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -643,7 +643,7 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, if (p_blob.length < 10) { DEBUG(1,("smb_raw_search_first: parms wrong size %d != expected_param_size\n", - p_blob.length)); + (int)p_blob.length)); return NT_STATUS_INVALID_PARAMETER; } @@ -688,7 +688,7 @@ NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, if (p_blob.length != 8) { DEBUG(1,("smb_raw_search_next: parms wrong size %d != expected_param_size\n", - p_blob.length)); + (int)p_blob.length)); return NT_STATUS_INVALID_PARAMETER; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index b523232bc0..207b5bee08 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -219,7 +219,7 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, if (parms->in.params.length > UINT16_MAX || parms->in.data.length > UINT16_MAX) { DEBUG(3,("Attempt to send invalid trans2 request (params %u, data %u)\n", - parms->in.params.length, parms->in.data.length)); + (unsigned)parms->in.params.length, (unsigned)parms->in.data.length)); return NULL; } diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c index 732b597c53..6b02cfb660 100644 --- a/source4/libcli/wins/winsrepl.c +++ b/source4/libcli/wins/winsrepl.c @@ -162,13 +162,13 @@ static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) if (!NT_STATUS_IS_OK(req->status)) { DEBUG(2,("Failed to parse incoming WINS packet - %s\n", nt_errstr(req->status))); - DEBUG(10,("packet length %d\n", req->buffer.length)); + DEBUG(10,("packet length %d\n", (int)req->buffer.length)); NDR_PRINT_DEBUG(wrepl_packet, req->packet); goto failed; } if (DEBUGLVL(10)) { - DEBUG(10,("Received WINS packet of length %d\n", req->buffer.length)); + DEBUG(10,("Received WINS packet of length %d\n", (int)req->buffer.length)); NDR_PRINT_DEBUG(wrepl_packet, req->packet); } @@ -390,7 +390,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, if (!NT_STATUS_IS_OK(req->status)) goto failed; if (DEBUGLVL(10)) { - DEBUG(10,("Sending WINS packet of length %d\n", req->buffer.length)); + DEBUG(10,("Sending WINS packet of length %d\n", (int)req->buffer.length)); NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); } -- cgit From 039393d6620816789b4ebd131974b23b6420f4dc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Jul 2005 10:52:31 +0000 Subject: r8523: match a zero message id in ldap replies to the last request sent. Thanks to simo for noticing that this is needed to catch the server sending a "can't decode request" error reply (This used to be commit 6e81e866dc7a5dc014d2d9f2e09803c6adfd1830) --- source4/libcli/ldap/ldap_client.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index a8463f7872..97b75602aa 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -106,6 +106,11 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message for (req=conn->pending; req; req=req->next) { if (req->messageid == msg->messageid) break; } + /* match a zero message id to the last request sent. + It seems that servers send 0 if unable to parse */ + if (req == NULL && msg->messageid == 0) { + req = conn->pending; + } if (req == NULL) { DEBUG(0,("ldap: no matching message id for %u\n", msg->messageid)); @@ -480,6 +485,9 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, req->state = LDAP_REQUEST_SEND; req->conn = conn; req->messageid = conn->next_messageid++; + if (conn->next_messageid == 0) { + conn->next_messageid = 1; + } req->type = msg->type; if (req->messageid == -1) { goto failed; -- cgit From f4576157edab9d3e39a88342312fc42ba6e59469 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 17 Jul 2005 14:16:41 +0000 Subject: r8530: Now our ldap server is able to fullfill present and substring searches (This used to be commit a910671bd8c6d2d8d5b6ff30fc07ead244e696f1) --- source4/libcli/ldap/ldap.c | 220 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 184 insertions(+), 36 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5a45e6524e..b5e142ff6c 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -34,17 +34,26 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree int i; switch (tree->operation) { - case LDB_OP_SIMPLE: - if ((tree->u.simple.value.length == 1) && - (((char *)(tree->u.simple.value.data))[0] == '*')) { - /* Just a presence test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write(data, tree->u.simple.attr, - strlen(tree->u.simple.attr)); - asn1_pop_tag(data); - return !data->has_error; + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return False; + } } + asn1_pop_tag(data); + break; + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return False; + } + asn1_pop_tag(data); + break; + + case LDB_OP_SIMPLE: /* equality test */ asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, tree->u.simple.attr, @@ -54,6 +63,51 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + case LDB_OP_EXTENDED: /* MatchingRuleAssertion ::= SEQUENCE { @@ -82,26 +136,6 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); asn1_pop_tag(data); break; - - - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return False; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return False; - } - asn1_pop_tag(data); - break; default: return False; @@ -440,6 +474,30 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value) + 1; + + chunks[chunk_num + 1] = NULL; + + return chunks; +} + /* parse the ASN.1 formatted search string into a ldb_parse_tree @@ -528,6 +586,100 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->u.simple.value.length = value.length; break; } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_memdup(ret, attr.data, attr.length + 1); + ret->u.substring.attr[attr.length] = '\0'; + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } case 7: { /* Normal presence, "attribute=*" */ char *attr; @@ -539,13 +691,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, goto failed; } - ret->operation = LDB_OP_SIMPLE; - ret->u.simple.attr = talloc_steal(ret, attr); - ret->u.simple.value.data = talloc_strdup(ret, "*"); - if (ret->u.simple.value.data == NULL) { - goto failed; - } - ret->u.simple.value.length = 1; + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + if (!asn1_end_tag(data)) { goto failed; } -- cgit From bfb11862698743ee36bc6050269378321e6e577c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 19 Jul 2005 09:09:00 +0000 Subject: r8585: add to ldb and ldap comparison functionality better pares filters Approx is currently only a stub need to dig more info to understand what it really means and how it works exactly (This used to be commit a9e8cd0bad27ed2b3c6a12302e787ba3c9a70a3c) --- source4/libcli/ldap/ldap.c | 105 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b5e142ff6c..b71c4a6dff 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -53,13 +53,13 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; - case LDB_OP_SIMPLE: + case LDB_OP_EQUALITY: /* equality test */ asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.simple.attr, - strlen(tree->u.simple.attr)); - asn1_write_OctetString(data, tree->u.simple.value.data, - tree->u.simple.value.length); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); asn1_pop_tag(data); break; @@ -101,6 +101,26 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + case LDB_OP_PRESENT: /* present test */ asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); @@ -108,6 +128,16 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); return !data->has_error; + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + case LDB_OP_EXTENDED: /* MatchingRuleAssertion ::= SEQUENCE { @@ -580,10 +610,10 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, goto failed; } - ret->operation = LDB_OP_SIMPLE; - ret->u.simple.attr = talloc_steal(ret, attrib); - ret->u.simple.value.data = talloc_steal(ret, value.data); - ret->u.simple.value.length = value.length; + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; break; } case 4: { @@ -680,6 +710,44 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } break; } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } case 7: { /* Normal presence, "attribute=*" */ char *attr; @@ -699,6 +767,25 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } break; } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } case 9: { char *oid, *attr, *value; uint8_t dnAttributes; -- cgit From d9cfd55dbb969b08914fd306fb9d123e52ad6541 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Jul 2005 04:21:10 +0000 Subject: r8628: add retries to the normal paths of nbt name resolution. UDP broadcasts are not 100% reliable :) (This used to be commit 0f8f1cd18e20ea4f3a06bb093b00b930cfd005b2) --- source4/libcli/resolve/nbtlist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 0026c6fceb..7080c62e43 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -140,9 +140,9 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, if (!state->io_queries[i].in.dest_addr) goto failed; state->io_queries[i].in.broadcast = broadcast; state->io_queries[i].in.wins_lookup = wins_lookup; - state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 3); + state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 1); - state->io_queries[i].in.retries = 0; + state->io_queries[i].in.retries = 2; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); if (!state->queries[i]) goto failed; -- cgit From 176c0d1b771d0e81167a12eb81eddb40732b074a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 22 Jul 2005 04:06:28 +0000 Subject: r8699: removed invalid comment (This used to be commit f5910ceef5e1ec3fe40b4589e919fe502593b582) --- source4/libcli/composite/sesssetup.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 2a75fb4e20..43e07993cb 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -169,12 +169,10 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { DATA_BLOB session_key; - /* TODO: NTLMv2 in the client session setup */ if (lp_client_ntlmv2_auth()) { DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_netbios_name(), lp_workgroup()); DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key; - /* TODO - test with various domain cases, and without domain */ if (!SMBNTLMv2encrypt_hash(state, state->setup.nt1.in.user, state->setup.nt1.in.domain, nt_hash->hash, &session->transport->negotiate.secblob, -- cgit From a04e899bc07825acecd0e1d3bd5e9898b52a0bd9 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Mon, 25 Jul 2005 22:56:28 +0000 Subject: r8760: Rework monitor messaging code a bit, as Metze once suggested. enum type has now been replaced with unsigned 32-bit field and message data is passed as void pointer. This allows various extension implementers to plug their monitor messages in more easily. rafal (This used to be commit 4a6ab58133a59d3da3209b3e46c2a8cf848d25e7) --- source4/libcli/composite/monitor.h | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/monitor.h b/source4/libcli/composite/monitor.h index 729f37204f..6173ca9057 100644 --- a/source4/libcli/composite/monitor.h +++ b/source4/libcli/composite/monitor.h @@ -21,35 +21,20 @@ */ /* - * Monitor structure definition. Composite function monitoring allows client - * application to be notified on function progress. This enables eg. gui - * client to display progress bars, status messages, etc. + * Monitor structure and message types definitions. Composite function monitoring + * allows client application to be notified on function progress. This enables + * eg. gui client to display progress bars, status messages, etc. */ -enum monitor_type { - rpc_create_user, - rpc_open_user, - rpc_query_user, - rpc_close_user -}; - -struct monitor_msg { - enum monitor_type type; - union monitor_data { - struct rpc_create_user { - uint32_t rid; - } rpc_create_user; - struct rpc_open_user { - uint32_t rid, access_mask; - } rpc_open_user; +#define rpc_create_user (0x00000001) /* userman.h */ +#define rpc_open_user (0x00000002) /* userinfo.h */ +#define rpc_query_user (0x00000003) /* userinfo.h */ +#define rpc_close_user (0x00000004) /* userinfo.h */ - struct rpc_query_user { - uint16_t level; - } rpc_query_user; - struct rpc_close_user { - uint32_t rid; - } rpc_close_user; - } data; +struct monitor_msg { + uint32_t type; + void *data; + size_t data_size; }; -- cgit From 528bb470bd138df2de742be696bb31191f9da492 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Jul 2005 07:23:11 +0000 Subject: r8776: fixed SMB connections for IP addresses, even when name resolve order doesn't include 'host' (This used to be commit 77a1e3076a8d5c711fc96a69dd1a58c00d1f9604) --- source4/libcli/composite/connect.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index b1d2eb2847..d6d87380ec 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -341,17 +341,24 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec if (state->sock == NULL) goto failed; state->io = io; - state->stage = CONNECT_RESOLVE; c->state = SMBCLI_REQUEST_SEND; c->event_ctx = talloc_reference(c, state->sock->event.ctx); c->private = state; - make_nbt_name_server(&name, io->in.dest_host); + /* if the destination is an IP address, then skip the name resolution part */ + if (is_ipaddress(io->in.dest_host)) { + state->stage = CONNECT_SOCKET; + state->creq = smbcli_sock_connect_send(state->sock, io->in.dest_host, + state->io->in.port, + io->in.dest_host); + } else { + state->stage = CONNECT_RESOLVE; + make_nbt_name_server(&name, io->in.dest_host); + state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); + } - state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); if (state->creq == NULL) goto failed; - state->creq->async.private = c; state->creq->async.fn = composite_handler; -- cgit From d929f32dbe577b2bd389497433fb0a05c109a04b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Jul 2005 07:23:57 +0000 Subject: r8777: make sure that the tree connect is a child of the return cli state structure. This fixes the BASE-DISCONNECT test (This used to be commit 86fe5817b1abc754763eede64b615dc8c9db5362) --- source4/libcli/cliconnect.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 489aea82dd..624b54c3f2 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -154,6 +154,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, (*ret_cli)->tree = tree; (*ret_cli)->session = tree->session; (*ret_cli)->transport = tree->session->transport; + + talloc_steal(*ret_cli, tree); done: return status; @@ -173,14 +175,7 @@ NTSTATUS smbcli_tdis(struct smbcli_state *cli) ****************************************************************************/ struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) { - struct smbcli_state *cli; - - cli = talloc_zero(mem_ctx, struct smbcli_state); - if (cli) { - ZERO_STRUCTP(cli); - } - - return cli; + return talloc_zero(mem_ctx, struct smbcli_state); } /* -- cgit From 0102f2752f7c429f95048c277cd1793683a2750e Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 26 Jul 2005 23:02:35 +0000 Subject: r8788: New monitor messages. rafal (This used to be commit 40061d7bd66be702d92c80da2c5f955b640eda22) --- source4/libcli/composite/monitor.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/monitor.h b/source4/libcli/composite/monitor.h index 6173ca9057..dce9dedc92 100644 --- a/source4/libcli/composite/monitor.h +++ b/source4/libcli/composite/monitor.h @@ -31,6 +31,8 @@ #define rpc_open_user (0x00000002) /* userinfo.h */ #define rpc_query_user (0x00000003) /* userinfo.h */ #define rpc_close_user (0x00000004) /* userinfo.h */ +#define rpc_lookup_name (0x00000005) /* userman.h */ +#define rpc_delete_user (0x00000006) /* userman.h */ struct monitor_msg { -- cgit From 6553dd0c60e922f42de347a02c8f792f087c393c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Jul 2005 00:27:28 +0000 Subject: r8811: Fix the build.. (This used to be commit fac77f5fa267da57a55e88cad8993897e80741a0) --- source4/libcli/ldap/ldap_ndr.c | 1 + source4/libcli/nbt/nbtname.c | 1 + source4/libcli/raw/rawfsinfo.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index f490b9983d..bc19e49535 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_misc.h" /* encode a NDR uint32 as a ldap filter element diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index d7f0b1b077..ae6df8a18d 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -27,6 +27,7 @@ #include "includes.h" #include "system/iconv.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "librpc/gen_ndr/ndr_misc.h" /* don't allow an unlimited number of name components */ #define MAX_COMPONENTS 10 diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 3daa1c0f53..61f5a5027d 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_misc.h" /**************************************************************************** Query FS Info - SMBdskattr call (async send) -- cgit From d0496a4ee626f829f1b5032122d2daf53e0bd2e2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Jul 2005 11:27:58 +0000 Subject: r8825: Move list of object files to .mk file (This used to be commit 604422b1f967733b009a6e93520cb196d1eb5a89) --- source4/libcli/config.m4 | 24 +----------------------- source4/libcli/config.mk | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 1c29a9599f..6e0a88ec35 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -5,26 +5,4 @@ if test x"$with_ads_support" = x"yes"; then LIBCLI_RAW_LIBS="KRB5" fi -SMB_SUBSYSTEM(LIBCLI_RAW,[], - [libcli/raw/rawfile.o - libcli/raw/smb_signing.o - libcli/raw/clisocket.o - libcli/raw/clitransport.o - libcli/raw/clisession.o - libcli/raw/clitree.o - libcli/raw/rawrequest.o - libcli/raw/rawreadwrite.o - libcli/raw/rawsearch.o - libcli/raw/rawsetfileinfo.o - libcli/raw/raweas.o - libcli/raw/rawtrans.o - libcli/raw/clioplock.o - libcli/raw/rawnegotiate.o - libcli/raw/rawfsinfo.o - libcli/raw/rawfileinfo.o - libcli/raw/rawnotify.o - libcli/raw/rawioctl.o - libcli/raw/rawacl.o - libcli/raw/rawdate.o], - [${LIBCLI_RAW_LIBS}]) - +SMB_SUBSYSTEM(LIBCLI_RAW_KRB5,[], [], [${LIBCLI_RAW_LIBS}]) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 7779adabaf..5787b1241f 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -81,3 +81,26 @@ ADD_OBJ_FILES = libcli/clireadwrite.o \ libcli/clitrans2.o \ libcli/climessage.o \ libcli/clideltree.o + +[SUBSYSTEM::LIBCLI_RAW] +REQUIRED_SUBSYSTEMS = LIBCLI_RAW_KRB5 +OBJ_FILES = libcli/raw/rawfile.o \ + libcli/raw/smb_signing.o \ + libcli/raw/clisocket.o \ + libcli/raw/clitransport.o \ + libcli/raw/clisession.o \ + libcli/raw/clitree.o \ + libcli/raw/rawrequest.o \ + libcli/raw/rawreadwrite.o \ + libcli/raw/rawsearch.o \ + libcli/raw/rawsetfileinfo.o \ + libcli/raw/raweas.o \ + libcli/raw/rawtrans.o \ + libcli/raw/clioplock.o \ + libcli/raw/rawnegotiate.o \ + libcli/raw/rawfsinfo.o \ + libcli/raw/rawfileinfo.o \ + libcli/raw/rawnotify.o \ + libcli/raw/rawioctl.o \ + libcli/raw/rawacl.o \ + libcli/raw/rawdate.o -- cgit From f297f82398d77e5d2fe5faf5de8b581ad5a6acd1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 2 Aug 2005 14:04:22 +0000 Subject: r8917: Better support for extended ldap search operations Try to follow the RFC where possible and adapt to openLdap and AD way of handling this structure (This used to be commit d844d45d87b4114bc1b9af2e40f8c27ba3e219de) --- source4/libcli/ldap/ldap.c | 66 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b71c4a6dff..f7f6feea38 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -787,36 +787,68 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, break; } case 9: { - char *oid, *attr, *value; + char *oid = NULL, *attr = NULL, *value; uint8_t dnAttributes; /* an extended search */ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, &oid); - asn1_end_tag(data); - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, &attr); - asn1_end_tag(data); + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, &attr); + asn1_end_tag(data); + } asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); asn1_read_LDAPString(data, &value); asn1_end_tag(data); - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - if ((data->has_error) || (oid == NULL) || (value == NULL)) { + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { goto failed; } - ret->operation = LDB_OP_EXTENDED; - ret->u.extended.attr = talloc_steal(ret, attr); - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; + if (oid) { + ret->operation = LDB_OP_EXTENDED; + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } if (!asn1_end_tag(data)) { goto failed; } -- cgit From 223262c11e94c1e67b8cdec1a264d7f93a9afdc4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Aug 2005 04:24:37 +0000 Subject: r9048: added a new DOS error code (thanks to EMC) (This used to be commit 1936c20939a6e1311665b44a71a31ab231ba7b28) --- source4/libcli/util/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index b7e3bcabde..08cd844b3a 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -614,6 +614,7 @@ static const nt_err_code_struct nt_errs[] = DOS_CODE(ERRDOS, ERRinvalidprintmonitor), DOS_CODE(ERRDOS, ERRprintmonitorinuse), DOS_CODE(ERRDOS, ERRprinterhasjobsqueued), + DOS_CODE(ERRDOS, ERReainconsistent), DOS_CODE(ERRSRV, ERRerror), DOS_CODE(ERRSRV, ERRbadpw), -- cgit From 2fa50ab671ba4a7e552e001f0dfde3a7cc330f8e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 9 Aug 2005 03:09:47 +0000 Subject: r9222: Rename smb_tree_connect() to smb_raw_tcon() to match other raw function names. (This used to be commit 26b191b3c9529b2dae5d004819dab46657064408) --- source4/libcli/cliconnect.c | 4 ++-- source4/libcli/composite/connect.c | 4 ++-- source4/libcli/raw/clitree.c | 16 ++++++++-------- source4/libcli/util/clilsa.c | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 624b54c3f2..cc02af1162 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -83,7 +83,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, return status; } -/* wrapper around smb_tree_connect() */ +/* wrapper around smb_raw_tcon() */ NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, const char *devtype, const char *password) { @@ -116,7 +116,7 @@ NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, tcon.tconx.in.path = sharename; tcon.tconx.in.device = devtype; - status = smb_tree_connect(cli->tree, mem_ctx, &tcon); + status = smb_raw_tcon(cli->tree, mem_ctx, &tcon); cli->tree->tid = tcon.tconx.out.tid; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index d6d87380ec..adac9bcf67 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -77,7 +77,7 @@ static NTSTATUS connect_tcon(struct composite_context *c, struct connect_state *state = talloc_get_type(c->private, struct connect_state); NTSTATUS status; - status = smb_tree_connect_recv(state->req, c, state->io_tcon); + status = smb_raw_tcon_recv(state->req, c, state->io_tcon); NT_STATUS_NOT_OK_RETURN(status); io->out.tree->tid = state->io_tcon->tconx.out.tid; @@ -134,7 +134,7 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->io_tcon->tconx.in.device = io->in.service_type; } - state->req = smb_tree_connect_send(io->out.tree, state->io_tcon); + state->req = smb_raw_tcon_send(io->out.tree, state->io_tcon); NT_STATUS_HAVE_NO_MEMORY(state->req); state->req->async.fn = request_handler; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 76cb1a43fe..25f346ef5d 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -56,8 +56,8 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session, /**************************************************************************** Send a tconX (async send) ****************************************************************************/ -struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, - union smb_tcon *parms) +struct smbcli_request *smb_raw_tcon_send(struct smbcli_tree *tree, + union smb_tcon *parms) { struct smbcli_request *req = NULL; @@ -92,8 +92,8 @@ struct smbcli_request *smb_tree_connect_send(struct smbcli_tree *tree, /**************************************************************************** Send a tconX (async recv) ****************************************************************************/ -NTSTATUS smb_tree_connect_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, - union smb_tcon *parms) +NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, + union smb_tcon *parms) { uint8_t *p; @@ -134,11 +134,11 @@ failed: /**************************************************************************** Send a tconX (sync interface) ****************************************************************************/ -NTSTATUS smb_tree_connect(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, - union smb_tcon *parms) +NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, + union smb_tcon *parms) { - struct smbcli_request *req = smb_tree_connect_send(tree, parms); - return smb_tree_connect_recv(req, mem_ctx, parms); + struct smbcli_request *req = smb_raw_tcon_send(tree, parms); + return smb_raw_tcon_recv(req, mem_ctx, parms); } diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index ad2006756b..f5de5014e3 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -69,7 +69,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) tcon.tconx.in.password = data_blob(NULL, 0); tcon.tconx.in.path = "ipc$"; tcon.tconx.in.device = "IPC"; - status = smb_tree_connect(lsa->ipc_tree, lsa, &tcon); + status = smb_raw_tcon(lsa->ipc_tree, lsa, &tcon); if (!NT_STATUS_IS_OK(status)) { talloc_free(lsa); return status; -- cgit From 172cee9adc86ab1950b50ffc008587e6d42585ed Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 9 Aug 2005 04:11:09 +0000 Subject: r9223: Rename smb_raw_session_setup() to smb_raw_sesssetup(). (This used to be commit 5e6d330e7388e47e1b2bfc96fff07682e90f63a5) --- source4/libcli/cliconnect.c | 2 +- source4/libcli/composite/sesssetup.c | 10 +++++----- source4/libcli/raw/clisession.c | 17 +++++++++-------- 3 files changed, 15 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index cc02af1162..aba7f361a2 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -61,7 +61,7 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli) return smb_raw_negotiate(cli->transport, lp_maxprotocol()); } -/* wrapper around smb_raw_session_setup() */ +/* wrapper around smb_raw_sesssetup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, struct cli_credentials *credentials) { diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 43e07993cb..832f7e3d60 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -79,7 +79,7 @@ static void request_handler(struct smbcli_request *req) DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); - c->status = smb_raw_session_setup_recv(req, state, &state->setup); + c->status = smb_raw_sesssetup_recv(req, state, &state->setup); switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: @@ -115,7 +115,7 @@ static void request_handler(struct smbcli_request *req) smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } - state->req = smb_raw_session_setup_send(session, &state->setup); + state->req = smb_raw_sesssetup_send(session, &state->setup); state->req->async.fn = request_handler; state->req->async.private = c; return; @@ -221,7 +221,7 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, return NULL; } - return smb_raw_session_setup_send(session, &state->setup); + return smb_raw_sesssetup_send(session, &state->setup); } @@ -256,7 +256,7 @@ static struct smbcli_request *session_setup_old(struct composite_context *c, strlen(password)); } - return smb_raw_session_setup_send(session, &state->setup); + return smb_raw_sesssetup_send(session, &state->setup); } @@ -344,7 +344,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } - return smb_raw_session_setup_send(session, &state->setup); + return smb_raw_sesssetup_send(session, &state->setup); } diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 130959e776..2942279b12 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -78,7 +78,8 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, /**************************************************************************** Perform a session setup (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session, union smb_sesssetup *parms) +struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session, + union smb_sesssetup *parms) { struct smbcli_request *req = NULL; @@ -150,9 +151,9 @@ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session /**************************************************************************** Perform a session setup (async recv) ****************************************************************************/ -NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req, - TALLOC_CTX *mem_ctx, - union smb_sesssetup *parms) +NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, + TALLOC_CTX *mem_ctx, + union smb_sesssetup *parms) { uint16_t len; uint8_t *p; @@ -222,11 +223,11 @@ failed: /* Perform a session setup (sync interface) */ -NTSTATUS smb_raw_session_setup(struct smbcli_session *session, TALLOC_CTX *mem_ctx, - union smb_sesssetup *parms) +NTSTATUS smb_raw_sesssetup(struct smbcli_session *session, + TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) { - struct smbcli_request *req = smb_raw_session_setup_send(session, parms); - return smb_raw_session_setup_recv(req, mem_ctx, parms); + struct smbcli_request *req = smb_raw_sesssetup_send(session, parms); + return smb_raw_sesssetup_recv(req, mem_ctx, parms); } -- cgit From 3be75a4c6d4b9d86f1b85c75fb2f41c6c0eeec94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 Aug 2005 13:12:45 +0000 Subject: r9240: - move struct security_token to the idl file, with this we can the ndr_pull/push/print functions for it in the ntacl-lsm module - fix compiler warnings in the ldap_encode_ndr_* code metze (This used to be commit 83d65d0d7ed9c240ad44aa2c881c1f07212bfda4) --- source4/libcli/ldap/ldap_ndr.c | 10 ++++---- source4/libcli/security/access_check.c | 2 +- source4/libcli/security/dom_sid.c | 2 +- source4/libcli/security/privilege.c | 2 +- source4/libcli/security/security.h | 36 --------------------------- source4/libcli/security/security_descriptor.c | 2 +- source4/libcli/security/security_token.c | 2 +- 7 files changed, 10 insertions(+), 46 deletions(-) delete mode 100644 source4/libcli/security/security.h (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index bc19e49535..0cccdbe971 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -29,7 +29,7 @@ /* encode a NDR uint32 as a ldap filter element */ -const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) { uint8_t buf[4]; struct ldb_val val; @@ -42,11 +42,11 @@ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) /* encode a NDR dom_sid as a ldap filter element */ -const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { DATA_BLOB blob; NTSTATUS status; - const char *ret; + char *ret; status = ndr_push_struct_blob(&blob, mem_ctx, sid, (ndr_push_flags_fn_t)ndr_push_dom_sid); if (!NT_STATUS_IS_OK(status)) { @@ -61,11 +61,11 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *s /* encode a NDR GUID as a ldap filter element */ -const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) { DATA_BLOB blob; NTSTATUS status; - const char *ret; + char *ret; status = ndr_push_struct_blob(&blob, mem_ctx, guid, (ndr_push_flags_fn_t)ndr_push_GUID); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 632b9bdf32..c10751abce 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" /* diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 80e481c3e4..f457900efc 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" /***************************************************************** Compare the auth portion of two sids. diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index ed98e9ce32..aa01dc2c65 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" static const struct { diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h deleted file mode 100644 index b11d10f6f6..0000000000 --- a/source4/libcli/security/security.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - security utility functions - - Copyright (C) Andrew Tridgell 2004 - - 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. -*/ - -#ifndef _SAMBA_SECURITY_H -#define _SAMBA_SECURITY_H - -#include "librpc/gen_ndr/ndr_security.h" - -struct security_token { - struct dom_sid *user_sid; - struct dom_sid *group_sid; - uint32_t num_sids; - struct dom_sid **sids; - uint64_t privilege_mask; -}; - -#endif /* _SAMBA_SECURITY_H */ diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index d1978fd795..703abf7970 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" /* return a blank security descriptor (no owners, dacl or sacl) diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 663c4f28bc..ea1fae0c33 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" /* return a blank security token -- cgit From 76787d5da440cd1cb224484c34a86c1baa5787d9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 13 Aug 2005 01:15:32 +0000 Subject: r9291: Add a stub for smb_raw_lpq() which is in smb_interfaces.h but doesn't seem to be used anywhere yet. (This used to be commit 9e5ce3a28892241e2b080c0fa187ee99042c2330) --- source4/libcli/config.mk | 3 ++- source4/libcli/raw/rawlpq.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/raw/rawlpq.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 5787b1241f..aec06f8023 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -103,4 +103,5 @@ OBJ_FILES = libcli/raw/rawfile.o \ libcli/raw/rawnotify.o \ libcli/raw/rawioctl.o \ libcli/raw/rawacl.o \ - libcli/raw/rawdate.o + libcli/raw/rawdate.o \ + libcli/raw/rawlpq.o diff --git a/source4/libcli/raw/rawlpq.c b/source4/libcli/raw/rawlpq.c new file mode 100644 index 0000000000..e83ee48707 --- /dev/null +++ b/source4/libcli/raw/rawlpq.c @@ -0,0 +1,48 @@ +/* + Unix SMB/CIFS implementation. + client lpq operations + Copyright (C) Tim Potter 2005 + + 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 "libcli/raw/libcliraw.h" + +/**************************************************************************** + lpq - async send +****************************************************************************/ +struct smbcli_request *smb_raw_lpq_send(struct smbcli_tree *tree, + union smb_lpq *parms) +{ + return NULL; +} + +/**************************************************************************** + lpq - async receive +****************************************************************************/ +NTSTATUS smb_raw_lpq_recv(struct smbcli_request *req, union smb_lpq *parms) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + lpq - sync interface +*/ +NTSTATUS smb_raw_lpq(struct smbcli_tree *tree, union smb_lpq *parms) +{ + struct smbcli_request *req = smb_raw_lpq_send(tree, parms); + return smb_raw_lpq_recv(req, parms); +} -- cgit From 684c824e9ac51ee2d6b748973757697a8ead2634 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Aug 2005 07:59:00 +0000 Subject: r9421: Move arcfour code into it's own file, in lib/crypto. Andrew Bartlett (This used to be commit ca6cf462708810637544d4b4bef0f404fb89a002) --- source4/libcli/util/smbdes.c | 67 -------------------------------------------- 1 file changed, 67 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index d214d4cfe4..d02cae602f 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -365,73 +365,6 @@ void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int des_crypt56(out + 8, in + 8, key+7, forw); } -/* initialise the arcfour sbox with key */ -void arcfour_init(struct arcfour_state *state, const DATA_BLOB *key) -{ - int ind; - uint8_t j = 0; - for (ind = 0; ind < sizeof(state->sbox); ind++) { - state->sbox[ind] = (uint8_t)ind; - } - - for (ind = 0; ind < sizeof(state->sbox); ind++) { - uint8_t tc; - - j += (state->sbox[ind] + key->data[ind%key->length]); - - tc = state->sbox[ind]; - state->sbox[ind] = state->sbox[j]; - state->sbox[j] = tc; - } - state->index_i = 0; - state->index_j = 0; -} - -/* crypt the data with arcfour */ -void arcfour_crypt_sbox(struct arcfour_state *state, uint8_t *data, int len) -{ - int ind; - - for (ind = 0; ind < len; ind++) { - uint8_t tc; - uint8_t t; - - state->index_i++; - state->index_j += state->sbox[state->index_i]; - - tc = state->sbox[state->index_i]; - state->sbox[state->index_i] = state->sbox[state->index_j]; - state->sbox[state->index_j] = tc; - - t = state->sbox[state->index_i] + state->sbox[state->index_j]; - data[ind] = data[ind] ^ state->sbox[t]; - } -} - -/* - arcfour encryption with a blob key -*/ -void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) -{ - struct arcfour_state state; - arcfour_init(&state, key); - arcfour_crypt_sbox(&state, data, len); -} - -/* - a variant that assumes a 16 byte key. This should be removed - when the last user is gone -*/ -void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len) -{ - DATA_BLOB key = data_blob(keystr, 16); - - arcfour_crypt_blob(data, len, &key); - - data_blob_free(&key); -} - - /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ -- cgit From 5bd6a114711c0033403a656b42574380a6ebcd3d Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 22 Aug 2005 14:07:52 +0000 Subject: r9476: Make intention to ignore result of receiving excplicit. Fixes warning found by Coverity (This used to be commit d1b7a4a24c3af1bfcc289a3476c9fb33ed2fb840) --- source4/libcli/raw/rawsearch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index a9b49c07a4..65928d1154 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -724,7 +724,7 @@ NTSTATUS smb_raw_search_close(struct smbcli_tree *tree, SSVAL(req->out.vwv, VWV(0), io->findclose.in.handle); if (smbcli_request_send(req)) { - smbcli_request_receive(req); + (void) smbcli_request_receive(req); } return smbcli_request_destroy(req); -- cgit From 294f0aaf9ca61a72ed33b8f0b999f6871005da73 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 22 Aug 2005 16:02:11 +0000 Subject: r9479: More fixes for explicit ignoring of returned result to fix Coverity warnings (This used to be commit 4f9f4312e98cce7589fc8e094d08e76cc697ab3d) --- source4/libcli/raw/clitree.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 25f346ef5d..74e14db591 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -153,7 +153,7 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) req = smbcli_request_setup(tree, SMBtdis, 0, 0); if (smbcli_request_send(req)) { - smbcli_request_receive(req); + (void) smbcli_request_receive(req); } return smbcli_request_destroy(req); } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index b49009ac22..e01626a15c 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -389,7 +389,7 @@ BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const u */ NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req) { - smbcli_request_receive(req); + (void) smbcli_request_receive(req); return smbcli_request_destroy(req); } -- cgit From ba90b652d918fb34f1e43083f8283f669c73c340 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 23 Aug 2005 05:29:37 +0000 Subject: r9505: Work on GENSEC and the code that calls it, for tighter interface requirements, and for better error reporting. In particular, the composite session setup (extended security/SPNEGO) code now returns errors, rather than NT_STATUS_NO_MEMORY. This is seen particularly when GENSEC fails to start. The tighter interface rules apply to NTLMSSP, which must be called exactly the right number of times. This is to match some of our other less-tested modules, where adding flexablity is harder. (and this is security code, so let's just get it right). As such, the DCE/RPC and LDAP clients have been updated. Andrew Bartlett (This used to be commit 134550cf752b9edad66c3368750bfb4bbd9d55d1) --- source4/libcli/composite/connect.c | 6 ++ source4/libcli/composite/sesssetup.c | 144 ++++++++++++++++++++++------------- source4/libcli/ldap/ldap_bind.c | 34 +++++++-- 3 files changed, 121 insertions(+), 63 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index adac9bcf67..4d35f5c73a 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -136,6 +136,9 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->req = smb_raw_tcon_send(io->out.tree, state->io_tcon); NT_STATUS_HAVE_NO_MEMORY(state->req); + if (state->req->state == SMBCLI_REQUEST_ERROR) { + return state->req->status; + } state->req->async.fn = request_handler; state->req->async.private = c; @@ -171,6 +174,9 @@ static NTSTATUS connect_negprot(struct composite_context *c, state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); NT_STATUS_HAVE_NO_MEMORY(state->creq); + if (state->creq->state == SMBCLI_REQUEST_ERROR) { + return state->creq->status; + } state->creq->async.fn = composite_handler; state->creq->async.private = c; diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index 832f7e3d60..b27290d5e4 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -29,7 +29,7 @@ struct sesssetup_state { union smb_sesssetup setup; - NTSTATUS session_key_err; + NTSTATUS gensec_status; struct smb_composite_sesssetup *io; struct smbcli_request *req; }; @@ -78,6 +78,7 @@ static void request_handler(struct smbcli_request *req) struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); + NTSTATUS session_key_err; c->status = smb_raw_sesssetup_recv(req, state, &state->setup); @@ -96,29 +97,41 @@ static void request_handler(struct smbcli_request *req) !NT_STATUS_IS_OK(c->status)) { break; } - c->status = gensec_update(session->gensec, state, - state->setup.spnego.out.secblob, - &state->setup.spnego.in.secblob); - if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && - !NT_STATUS_IS_OK(c->status)) { - break; - } - if (state->setup.spnego.in.secblob.length == 0) { - break; + if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + + /* The status value here, from the earlier pass at GENSEC is + * vital to the security of the system. Even if the other end + * accepts, if GENSEC claims 'MORE_PROCESSING_REQUIRED' then + * you must keep feeding it blobs, or else the remote + * host/attacker might avoid mutal authentication + * requirements */ + + state->gensec_status = gensec_update(session->gensec, state, + state->setup.spnego.out.secblob, + &state->setup.spnego.in.secblob); + c->status = state->gensec_status; + if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(c->status)) { + break; + } + } else { + state->setup.spnego.in.secblob = data_blob(NULL, 0); } - + /* we need to do another round of session setup. We keep going until both sides are happy */ - state->session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(state->session_key_err)) { + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { set_user_session_key(session, &session_key); smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } - state->req = smb_raw_sesssetup_send(session, &state->setup); - state->req->async.fn = request_handler; - state->req->async.private = c; - return; + if (state->setup.spnego.in.secblob.length) { + state->req = smb_raw_sesssetup_send(session, &state->setup); + state->req->async.fn = request_handler; + state->req->async.private = c; + return; + } } /* enforce the local signing required flag */ @@ -144,9 +157,10 @@ static void request_handler(struct smbcli_request *req) /* send a nt1 style session setup */ -static struct smbcli_request *session_setup_nt1(struct composite_context *c, - struct smbcli_session *session, - struct smb_composite_sesssetup *io) +static NTSTATUS session_setup_nt1(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req) { struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); const struct samr_Password *nt_hash = cli_credentials_get_nt_hash(io->in.credentials, state); @@ -180,7 +194,7 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &session_key)) { data_blob_free(&names_blob); - return NULL; + return NT_STATUS_NO_MEMORY; } data_blob_free(&names_blob); state->setup.nt1.in.password1 = lmv2_response; @@ -218,19 +232,24 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c, state->setup.nt1.in.password2 = data_blob(NULL, 0); } else { /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ - return NULL; + return NT_STATUS_INVALID_PARAMETER; } - return smb_raw_sesssetup_send(session, &state->setup); + *req = smb_raw_sesssetup_send(session, &state->setup); + if (!*req) { + return NT_STATUS_NO_MEMORY; + } + return (*req)->status; } /* old style session setup (pre NT1 protocol level) */ -static struct smbcli_request *session_setup_old(struct composite_context *c, - struct smbcli_session *session, - struct smb_composite_sesssetup *io) +static NTSTATUS session_setup_old(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req) { struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); @@ -256,19 +275,24 @@ static struct smbcli_request *session_setup_old(struct composite_context *c, strlen(password)); } - return smb_raw_sesssetup_send(session, &state->setup); + *req = smb_raw_sesssetup_send(session, &state->setup); + if (!*req) { + return NT_STATUS_NO_MEMORY; + } + return (*req)->status; } /* - old style session setup (pre NT1 protocol level) + Modern, all singing, all dancing extended security (and possibly SPNEGO) request */ -static struct smbcli_request *session_setup_spnego(struct composite_context *c, - struct smbcli_session *session, - struct smb_composite_sesssetup *io) +static NTSTATUS session_setup_spnego(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req) { struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); - NTSTATUS status; + NTSTATUS status, session_key_err; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); const char *chosen_oid = NULL; @@ -290,7 +314,7 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, status = gensec_client_start(session, &session->gensec, c->event_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); - return NULL; + return status; } gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); @@ -299,21 +323,21 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", nt_errstr(status))); - return NULL; + return status; } status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", nt_errstr(status))); - return NULL; + return status; } status = gensec_set_target_service(session->gensec, "cifs"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC target service: %s\n", nt_errstr(status))); - return NULL; + return status; } if (session->transport->negotiate.secblob.length) { @@ -327,24 +351,30 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c, if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return NULL; + return status; } status = gensec_update(session->gensec, state, session->transport->negotiate.secblob, &state->setup.spnego.in.secblob); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return NULL; + return status; } + state->gensec_status = status; - state->session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(state->session_key_err)) { + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); } - return smb_raw_sesssetup_send(session, &state->setup); + *req = smb_raw_sesssetup_send(session, &state->setup); + if (!*req) { + return NT_STATUS_NO_MEMORY; + } + return (*req)->status; } @@ -358,12 +388,16 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se { struct composite_context *c; struct sesssetup_state *state; + NTSTATUS status; c = talloc_zero(session, struct composite_context); - if (c == NULL) goto failed; + if (c == NULL) return NULL; state = talloc(c, struct sesssetup_state); - if (state == NULL) goto failed; + if (state == NULL) { + c->state = SMBCLI_REQUEST_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } state->io = io; @@ -380,24 +414,24 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se /* see what session setup interface we will use */ if (session->transport->negotiate.protocol < PROTOCOL_NT1) { - state->req = session_setup_old(c, session, io); + status = session_setup_old(c, session, io, &state->req); } else if (!session->transport->options.use_spnego || !(io->in.capabilities & CAP_EXTENDED_SECURITY)) { - state->req = session_setup_nt1(c, session, io); + status = session_setup_nt1(c, session, io, &state->req); } else { - state->req = session_setup_spnego(c, session, io); + status = session_setup_spnego(c, session, io, &state->req); } - if (state->req == NULL) goto failed; - - state->req->async.fn = request_handler; - state->req->async.private = c; + if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || + NT_STATUS_IS_OK(status)) { + state->req->async.fn = request_handler; + state->req->async.private = c; + return c; + } + c->state = SMBCLI_REQUEST_ERROR; + c->status = status; return c; - -failed: - talloc_free(c); - return NULL; } diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index e70a56779b..738222da86 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -141,6 +141,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr { NTSTATUS status; TALLOC_CTX *tmp_ctx = NULL; + DATA_BLOB input = data_blob(NULL, 0); DATA_BLOB output = data_blob(NULL, 0); @@ -183,21 +184,35 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr tmp_ctx = talloc_new(conn); if (tmp_ctx == NULL) goto failed; - status = gensec_update(conn->gensec, tmp_ctx, input, &output); - while (1) { + NTSTATUS gensec_status; struct ldap_message *response; struct ldap_message *msg; struct ldap_request *req; int result = LDAP_OTHER; - if (NT_STATUS_IS_OK(status) && output.length == 0) { - break; - } + status = gensec_update(conn->gensec, tmp_ctx, + input, + &output); + /* The status value here, from GENSEC is vital to the security + * of the system. Even if the other end accepts, if GENSEC + * claims 'MORE_PROCESSING_REQUIRED' then you must keep + * feeding it blobs, or else the remote host/attacker might + * avoid mutal authentication requirements. + * + * Likewise, you must not feed GENSEC too much (after the OK), + * it doesn't like that either + */ + + gensec_status = status; + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { break; } + if (output.length == 0) { + break; + } msg = new_ldap_sasl_bind_msg(tmp_ctx, "GSS-SPNEGO", &output); if (msg == NULL) { @@ -225,12 +240,15 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr result = response->r.BindResponse.response.resultcode; if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; } - status = gensec_update(conn->gensec, tmp_ctx, - response->r.BindResponse.SASL.secblob, - &output); + /* This is where we check if GENSEC wanted to be fed more data */ + if (!NT_STATUS_EQUAL(gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + break; + } + input = response->r.BindResponse.SASL.secblob; } if (NT_STATUS_IS_OK(status) && -- cgit From aaa0aff2d6cea65b07320790c16fff127c12a65b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Aug 2005 09:29:32 +0000 Subject: r9510: fix the memory tree metze (This used to be commit 6d412cf0a4186ec04cee61dd5387903de051fde7) --- source4/libcli/security/dom_sid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index f457900efc..c19959f8ae 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -122,7 +122,7 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) return NULL; } - ret->sub_auths = talloc_array(mem_ctx, uint32_t, num_sub_auths); + ret->sub_auths = talloc_array(ret, uint32_t, num_sub_auths); if (!ret->sub_auths) { return NULL; } -- cgit From 7b211a11c34d15aa51d40bab34080e31e48140d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Aug 2005 09:45:38 +0000 Subject: r9511: - fix the memory trees - add a note about a possible talloc_free() metze (This used to be commit 550e3030f0e02720b527f3b4923457f05f484e6e) --- source4/libcli/security/security_descriptor.c | 5 +++-- source4/libcli/security/security_token.c | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 703abf7970..c28960be80 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -317,14 +317,14 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, if (sd == NULL) return NULL; if (owner_sid) { - sd->owner_sid = dom_sid_parse_talloc(mem_ctx, owner_sid); + sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid); if (sd->owner_sid == NULL) { talloc_free(sd); return NULL; } } if (group_sid) { - sd->group_sid = dom_sid_parse_talloc(mem_ctx, group_sid); + sd->group_sid = dom_sid_parse_talloc(sd, group_sid); if (sd->group_sid == NULL) { talloc_free(sd); return NULL; @@ -353,6 +353,7 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, } ace->trustee = *sid; status = security_descriptor_dacl_add(sd, ace); + /* TODO: check: would talloc_free(ace) here be correct? */ if (!NT_STATUS_IS_OK(status)) { va_end(ap); talloc_free(sd); diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index ea1fae0c33..a23aa92bf3 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -78,14 +78,14 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, * The only difference between guest and "anonymous" * is the addition of Authenticated_Users. */ - ptoken->sids[2] = dom_sid_parse_talloc(mem_ctx, SID_WORLD); + ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD); NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); - ptoken->sids[3] = dom_sid_parse_talloc(mem_ctx, SID_NT_NETWORK); + ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK); NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]); ptoken->num_sids = 4; if (is_authenticated) { - ptoken->sids[4] = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHENTICATED_USERS); + ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); ptoken->num_sids++; } @@ -99,9 +99,9 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, break; } } - + if (check_sid_idx == ptoken->num_sids) { - ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken, groupSIDs[i]); + ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); } } -- cgit From 36dcb8425dfe861f74994d13a3b46ade323868d0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Aug 2005 11:40:26 +0000 Subject: r9514: add some new error codes I was getting with DsGetNCChanges() and DsAddEntry() metze (This used to be commit 2cbbb8ace215f56e4e9affd54027bbd74309ae3a) --- source4/libcli/util/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 577c004422..4f977b7e75 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -69,6 +69,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, @@ -80,6 +81,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_DRA_INVALID_PARAMETER", WERR_DS_DRA_INVALID_PARAMETER }, { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, + { "WERR_DS_SINGLE_VALUE_CONSTRAINT", WERR_DS_SINGLE_VALUE_CONSTRAINT }, { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE }, -- cgit From 38e2d25eda98df1b87355e4fdddb1127a6e42762 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Aug 2005 10:58:29 +0000 Subject: r9573: fixed a comment (This used to be commit d151a9459dcbfc88b0dc2ec9dd1cafa18ad5b8f8) --- source4/libcli/security/security_descriptor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index c28960be80..91448e7c35 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -297,7 +297,7 @@ BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, sd = security_descriptor_create(mem_ctx, mysid, mygroup, - SID_AUTHENTICATED_USERS, + SID_NT_AUTHENTICATED_USERS, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_ALL, SEC_ACE_FLAG_OBJECT_INHERIT, -- cgit From 81021aaa953661e711ba0030ab2644664587ad5b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Aug 2005 08:42:29 +0000 Subject: r9638: add error code that you get when you call DsGetNCChanges() with a tmp_highest_usn which is higher than the real highest of the source dsa metze (This used to be commit e4424d2a6dc7a783e8b3af4a164f8dc801130e44) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 4f977b7e75..eecf923bac 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -81,6 +81,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_DRA_INVALID_PARAMETER", WERR_DS_DRA_INVALID_PARAMETER }, { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, + { "WERR_DS_DRA_INTERNAL_ERROR", WERR_DS_DRA_INTERNAL_ERROR }, { "WERR_DS_SINGLE_VALUE_CONSTRAINT", WERR_DS_SINGLE_VALUE_CONSTRAINT }, { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, -- cgit From c98c6aa5611f26ab591c50fcded1fc55e81a0d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 28 Aug 2005 02:37:14 +0000 Subject: r9702: r9680@blu: tridge | 2005-08-27 18:45:08 +1000 - fixed ncacn_ip_tcp to use the generic async name resolution methods, so NBT names now work (as requested several times by abartlet!) - changed resolve_name() to take an event_context, so it doesn't cause the whole process to block - cleaned up the talloc_find_parent_bytype() calls to go via a cleaner event_context_find() call (This used to be commit b3d491b210a8b889a25efcb273e70fefbd01b7f7) --- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/resolve/resolve.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index b325fa473e..90fb98603e 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -326,7 +326,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in nbt_name.type = name_type; nbt_name.scope = NULL; - status = resolve_name(&nbt_name, sock, &address); + status = resolve_name(&nbt_name, sock, &address, sock->event.ctx); if (!NT_STATUS_IS_OK(status)) { return False; } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 3607400155..733eddf643 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -176,9 +176,10 @@ NTSTATUS resolve_name_recv(struct composite_context *c, /* general name resolution - sync call */ -NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) +NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr, + struct event_context *ev) { - struct composite_context *c = resolve_name_send(name, NULL, lp_name_resolve_order()); + struct composite_context *c = resolve_name_send(name, ev, lp_name_resolve_order()); return resolve_name_recv(c, mem_ctx, reply_addr); } -- cgit From 24186a80eb4887b5fb3e72e4b877b456cbe8e35f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Aug 2005 04:30:22 +0000 Subject: r9728: A *major* update to the credentials system, to incorporate the Kerberos CCACHE into the system. This again allows the use of the system ccache when no username is specified, and brings more code in common between gensec_krb5 and gensec_gssapi. It also has a side-effect that may (or may not) be expected: If there is a ccache, even if it is not used (perhaps the remote server didn't want kerberos), it will change the default username. Andrew Bartlett (This used to be commit 6202267f6ec1446d6bd11d1d37d05a977bc8d315) --- source4/libcli/composite/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index b27290d5e4..b925f99bed 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -174,7 +174,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, state->setup.nt1.in.capabilities = io->in.capabilities; state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); - state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials); + state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials, state); state->setup.nt1.in.domain = cli_credentials_get_domain(io->in.credentials); if (!password) { @@ -260,7 +260,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, state->setup.old.in.vc_num = 1; state->setup.old.in.sesskey = io->in.sesskey; state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); - state->setup.old.in.user = cli_credentials_get_username(io->in.credentials); + state->setup.old.in.user = cli_credentials_get_username(io->in.credentials, state); state->setup.old.in.os = "Unix"; state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); -- cgit From 181fde4729d9d7ae9677ec970c7bd7d9bd1455b3 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 31 Aug 2005 13:36:35 +0000 Subject: r9824: r9495@cabra: derrell | 2005-08-31 09:33:55 -0400 add a readme file to indicate what the smbc directory is for (This used to be commit c1a9ea47a326adf529dbf207a75d23f326887a14) --- source4/libcli/smbc/README | 1 + 1 file changed, 1 insertion(+) create mode 100644 source4/libcli/smbc/README (limited to 'source4/libcli') diff --git a/source4/libcli/smbc/README b/source4/libcli/smbc/README new file mode 100644 index 0000000000..66b0782722 --- /dev/null +++ b/source4/libcli/smbc/README @@ -0,0 +1 @@ +This is where the new samba4 libsmbclient will live. -- cgit From 1e05f9a00ae7544f483277cf99f49b8646d1010a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Sep 2005 14:43:15 +0000 Subject: r10081: - create a seperate WINSDB subsystem - use LIBCLI_WREPL for the winsreplication client code - fix some dependencies metze (This used to be commit 7dd931ee5ac1408da8d14d00f43d19473e06871e) --- source4/libcli/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index aec06f8023..663d535a96 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -53,10 +53,10 @@ ADD_OBJ_FILES = \ NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP -[SUBSYSTEM::LIBCLI_WINS] +[SUBSYSTEM::LIBCLI_WREPL] ADD_OBJ_FILES = \ libcli/wins/winsrepl.o -REQUIRED_SUBSYSTEMS = LIBCLI_NBT NDR_WINS SOCKET LIBEVENTS +REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ -- cgit From 561a02d646b3a43014db7814f3af91d1f67110b2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 9 Sep 2005 04:21:19 +0000 Subject: r10103: Put an #ifdef guard around ENOTSUP to fix systems that don't have it (OpenBSD 3.7). (This used to be commit cc24af6545b19ad7710c43399c396e1807f80eeb) --- source4/libcli/util/errormap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 808f5427c6..95fac97428 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1278,7 +1278,9 @@ const struct unix_error_map unix_nt_errmap[] = { { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, { EBUSY, NT_STATUS_SHARING_VIOLATION }, +#ifdef ENOTSUP { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, +#endif #ifdef EHOSTUNREACH { EHOSTUNREACH, NT_STATUS_HOST_UNREACHABLE }, #endif -- cgit From 63ef3c7fdc74e025c5547c391cf61a14ab68dd48 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Sep 2005 16:00:02 +0000 Subject: r10113: rename libcli/wins to libcli/wrepl metze (This used to be commit d8b84112bb40605b07a77ab5f7a44ac1807ccc59) --- source4/libcli/config.mk | 2 +- source4/libcli/wins/winsrepl.c | 701 ---------------------------------------- source4/libcli/wins/winsrepl.h | 114 ------- source4/libcli/wrepl/winsrepl.c | 701 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/wrepl/winsrepl.h | 114 +++++++ 5 files changed, 816 insertions(+), 816 deletions(-) delete mode 100644 source4/libcli/wins/winsrepl.c delete mode 100644 source4/libcli/wins/winsrepl.h create mode 100644 source4/libcli/wrepl/winsrepl.c create mode 100644 source4/libcli/wrepl/winsrepl.h (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 663d535a96..248e0c2b95 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -55,7 +55,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_LDAP [SUBSYSTEM::LIBCLI_WREPL] ADD_OBJ_FILES = \ - libcli/wins/winsrepl.o + libcli/wrepl/winsrepl.o REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] diff --git a/source4/libcli/wins/winsrepl.c b/source4/libcli/wins/winsrepl.c deleted file mode 100644 index 6b02cfb660..0000000000 --- a/source4/libcli/wins/winsrepl.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - low level WINS replication client code - - Copyright (C) Andrew Tridgell 2005 - - 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 "lib/events/events.h" -#include "dlinklist.h" -#include "lib/socket/socket.h" -#include "libcli/wins/winsrepl.h" - -/* - mark all pending requests as dead - called when a socket error happens -*/ -static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket) -{ - event_set_fd_flags(wrepl_socket->fde, 0); - - while (wrepl_socket->send_queue) { - struct wrepl_request *req = wrepl_socket->send_queue; - DLIST_REMOVE(wrepl_socket->send_queue, req); - req->state = WREPL_REQUEST_ERROR; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - if (req->async.fn) { - req->async.fn(req); - } - } - while (wrepl_socket->recv_queue) { - struct wrepl_request *req = wrepl_socket->recv_queue; - DLIST_REMOVE(wrepl_socket->recv_queue, req); - req->state = WREPL_REQUEST_ERROR; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - if (req->async.fn) { - req->async.fn(req); - } - } -} - -/* - handle send events -*/ -static void wrepl_handler_send(struct wrepl_socket *wrepl_socket) -{ - while (wrepl_socket->send_queue) { - struct wrepl_request *req = wrepl_socket->send_queue; - size_t nsent; - NTSTATUS status; - - status = socket_send(wrepl_socket->sock, &req->buffer, &nsent, 0); - if (NT_STATUS_IS_ERR(status)) { - wrepl_socket_dead(wrepl_socket); - return; - } - if (!NT_STATUS_IS_OK(status) || nsent == 0) return; - - req->buffer.data += nsent; - req->buffer.length -= nsent; - if (req->buffer.length != 0) { - return; - } - - DLIST_REMOVE(wrepl_socket->send_queue, req); - DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); - req->state = WREPL_REQUEST_RECV; - - EVENT_FD_READABLE(wrepl_socket->fde); - } - - EVENT_FD_NOT_WRITEABLE(wrepl_socket->fde); -} - - -/* - handle recv events -*/ -static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) -{ - size_t nread; - struct wrepl_request *req = wrepl_socket->recv_queue; - DATA_BLOB blob; - - if (req == NULL) { - EVENT_FD_NOT_READABLE(wrepl_socket->fde); - return; - } - - if (req->buffer.length == 0) { - req->buffer = data_blob_talloc(req, NULL, 4); - if (req->buffer.data == NULL) { - req->status = NT_STATUS_NO_MEMORY; - goto failed; - } - req->num_read = 0; - } - - /* read in the packet length */ - if (req->num_read < 4) { - uint32_t req_length; - - req->status = socket_recv(wrepl_socket->sock, - req->buffer.data + req->num_read, - 4 - req->num_read, - &nread, 0); - if (NT_STATUS_IS_ERR(req->status)) goto failed; - if (!NT_STATUS_IS_OK(req->status)) return; - - req->num_read += nread; - if (req->num_read != 4) return; - - req_length = RIVAL(req->buffer.data, 0) + 4; - - req->buffer.data = talloc_realloc(req, req->buffer.data, - uint8_t, req_length); - if (req->buffer.data == NULL) { - req->status = NT_STATUS_NO_MEMORY; - goto failed; - } - req->buffer.length = req_length; - } - - /* read in the body */ - req->status = socket_recv(wrepl_socket->sock, - req->buffer.data + req->num_read, - req->buffer.length - req->num_read, - &nread, 0); - if (NT_STATUS_IS_ERR(req->status)) goto failed; - if (!NT_STATUS_IS_OK(req->status)) return; - - req->num_read += nread; - if (req->num_read != req->buffer.length) return; - - req->packet = talloc(req, struct wrepl_packet); - if (req->packet == NULL) { - req->status = NT_STATUS_NO_MEMORY; - goto failed; - } - - blob.data = req->buffer.data + 4; - blob.length = req->buffer.length - 4; - - /* we have a full request - parse it */ - req->status = ndr_pull_struct_blob(&blob, - req->packet, req->packet, - (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); - if (!NT_STATUS_IS_OK(req->status)) { - DEBUG(2,("Failed to parse incoming WINS packet - %s\n", - nt_errstr(req->status))); - DEBUG(10,("packet length %d\n", (int)req->buffer.length)); - NDR_PRINT_DEBUG(wrepl_packet, req->packet); - goto failed; - } - - if (DEBUGLVL(10)) { - DEBUG(10,("Received WINS packet of length %d\n", (int)req->buffer.length)); - NDR_PRINT_DEBUG(wrepl_packet, req->packet); - } - - DLIST_REMOVE(wrepl_socket->recv_queue, req); - req->state = WREPL_REQUEST_DONE; - if (req->async.fn) { - req->async.fn(req); - } - return; - -failed: - if (req->state == WREPL_REQUEST_RECV) { - DLIST_REMOVE(wrepl_socket->recv_queue, req); - } - req->state = WREPL_REQUEST_ERROR; - if (req->async.fn) { - req->async.fn(req); - } -} - - -/* - handler for winrepl events -*/ -static void wrepl_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) -{ - struct wrepl_socket *wrepl_socket = talloc_get_type(private, - struct wrepl_socket); - if (flags & EVENT_FD_WRITE) { - wrepl_handler_send(wrepl_socket); - } - if (flags & EVENT_FD_READ) { - wrepl_handler_recv(wrepl_socket); - } -} - - -/* - handler for winrepl connection completion -*/ -static void wrepl_connect_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) -{ - struct wrepl_socket *wrepl_socket = talloc_get_type(private, - struct wrepl_socket); - struct wrepl_request *req = wrepl_socket->recv_queue; - - talloc_free(fde); - - if (req == NULL) return; - - req->status = socket_connect_complete(wrepl_socket->sock, 0); - if (NT_STATUS_IS_ERR(req->status)) goto failed; - - if (!NT_STATUS_IS_OK(req->status)) return; - - wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, - socket_get_fd(wrepl_socket->sock), - 0, - wrepl_handler, wrepl_socket); - if (wrepl_socket->fde == NULL) { - req->status = NT_STATUS_NO_MEMORY; - } - - -failed: - DLIST_REMOVE(wrepl_socket->recv_queue, req); - if (!NT_STATUS_IS_OK(req->status)) { - req->state = WREPL_REQUEST_ERROR; - } else { - req->state = WREPL_REQUEST_DONE; - } - if (req->async.fn) { - req->async.fn(req); - } -} - - -/* - initialise a wrepl_socket. The event_ctx is optional, if provided then - operations will use that event context -*/ -struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) -{ - struct wrepl_socket *wrepl_socket; - NTSTATUS status; - - wrepl_socket = talloc(mem_ctx, struct wrepl_socket); - if (wrepl_socket == NULL) goto failed; - - if (event_ctx == NULL) { - wrepl_socket->event_ctx = event_context_init(wrepl_socket); - } else { - wrepl_socket->event_ctx = talloc_reference(wrepl_socket, event_ctx); - } - if (wrepl_socket->event_ctx == NULL) goto failed; - - status = socket_create("ip", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0); - if (!NT_STATUS_IS_OK(status)) goto failed; - - talloc_steal(wrepl_socket, wrepl_socket->sock); - - wrepl_socket->send_queue = NULL; - wrepl_socket->recv_queue = NULL; - - wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, - socket_get_fd(wrepl_socket->sock), - EVENT_FD_WRITE, - wrepl_connect_handler, wrepl_socket); - - set_blocking(socket_get_fd(wrepl_socket->sock), False); - - return wrepl_socket; - -failed: - talloc_free(wrepl_socket); - return NULL; -} - - -/* - destroy a wrepl_request -*/ -static int wrepl_request_destructor(void *ptr) -{ - struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); - if (req->state == WREPL_REQUEST_SEND) { - DLIST_REMOVE(req->wrepl_socket->send_queue, req); - } - if (req->state == WREPL_REQUEST_RECV) { - DLIST_REMOVE(req->wrepl_socket->recv_queue, req); - } - req->state = WREPL_REQUEST_ERROR; - return 0; -} - -/* - wait for a request to complete -*/ -static NTSTATUS wrepl_request_wait(struct wrepl_request *req) -{ - NT_STATUS_HAVE_NO_MEMORY(req); - while (req->state < WREPL_REQUEST_DONE) { - event_loop_once(req->wrepl_socket->event_ctx); - } - return req->status; -} - - -/* - connect a wrepl_socket to a WINS server -*/ -struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, - const char *address) -{ - struct wrepl_request *req; - NTSTATUS status; - - req = talloc_zero(wrepl_socket, struct wrepl_request); - if (req == NULL) goto failed; - - req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_RECV; - - DLIST_ADD(wrepl_socket->recv_queue, req); - - talloc_set_destructor(req, wrepl_request_destructor); - - status = socket_connect(wrepl_socket->sock, NULL, 0, address, - WINS_REPLICATION_PORT, 0); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) goto failed; - - return req; - -failed: - talloc_free(req); - return NULL; -} - -/* - connect a wrepl_socket to a WINS server - recv side -*/ -NTSTATUS wrepl_connect_recv(struct wrepl_request *req) -{ - return wrepl_request_wait(req); -} - - -/* - connect a wrepl_socket to a WINS server - sync API -*/ -NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *address) -{ - struct wrepl_request *req = wrepl_connect_send(wrepl_socket, address); - return wrepl_connect_recv(req); -} - - -/* - send a generic wins replication request -*/ -struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, - struct wrepl_packet *packet) -{ - struct wrepl_request *req; - struct wrepl_wrap wrap; - - req = talloc_zero(wrepl_socket, struct wrepl_request); - if (req == NULL) goto failed; - - req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_SEND; - - wrap.packet = *packet; - req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, - (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); - if (!NT_STATUS_IS_OK(req->status)) goto failed; - - if (DEBUGLVL(10)) { - DEBUG(10,("Sending WINS packet of length %d\n", (int)req->buffer.length)); - NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); - } - - DLIST_ADD(wrepl_socket->send_queue, req); - - talloc_set_destructor(req, wrepl_request_destructor); - - EVENT_FD_WRITEABLE(wrepl_socket->fde); - - return req; - -failed: - talloc_free(req); - return NULL; -} - -/* - receive a generic WINS replication reply -*/ -NTSTATUS wrepl_request_recv(struct wrepl_request *req, - TALLOC_CTX *mem_ctx, - struct wrepl_packet **packet) -{ - NTSTATUS status = wrepl_request_wait(req); - if (NT_STATUS_IS_OK(status)) { - *packet = talloc_steal(mem_ctx, req->packet); - } - talloc_free(req); - return status; -} - -/* - a full WINS replication request/response -*/ -NTSTATUS wrepl_request(struct wrepl_socket *wrepl_socket, - TALLOC_CTX *mem_ctx, - struct wrepl_packet *req_packet, - struct wrepl_packet **reply_packet) -{ - struct wrepl_request *req = wrepl_request_send(wrepl_socket, req_packet); - return wrepl_request_recv(req, mem_ctx, reply_packet); -} - - -/* - setup an association - send -*/ -struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket, - struct wrepl_associate *io) -{ - struct wrepl_packet *packet; - struct wrepl_request *req; - - packet = talloc_zero(wrepl_socket, struct wrepl_packet); - if (packet == NULL) return NULL; - - packet->opcode = WREPL_OPCODE_BITS; - packet->mess_type = WREPL_START_ASSOCIATION; - packet->message.start.minor_version = 2; - packet->message.start.major_version = 5; - - req = wrepl_request_send(wrepl_socket, packet); - - talloc_free(packet); - - return req; -} - -/* - setup an association - recv -*/ -NTSTATUS wrepl_associate_recv(struct wrepl_request *req, - struct wrepl_associate *io) -{ - struct wrepl_packet *packet=NULL; - NTSTATUS status; - status = wrepl_request_recv(req, req->wrepl_socket, &packet); - if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) { - status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - if (NT_STATUS_IS_OK(status)) { - io->out.assoc_ctx = packet->message.start_reply.assoc_ctx; - } - talloc_free(packet); - return status; -} - -/* - setup an association - sync api -*/ -NTSTATUS wrepl_associate(struct wrepl_socket *wrepl_socket, - struct wrepl_associate *io) -{ - struct wrepl_request *req = wrepl_associate_send(wrepl_socket, io); - return wrepl_associate_recv(req, io); -} - - -/* - fetch the partner tables - send -*/ -struct wrepl_request *wrepl_pull_table_send(struct wrepl_socket *wrepl_socket, - struct wrepl_pull_table *io) -{ - struct wrepl_packet *packet; - struct wrepl_request *req; - - packet = talloc_zero(wrepl_socket, struct wrepl_packet); - if (packet == NULL) return NULL; - - packet->opcode = WREPL_OPCODE_BITS; - packet->assoc_ctx = io->in.assoc_ctx; - packet->mess_type = WREPL_REPLICATION; - packet->message.replication.command = WREPL_REPL_TABLE_QUERY; - - req = wrepl_request_send(wrepl_socket, packet); - - talloc_free(packet); - - return req; -} - - -/* - fetch the partner tables - recv -*/ -NTSTATUS wrepl_pull_table_recv(struct wrepl_request *req, - TALLOC_CTX *mem_ctx, - struct wrepl_pull_table *io) -{ - struct wrepl_packet *packet=NULL; - NTSTATUS status; - struct wrepl_table *table; - int i; - - status = wrepl_request_recv(req, req->wrepl_socket, &packet); - if (packet->mess_type != WREPL_REPLICATION) { - status = NT_STATUS_NETWORK_ACCESS_DENIED; - } else if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) { - status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - if (!NT_STATUS_IS_OK(status)) goto failed; - - table = &packet->message.replication.info.table; - io->out.num_partners = table->partner_count; - io->out.partners = talloc_steal(mem_ctx, table->partners); - for (i=0;iout.num_partners;i++) { - talloc_steal(io->out.partners, io->out.partners[i].address); - } - -failed: - talloc_free(packet); - return status; -} - - -/* - fetch the partner table - sync api -*/ -NTSTATUS wrepl_pull_table(struct wrepl_socket *wrepl_socket, - TALLOC_CTX *mem_ctx, - struct wrepl_pull_table *io) -{ - struct wrepl_request *req = wrepl_pull_table_send(wrepl_socket, io); - return wrepl_pull_table_recv(req, mem_ctx, io); -} - - -/* - fetch the names for a WINS partner - send -*/ -struct wrepl_request *wrepl_pull_names_send(struct wrepl_socket *wrepl_socket, - struct wrepl_pull_names *io) -{ - struct wrepl_packet *packet; - struct wrepl_request *req; - - packet = talloc_zero(wrepl_socket, struct wrepl_packet); - if (packet == NULL) return NULL; - - packet->opcode = WREPL_OPCODE_BITS; - packet->assoc_ctx = io->in.assoc_ctx; - packet->mess_type = WREPL_REPLICATION; - packet->message.replication.command = WREPL_REPL_SEND_REQUEST; - packet->message.replication.info.owner = io->in.partner; - - req = wrepl_request_send(wrepl_socket, packet); - - talloc_free(packet); - - return req; -} - - -/* - extract a nbt_name from a WINS name buffer -*/ -static NTSTATUS wrepl_extract_name(struct nbt_name *name, - TALLOC_CTX *mem_ctx, - uint8_t *namebuf, uint32_t len) -{ - char *s; - - /* oh wow, what a nasty bug in windows ... */ - if (namebuf[0] == 0x1b && len >= 16) { - namebuf[0] = namebuf[15]; - namebuf[15] = 0x1b; - } - - if (len < 17) { - make_nbt_name_client(name, talloc_strndup(mem_ctx, namebuf, len)); - return NT_STATUS_OK; - } - - s = talloc_strndup(mem_ctx, namebuf, 15); - trim_string(s, NULL, " "); - name->name = s; - name->type = namebuf[15]; - if (len > 18) { - name->scope = talloc_strndup(mem_ctx, namebuf+17, len-17); - } else { - name->scope = NULL; - } - - return NT_STATUS_OK; -} - -/* - fetch the names for a WINS partner - recv -*/ -NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, - TALLOC_CTX *mem_ctx, - struct wrepl_pull_names *io) -{ - struct wrepl_packet *packet=NULL; - NTSTATUS status; - int i; - - status = wrepl_request_recv(req, req->wrepl_socket, &packet); - if (packet->mess_type != WREPL_REPLICATION || - packet->message.replication.command != WREPL_REPL_SEND_REPLY) { - status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - if (!NT_STATUS_IS_OK(status)) goto failed; - - io->out.num_names = packet->message.replication.info.reply.num_names; - - status = NT_STATUS_NO_MEMORY; - - io->out.names = talloc_array(packet, struct wrepl_name, io->out.num_names); - if (io->out.names == NULL) goto failed; - - /* convert the list of names and addresses to a sane format */ - for (i=0;iout.num_names;i++) { - struct wrepl_wins_name *wname = &packet->message.replication.info.reply.names[i]; - struct wrepl_name *name = &io->out.names[i]; - status = wrepl_extract_name(&name->name, io->out.names, - wname->name, wname->name_len); - if (!NT_STATUS_IS_OK(status)) goto failed; - - /* trying to save 1 or 2 bytes on the wire isn't a good idea */ - if (wname->flags & 2) { - int j; - - name->num_addresses = wname->addresses.addresses.num_ips; - name->addresses = talloc_array(io->out.names, - struct wrepl_address, - name->num_addresses); - if (name->addresses == NULL) goto failed; - for (j=0;jnum_addresses;j++) { - name->addresses[j].owner = - talloc_steal(name->addresses, - wname->addresses.addresses.ips[j].owner); - name->addresses[j].address = - talloc_steal(name->addresses, - wname->addresses.addresses.ips[j].ip); - } - } else { - name->num_addresses = 1; - name->addresses = talloc(io->out.names, struct wrepl_address); - if (name->addresses == NULL) goto failed; - name->addresses[0].owner = talloc_steal(name->addresses, - wname->addresses.address.owner); - name->addresses[0].address = talloc_steal(name->addresses, - wname->addresses.address.ip); - } - } - - talloc_steal(mem_ctx, io->out.names); - status = NT_STATUS_OK; - -failed: - talloc_free(packet); - return status; -} - - - -/* - fetch the names for a WINS partner - sync api -*/ -NTSTATUS wrepl_pull_names(struct wrepl_socket *wrepl_socket, - TALLOC_CTX *mem_ctx, - struct wrepl_pull_names *io) -{ - struct wrepl_request *req = wrepl_pull_names_send(wrepl_socket, io); - return wrepl_pull_names_recv(req, mem_ctx, io); -} diff --git a/source4/libcli/wins/winsrepl.h b/source4/libcli/wins/winsrepl.h deleted file mode 100644 index 79b7f1fd70..0000000000 --- a/source4/libcli/wins/winsrepl.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - structures for WINS replication client library - - Copyright (C) Andrew Tridgell 2005 - - 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 "librpc/gen_ndr/ndr_nbt.h" -#include "librpc/gen_ndr/ndr_winsrepl.h" - -/* - main context structure for the wins replication client library -*/ -struct wrepl_socket { - struct socket_context *sock; - struct event_context *event_ctx; - - /* a queue of requests pending to be sent */ - struct wrepl_request *send_queue; - - /* a queue of replies waiting to be received */ - struct wrepl_request *recv_queue; - - /* the fd event */ - struct fd_event *fde; -}; - -enum wrepl_request_state { - WREPL_REQUEST_SEND = 0, - WREPL_REQUEST_RECV = 1, - WREPL_REQUEST_DONE = 2, - WREPL_REQUEST_ERROR = 3 -}; - -/* - a WINS replication request -*/ -struct wrepl_request { - struct wrepl_request *next, *prev; - struct wrepl_socket *wrepl_socket; - - enum wrepl_request_state state; - NTSTATUS status; - - DATA_BLOB buffer; - - size_t num_read; - - struct wrepl_packet *packet; - - struct { - void (*fn)(struct wrepl_request *); - void *private; - } async; -}; - - -/* - setup an association -*/ -struct wrepl_associate { - struct { - uint32_t assoc_ctx; - } out; -}; - -/* - pull the partner table -*/ -struct wrepl_pull_table { - struct { - uint32_t assoc_ctx; - } in; - struct { - uint32_t num_partners; - struct wrepl_wins_owner *partners; - } out; -}; - -/* - a full pull replication -*/ -struct wrepl_pull_names { - struct { - uint32_t assoc_ctx; - struct wrepl_wins_owner partner; - } in; - struct { - uint32_t num_names; - struct wrepl_name { - struct nbt_name name; - uint32_t num_addresses; - struct wrepl_address { - const char *owner; - const char *address; - } *addresses; - } *names; - } out; -}; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c new file mode 100644 index 0000000000..d209cb2756 --- /dev/null +++ b/source4/libcli/wrepl/winsrepl.c @@ -0,0 +1,701 @@ +/* + Unix SMB/CIFS implementation. + + low level WINS replication client code + + Copyright (C) Andrew Tridgell 2005 + + 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 "lib/events/events.h" +#include "dlinklist.h" +#include "lib/socket/socket.h" +#include "libcli/wrepl/winsrepl.h" + +/* + mark all pending requests as dead - called when a socket error happens +*/ +static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket) +{ + event_set_fd_flags(wrepl_socket->fde, 0); + + while (wrepl_socket->send_queue) { + struct wrepl_request *req = wrepl_socket->send_queue; + DLIST_REMOVE(wrepl_socket->send_queue, req); + req->state = WREPL_REQUEST_ERROR; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } + while (wrepl_socket->recv_queue) { + struct wrepl_request *req = wrepl_socket->recv_queue; + DLIST_REMOVE(wrepl_socket->recv_queue, req); + req->state = WREPL_REQUEST_ERROR; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } +} + +/* + handle send events +*/ +static void wrepl_handler_send(struct wrepl_socket *wrepl_socket) +{ + while (wrepl_socket->send_queue) { + struct wrepl_request *req = wrepl_socket->send_queue; + size_t nsent; + NTSTATUS status; + + status = socket_send(wrepl_socket->sock, &req->buffer, &nsent, 0); + if (NT_STATUS_IS_ERR(status)) { + wrepl_socket_dead(wrepl_socket); + return; + } + if (!NT_STATUS_IS_OK(status) || nsent == 0) return; + + req->buffer.data += nsent; + req->buffer.length -= nsent; + if (req->buffer.length != 0) { + return; + } + + DLIST_REMOVE(wrepl_socket->send_queue, req); + DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); + req->state = WREPL_REQUEST_RECV; + + EVENT_FD_READABLE(wrepl_socket->fde); + } + + EVENT_FD_NOT_WRITEABLE(wrepl_socket->fde); +} + + +/* + handle recv events +*/ +static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) +{ + size_t nread; + struct wrepl_request *req = wrepl_socket->recv_queue; + DATA_BLOB blob; + + if (req == NULL) { + EVENT_FD_NOT_READABLE(wrepl_socket->fde); + return; + } + + if (req->buffer.length == 0) { + req->buffer = data_blob_talloc(req, NULL, 4); + if (req->buffer.data == NULL) { + req->status = NT_STATUS_NO_MEMORY; + goto failed; + } + req->num_read = 0; + } + + /* read in the packet length */ + if (req->num_read < 4) { + uint32_t req_length; + + req->status = socket_recv(wrepl_socket->sock, + req->buffer.data + req->num_read, + 4 - req->num_read, + &nread, 0); + if (NT_STATUS_IS_ERR(req->status)) goto failed; + if (!NT_STATUS_IS_OK(req->status)) return; + + req->num_read += nread; + if (req->num_read != 4) return; + + req_length = RIVAL(req->buffer.data, 0) + 4; + + req->buffer.data = talloc_realloc(req, req->buffer.data, + uint8_t, req_length); + if (req->buffer.data == NULL) { + req->status = NT_STATUS_NO_MEMORY; + goto failed; + } + req->buffer.length = req_length; + } + + /* read in the body */ + req->status = socket_recv(wrepl_socket->sock, + req->buffer.data + req->num_read, + req->buffer.length - req->num_read, + &nread, 0); + if (NT_STATUS_IS_ERR(req->status)) goto failed; + if (!NT_STATUS_IS_OK(req->status)) return; + + req->num_read += nread; + if (req->num_read != req->buffer.length) return; + + req->packet = talloc(req, struct wrepl_packet); + if (req->packet == NULL) { + req->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + blob.data = req->buffer.data + 4; + blob.length = req->buffer.length - 4; + + /* we have a full request - parse it */ + req->status = ndr_pull_struct_blob(&blob, + req->packet, req->packet, + (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); + if (!NT_STATUS_IS_OK(req->status)) { + DEBUG(2,("Failed to parse incoming WINS packet - %s\n", + nt_errstr(req->status))); + DEBUG(10,("packet length %d\n", (int)req->buffer.length)); + NDR_PRINT_DEBUG(wrepl_packet, req->packet); + goto failed; + } + + if (DEBUGLVL(10)) { + DEBUG(10,("Received WINS packet of length %d\n", (int)req->buffer.length)); + NDR_PRINT_DEBUG(wrepl_packet, req->packet); + } + + DLIST_REMOVE(wrepl_socket->recv_queue, req); + req->state = WREPL_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + return; + +failed: + if (req->state == WREPL_REQUEST_RECV) { + DLIST_REMOVE(wrepl_socket->recv_queue, req); + } + req->state = WREPL_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + handler for winrepl events +*/ +static void wrepl_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct wrepl_socket *wrepl_socket = talloc_get_type(private, + struct wrepl_socket); + if (flags & EVENT_FD_WRITE) { + wrepl_handler_send(wrepl_socket); + } + if (flags & EVENT_FD_READ) { + wrepl_handler_recv(wrepl_socket); + } +} + + +/* + handler for winrepl connection completion +*/ +static void wrepl_connect_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct wrepl_socket *wrepl_socket = talloc_get_type(private, + struct wrepl_socket); + struct wrepl_request *req = wrepl_socket->recv_queue; + + talloc_free(fde); + + if (req == NULL) return; + + req->status = socket_connect_complete(wrepl_socket->sock, 0); + if (NT_STATUS_IS_ERR(req->status)) goto failed; + + if (!NT_STATUS_IS_OK(req->status)) return; + + wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + 0, + wrepl_handler, wrepl_socket); + if (wrepl_socket->fde == NULL) { + req->status = NT_STATUS_NO_MEMORY; + } + + +failed: + DLIST_REMOVE(wrepl_socket->recv_queue, req); + if (!NT_STATUS_IS_OK(req->status)) { + req->state = WREPL_REQUEST_ERROR; + } else { + req->state = WREPL_REQUEST_DONE; + } + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + initialise a wrepl_socket. The event_ctx is optional, if provided then + operations will use that event context +*/ +struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) +{ + struct wrepl_socket *wrepl_socket; + NTSTATUS status; + + wrepl_socket = talloc(mem_ctx, struct wrepl_socket); + if (wrepl_socket == NULL) goto failed; + + if (event_ctx == NULL) { + wrepl_socket->event_ctx = event_context_init(wrepl_socket); + } else { + wrepl_socket->event_ctx = talloc_reference(wrepl_socket, event_ctx); + } + if (wrepl_socket->event_ctx == NULL) goto failed; + + status = socket_create("ip", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0); + if (!NT_STATUS_IS_OK(status)) goto failed; + + talloc_steal(wrepl_socket, wrepl_socket->sock); + + wrepl_socket->send_queue = NULL; + wrepl_socket->recv_queue = NULL; + + wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + EVENT_FD_WRITE, + wrepl_connect_handler, wrepl_socket); + + set_blocking(socket_get_fd(wrepl_socket->sock), False); + + return wrepl_socket; + +failed: + talloc_free(wrepl_socket); + return NULL; +} + + +/* + destroy a wrepl_request +*/ +static int wrepl_request_destructor(void *ptr) +{ + struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); + if (req->state == WREPL_REQUEST_SEND) { + DLIST_REMOVE(req->wrepl_socket->send_queue, req); + } + if (req->state == WREPL_REQUEST_RECV) { + DLIST_REMOVE(req->wrepl_socket->recv_queue, req); + } + req->state = WREPL_REQUEST_ERROR; + return 0; +} + +/* + wait for a request to complete +*/ +static NTSTATUS wrepl_request_wait(struct wrepl_request *req) +{ + NT_STATUS_HAVE_NO_MEMORY(req); + while (req->state < WREPL_REQUEST_DONE) { + event_loop_once(req->wrepl_socket->event_ctx); + } + return req->status; +} + + +/* + connect a wrepl_socket to a WINS server +*/ +struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, + const char *address) +{ + struct wrepl_request *req; + NTSTATUS status; + + req = talloc_zero(wrepl_socket, struct wrepl_request); + if (req == NULL) goto failed; + + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_RECV; + + DLIST_ADD(wrepl_socket->recv_queue, req); + + talloc_set_destructor(req, wrepl_request_destructor); + + status = socket_connect(wrepl_socket->sock, NULL, 0, address, + WINS_REPLICATION_PORT, 0); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) goto failed; + + return req; + +failed: + talloc_free(req); + return NULL; +} + +/* + connect a wrepl_socket to a WINS server - recv side +*/ +NTSTATUS wrepl_connect_recv(struct wrepl_request *req) +{ + return wrepl_request_wait(req); +} + + +/* + connect a wrepl_socket to a WINS server - sync API +*/ +NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *address) +{ + struct wrepl_request *req = wrepl_connect_send(wrepl_socket, address); + return wrepl_connect_recv(req); +} + + +/* + send a generic wins replication request +*/ +struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, + struct wrepl_packet *packet) +{ + struct wrepl_request *req; + struct wrepl_wrap wrap; + + req = talloc_zero(wrepl_socket, struct wrepl_request); + if (req == NULL) goto failed; + + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_SEND; + + wrap.packet = *packet; + req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, + (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); + if (!NT_STATUS_IS_OK(req->status)) goto failed; + + if (DEBUGLVL(10)) { + DEBUG(10,("Sending WINS packet of length %d\n", (int)req->buffer.length)); + NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); + } + + DLIST_ADD(wrepl_socket->send_queue, req); + + talloc_set_destructor(req, wrepl_request_destructor); + + EVENT_FD_WRITEABLE(wrepl_socket->fde); + + return req; + +failed: + talloc_free(req); + return NULL; +} + +/* + receive a generic WINS replication reply +*/ +NTSTATUS wrepl_request_recv(struct wrepl_request *req, + TALLOC_CTX *mem_ctx, + struct wrepl_packet **packet) +{ + NTSTATUS status = wrepl_request_wait(req); + if (NT_STATUS_IS_OK(status)) { + *packet = talloc_steal(mem_ctx, req->packet); + } + talloc_free(req); + return status; +} + +/* + a full WINS replication request/response +*/ +NTSTATUS wrepl_request(struct wrepl_socket *wrepl_socket, + TALLOC_CTX *mem_ctx, + struct wrepl_packet *req_packet, + struct wrepl_packet **reply_packet) +{ + struct wrepl_request *req = wrepl_request_send(wrepl_socket, req_packet); + return wrepl_request_recv(req, mem_ctx, reply_packet); +} + + +/* + setup an association - send +*/ +struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket, + struct wrepl_associate *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->mess_type = WREPL_START_ASSOCIATION; + packet->message.start.minor_version = 2; + packet->message.start.major_version = 5; + + req = wrepl_request_send(wrepl_socket, packet); + + talloc_free(packet); + + return req; +} + +/* + setup an association - recv +*/ +NTSTATUS wrepl_associate_recv(struct wrepl_request *req, + struct wrepl_associate *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + if (NT_STATUS_IS_OK(status)) { + io->out.assoc_ctx = packet->message.start_reply.assoc_ctx; + } + talloc_free(packet); + return status; +} + +/* + setup an association - sync api +*/ +NTSTATUS wrepl_associate(struct wrepl_socket *wrepl_socket, + struct wrepl_associate *io) +{ + struct wrepl_request *req = wrepl_associate_send(wrepl_socket, io); + return wrepl_associate_recv(req, io); +} + + +/* + fetch the partner tables - send +*/ +struct wrepl_request *wrepl_pull_table_send(struct wrepl_socket *wrepl_socket, + struct wrepl_pull_table *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->assoc_ctx = io->in.assoc_ctx; + packet->mess_type = WREPL_REPLICATION; + packet->message.replication.command = WREPL_REPL_TABLE_QUERY; + + req = wrepl_request_send(wrepl_socket, packet); + + talloc_free(packet); + + return req; +} + + +/* + fetch the partner tables - recv +*/ +NTSTATUS wrepl_pull_table_recv(struct wrepl_request *req, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_table *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + struct wrepl_table *table; + int i; + + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + if (packet->mess_type != WREPL_REPLICATION) { + status = NT_STATUS_NETWORK_ACCESS_DENIED; + } else if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + if (!NT_STATUS_IS_OK(status)) goto failed; + + table = &packet->message.replication.info.table; + io->out.num_partners = table->partner_count; + io->out.partners = talloc_steal(mem_ctx, table->partners); + for (i=0;iout.num_partners;i++) { + talloc_steal(io->out.partners, io->out.partners[i].address); + } + +failed: + talloc_free(packet); + return status; +} + + +/* + fetch the partner table - sync api +*/ +NTSTATUS wrepl_pull_table(struct wrepl_socket *wrepl_socket, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_table *io) +{ + struct wrepl_request *req = wrepl_pull_table_send(wrepl_socket, io); + return wrepl_pull_table_recv(req, mem_ctx, io); +} + + +/* + fetch the names for a WINS partner - send +*/ +struct wrepl_request *wrepl_pull_names_send(struct wrepl_socket *wrepl_socket, + struct wrepl_pull_names *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->assoc_ctx = io->in.assoc_ctx; + packet->mess_type = WREPL_REPLICATION; + packet->message.replication.command = WREPL_REPL_SEND_REQUEST; + packet->message.replication.info.owner = io->in.partner; + + req = wrepl_request_send(wrepl_socket, packet); + + talloc_free(packet); + + return req; +} + + +/* + extract a nbt_name from a WINS name buffer +*/ +static NTSTATUS wrepl_extract_name(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + uint8_t *namebuf, uint32_t len) +{ + char *s; + + /* oh wow, what a nasty bug in windows ... */ + if (namebuf[0] == 0x1b && len >= 16) { + namebuf[0] = namebuf[15]; + namebuf[15] = 0x1b; + } + + if (len < 17) { + make_nbt_name_client(name, talloc_strndup(mem_ctx, namebuf, len)); + return NT_STATUS_OK; + } + + s = talloc_strndup(mem_ctx, namebuf, 15); + trim_string(s, NULL, " "); + name->name = s; + name->type = namebuf[15]; + if (len > 18) { + name->scope = talloc_strndup(mem_ctx, namebuf+17, len-17); + } else { + name->scope = NULL; + } + + return NT_STATUS_OK; +} + +/* + fetch the names for a WINS partner - recv +*/ +NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_names *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + int i; + + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + if (packet->mess_type != WREPL_REPLICATION || + packet->message.replication.command != WREPL_REPL_SEND_REPLY) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + if (!NT_STATUS_IS_OK(status)) goto failed; + + io->out.num_names = packet->message.replication.info.reply.num_names; + + status = NT_STATUS_NO_MEMORY; + + io->out.names = talloc_array(packet, struct wrepl_name, io->out.num_names); + if (io->out.names == NULL) goto failed; + + /* convert the list of names and addresses to a sane format */ + for (i=0;iout.num_names;i++) { + struct wrepl_wins_name *wname = &packet->message.replication.info.reply.names[i]; + struct wrepl_name *name = &io->out.names[i]; + status = wrepl_extract_name(&name->name, io->out.names, + wname->name, wname->name_len); + if (!NT_STATUS_IS_OK(status)) goto failed; + + /* trying to save 1 or 2 bytes on the wire isn't a good idea */ + if (wname->flags & 2) { + int j; + + name->num_addresses = wname->addresses.addresses.num_ips; + name->addresses = talloc_array(io->out.names, + struct wrepl_address, + name->num_addresses); + if (name->addresses == NULL) goto failed; + for (j=0;jnum_addresses;j++) { + name->addresses[j].owner = + talloc_steal(name->addresses, + wname->addresses.addresses.ips[j].owner); + name->addresses[j].address = + talloc_steal(name->addresses, + wname->addresses.addresses.ips[j].ip); + } + } else { + name->num_addresses = 1; + name->addresses = talloc(io->out.names, struct wrepl_address); + if (name->addresses == NULL) goto failed; + name->addresses[0].owner = talloc_steal(name->addresses, + wname->addresses.address.owner); + name->addresses[0].address = talloc_steal(name->addresses, + wname->addresses.address.ip); + } + } + + talloc_steal(mem_ctx, io->out.names); + status = NT_STATUS_OK; + +failed: + talloc_free(packet); + return status; +} + + + +/* + fetch the names for a WINS partner - sync api +*/ +NTSTATUS wrepl_pull_names(struct wrepl_socket *wrepl_socket, + TALLOC_CTX *mem_ctx, + struct wrepl_pull_names *io) +{ + struct wrepl_request *req = wrepl_pull_names_send(wrepl_socket, io); + return wrepl_pull_names_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h new file mode 100644 index 0000000000..79b7f1fd70 --- /dev/null +++ b/source4/libcli/wrepl/winsrepl.h @@ -0,0 +1,114 @@ +/* + Unix SMB/CIFS implementation. + + structures for WINS replication client library + + Copyright (C) Andrew Tridgell 2005 + + 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 "librpc/gen_ndr/ndr_nbt.h" +#include "librpc/gen_ndr/ndr_winsrepl.h" + +/* + main context structure for the wins replication client library +*/ +struct wrepl_socket { + struct socket_context *sock; + struct event_context *event_ctx; + + /* a queue of requests pending to be sent */ + struct wrepl_request *send_queue; + + /* a queue of replies waiting to be received */ + struct wrepl_request *recv_queue; + + /* the fd event */ + struct fd_event *fde; +}; + +enum wrepl_request_state { + WREPL_REQUEST_SEND = 0, + WREPL_REQUEST_RECV = 1, + WREPL_REQUEST_DONE = 2, + WREPL_REQUEST_ERROR = 3 +}; + +/* + a WINS replication request +*/ +struct wrepl_request { + struct wrepl_request *next, *prev; + struct wrepl_socket *wrepl_socket; + + enum wrepl_request_state state; + NTSTATUS status; + + DATA_BLOB buffer; + + size_t num_read; + + struct wrepl_packet *packet; + + struct { + void (*fn)(struct wrepl_request *); + void *private; + } async; +}; + + +/* + setup an association +*/ +struct wrepl_associate { + struct { + uint32_t assoc_ctx; + } out; +}; + +/* + pull the partner table +*/ +struct wrepl_pull_table { + struct { + uint32_t assoc_ctx; + } in; + struct { + uint32_t num_partners; + struct wrepl_wins_owner *partners; + } out; +}; + +/* + a full pull replication +*/ +struct wrepl_pull_names { + struct { + uint32_t assoc_ctx; + struct wrepl_wins_owner partner; + } in; + struct { + uint32_t num_names; + struct wrepl_name { + struct nbt_name name; + uint32_t num_addresses; + struct wrepl_address { + const char *owner; + const char *address; + } *addresses; + } *names; + } out; +}; -- cgit From 13f7e6a0c6d3cc4c0cff59827f49a245712d99b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Sep 2005 16:01:49 +0000 Subject: r10115: bind client connection to the best interface, to the partner metze (This used to be commit e44aca0a8eb41abbaa494d379dd61713dc57c4f3) --- source4/libcli/wrepl/winsrepl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index d209cb2756..910bed278c 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -339,7 +339,7 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, talloc_set_destructor(req, wrepl_request_destructor); - status = socket_connect(wrepl_socket->sock, NULL, 0, address, + status = socket_connect(wrepl_socket->sock, iface_best_ip(address), 0, address, WINS_REPLICATION_PORT, 0); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) goto failed; -- cgit From 9cd63ddb5d9f4c5191a8b4b32c99de4c72344111 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Sep 2005 19:55:34 +0000 Subject: r10129: fix sinple ip's in wins replication, packets metze (This used to be commit 7492afa48db68ee29048f8e1a56ccff712a3d162) --- source4/libcli/wrepl/winsrepl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 910bed278c..516c72ef29 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -672,10 +672,9 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, name->num_addresses = 1; name->addresses = talloc(io->out.names, struct wrepl_address); if (name->addresses == NULL) goto failed; - name->addresses[0].owner = talloc_steal(name->addresses, - wname->addresses.address.owner); + name->addresses[0].owner = io->in.partner.address; name->addresses[0].address = talloc_steal(name->addresses, - wname->addresses.address.ip); + wname->addresses.ip); } } -- cgit From f642fd96d0b196e7bb71bb73ffbefac32786d25f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 12 Sep 2005 21:40:40 +0000 Subject: r10185: Fix another two sets of unhandled enumeration warnings, plus correct some awful indentation. (-: (This used to be commit 2f24fc7a7a195c04f88a25d52efc02ddf491126c) --- source4/libcli/security/access_check.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index c10751abce..0ffca1ade8 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -67,13 +67,15 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, } switch (ace->type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED: - granted |= ace->access_mask; - break; - case SEC_ACE_TYPE_ACCESS_DENIED: - case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - denied |= ace->access_mask; - break; + case SEC_ACE_TYPE_ACCESS_ALLOWED: + granted |= ace->access_mask; + break; + case SEC_ACE_TYPE_ACCESS_DENIED: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + denied |= ace->access_mask; + break; + default: /* Other ACE types not handled/supported */ + break; } } @@ -153,6 +155,8 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, return NT_STATUS_ACCESS_DENIED; } break; + default: /* Other ACE types not handled/supported */ + break; } } -- cgit From 45f760973d9b5c0663608e779eb337c0648e9313 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Sep 2005 12:46:03 +0000 Subject: r10200: added a composite_trigger_done() call that allows a composite function to cause an event to happen immediately. This allows metzes patch for recognising IPs in resolve_name() to work, and also allows us to remove some of the other code where we currently do specific checks for is_ipaddress(). (This used to be commit 9cc000d868e1257ef6429f6f6f1f9d3c28ca330f) --- source4/libcli/composite/composite.c | 24 ++++++++++++++++++++++++ source4/libcli/composite/connect.c | 14 +++----------- source4/libcli/resolve/resolve.c | 9 +++++++++ 3 files changed, 36 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 2b8ddea897..f04309bbfb 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -44,3 +44,27 @@ NTSTATUS composite_wait(struct composite_context *c) } +/* + callback from composite_trigger_done() +*/ +static void composite_trigger(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct composite_context *c = talloc_get_type(ptr, struct composite_context); + c->state = SMBCLI_REQUEST_DONE; + if (c->async.fn) { + c->async.fn(c); + } +} + + +/* + trigger an immediate 'done' event on a composite context + this is used when the composite code works out that the call + can be completed without waiting for any external event +*/ +void composite_trigger_done(struct composite_context *c) +{ + /* a zero timeout means immediate */ + event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); +} diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c index 4d35f5c73a..a5ce5308e5 100644 --- a/source4/libcli/composite/connect.c +++ b/source4/libcli/composite/connect.c @@ -352,17 +352,9 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec c->event_ctx = talloc_reference(c, state->sock->event.ctx); c->private = state; - /* if the destination is an IP address, then skip the name resolution part */ - if (is_ipaddress(io->in.dest_host)) { - state->stage = CONNECT_SOCKET; - state->creq = smbcli_sock_connect_send(state->sock, io->in.dest_host, - state->io->in.port, - io->in.dest_host); - } else { - state->stage = CONNECT_RESOLVE; - make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); - } + state->stage = CONNECT_RESOLVE; + make_nbt_name_server(&name, io->in.dest_host); + state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); if (state->creq == NULL) goto failed; state->creq->async.private = c; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 733eddf643..d62890434b 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -144,6 +144,15 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ c->event_ctx = talloc_reference(c, event_ctx); } + if (is_ipaddress(state->name.name) || + strcasecmp(state->name.name, "localhost") == 0) { + struct ipv4_addr ip = interpret_addr2(state->name.name); + state->reply_addr = talloc_strdup(state, sys_inet_ntoa(ip)); + if (!state->reply_addr) goto failed; + composite_trigger_done(c); + return c; + } + state->req = setup_next_method(c); if (state->req == NULL) goto failed; -- cgit From a129ad36eb34bbeda80c75b2f8d771bdaca8451e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Sep 2005 22:05:45 +0000 Subject: r10213: fixed a memory leak in the ldap client and server code spotted by Karl Melcher. ldap_encode() now takes a memory context to use for the data blob (This used to be commit 09948a59336a7f02bf2b4605f2d4d886e65b85f2) --- source4/libcli/cldap/cldap.c | 9 +++------ source4/libcli/ldap/ldap.c | 4 ++-- source4/libcli/ldap/ldap_client.c | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 4ffa40d134..07744553c8 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -337,12 +337,11 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, goto failed; } - if (!ldap_encode(msg, &req->encoded)) { + if (!ldap_encode(msg, &req->encoded, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest_addr, req->dest_port)); goto failed; } - talloc_steal(req, req->encoded.data); DLIST_ADD_END(cldap->send_queue, req, struct cldap_request *); @@ -389,13 +388,12 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultEntry; msg->r.SearchResultEntry = *io->response; - if (!ldap_encode(msg, &blob1)) { + if (!ldap_encode(msg, &blob1, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest_addr, req->dest_port)); status = NT_STATUS_INVALID_PARAMETER; goto failed; } - talloc_steal(req, blob1.data); } else { blob1 = data_blob(NULL, 0); } @@ -403,13 +401,12 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultDone; msg->r.SearchResultDone = *io->result; - if (!ldap_encode(msg, &blob2)) { + if (!ldap_encode(msg, &blob2, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest_addr, req->dest_port)); status = NT_STATUS_INVALID_PARAMETER; goto failed; } - talloc_steal(req, blob2.data); req->encoded = data_blob_talloc(req, NULL, blob1.length + blob2.length); if (req->encoded.data == NULL) goto failed; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index f7f6feea38..815d543038 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -189,7 +189,7 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) +BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data data; int i, j; @@ -462,7 +462,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) return False; } - *result = data_blob(data.data, data.length); + *result = data_blob_talloc(mem_ctx, data.data, data.length); asn1_free(&data); return True; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 97b75602aa..800e523eb4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -497,7 +497,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; - if (!ldap_encode(msg, &req->data)) { + if (!ldap_encode(msg, &req->data, req)) { goto failed; } -- cgit From 5b02ee9b9d7037b385cf4f1c3eca81b28ff19690 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 Sep 2005 00:39:19 +0000 Subject: r10336: Add sconscript for a couple more subsystems. (This used to be commit 59d4450453c25f5cce9b67b808ff0c4433c1d194) --- source4/libcli/SConscript | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 source4/libcli/SConscript (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript new file mode 100644 index 0000000000..4992197166 --- /dev/null +++ b/source4/libcli/SConscript @@ -0,0 +1,40 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_utils', + ['util/asn1.c', 'util/doserr.c','util/errormap.c','util/clierror.c', + 'util/nterr.c','util/smbdes.c']) + +hostenv.StaticLibrary('cli_lsa', ['util/clilsa.c']) +hostenv.StaticLibrary('cli_composite_base', ['composite/composite.c']) +hostenv.StaticLibrary('cli_composite', + ['composite/loadfile.c','composite/savefile.c','composite/connect.c', + 'composite/sesssetup.c','composite/fetchfile.c','composite/appendacl.c', + 'composite/fsinfo.c']) + +hostenv.StaticLibrary('cli_nbt', + ['nbt/nbtname.c','nbt/nbtsocket.c','nbt/namequery.c','nbt/nameregister.c', + 'nbt/namerefresh.c','nbt/namerelease.c']) + +hostenv.StaticLibrary('cli_dgram', + [ 'dgram/dgramsocket.c','dgram/mailslot.c','dgram/netlogon.c', + 'dgram/ntlogon.c','dgram/browse.c']) + +hostenv.StaticLibrary('cli_cldap', ['cldap/cldap.c']) +hostenv.StaticLibrary('cli_wrepl', ['wrepl/winsrepl.c']) +hostenv.StaticLibrary('cli_resolve', + ['resolve/resolve.c','resolve/nbtlist.c','resolve/bcast.c','resolve/wins.c', + 'resolve/host.c']) + + +hostenv.StaticLibrary('smb', + ['clireadwrite.c', 'cliconnect.c','clifile.c','clilist.c','clitrans2.c', + 'climessage.c','clideltree.c']) + +hostenv.StaticLibrary('cli_raw', + ['raw/rawfile.c','raw/smb_signing.c','raw/clisocket.c', + 'raw/clitransport.c','raw/clisession.c','raw/clitree.c', + 'raw/rawrequest.c','raw/rawreadwrite.c','raw/rawsearch.c', + 'raw/rawsetfileinfo.c','raw/raweas.c','raw/rawtrans.c', + 'raw/clioplock.c','raw/rawnegotiate.c','raw/rawfsinfo.c', + 'raw/rawfileinfo.c','raw/rawnotify.c','raw/rawioctl.c', + 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c']) -- cgit From 6812c73534001d2dd05a9a74358d2b6d0029f1a7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 Sep 2005 11:59:03 +0000 Subject: r10348: Add scons scripts for remaining subsystems. Most subsystems build now, but final linking still fails (as does generating files asn1, et, idl and proto files) (This used to be commit 4f0d7f75b99c7f4388d8acb0838577d86baf68b5) --- source4/libcli/SConscript | 3 ++- source4/libcli/auth/SConscript | 3 +++ source4/libcli/ldap/SConscript | 5 +++++ source4/libcli/security/SConscript | 5 +++++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/auth/SConscript create mode 100644 source4/libcli/ldap/SConscript create mode 100644 source4/libcli/security/SConscript (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index 4992197166..d073f2e5db 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -1,5 +1,4 @@ Import('hostenv') - hostenv.StaticLibrary('cli_utils', ['util/asn1.c', 'util/doserr.c','util/errormap.c','util/clierror.c', 'util/nterr.c','util/smbdes.c']) @@ -38,3 +37,5 @@ hostenv.StaticLibrary('cli_raw', 'raw/clioplock.c','raw/rawnegotiate.c','raw/rawfsinfo.c', 'raw/rawfileinfo.c','raw/rawnotify.c','raw/rawioctl.c', 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c']) + +SConscript(dirs=['auth','ldap','security'],exports='hostenv') diff --git a/source4/libcli/auth/SConscript b/source4/libcli/auth/SConscript new file mode 100644 index 0000000000..d527faac30 --- /dev/null +++ b/source4/libcli/auth/SConscript @@ -0,0 +1,3 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_auth',['credentials.c','session.c','smbencrypt.c']) diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript new file mode 100644 index 0000000000..eef9a9f41c --- /dev/null +++ b/source4/libcli/ldap/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_ldap', + ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', + 'ldap_ildap.c']) diff --git a/source4/libcli/security/SConscript b/source4/libcli/security/SConscript new file mode 100644 index 0000000000..e81051e07e --- /dev/null +++ b/source4/libcli/security/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_security', + ['security_token.c','security_descriptor.c','dom_sid.c', + 'access_check.c','privilege.c']) -- cgit From e0febb258a29ac5deb034075219114337f468001 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Sep 2005 16:35:15 +0000 Subject: r10395: While playing with winbind, I found a segfault because I had given resolve_name_send a stack-allocated method list. Duplicate it. Volker (This used to be commit 17dbbf965bcf038be7450781e28acb5e061eb295) --- source4/libcli/resolve/resolve.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index d62890434b..c21b29b57f 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -133,7 +133,8 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ if (!NT_STATUS_IS_OK(status)) goto failed; if (methods == NULL) goto failed; - state->methods = methods; + state->methods = str_list_copy(state, methods); + if (state->methods == NULL) goto failed; c->state = SMBCLI_REQUEST_SEND; c->private = state; -- cgit From 51cbc188df03f9ee38599fe5a87ec2608117a845 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Sep 2005 01:50:58 +0000 Subject: r10402: Make the RPC-SAMLOGON test pass against Win2k3 SP0 again. I still have issues with Win2k3 SP1, and Samba4 doesn't pass it's own test for the moment, but I'm working on these issues :-) This required a change to the credentials API, so that the special case for NTLM logins using a principal was indeed handled as a special, not general case. Also don't set the realm from a ccache, as then it overrides --option=realm=. Andrew Bartlett (This used to be commit 194e8f07c0cb4685797c5a7a074577c62dfdebe3) --- source4/libcli/composite/sesssetup.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c index b925f99bed..3bd9ed285d 100644 --- a/source4/libcli/composite/sesssetup.c +++ b/source4/libcli/composite/sesssetup.c @@ -174,8 +174,9 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, state->setup.nt1.in.capabilities = io->in.capabilities; state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); - state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials, state); - state->setup.nt1.in.domain = cli_credentials_get_domain(io->in.credentials); + cli_credentials_get_ntlm_username_domain(io->in.credentials, state, + &state->setup.nt1.in.user, + &state->setup.nt1.in.domain); if (!password) { state->setup.nt1.in.password1 = data_blob(NULL, 0); @@ -259,10 +260,11 @@ static NTSTATUS session_setup_old(struct composite_context *c, state->setup.old.in.mpx_max = session->transport->options.max_mux; state->setup.old.in.vc_num = 1; state->setup.old.in.sesskey = io->in.sesskey; - state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials); - state->setup.old.in.user = cli_credentials_get_username(io->in.credentials, state); state->setup.old.in.os = "Unix"; state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); + cli_credentials_get_ntlm_username_domain(io->in.credentials, state, + &state->setup.old.in.user, + &state->setup.old.in.domain); if (!password) { state->setup.old.in.password = data_blob(NULL, 0); -- cgit From f3b412fbd6dd94d64eb6a63d88baef2816891c29 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 Sep 2005 00:38:22 +0000 Subject: r10438: Move portability functions to lib/replace/; replace now simply ensures that a given set of (working) POSIX functions are available (without prefixes to their names, etc). See lib/replace/README for a list. Functions that behave different from their POSIX specification (such as sys_select, sys_read, etc) have kept the sys_ prefix. (This used to be commit 29919a71059b29fa27a49b1f5b84bb8881de65fc) --- source4/libcli/resolve/host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 9f48f83ba4..a5edfcbc8a 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -105,7 +105,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, /* enusre the address looks good */ address[ret] = 0; if (strcmp(address, "0.0.0.0") == 0 || - sys_inet_addr(address) == INADDR_NONE) { + inet_addr(address) == INADDR_NONE) { goto failed; } -- cgit From 3d4ea18d4dd9031adc16348c16595d6c216b2d84 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 Sep 2005 16:23:41 +0000 Subject: r10478: More work on proto headers; we now generate a couple of smaller ones that are then included by include/proto.h (This used to be commit 703ffbaaaca11f3d8781cfe9e7542fcaa626d991) --- source4/libcli/SConscript | 24 ++++++++++++++++++++---- source4/libcli/auth/SConscript | 3 --- source4/libcli/ldap/SConscript | 5 ----- source4/libcli/security/SConscript | 5 ----- 4 files changed, 20 insertions(+), 17 deletions(-) delete mode 100644 source4/libcli/auth/SConscript delete mode 100644 source4/libcli/ldap/SConscript delete mode 100644 source4/libcli/security/SConscript (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index d073f2e5db..8240e0fc2b 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -1,7 +1,8 @@ Import('hostenv') -hostenv.StaticLibrary('cli_utils', - ['util/asn1.c', 'util/doserr.c','util/errormap.c','util/clierror.c', - 'util/nterr.c','util/smbdes.c']) +proto_files = [] +cli_utils_files = ['util/asn1.c', 'util/doserr.c','util/errormap.c','util/clierror.c', 'util/nterr.c','util/smbdes.c'] +proto_files += cli_utils_files +hostenv.StaticLibrary('cli_utils', cli_utils_files) hostenv.StaticLibrary('cli_lsa', ['util/clilsa.c']) hostenv.StaticLibrary('cli_composite_base', ['composite/composite.c']) @@ -38,4 +39,19 @@ hostenv.StaticLibrary('cli_raw', 'raw/rawfileinfo.c','raw/rawnotify.c','raw/rawioctl.c', 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c']) -SConscript(dirs=['auth','ldap','security'],exports='hostenv') +security_files = ['security/security_token.c','security/security_descriptor.c', + 'security/dom_sid.c', 'security/access_check.c', + 'security/privilege.c', '../librpc/ndr/ndr_sec_helper.c'] +proto_files += security_files +hostenv.StaticLibrary('cli_security', security_files) + +auth_files = ['auth/credentials.c','auth/session.c','auth/smbencrypt.c'] +proto_files += auth_files +hostenv.StaticLibrary('cli_auth',auth_files) + +ldap_files = ['ldap/ldap.c','ldap/ldap_client.c','ldap/ldap_bind.c', + 'ldap/ldap_msg.c','ldap/ldap_ndr.c','ldap/ldap_ildap.c'] +proto_files += ldap_files +hostenv.StaticLibrary('cli_ldap',ldap_files) + +hostenv.proto_headers += hostenv.CProtoHeader('proto.h', proto_files) diff --git a/source4/libcli/auth/SConscript b/source4/libcli/auth/SConscript deleted file mode 100644 index d527faac30..0000000000 --- a/source4/libcli/auth/SConscript +++ /dev/null @@ -1,3 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_auth',['credentials.c','session.c','smbencrypt.c']) diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript deleted file mode 100644 index eef9a9f41c..0000000000 --- a/source4/libcli/ldap/SConscript +++ /dev/null @@ -1,5 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_ldap', - ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', - 'ldap_ildap.c']) diff --git a/source4/libcli/security/SConscript b/source4/libcli/security/SConscript deleted file mode 100644 index e81051e07e..0000000000 --- a/source4/libcli/security/SConscript +++ /dev/null @@ -1,5 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_security', - ['security_token.c','security_descriptor.c','dom_sid.c', - 'access_check.c','privilege.c']) -- cgit From b0de111292c3c013fd557900bc517ad45c632ae7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 24 Sep 2005 23:35:50 +0000 Subject: r10482: Add files to proto_files enough to build libcli and librpc directories. (This used to be commit 4a03773c99f81d706307d69cb14af731dc8a8783) --- source4/libcli/SConscript | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index 8240e0fc2b..4c715325d5 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -6,14 +6,19 @@ hostenv.StaticLibrary('cli_utils', cli_utils_files) hostenv.StaticLibrary('cli_lsa', ['util/clilsa.c']) hostenv.StaticLibrary('cli_composite_base', ['composite/composite.c']) -hostenv.StaticLibrary('cli_composite', - ['composite/loadfile.c','composite/savefile.c','composite/connect.c', + +cli_composite_files = ['composite/loadfile.c','composite/savefile.c','composite/connect.c', 'composite/sesssetup.c','composite/fetchfile.c','composite/appendacl.c', - 'composite/fsinfo.c']) + 'composite/fsinfo.c'] + +hostenv.StaticLibrary('cli_composite', cli_composite_files) +proto_files += ['util/clilsa.c', 'composite/composite.c'] + cli_composite_files + +cli_nbt_files = ['nbt/nbtname.c','nbt/nbtsocket.c','nbt/namequery.c','nbt/nameregister.c', + 'nbt/namerefresh.c','nbt/namerelease.c'] -hostenv.StaticLibrary('cli_nbt', - ['nbt/nbtname.c','nbt/nbtsocket.c','nbt/namequery.c','nbt/nameregister.c', - 'nbt/namerefresh.c','nbt/namerelease.c']) +hostenv.StaticLibrary('cli_nbt', cli_nbt_files) +proto_files += cli_nbt_files hostenv.StaticLibrary('cli_dgram', [ 'dgram/dgramsocket.c','dgram/mailslot.c','dgram/netlogon.c', @@ -21,23 +26,29 @@ hostenv.StaticLibrary('cli_dgram', hostenv.StaticLibrary('cli_cldap', ['cldap/cldap.c']) hostenv.StaticLibrary('cli_wrepl', ['wrepl/winsrepl.c']) -hostenv.StaticLibrary('cli_resolve', - ['resolve/resolve.c','resolve/nbtlist.c','resolve/bcast.c','resolve/wins.c', - 'resolve/host.c']) +cli_resolve_files = ['resolve/resolve.c','resolve/nbtlist.c','resolve/bcast.c','resolve/wins.c', + 'resolve/host.c'] -hostenv.StaticLibrary('smb', - ['clireadwrite.c', 'cliconnect.c','clifile.c','clilist.c','clitrans2.c', - 'climessage.c','clideltree.c']) +hostenv.StaticLibrary('cli_resolve', cli_resolve_files) +proto_files += cli_resolve_files -hostenv.StaticLibrary('cli_raw', - ['raw/rawfile.c','raw/smb_signing.c','raw/clisocket.c', +smb_files = ['clireadwrite.c', 'cliconnect.c','clifile.c','clilist.c','clitrans2.c', + 'climessage.c','clideltree.c'] + +hostenv.StaticLibrary('smb', smb_files) +proto_files += smb_files + +cli_raw_files = ['raw/rawfile.c','raw/smb_signing.c','raw/clisocket.c', 'raw/clitransport.c','raw/clisession.c','raw/clitree.c', 'raw/rawrequest.c','raw/rawreadwrite.c','raw/rawsearch.c', 'raw/rawsetfileinfo.c','raw/raweas.c','raw/rawtrans.c', 'raw/clioplock.c','raw/rawnegotiate.c','raw/rawfsinfo.c', 'raw/rawfileinfo.c','raw/rawnotify.c','raw/rawioctl.c', - 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c']) + 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c'] + +hostenv.StaticLibrary('cli_raw', cli_raw_files) +proto_files += cli_raw_files security_files = ['security/security_token.c','security/security_descriptor.c', 'security/dom_sid.c', 'security/access_check.c', -- cgit From 9593101ec118dd242bf25fabf3e17c58269e632c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Sep 2005 21:01:56 +0000 Subject: r10491: First step towards wbinfo -t: This issues a name request for the primary domain and gets the DC's name via a mailslot call. Metze, I renamed wbsrv_queue_reply to wbsrv_send_reply in accordance with irpc_send_reply. Having _queue_ here and _send_ there is a bit confusing. And as everything is async anyway, the semantics should not be too much of a problem. Volker (This used to be commit 4637964b19c6e9f7d201b287e2d409d029fced01) --- source4/libcli/dgram/libdgram.h | 1 + source4/libcli/dgram/ntlogon.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index b9dfe84996..5bddd220d0 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -137,6 +137,7 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_packet *netlogon); NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, + enum dgram_msg_type msg_type, struct nbt_name *dest_name, const char *dest_address, int dest_port, diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 03d1266af0..efa5d4ab9e 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -32,6 +32,7 @@ send a ntlogon mailslot request */ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, + enum dgram_msg_type msg_type, struct nbt_name *dest_name, const char *dest_address, int dest_port, @@ -50,7 +51,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, } - status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + status = dgram_mailslot_send(dgmsock, msg_type, NBT_MAILSLOT_NTLOGON, dest_name, dest_address, dest_port, src_name, &blob); -- cgit From f51e98212f7f6fe49f0247532da257c5f451d745 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 26 Sep 2005 07:34:09 +0000 Subject: r10499: Export cli_ldap library. (This used to be commit 3c9c3a52e3999f15df747bbd69479896bbec3a6b) --- source4/libcli/SConscript | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index 4c715325d5..76143b97cf 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -63,6 +63,8 @@ hostenv.StaticLibrary('cli_auth',auth_files) ldap_files = ['ldap/ldap.c','ldap/ldap_client.c','ldap/ldap_bind.c', 'ldap/ldap_msg.c','ldap/ldap_ndr.c','ldap/ldap_ildap.c'] proto_files += ldap_files -hostenv.StaticLibrary('cli_ldap',ldap_files) +cli_ldap = hostenv.StaticLibrary('cli_ldap',ldap_files) + +Export('cli_ldap') hostenv.proto_headers += hostenv.CProtoHeader('proto.h', proto_files) -- cgit From ab4d635b92b116b02b88843b4ec4f5b7517bab1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 26 Sep 2005 11:47:55 +0000 Subject: r10504: - seperate implementation specific stuff, from the generic composite stuff. - don't use SMBCLI_REQUEST_* state's in the genreic composite stuff - move monitor_fn to libnet. NOTE: I have maybe found some bugs, in code that is dirrectly in DONE or ERROR state in the _send() function. I haven't fixed this bugs in this commit! We may need some composite_trigger_*() functions or so. And maybe some other generic helper functions... metze (This used to be commit 4527815a0a9b96e460f301cb1f0c0b3964c166fc) --- source4/libcli/cliconnect.c | 1 + source4/libcli/composite/appendacl.c | 311 ------------------ source4/libcli/composite/composite.c | 4 +- source4/libcli/composite/composite.h | 147 +-------- source4/libcli/composite/connect.c | 395 ----------------------- source4/libcli/composite/fetchfile.c | 186 ----------- source4/libcli/composite/fsinfo.c | 200 ------------ source4/libcli/composite/loadfile.c | 293 ----------------- source4/libcli/composite/monitor.h | 42 --- source4/libcli/composite/savefile.c | 288 ----------------- source4/libcli/composite/sesssetup.c | 458 -------------------------- source4/libcli/config.mk | 24 +- source4/libcli/nbt/namerefresh.c | 23 +- source4/libcli/nbt/nameregister.c | 43 ++- source4/libcli/raw/clisocket.c | 16 +- source4/libcli/raw/clitree.c | 1 + source4/libcli/resolve/host.c | 18 +- source4/libcli/resolve/nbtlist.c | 20 +- source4/libcli/resolve/resolve.c | 46 +-- source4/libcli/smb_composite/appendacl.c | 312 ++++++++++++++++++ source4/libcli/smb_composite/connect.c | 396 +++++++++++++++++++++++ source4/libcli/smb_composite/fetchfile.c | 187 +++++++++++ source4/libcli/smb_composite/fsinfo.c | 201 ++++++++++++ source4/libcli/smb_composite/loadfile.c | 294 +++++++++++++++++ source4/libcli/smb_composite/savefile.c | 289 +++++++++++++++++ source4/libcli/smb_composite/sesssetup.c | 459 +++++++++++++++++++++++++++ source4/libcli/smb_composite/smb_composite.h | 152 +++++++++ 27 files changed, 2403 insertions(+), 2403 deletions(-) delete mode 100644 source4/libcli/composite/appendacl.c delete mode 100644 source4/libcli/composite/connect.c delete mode 100644 source4/libcli/composite/fetchfile.c delete mode 100644 source4/libcli/composite/fsinfo.c delete mode 100644 source4/libcli/composite/loadfile.c delete mode 100644 source4/libcli/composite/monitor.h delete mode 100644 source4/libcli/composite/savefile.c delete mode 100644 source4/libcli/composite/sesssetup.c create mode 100644 source4/libcli/smb_composite/appendacl.c create mode 100644 source4/libcli/smb_composite/connect.c create mode 100644 source4/libcli/smb_composite/fetchfile.c create mode 100644 source4/libcli/smb_composite/fsinfo.c create mode 100644 source4/libcli/smb_composite/loadfile.c create mode 100644 source4/libcli/smb_composite/savefile.c create mode 100644 source4/libcli/smb_composite/sesssetup.c create mode 100644 source4/libcli/smb_composite/smb_composite.h (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index aba7f361a2..00c5012074 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" /* wrapper around smbcli_sock_connect() diff --git a/source4/libcli/composite/appendacl.c b/source4/libcli/composite/appendacl.c deleted file mode 100644 index 76702e6bca..0000000000 --- a/source4/libcli/composite/appendacl.c +++ /dev/null @@ -1,311 +0,0 @@ -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* the stages of this call */ -enum appendacl_stage {APPENDACL_OPENPATH, APPENDACL_GET, - APPENDACL_SET, APPENDACL_GETAGAIN, APPENDACL_CLOSEPATH}; - -static void appendacl_handler(struct smbcli_request *req); - -struct appendacl_state { - enum appendacl_stage stage; - struct smb_composite_appendacl *io; - - union smb_open *io_open; - union smb_setfileinfo *io_setfileinfo; - union smb_fileinfo *io_fileinfo; - - struct smbcli_request *req; -}; - - -static NTSTATUS appendacl_open(struct composite_context *c, - struct smb_composite_appendacl *io) -{ - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - - status = smb_raw_open_recv(state->req, c, state->io_open); - NT_STATUS_NOT_OK_RETURN(status); - - /* setup structures for getting fileinfo */ - state->io_fileinfo = talloc(c, union smb_fileinfo); - NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); - - state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; - state->io_fileinfo->query_secdesc.in.fnum = state->io_open->ntcreatex.out.fnum; - state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; - - state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* set the handler */ - state->req->async.fn = appendacl_handler; - state->req->async.private = c; - state->stage = APPENDACL_GET; - - talloc_free (state->io_open); - - return NT_STATUS_OK; -} - -static NTSTATUS appendacl_get(struct composite_context *c, - struct smb_composite_appendacl *io) -{ - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - struct smbcli_tree *tree = state->req->tree; - int i; - NTSTATUS status; - - status = smb_raw_fileinfo_recv(state->req, state->io_fileinfo, state->io_fileinfo); - NT_STATUS_NOT_OK_RETURN(status); - - /* setup structures for setting fileinfo */ - state->io_setfileinfo = talloc(c, union smb_setfileinfo); - NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo); - - state->io_setfileinfo->set_secdesc.level = RAW_SFILEINFO_SEC_DESC; - state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.in.fnum; - - state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL; - state->io_setfileinfo->set_secdesc.in.sd = state->io_fileinfo->query_secdesc.out.sd; - talloc_steal(state->io_setfileinfo, state->io_setfileinfo->set_secdesc.in.sd); - - /* append all aces from io->in.sd->dacl to new security descriptor */ - if (io->in.sd->dacl != NULL) { - for (i = 0; i < io->in.sd->dacl->num_aces; i++) { - security_descriptor_dacl_add(state->io_setfileinfo->set_secdesc.in.sd, - &(io->in.sd->dacl->aces[i])); - } - } - - status = smb_raw_setfileinfo(tree, state->io_setfileinfo); - NT_STATUS_NOT_OK_RETURN(status); - - state->req = smb_raw_setfileinfo_send(tree, state->io_setfileinfo); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call handler when done setting new security descriptor on file */ - state->req->async.fn = appendacl_handler; - state->req->async.private = c; - state->stage = APPENDACL_SET; - - talloc_free (state->io_fileinfo); - - return NT_STATUS_OK; -} - -static NTSTATUS appendacl_set(struct composite_context *c, - struct smb_composite_appendacl *io) -{ - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - - status = smbcli_request_simple_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - /* setup structures for getting fileinfo */ - state->io_fileinfo = talloc(c, union smb_fileinfo); - NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); - - - state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; - state->io_fileinfo->query_secdesc.in.fnum = state->io_setfileinfo->set_secdesc.file.fnum; - state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; - - state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* set the handler */ - state->req->async.fn = appendacl_handler; - state->req->async.private = c; - state->stage = APPENDACL_GETAGAIN; - - talloc_free (state->io_setfileinfo); - - return NT_STATUS_OK; -} - - -static NTSTATUS appendacl_getagain(struct composite_context *c, - struct smb_composite_appendacl *io) -{ - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - struct smbcli_tree *tree = state->req->tree; - union smb_close *io_close; - NTSTATUS status; - - status = smb_raw_fileinfo_recv(state->req, c, state->io_fileinfo); - NT_STATUS_NOT_OK_RETURN(status); - - io->out.sd = state->io_fileinfo->query_secdesc.out.sd; - - /* setup structures for close */ - io_close = talloc(c, union smb_close); - NT_STATUS_HAVE_NO_MEMORY(io_close); - - io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = state->io_fileinfo->query_secdesc.in.fnum; - io_close->close.in.write_time = 0; - - state->req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler */ - state->req->async.fn = appendacl_handler; - state->req->async.private = c; - state->stage = APPENDACL_CLOSEPATH; - - talloc_free (state->io_fileinfo); - - return NT_STATUS_OK; -} - - - -static NTSTATUS appendacl_close(struct composite_context *c, - struct smb_composite_appendacl *io) -{ - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - NTSTATUS status; - - status = smbcli_request_simple_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - c->state = SMBCLI_REQUEST_DONE; - - return NT_STATUS_OK; -} - -/* - handler for completion of a sub-request in appendacl -*/ -static void appendacl_handler(struct smbcli_request *req) -{ - struct composite_context *c = req->async.private; - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - - /* when this handler is called, the stage indicates what - call has just finished */ - switch (state->stage) { - case APPENDACL_OPENPATH: - c->status = appendacl_open(c, state->io); - break; - - case APPENDACL_GET: - c->status = appendacl_get(c, state->io); - break; - - case APPENDACL_SET: - c->status = appendacl_set(c, state->io); - break; - - case APPENDACL_GETAGAIN: - c->status = appendacl_getagain(c, state->io); - break; - - case APPENDACL_CLOSEPATH: - c->status = appendacl_close(c, state->io); - break; - } - - /* We should get here if c->state >= SMBCLI_REQUEST_DONE */ - if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; - } - - if (c->state >= SMBCLI_REQUEST_DONE && - c->async.fn) { - c->async.fn(c); - } -} - - -/* - composite appendacl call - does an open followed by a number setfileinfo, - after that new acls are read with fileinfo, followed by a close -*/ -struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree, - struct smb_composite_appendacl *io) -{ - struct composite_context *c; - struct appendacl_state *state; - - c = talloc_zero(tree, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct appendacl_state); - if (state == NULL) goto failed; - - state->io = io; - - c->private = state; - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = tree->session->transport->socket->event.ctx; - - /* setup structures for opening file */ - state->io_open = talloc_zero(c, union smb_open); - if (state->io_open == NULL) goto failed; - - state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; - state->io_open->ntcreatex.in.root_fid = 0; - state->io_open->ntcreatex.in.flags = 0; - state->io_open->ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; - state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; - state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; - state->io_open->ntcreatex.in.security_flags = 0; - state->io_open->ntcreatex.in.fname = io->in.fname; - - /* send the open on its way */ - state->req = smb_raw_open_send(tree, state->io_open); - if (state->req == NULL) goto failed; - - /* setup the callback handler */ - state->req->async.fn = appendacl_handler; - state->req->async.private = c; - state->stage = APPENDACL_OPENPATH; - - return c; - -failed: - talloc_free(c); - return NULL; -} - - -/* - composite appendacl call - recv side -*/ -NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) -{ - NTSTATUS status; - - status = composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state); - state->io->out.sd = security_descriptor_copy (mem_ctx, state->io->out.sd); - } - - talloc_free(c); - return status; -} - - -/* - composite appendacl call - sync interface -*/ -NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree, - TALLOC_CTX *mem_ctx, - struct smb_composite_appendacl *io) -{ - struct composite_context *c = smb_composite_appendacl_send(tree, io); - return smb_composite_appendacl_recv(c, mem_ctx); -} - diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index f04309bbfb..4a5247c9ea 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -34,7 +34,7 @@ NTSTATUS composite_wait(struct composite_context *c) { if (c == NULL) return NT_STATUS_NO_MEMORY; - while (c->state < SMBCLI_REQUEST_DONE) { + while (c->state < COMPOSITE_STATE_DONE) { if (event_loop_once(c->event_ctx) != 0) { return NT_STATUS_UNSUCCESSFUL; } @@ -51,7 +51,6 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te, struct timeval t, void *ptr) { struct composite_context *c = talloc_get_type(ptr, struct composite_context); - c->state = SMBCLI_REQUEST_DONE; if (c->async.fn) { c->async.fn(c); } @@ -65,6 +64,7 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te, */ void composite_trigger_done(struct composite_context *c) { + c->state = COMPOSITE_STATE_DONE; /* a zero timeout means immediate */ event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); } diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index be7fbd9972..83857edd14 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - SMB composite request interfaces + composite request interfaces Copyright (C) Andrew Tridgell 2005 @@ -23,19 +23,28 @@ /* this defines the structures associated with "composite" requests. Composite requests are libcli requests that are internally - implemented as multiple libcli/raw/ calls, but can be treated as a + implemented as multiple async calls, but can be treated as a single call via these composite calls. The composite calls are - particularly designed to be used in async applications + particularly designed to be used in async applications. + you can also stack multiple level of composite call */ +/* + a composite call moves between the following 3 states. +*/ +enum composite_state {COMPOSITE_STATE_INIT, /* we are creating the request */ + COMPOSITE_STATE_IN_PROGRESS, /* the request is in the outgoing socket Q */ + COMPOSITE_STATE_DONE, /* the request is received by the caller finished */ + COMPOSITE_STATE_ERROR}; /* a packet or transport level error has occurred */ +/* the context of one "composite" call */ struct composite_context { /* the external state - will be queried by the caller */ - enum smbcli_request_state state; + enum composite_state state; /* a private pointer for use by the composite function implementation */ - void *private; + void *private_data; /* status code when finished */ NTSTATUS status; @@ -46,132 +55,6 @@ struct composite_context { /* information on what to do on completion */ struct { void (*fn)(struct composite_context *); - void *private; + void *private_data; } async; - - /* information about the progress */ - void (*monitor_fn)(struct monitor_msg *); -}; - - -/* - a composite open/read(s)/close request that loads a whole file - into memory. Used as a demo of the composite system. -*/ -struct smb_composite_loadfile { - struct { - const char *fname; - } in; - struct { - uint8_t *data; - uint32_t size; - } out; -}; - -struct smb_composite_fetchfile { - struct { - const char *dest_host; - int port; - const char *called_name; - const char *service; - const char *service_type; - struct cli_credentials *credentials; - const char *workgroup; - const char *filename; - } in; - struct { - uint8_t *data; - uint32_t size; - } out; -}; - -/* - a composite open/write(s)/close request that saves a whole file from - memory. Used as a demo of the composite system. -*/ -struct smb_composite_savefile { - struct { - const char *fname; - uint8_t *data; - uint32_t size; - } in; -}; - - -/* - a composite request for a full connection to a remote server. Includes - - - socket establishment - - session request - - negprot - - session setup - - tree connect -*/ -struct smb_composite_connect { - struct { - const char *dest_host; - int port; - const char *called_name; - const char *service; - const char *service_type; - struct cli_credentials *credentials; - const char *workgroup; - } in; - struct { - struct smbcli_tree *tree; - } out; -}; - - -/* - generic session setup interface that takes care of which - session setup varient to use -*/ -struct smb_composite_sesssetup { - struct { - uint32_t sesskey; - uint32_t capabilities; - struct cli_credentials *credentials; - const char *workgroup; - } in; - struct { - uint16_t vuid; - } out; -}; - -/* - query file system info -*/ -struct smb_composite_fsinfo { - struct { - const char *dest_host; - int port; - const char *called_name; - const char *service; - const char *service_type; - struct cli_credentials *credentials; - const char *workgroup; - enum smb_fsinfo_level level; - } in; - - struct { - union smb_fsinfo *fsinfo; - } out; -}; - -/* - composite call for appending new acl to the file's security descriptor and get - new full acl -*/ - -struct smb_composite_appendacl { - struct { - const char *fname; - - const struct security_descriptor *sd; - } in; - - struct { - struct security_descriptor *sd; - } out; }; diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c deleted file mode 100644 index a5ce5308e5..0000000000 --- a/source4/libcli/composite/connect.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - 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. -*/ -/* - a composite API for making a full SMB connection -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" - -/* the stages of this call */ -enum connect_stage {CONNECT_RESOLVE, - CONNECT_SOCKET, - CONNECT_SESSION_REQUEST, - CONNECT_NEGPROT, - CONNECT_SESSION_SETUP, - CONNECT_TCON}; - -struct connect_state { - enum connect_stage stage; - struct smbcli_socket *sock; - struct smbcli_transport *transport; - struct smbcli_session *session; - struct smb_composite_connect *io; - union smb_tcon *io_tcon; - struct smb_composite_sesssetup *io_setup; - struct smbcli_request *req; - struct composite_context *creq; -}; - - -static void request_handler(struct smbcli_request *); -static void composite_handler(struct composite_context *); - -/* - setup a negprot send -*/ -static NTSTATUS connect_send_negprot(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - - state->req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - state->req->async.fn = request_handler; - state->req->async.private = c; - state->stage = CONNECT_NEGPROT; - - return NT_STATUS_OK; -} - - -/* - a tree connect request has competed -*/ -static NTSTATUS connect_tcon(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; - - status = smb_raw_tcon_recv(state->req, c, state->io_tcon); - NT_STATUS_NOT_OK_RETURN(status); - - io->out.tree->tid = state->io_tcon->tconx.out.tid; - if (state->io_tcon->tconx.out.dev_type) { - io->out.tree->device = talloc_strdup(io->out.tree, - state->io_tcon->tconx.out.dev_type); - } - if (state->io_tcon->tconx.out.fs_type) { - io->out.tree->fs_type = talloc_strdup(io->out.tree, - state->io_tcon->tconx.out.fs_type); - } - - /* all done! */ - c->state = SMBCLI_REQUEST_DONE; - - return NT_STATUS_OK; -} - - -/* - a session setup request has competed -*/ -static NTSTATUS connect_session_setup(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; - - status = smb_composite_sesssetup_recv(state->creq); - NT_STATUS_NOT_OK_RETURN(status); - - state->session->vuid = state->io_setup->out.vuid; - - /* setup for a tconx */ - io->out.tree = smbcli_tree_init(state->session, state, True); - NT_STATUS_HAVE_NO_MEMORY(io->out.tree); - - state->io_tcon = talloc(c, union smb_tcon); - NT_STATUS_HAVE_NO_MEMORY(state->io_tcon); - - /* connect to a share using a tree connect */ - state->io_tcon->generic.level = RAW_TCON_TCONX; - state->io_tcon->tconx.in.flags = 0; - state->io_tcon->tconx.in.password = data_blob(NULL, 0); - - state->io_tcon->tconx.in.path = talloc_asprintf(state->io_tcon, - "\\\\%s\\%s", - io->in.called_name, - io->in.service); - NT_STATUS_HAVE_NO_MEMORY(state->io_tcon->tconx.in.path); - if (!io->in.service_type) { - state->io_tcon->tconx.in.device = "?????"; - } else { - state->io_tcon->tconx.in.device = io->in.service_type; - } - - state->req = smb_raw_tcon_send(io->out.tree, state->io_tcon); - NT_STATUS_HAVE_NO_MEMORY(state->req); - if (state->req->state == SMBCLI_REQUEST_ERROR) { - return state->req->status; - } - - state->req->async.fn = request_handler; - state->req->async.private = c; - state->stage = CONNECT_TCON; - - return NT_STATUS_OK; -} - -/* - a negprot request has competed -*/ -static NTSTATUS connect_negprot(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; - - status = smb_raw_negotiate_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - /* next step is a session setup */ - state->session = smbcli_session_init(state->transport, state, True); - NT_STATUS_HAVE_NO_MEMORY(state->session); - - state->io_setup = talloc(c, struct smb_composite_sesssetup); - NT_STATUS_HAVE_NO_MEMORY(state->io_setup); - - /* prepare a session setup to establish a security context */ - state->io_setup->in.sesskey = state->transport->negotiate.sesskey; - state->io_setup->in.capabilities = state->transport->negotiate.capabilities; - state->io_setup->in.credentials = io->in.credentials; - state->io_setup->in.workgroup = io->in.workgroup; - - state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); - NT_STATUS_HAVE_NO_MEMORY(state->creq); - if (state->creq->state == SMBCLI_REQUEST_ERROR) { - return state->creq->status; - } - - state->creq->async.fn = composite_handler; - state->creq->async.private = c; - state->stage = CONNECT_SESSION_SETUP; - - return NT_STATUS_OK; -} - - -/* - a session request operation has competed -*/ -static NTSTATUS connect_session_request(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; - - status = smbcli_transport_connect_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - /* next step is a negprot */ - return connect_send_negprot(c, io); -} - -/* - a socket connection operation has competed -*/ -static NTSTATUS connect_socket(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; - struct nbt_name calling, called; - - status = smbcli_sock_connect_recv(state->creq); - NT_STATUS_NOT_OK_RETURN(status); - - /* the socket is up - we can initialise the smbcli transport layer */ - state->transport = smbcli_transport_init(state->sock, state, True); - NT_STATUS_HAVE_NO_MEMORY(state->transport); - - make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials)); - - nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); - - /* we have a connected socket - next step is a session - request, if needed. Port 445 doesn't need it, so it goes - straight to the negprot */ - if (state->sock->port == 445) { - status = nbt_name_dup(state->transport, &called, - &state->transport->called); - NT_STATUS_NOT_OK_RETURN(status); - return connect_send_negprot(c, io); - } - - state->req = smbcli_transport_connect_send(state->transport, &calling, &called); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - state->req->async.fn = request_handler; - state->req->async.private = c; - state->stage = CONNECT_SESSION_REQUEST; - - return NT_STATUS_OK; -} - - -/* - called when name resolution is finished -*/ -static NTSTATUS connect_resolve(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - NTSTATUS status; - const char *address; - - status = resolve_name_recv(state->creq, state, &address); - NT_STATUS_NOT_OK_RETURN(status); - - state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port, io->in.dest_host); - NT_STATUS_HAVE_NO_MEMORY(state->creq); - - state->stage = CONNECT_SOCKET; - state->creq->async.private = c; - state->creq->async.fn = composite_handler; - - return NT_STATUS_OK; -} - - -/* - handle and dispatch state transitions -*/ -static void state_handler(struct composite_context *c) -{ - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - - switch (state->stage) { - case CONNECT_RESOLVE: - c->status = connect_resolve(c, state->io); - break; - case CONNECT_SOCKET: - c->status = connect_socket(c, state->io); - break; - case CONNECT_SESSION_REQUEST: - c->status = connect_session_request(c, state->io); - break; - case CONNECT_NEGPROT: - c->status = connect_negprot(c, state->io); - break; - case CONNECT_SESSION_SETUP: - c->status = connect_session_setup(c, state->io); - break; - case CONNECT_TCON: - c->status = connect_tcon(c, state->io); - break; - } - - if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; - } - - if (c->state >= SMBCLI_REQUEST_DONE && - c->async.fn) { - c->async.fn(c); - } -} - - -/* - handler for completion of a smbcli_request sub-request -*/ -static void request_handler(struct smbcli_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - state_handler(c); -} - -/* - handler for completion of a smbcli_composite sub-request -*/ -static void composite_handler(struct composite_context *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - state_handler(c); -} - -/* - a function to establish a smbcli_tree from scratch -*/ -struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io, - struct event_context *event_ctx) -{ - struct composite_context *c; - struct connect_state *state; - struct nbt_name name; - - c = talloc_zero(NULL, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct connect_state); - if (state == NULL) goto failed; - - state->sock = smbcli_sock_init(state, event_ctx); - if (state->sock == NULL) goto failed; - - state->io = io; - - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = talloc_reference(c, state->sock->event.ctx); - c->private = state; - - state->stage = CONNECT_RESOLVE; - make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); - - if (state->creq == NULL) goto failed; - state->creq->async.private = c; - state->creq->async.fn = composite_handler; - - return c; -failed: - talloc_free(c); - return NULL; -} - -/* - recv half of async composite connect code -*/ -NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) -{ - NTSTATUS status; - - status = composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct connect_state *state = talloc_get_type(c->private, struct connect_state); - talloc_steal(mem_ctx, state->io->out.tree); - } - - talloc_free(c); - return status; -} - -/* - sync version of smb_composite_connect -*/ -NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, - struct event_context *ev) -{ - struct composite_context *c = smb_composite_connect_send(io, ev); - return smb_composite_connect_recv(c, mem_ctx); -} diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c deleted file mode 100644 index c9e8321db2..0000000000 --- a/source4/libcli/composite/fetchfile.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Volker Lendecke 2005 - - 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. -*/ -/* - a composite API for loading a whole file into memory -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" - -enum fetchfile_stage {FETCHFILE_CONNECT, - FETCHFILE_READ}; - -struct fetchfile_state { - enum fetchfile_stage stage; - struct smb_composite_fetchfile *io; - struct composite_context *req; - struct smb_composite_connect *connect; - struct smb_composite_loadfile *loadfile; -}; - -static void fetchfile_composite_handler(struct composite_context *req); - -static NTSTATUS fetchfile_connect(struct composite_context *c, - struct smb_composite_fetchfile *io) -{ - NTSTATUS status; - struct fetchfile_state *state; - state = talloc_get_type(c->private, struct fetchfile_state); - - status = smb_composite_connect_recv(state->req, c); - NT_STATUS_NOT_OK_RETURN(status); - - state->loadfile = talloc(state, struct smb_composite_loadfile); - NT_STATUS_HAVE_NO_MEMORY(state->loadfile); - - state->loadfile->in.fname = io->in.filename; - - state->req = smb_composite_loadfile_send(state->connect->out.tree, - state->loadfile); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - state->req->async.private = c; - state->req->async.fn = fetchfile_composite_handler; - - state->stage = FETCHFILE_READ; - c->event_ctx = talloc_reference(c, state->req->event_ctx); - - return NT_STATUS_OK; -} - -static NTSTATUS fetchfile_read(struct composite_context *c, - struct smb_composite_fetchfile *io) -{ - NTSTATUS status; - struct fetchfile_state *state; - state = talloc_get_type(c->private, struct fetchfile_state); - - status = smb_composite_loadfile_recv(state->req, NULL); - NT_STATUS_NOT_OK_RETURN(status); - - io->out.data = state->loadfile->out.data; - io->out.size = state->loadfile->out.size; - - c->state = SMBCLI_REQUEST_DONE; - if (c->async.fn) - c->async.fn(c); - - return NT_STATUS_OK; -} - -static void fetchfile_state_handler(struct composite_context *c) -{ - struct fetchfile_state *state; - NTSTATUS status; - - state = talloc_get_type(c->private, struct fetchfile_state); - - /* when this handler is called, the stage indicates what - call has just finished */ - switch (state->stage) { - case FETCHFILE_CONNECT: - status = fetchfile_connect(c, state->io); - break; - case FETCHFILE_READ: - status = fetchfile_read(c, state->io); - break; - } - - if (!NT_STATUS_IS_OK(status)) { - c->status = status; - c->state = SMBCLI_REQUEST_ERROR; - if (c->async.fn) { - c->async.fn(c); - } - } -} - -static void fetchfile_composite_handler(struct composite_context *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - fetchfile_state_handler(c); -} - -struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, - struct event_context *event_ctx) -{ - struct composite_context *c; - struct fetchfile_state *state; - - c = talloc_zero(NULL, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct fetchfile_state); - if (state == NULL) goto failed; - - state->connect = talloc(state, struct smb_composite_connect); - if (state->connect == NULL) goto failed; - - state->io = io; - - state->connect->in.dest_host = io->in.dest_host; - state->connect->in.port = io->in.port; - state->connect->in.called_name = io->in.called_name; - state->connect->in.service = io->in.service; - state->connect->in.service_type = io->in.service_type; - state->connect->in.credentials = io->in.credentials; - state->connect->in.workgroup = io->in.workgroup; - - state->req = smb_composite_connect_send(state->connect, event_ctx); - if (state->req == NULL) goto failed; - - state->req->async.private = c; - state->req->async.fn = fetchfile_composite_handler; - - c->state = SMBCLI_REQUEST_SEND; - state->stage = FETCHFILE_CONNECT; - c->event_ctx = talloc_reference(c, state->req->event_ctx); - c->private = state; - - return c; - failed: - talloc_free(c); - return NULL; -} - -NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c, - TALLOC_CTX *mem_ctx) -{ - NTSTATUS status; - - status = composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct fetchfile_state *state = talloc_get_type(c->private, struct fetchfile_state); - talloc_steal(mem_ctx, state->io->out.data); - } - - talloc_free(c); - return status; -} - -NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io, - TALLOC_CTX *mem_ctx) -{ - struct composite_context *c = smb_composite_fetchfile_send(io, NULL); - return smb_composite_fetchfile_recv(c, mem_ctx); -} diff --git a/source4/libcli/composite/fsinfo.c b/source4/libcli/composite/fsinfo.c deleted file mode 100644 index e0accbb6a6..0000000000 --- a/source4/libcli/composite/fsinfo.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - a composite API for quering file system information -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* the stages of this call */ -enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY}; - - -static void fsinfo_raw_handler(struct smbcli_request *req); -static void fsinfo_composite_handler(struct composite_context *c); -static void fsinfo_state_handler(struct composite_context *c); - -struct fsinfo_state { - enum fsinfo_stage stage; - struct composite_context *creq; - struct smb_composite_fsinfo *io; - struct smb_composite_connect *connect; - union smb_fsinfo *fsinfo; - struct smbcli_tree *tree; - struct smbcli_request *req; -}; - -static NTSTATUS fsinfo_connect(struct composite_context *c, - struct smb_composite_fsinfo *io) -{ - NTSTATUS status; - struct fsinfo_state *state; - state = talloc_get_type(c->private, struct fsinfo_state); - - status = smb_composite_connect_recv(state->creq, c); - NT_STATUS_NOT_OK_RETURN(status); - - state->fsinfo = talloc(state, union smb_fsinfo); - NT_STATUS_HAVE_NO_MEMORY(state->fsinfo); - - state->fsinfo->generic.level = io->in.level; - - state->req = smb_raw_fsinfo_send(state->connect->out.tree, - state, - state->fsinfo); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - state->req->async.private = c; - state->req->async.fn = fsinfo_raw_handler; - - state->stage = FSINFO_QUERY; - c->event_ctx = talloc_reference(c, state->req->session->transport->socket->event.ctx); - - return NT_STATUS_OK; -} - -static NTSTATUS fsinfo_query(struct composite_context *c, - struct smb_composite_fsinfo *io) -{ - NTSTATUS status; - struct fsinfo_state *state; - state = talloc_get_type(c->private, struct fsinfo_state); - - status = smb_raw_fsinfo_recv(state->req, state, state->fsinfo); - NT_STATUS_NOT_OK_RETURN(status); - - state->io->out.fsinfo = state->fsinfo; - - c->state = SMBCLI_REQUEST_DONE; - - if (c->async.fn) - c->async.fn(c); - - return NT_STATUS_OK; - -} - -/* - handler for completion of a sub-request in fsinfo -*/ -static void fsinfo_state_handler(struct composite_context *req) -{ - struct fsinfo_state *state = talloc_get_type(req->private, struct fsinfo_state); - - /* when this handler is called, the stage indicates what - call has just finished */ - switch (state->stage) { - case FSINFO_CONNECT: - req->status = fsinfo_connect(req, state->io); - break; - - case FSINFO_QUERY: - req->status = fsinfo_query(req, state->io); - break; - } - - if (!NT_STATUS_IS_OK(req->status)) { - req->state = SMBCLI_REQUEST_ERROR; - } - - if (req->state >= SMBCLI_REQUEST_DONE && req->async.fn) { - req->async.fn(req); - } -} - -/* - As raw and composite handlers take different requests, we need to handlers - to adapt both for the same state machine in fsinfo_state_handler() -*/ -static void fsinfo_raw_handler(struct smbcli_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - fsinfo_state_handler(c); -} - -static void fsinfo_composite_handler(struct composite_context *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - fsinfo_state_handler(c); -} - -/* - composite fsinfo call - connects to a tree and queries a file system information -*/ -struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, - struct smb_composite_fsinfo *io) -{ - struct composite_context *c; - struct fsinfo_state *state; - - c = talloc_zero(tree, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct fsinfo_state); - if (state == NULL) goto failed; - - state->io = io; - - state->connect = talloc(state, struct smb_composite_connect); - - if (state->connect == NULL) goto failed; - - state->connect->in.dest_host = io->in.dest_host; - state->connect->in.port = io->in.port; - state->connect->in.called_name = io->in.called_name; - state->connect->in.service = io->in.service; - state->connect->in.service_type = io->in.service_type; - state->connect->in.credentials = io->in.credentials; - state->connect->in.workgroup = io->in.workgroup; - - c->state = SMBCLI_REQUEST_SEND; - state->stage = FSINFO_CONNECT; - c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); - c->private = state; - - state->creq = smb_composite_connect_send(state->connect, c->event_ctx); - - if (state->creq == NULL) goto failed; - - state->creq->async.private = c; - state->creq->async.fn = fsinfo_composite_handler; - - return c; -failed: - talloc_free(c); - return NULL; -} - -/* - composite fsinfo call - recv side -*/ -NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) -{ - NTSTATUS status; - - status = composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct fsinfo_state *state = talloc_get_type(c->private, struct fsinfo_state); - talloc_steal(mem_ctx, state->io->out.fsinfo); - } - - talloc_free(c); - return status; -} - - -/* - composite fsinfo call - sync interface -*/ -NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, - TALLOC_CTX *mem_ctx, - struct smb_composite_fsinfo *io) -{ - struct composite_context *c = smb_composite_fsinfo_send(tree, io); - return smb_composite_fsinfo_recv(c, mem_ctx); -} - diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c deleted file mode 100644 index 69a8219dba..0000000000 --- a/source4/libcli/composite/loadfile.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - 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. -*/ -/* - a composite API for loading a whole file into memory -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* the stages of this call */ -enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE}; - - -static void loadfile_handler(struct smbcli_request *req); - -struct loadfile_state { - enum loadfile_stage stage; - struct smb_composite_loadfile *io; - struct smbcli_request *req; - union smb_open *io_open; - union smb_read *io_read; -}; - -/* - setup for the close -*/ -static NTSTATUS setup_close(struct composite_context *c, - struct smbcli_tree *tree, uint16_t fnum) -{ - struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - union smb_close *io_close; - - /* nothing to read, setup the close */ - io_close = talloc(c, union smb_close); - NT_STATUS_HAVE_NO_MEMORY(io_close); - - io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = fnum; - io_close->close.in.write_time = 0; - - state->req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the close is done */ - state->req->async.fn = loadfile_handler; - state->req->async.private = c; - state->stage = LOADFILE_CLOSE; - - return NT_STATUS_OK; -} - -/* - called when the open is done - pull the results and setup for the - first readx, or close if the file is zero size -*/ -static NTSTATUS loadfile_open(struct composite_context *c, - struct smb_composite_loadfile *io) -{ - struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - - status = smb_raw_open_recv(state->req, c, state->io_open); - NT_STATUS_NOT_OK_RETURN(status); - - /* don't allow stupidly large loads */ - if (state->io_open->ntcreatex.out.size > 100*1000*1000) { - return NT_STATUS_INSUFFICIENT_RESOURCES; - } - - /* allocate space for the file data */ - io->out.size = state->io_open->ntcreatex.out.size; - io->out.data = talloc_array(c, uint8_t, io->out.size); - NT_STATUS_HAVE_NO_MEMORY(io->out.data); - - if (io->out.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); - } - - /* setup for the read */ - state->io_read = talloc(c, union smb_read); - NT_STATUS_HAVE_NO_MEMORY(state->io_read); - - state->io_read->readx.level = RAW_READ_READX; - state->io_read->readx.in.fnum = state->io_open->ntcreatex.out.fnum; - state->io_read->readx.in.offset = 0; - state->io_read->readx.in.mincnt = MIN(32768, io->out.size); - state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; - state->io_read->readx.in.remaining = 0; - state->io_read->readx.out.data = io->out.data; - - state->req = smb_raw_read_send(tree, state->io_read); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the first read is done */ - state->req->async.fn = loadfile_handler; - state->req->async.private = c; - state->stage = LOADFILE_READ; - - talloc_free(state->io_open); - - return NT_STATUS_OK; -} - - -/* - called when a read is done - pull the results and setup for the - next read, or close if the file is all done -*/ -static NTSTATUS loadfile_read(struct composite_context *c, - struct smb_composite_loadfile *io) -{ - struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - - status = smb_raw_read_recv(state->req, state->io_read); - NT_STATUS_NOT_OK_RETURN(status); - - /* we might be done */ - if (state->io_read->readx.in.offset + - state->io_read->readx.out.nread == io->out.size) { - return setup_close(c, tree, state->io_read->readx.in.fnum); - } - - /* setup for the next read */ - state->io_read->readx.in.offset += state->io_read->readx.out.nread; - state->io_read->readx.in.mincnt = MIN(32768, io->out.size - state->io_read->readx.in.offset); - state->io_read->readx.out.data = io->out.data + state->io_read->readx.in.offset; - - state->req = smb_raw_read_send(tree, state->io_read); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the read is done */ - state->req->async.fn = loadfile_handler; - state->req->async.private = c; - - return NT_STATUS_OK; -} - -/* - called when the close is done, check the status and cleanup -*/ -static NTSTATUS loadfile_close(struct composite_context *c, - struct smb_composite_loadfile *io) -{ - struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - NTSTATUS status; - - status = smbcli_request_simple_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - c->state = SMBCLI_REQUEST_DONE; - - return NT_STATUS_OK; -} - - -/* - handler for completion of a sub-request in loadfile -*/ -static void loadfile_handler(struct smbcli_request *req) -{ - struct composite_context *c = req->async.private; - struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - - /* when this handler is called, the stage indicates what - call has just finished */ - switch (state->stage) { - case LOADFILE_OPEN: - c->status = loadfile_open(c, state->io); - break; - - case LOADFILE_READ: - c->status = loadfile_read(c, state->io); - break; - - case LOADFILE_CLOSE: - c->status = loadfile_close(c, state->io); - break; - } - - if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; - } - - if (c->state >= SMBCLI_REQUEST_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - composite loadfile call - does an openx followed by a number of readx calls, - followed by a close -*/ -struct composite_context *smb_composite_loadfile_send(struct smbcli_tree *tree, - struct smb_composite_loadfile *io) -{ - struct composite_context *c; - struct loadfile_state *state; - - c = talloc_zero(tree, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct loadfile_state); - if (state == NULL) goto failed; - - state->io = io; - - c->private = state; - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = tree->session->transport->socket->event.ctx; - - /* setup for the open */ - state->io_open = talloc_zero(c, union smb_open); - if (state->io_open == NULL) goto failed; - - state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; - state->io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; - state->io_open->ntcreatex.in.access_mask = SEC_FILE_READ_DATA; - state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; - state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; - state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; - state->io_open->ntcreatex.in.fname = io->in.fname; - - /* send the open on its way */ - state->req = smb_raw_open_send(tree, state->io_open); - if (state->req == NULL) goto failed; - - /* setup the callback handler */ - state->req->async.fn = loadfile_handler; - state->req->async.private = c; - state->stage = LOADFILE_OPEN; - - return c; - -failed: - talloc_free(c); - return NULL; -} - - -/* - composite loadfile call - recv side -*/ -NTSTATUS smb_composite_loadfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) -{ - NTSTATUS status; - - status = composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state); - talloc_steal(mem_ctx, state->io->out.data); - } - - talloc_free(c); - return status; -} - - -/* - composite loadfile call - sync interface -*/ -NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree, - TALLOC_CTX *mem_ctx, - struct smb_composite_loadfile *io) -{ - struct composite_context *c = smb_composite_loadfile_send(tree, io); - return smb_composite_loadfile_recv(c, mem_ctx); -} - diff --git a/source4/libcli/composite/monitor.h b/source4/libcli/composite/monitor.h deleted file mode 100644 index dce9dedc92..0000000000 --- a/source4/libcli/composite/monitor.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Definitions of composite function monitoring messages. - - Copyright (C) Rafal Szczesniak 2005 - - 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. -*/ - -/* - * Monitor structure and message types definitions. Composite function monitoring - * allows client application to be notified on function progress. This enables - * eg. gui client to display progress bars, status messages, etc. - */ - - -#define rpc_create_user (0x00000001) /* userman.h */ -#define rpc_open_user (0x00000002) /* userinfo.h */ -#define rpc_query_user (0x00000003) /* userinfo.h */ -#define rpc_close_user (0x00000004) /* userinfo.h */ -#define rpc_lookup_name (0x00000005) /* userman.h */ -#define rpc_delete_user (0x00000006) /* userman.h */ - - -struct monitor_msg { - uint32_t type; - void *data; - size_t data_size; -}; diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c deleted file mode 100644 index 0b08963966..0000000000 --- a/source4/libcli/composite/savefile.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - 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. -*/ -/* - a composite API for saving a whole file from memory -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* the stages of this call */ -enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE}; - -static void savefile_handler(struct smbcli_request *req); - -struct savefile_state { - enum savefile_stage stage; - off_t total_written; - struct smb_composite_savefile *io; - union smb_open *io_open; - union smb_write *io_write; - struct smbcli_request *req; -}; - - -/* - setup for the close -*/ -static NTSTATUS setup_close(struct composite_context *c, - struct smbcli_tree *tree, uint16_t fnum) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - union smb_close *io_close; - - /* nothing to write, setup the close */ - io_close = talloc(c, union smb_close); - NT_STATUS_HAVE_NO_MEMORY(io_close); - - io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = fnum; - io_close->close.in.write_time = 0; - - state->req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the close is done */ - state->stage = SAVEFILE_CLOSE; - state->req->async.fn = savefile_handler; - state->req->async.private = c; - - return NT_STATUS_OK; -} - -/* - called when the open is done - pull the results and setup for the - first writex, or close if the file is zero size -*/ -static NTSTATUS savefile_open(struct composite_context *c, - struct smb_composite_savefile *io) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - union smb_write *io_write; - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - - status = smb_raw_open_recv(state->req, c, state->io_open); - NT_STATUS_NOT_OK_RETURN(status); - - if (io->in.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); - } - - /* setup for the first write */ - io_write = talloc(c, union smb_write); - NT_STATUS_HAVE_NO_MEMORY(io_write); - - io_write->writex.level = RAW_WRITE_WRITEX; - io_write->writex.in.fnum = state->io_open->ntcreatex.out.fnum; - io_write->writex.in.offset = 0; - io_write->writex.in.wmode = 0; - io_write->writex.in.remaining = 0; - io_write->writex.in.count = MIN(max_xmit - 100, io->in.size); - io_write->writex.in.data = io->in.data; - state->io_write = io_write; - - state->req = smb_raw_write_send(tree, io_write); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the first write is done */ - state->stage = SAVEFILE_WRITE; - state->req->async.fn = savefile_handler; - state->req->async.private = c; - talloc_free(state->io_open); - - return NT_STATUS_OK; -} - - -/* - called when a write is done - pull the results and setup for the - next write, or close if the file is all done -*/ -static NTSTATUS savefile_write(struct composite_context *c, - struct smb_composite_savefile *io) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - - status = smb_raw_write_recv(state->req, state->io_write); - NT_STATUS_NOT_OK_RETURN(status); - - state->total_written += state->io_write->writex.out.nwritten; - - /* we might be done */ - if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count || - state->total_written == io->in.size) { - return setup_close(c, tree, state->io_write->writex.in.fnum); - } - - /* setup for the next write */ - state->io_write->writex.in.offset = state->total_written; - state->io_write->writex.in.count = MIN(max_xmit - 100, - io->in.size - state->total_written); - state->io_write->writex.in.data = io->in.data + state->total_written; - - state->req = smb_raw_write_send(tree, state->io_write); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the write is done */ - state->req->async.fn = savefile_handler; - state->req->async.private = c; - - return NT_STATUS_OK; -} - -/* - called when the close is done, check the status and cleanup -*/ -static NTSTATUS savefile_close(struct composite_context *c, - struct smb_composite_savefile *io) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - NTSTATUS status; - - status = smbcli_request_simple_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - if (state->total_written != io->in.size) { - return NT_STATUS_DISK_FULL; - } - - c->state = SMBCLI_REQUEST_DONE; - - return NT_STATUS_OK; -} - - -/* - handler for completion of a sub-request in savefile -*/ -static void savefile_handler(struct smbcli_request *req) -{ - struct composite_context *c = req->async.private; - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - - /* when this handler is called, the stage indicates what - call has just finished */ - switch (state->stage) { - case SAVEFILE_OPEN: - c->status = savefile_open(c, state->io); - break; - - case SAVEFILE_WRITE: - c->status = savefile_write(c, state->io); - break; - - case SAVEFILE_CLOSE: - c->status = savefile_close(c, state->io); - break; - } - - if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; - } - - if (c->state >= SMBCLI_REQUEST_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - composite savefile call - does an openx followed by a number of writex calls, - followed by a close -*/ -struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree, - struct smb_composite_savefile *io) -{ - struct composite_context *c; - struct savefile_state *state; - union smb_open *io_open; - - c = talloc_zero(tree, struct composite_context); - if (c == NULL) goto failed; - - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = tree->session->transport->socket->event.ctx; - - state = talloc(c, struct savefile_state); - if (state == NULL) goto failed; - - state->stage = SAVEFILE_OPEN; - state->total_written = 0; - state->io = io; - - /* setup for the open */ - io_open = talloc_zero(c, union smb_open); - if (io_open == NULL) goto failed; - - io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; - io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; - io_open->ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; - io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; - io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; - io_open->ntcreatex.in.fname = io->in.fname; - state->io_open = io_open; - - /* send the open on its way */ - state->req = smb_raw_open_send(tree, io_open); - if (state->req == NULL) goto failed; - - /* setup the callback handler */ - state->req->async.fn = savefile_handler; - state->req->async.private = c; - c->private = state; - - return c; - -failed: - talloc_free(c); - return NULL; -} - - -/* - composite savefile call - recv side -*/ -NTSTATUS smb_composite_savefile_recv(struct composite_context *c) -{ - NTSTATUS status; - status = composite_wait(c); - talloc_free(c); - return status; -} - - -/* - composite savefile call - sync interface -*/ -NTSTATUS smb_composite_savefile(struct smbcli_tree *tree, - struct smb_composite_savefile *io) -{ - struct composite_context *c = smb_composite_savefile_send(tree, io); - return smb_composite_savefile_recv(c); -} diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c deleted file mode 100644 index 3bd9ed285d..0000000000 --- a/source4/libcli/composite/sesssetup.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - 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. -*/ -/* - a composite API for making handling a generic async session setup -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "auth/auth.h" -#include "version.h" - -struct sesssetup_state { - union smb_sesssetup setup; - NTSTATUS gensec_status; - struct smb_composite_sesssetup *io; - struct smbcli_request *req; -}; - - -/* - form an encrypted lanman password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB lanman_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBencrypt(pass, challenge.data, blob.data); - return blob; -} - -/* - form an encrypted NT password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const struct samr_Password *nt_hash, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBOWFencrypt(nt_hash->hash, challenge.data, blob.data); - return blob; -} - -/* - store the user session key for a transport -*/ -static void set_user_session_key(struct smbcli_session *session, - const DATA_BLOB *session_key) -{ - session->user_session_key = data_blob_talloc(session, - session_key->data, - session_key->length); -} - -/* - handler for completion of a smbcli_request sub-request -*/ -static void request_handler(struct smbcli_request *req) -{ - struct composite_context *c = req->async.private; - struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); - struct smbcli_session *session = req->session; - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB null_data_blob = data_blob(NULL, 0); - NTSTATUS session_key_err; - - c->status = smb_raw_sesssetup_recv(req, state, &state->setup); - - switch (state->setup.old.level) { - case RAW_SESSSETUP_OLD: - state->io->out.vuid = state->setup.old.out.vuid; - break; - - case RAW_SESSSETUP_NT1: - state->io->out.vuid = state->setup.nt1.out.vuid; - break; - - case RAW_SESSSETUP_SPNEGO: - session->vuid = state->io->out.vuid = state->setup.spnego.out.vuid; - if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && - !NT_STATUS_IS_OK(c->status)) { - break; - } - if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - - /* The status value here, from the earlier pass at GENSEC is - * vital to the security of the system. Even if the other end - * accepts, if GENSEC claims 'MORE_PROCESSING_REQUIRED' then - * you must keep feeding it blobs, or else the remote - * host/attacker might avoid mutal authentication - * requirements */ - - state->gensec_status = gensec_update(session->gensec, state, - state->setup.spnego.out.secblob, - &state->setup.spnego.in.secblob); - c->status = state->gensec_status; - if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && - !NT_STATUS_IS_OK(c->status)) { - break; - } - } else { - state->setup.spnego.in.secblob = data_blob(NULL, 0); - } - - /* we need to do another round of session setup. We keep going until both sides - are happy */ - session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(session_key_err)) { - set_user_session_key(session, &session_key); - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); - } - - if (state->setup.spnego.in.secblob.length) { - state->req = smb_raw_sesssetup_send(session, &state->setup); - state->req->async.fn = request_handler; - state->req->async.private = c; - return; - } - } - - /* enforce the local signing required flag */ - if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) { - if (!session->transport->negotiate.sign_info.doing_signing - && session->transport->negotiate.sign_info.mandatory_signing) { - DEBUG(0, ("SMB signing required, but server does not support it\n")); - c->status = NT_STATUS_ACCESS_DENIED; - } - } - - if (NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_DONE; - } else { - c->state = SMBCLI_REQUEST_ERROR; - } - if (c->async.fn) { - c->async.fn(c); - } -} - - -/* - send a nt1 style session setup -*/ -static NTSTATUS session_setup_nt1(struct composite_context *c, - struct smbcli_session *session, - struct smb_composite_sesssetup *io, - struct smbcli_request **req) -{ - struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); - const struct samr_Password *nt_hash = cli_credentials_get_nt_hash(io->in.credentials, state); - const char *password = cli_credentials_get_password(io->in.credentials); - - state->setup.nt1.level = RAW_SESSSETUP_NT1; - state->setup.nt1.in.bufsize = session->transport->options.max_xmit; - state->setup.nt1.in.mpx_max = session->transport->options.max_mux; - state->setup.nt1.in.vc_num = 1; - state->setup.nt1.in.sesskey = io->in.sesskey; - state->setup.nt1.in.capabilities = io->in.capabilities; - state->setup.nt1.in.os = "Unix"; - state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); - cli_credentials_get_ntlm_username_domain(io->in.credentials, state, - &state->setup.nt1.in.user, - &state->setup.nt1.in.domain); - - if (!password) { - state->setup.nt1.in.password1 = data_blob(NULL, 0); - state->setup.nt1.in.password2 = data_blob(NULL, 0); - } else if (session->transport->negotiate.sec_mode & - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - DATA_BLOB session_key; - if (lp_client_ntlmv2_auth()) { - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_netbios_name(), lp_workgroup()); - DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key; - - if (!SMBNTLMv2encrypt_hash(state, - state->setup.nt1.in.user, state->setup.nt1.in.domain, - nt_hash->hash, &session->transport->negotiate.secblob, - &names_blob, - &lmv2_response, &ntlmv2_response, - &lmv2_session_key, &session_key)) { - data_blob_free(&names_blob); - return NT_STATUS_NO_MEMORY; - } - data_blob_free(&names_blob); - state->setup.nt1.in.password1 = lmv2_response; - state->setup.nt1.in.password2 = ntlmv2_response; - - smbcli_transport_simple_set_signing(session->transport, session_key, - state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); - - data_blob_free(&lmv2_session_key); - data_blob_free(&session_key); - } else { - - state->setup.nt1.in.password2 = nt_blob(state, nt_hash, - session->transport->negotiate.secblob); - if (lp_client_lanman_auth()) { - state->setup.nt1.in.password1 = lanman_blob(state, password, - session->transport->negotiate.secblob); - } else { - /* if not sending the LM password, send the NT password twice */ - state->setup.nt1.in.password1 = state->setup.nt1.in.password2; - } - - session_key = data_blob_talloc(session, NULL, 16); - SMBsesskeygen_ntv1(nt_hash->hash, session_key.data); - smbcli_transport_simple_set_signing(session->transport, session_key, - state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); - - data_blob_free(&session_key); - } - - } else if (lp_client_plaintext_auth()) { - state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); - state->setup.nt1.in.password2 = data_blob(NULL, 0); - } else { - /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ - return NT_STATUS_INVALID_PARAMETER; - } - - *req = smb_raw_sesssetup_send(session, &state->setup); - if (!*req) { - return NT_STATUS_NO_MEMORY; - } - return (*req)->status; -} - - -/* - old style session setup (pre NT1 protocol level) -*/ -static NTSTATUS session_setup_old(struct composite_context *c, - struct smbcli_session *session, - struct smb_composite_sesssetup *io, - struct smbcli_request **req) -{ - struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); - const char *password = cli_credentials_get_password(io->in.credentials); - - state->setup.old.level = RAW_SESSSETUP_OLD; - state->setup.old.in.bufsize = session->transport->options.max_xmit; - state->setup.old.in.mpx_max = session->transport->options.max_mux; - state->setup.old.in.vc_num = 1; - state->setup.old.in.sesskey = io->in.sesskey; - state->setup.old.in.os = "Unix"; - state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); - cli_credentials_get_ntlm_username_domain(io->in.credentials, state, - &state->setup.old.in.user, - &state->setup.old.in.domain); - - if (!password) { - state->setup.old.in.password = data_blob(NULL, 0); - } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - state->setup.old.in.password = lanman_blob(state, password, - session->transport->negotiate.secblob); - } else { - state->setup.old.in.password = data_blob_talloc(state, - password, - strlen(password)); - } - - *req = smb_raw_sesssetup_send(session, &state->setup); - if (!*req) { - return NT_STATUS_NO_MEMORY; - } - return (*req)->status; -} - - -/* - Modern, all singing, all dancing extended security (and possibly SPNEGO) request -*/ -static NTSTATUS session_setup_spnego(struct composite_context *c, - struct smbcli_session *session, - struct smb_composite_sesssetup *io, - struct smbcli_request **req) -{ - struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state); - NTSTATUS status, session_key_err; - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB null_data_blob = data_blob(NULL, 0); - const char *chosen_oid = NULL; - - state->setup.spnego.level = RAW_SESSSETUP_SPNEGO; - state->setup.spnego.in.bufsize = session->transport->options.max_xmit; - state->setup.spnego.in.mpx_max = session->transport->options.max_mux; - state->setup.spnego.in.vc_num = 1; - state->setup.spnego.in.sesskey = io->in.sesskey; - state->setup.spnego.in.capabilities = io->in.capabilities; - state->setup.spnego.in.os = "Unix"; - state->setup.spnego.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); - state->setup.spnego.in.workgroup = io->in.workgroup; - - state->setup.spnego.out.vuid = session->vuid; - - smbcli_temp_set_signing(session->transport); - - status = gensec_client_start(session, &session->gensec, c->event_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); - return status; - } - - gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); - - status = gensec_set_credentials(session->gensec, io->in.credentials); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", - nt_errstr(status))); - return status; - } - - status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - return status; - } - - status = gensec_set_target_service(session->gensec, "cifs"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target service: %s\n", - nt_errstr(status))); - return status; - } - - if (session->transport->negotiate.secblob.length) { - chosen_oid = GENSEC_OID_SPNEGO; - } else { - /* without a sec blob, means raw NTLMSSP */ - chosen_oid = GENSEC_OID_NTLMSSP; - } - - status = gensec_start_mech_by_oid(session->gensec, chosen_oid); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return status; - } - - status = gensec_update(session->gensec, state, - session->transport->negotiate.secblob, - &state->setup.spnego.in.secblob); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && - !NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return status; - } - state->gensec_status = status; - - session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(session_key_err)) { - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); - } - - *req = smb_raw_sesssetup_send(session, &state->setup); - if (!*req) { - return NT_STATUS_NO_MEMORY; - } - return (*req)->status; -} - - -/* - composite session setup function that hides the details of all the - different session setup varients, including the multi-pass nature of - the spnego varient -*/ -struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session, - struct smb_composite_sesssetup *io) -{ - struct composite_context *c; - struct sesssetup_state *state; - NTSTATUS status; - - c = talloc_zero(session, struct composite_context); - if (c == NULL) return NULL; - - state = talloc(c, struct sesssetup_state); - if (state == NULL) { - c->state = SMBCLI_REQUEST_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } - - state->io = io; - - c->state = SMBCLI_REQUEST_SEND; - c->private = state; - c->event_ctx = session->transport->socket->event.ctx; - - /* no session setup at all in earliest protocol varients */ - if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { - ZERO_STRUCT(io->out); - c->state = SMBCLI_REQUEST_DONE; - return c; - } - - /* see what session setup interface we will use */ - if (session->transport->negotiate.protocol < PROTOCOL_NT1) { - status = session_setup_old(c, session, io, &state->req); - } else if (!session->transport->options.use_spnego || - !(io->in.capabilities & CAP_EXTENDED_SECURITY)) { - status = session_setup_nt1(c, session, io, &state->req); - } else { - status = session_setup_spnego(c, session, io, &state->req); - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || - NT_STATUS_IS_OK(status)) { - state->req->async.fn = request_handler; - state->req->async.private = c; - return c; - } - - c->state = SMBCLI_REQUEST_ERROR; - c->status = status; - return c; -} - - -/* - receive a composite session setup reply -*/ -NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c) -{ - NTSTATUS status; - status = composite_wait(c); - talloc_free(c); - return status; -} - -/* - sync version of smb_composite_sesssetup -*/ -NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io) -{ - struct composite_context *c = smb_composite_sesssetup_send(session, io); - return smb_composite_sesssetup_recv(c); -} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 248e0c2b95..62530ed64b 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -10,21 +10,21 @@ ADD_OBJ_FILES = libcli/util/asn1.o \ ADD_OBJ_FILES = libcli/util/clilsa.o REQUIRED_SUBSYSTEMS = RPC_NDR_LSA -[SUBSYSTEM::LIBCLI_COMPOSITE_BASE] +[SUBSYSTEM::LIBCLI_COMPOSITE] ADD_OBJ_FILES = \ libcli/composite/composite.o REQUIRED_SUBSYSTEMS = LIBEVENTS -[SUBSYSTEM::LIBCLI_COMPOSITE] +[SUBSYSTEM::LIBCLI_SMB_COMPOSITE] ADD_OBJ_FILES = \ - libcli/composite/loadfile.o \ - libcli/composite/savefile.o \ - libcli/composite/connect.o \ - libcli/composite/sesssetup.o \ - libcli/composite/fetchfile.o \ - libcli/composite/appendacl.o \ - libcli/composite/fsinfo.o -REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE_BASE + libcli/smb_composite/loadfile.o \ + libcli/smb_composite/savefile.o \ + libcli/smb_composite/connect.o \ + libcli/smb_composite/sesssetup.o \ + libcli/smb_composite/fetchfile.o \ + libcli/smb_composite/appendacl.o \ + libcli/smb_composite/fsinfo.o +REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE [SUBSYSTEM::LIBCLI_NBT] ADD_OBJ_FILES = \ @@ -34,7 +34,7 @@ ADD_OBJ_FILES = \ libcli/nbt/nameregister.o \ libcli/nbt/namerefresh.o \ libcli/nbt/namerelease.o -REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS \ +REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ LIB_SECURITY_NDR [SUBSYSTEM::LIBCLI_DGRAM] @@ -69,7 +69,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI] REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ - LIBCLI_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ + LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM [SUBSYSTEM::LIBSMB] diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index a344f2c6e8..d9f2070d4c 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -22,7 +22,6 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" -#include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" /* @@ -154,7 +153,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - struct refresh_wins_state *state = talloc_get_type(c->private, + struct refresh_wins_state *state = talloc_get_type(c->private_data, struct refresh_wins_state); NTSTATUS status; @@ -164,7 +163,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) state->wins_servers++; state->address_idx = 0; if (state->wins_servers[0] == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = status; goto done; } @@ -172,14 +171,14 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) state->io->in.address = state->addresses[0]; state->req = nbt_name_refresh_send(state->nbtsock, state->io); if (state->req == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_refresh_wins_handler; state->req->async.private = c; } } else if (!NT_STATUS_IS_OK(status)) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = status; } else { if (state->io->out.rcode == 0 && @@ -188,20 +187,20 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) state->io->in.address = state->addresses[++(state->address_idx)]; state->req = nbt_name_refresh_send(state->nbtsock, state->io); if (state->req == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_refresh_wins_handler; state->req->async.private = c; } } else { - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; c->status = NT_STATUS_OK; } } done: - if (c->state >= SMBCLI_REQUEST_DONE && + if (c->state >= COMPOSITE_STATE_DONE && c->async.fn) { c->async.fn(c); } @@ -251,9 +250,9 @@ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbt state->req->async.fn = name_refresh_wins_handler; state->req->async.private = c; - c->private = state; - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = nbtsock->event_ctx; + c->private_data = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = nbtsock->event_ctx; return c; @@ -272,7 +271,7 @@ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct refresh_wins_state *state = - talloc_get_type(c->private, struct refresh_wins_state); + talloc_get_type(c->private_data, struct refresh_wins_state); io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); io->out.rcode = state->io->out.rcode; } diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 276b8e4ac3..4dac500780 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -22,7 +22,6 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" -#include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" /* @@ -156,14 +155,14 @@ struct register_bcast_state { static void name_register_bcast_handler(struct nbt_name_request *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - struct register_bcast_state *state = talloc_get_type(c->private, struct register_bcast_state); + struct register_bcast_state *state = talloc_get_type(c->private_data, struct register_bcast_state); NTSTATUS status; status = nbt_name_register_recv(state->req, state, state->io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { if (state->io->in.register_demand == True) { /* all done */ - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; c->status = NT_STATUS_OK; goto done; } @@ -173,17 +172,17 @@ static void name_register_bcast_handler(struct nbt_name_request *req) state->io->in.retries = 0; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_register_bcast_handler; state->req->async.private = c; } } else if (!NT_STATUS_IS_OK(status)) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = status; } else { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_CONFLICTING_ADDRESSES; DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n", state->io->out.reply_from, @@ -193,7 +192,7 @@ static void name_register_bcast_handler(struct nbt_name_request *req) } done: - if (c->state >= SMBCLI_REQUEST_DONE && + if (c->state >= COMPOSITE_STATE_DONE && c->async.fn) { c->async.fn(c); } @@ -203,7 +202,7 @@ done: the async send call for a 4 stage name registration */ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io) + struct nbt_name_register_bcast *io) { struct composite_context *c; struct register_bcast_state *state; @@ -236,9 +235,9 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n state->req->async.fn = name_register_bcast_handler; state->req->async.private = c; - c->private = state; - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = nbtsock->event_ctx; + c->private_data = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = nbtsock->event_ctx; return c; @@ -291,7 +290,7 @@ static void name_register_wins_handler(struct nbt_name_request *req) { struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - struct register_wins_state *state = talloc_get_type(c->private, + struct register_wins_state *state = talloc_get_type(c->private_data, struct register_wins_state); NTSTATUS status; @@ -301,7 +300,7 @@ static void name_register_wins_handler(struct nbt_name_request *req) state->wins_servers++; state->address_idx = 0; if (state->wins_servers[0] == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = status; goto done; } @@ -309,14 +308,14 @@ static void name_register_wins_handler(struct nbt_name_request *req) state->io->in.address = state->addresses[0]; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_register_wins_handler; state->req->async.private = c; } } else if (!NT_STATUS_IS_OK(status)) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = status; } else { if (state->io->out.rcode == 0 && @@ -325,20 +324,20 @@ static void name_register_wins_handler(struct nbt_name_request *req) state->io->in.address = state->addresses[++(state->address_idx)]; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_register_wins_handler; state->req->async.private = c; } } else { - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; c->status = NT_STATUS_OK; } } done: - if (c->state >= SMBCLI_REQUEST_DONE && + if (c->state >= COMPOSITE_STATE_DONE && c->async.fn) { c->async.fn(c); } @@ -390,9 +389,9 @@ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nb state->req->async.fn = name_register_wins_handler; state->req->async.private = c; - c->private = state; - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = nbtsock->event_ctx; + c->private_data = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = nbtsock->event_ctx; return c; @@ -411,7 +410,7 @@ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *me status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct register_wins_state *state = - talloc_get_type(c->private, struct register_wins_state); + talloc_get_type(c->private_data, struct register_wins_state); io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); io->out.rcode = state->io->out.rcode; } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 90fb98603e..688ee8a78b 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -78,17 +78,17 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, has either completed the connect() or has returned an error */ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) + uint16_t flags, void *private_data) { - struct composite_context *c = talloc_get_type(private, struct composite_context); - struct clisocket_connect *conn = talloc_get_type(c->private, struct clisocket_connect); + struct composite_context *c = talloc_get_type(private_data, struct composite_context); + struct clisocket_connect *conn = talloc_get_type(c->private_data, struct clisocket_connect); int i; c->status = socket_connect_complete(conn->sock->sock, 0); if (NT_STATUS_IS_OK(c->status)) { socket_set_option(conn->sock->sock, lp_socket_options(), NULL); conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_hostname); - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; if (c->async.fn) { c->async.fn(c); } @@ -107,7 +107,7 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even } } - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; if (c->async.fn) { c->async.fn(c); } @@ -195,8 +195,8 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, conn->dest_hostname = talloc_strdup(c, host_name); if (conn->dest_hostname == NULL) goto failed; - c->private = conn; - c->state = SMBCLI_REQUEST_SEND; + c->private_data = conn; + c->state = COMPOSITE_STATE_IN_PROGRESS; /* startup the connect process for each port in turn until one succeeds or tells us that it is pending */ @@ -212,7 +212,7 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, } } - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; return c; failed: diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 74e14db591..cae93bdbe2 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index a5edfcbc8a..13503b66b3 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -66,7 +66,7 @@ static int host_destructor(void *ptr) */ static void run_child(struct composite_context *c, int fd) { - struct host_state *state = talloc_get_type(c->private, struct host_state); + struct host_state *state = talloc_get_type(c->private_data, struct host_state); struct ipv4_addr ip; const char *address; @@ -84,10 +84,10 @@ static void run_child(struct composite_context *c, int fd) handle a read event on the pipe */ static void pipe_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) + uint16_t flags, void *private_data) { - struct composite_context *c = talloc_get_type(private, struct composite_context); - struct host_state *state = talloc_get_type(c->private, struct host_state); + struct composite_context *c = talloc_get_type(private_data, struct composite_context); + struct host_state *state = talloc_get_type(c->private_data, struct host_state); char address[128]; int ret; @@ -113,7 +113,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, if (state->reply_addr == NULL) goto failed; c->status = NT_STATUS_OK; - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; if (c->async.fn) { c->async.fn(c); } @@ -121,7 +121,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, failed: c->status = NT_STATUS_BAD_NETWORK_NAME; - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; if (c->async.fn) { c->async.fn(c); } @@ -148,8 +148,8 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, status = nbt_name_dup(state, name, &state->name); if (!NT_STATUS_IS_OK(status)) goto failed; - c->state = SMBCLI_REQUEST_SEND; - c->private = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = state; c->event_ctx = talloc_reference(c, event_ctx); /* setup a pipe to chat to our child */ @@ -206,7 +206,7 @@ NTSTATUS resolve_name_host_recv(struct composite_context *c, status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct host_state *state = talloc_get_type(c->private, struct host_state); + struct host_state *state = talloc_get_type(c->private_data, struct host_state); *reply_addr = talloc_steal(mem_ctx, state->reply_addr); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 7080c62e43..4fb4ccbb20 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -44,8 +44,8 @@ struct nbtlist_state { static void nbtlist_handler(struct nbt_name_request *req) { struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); + struct composite_context); + struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state); int i; for (i=0;inum_queries;i++) { @@ -54,20 +54,20 @@ static void nbtlist_handler(struct nbt_name_request *req) if (i == state->num_queries) { /* not for us?! */ c->status = NT_STATUS_INTERNAL_ERROR; - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; goto done; - } + } c->status = nbt_name_query_recv(req, state, &state->io_queries[i]); if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; } else { if (state->io_queries[i].out.num_addrs < 1) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; } else { struct nbt_name_query *q = &state->io_queries[i]; - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; /* favor a local address if possible */ state->reply_addr = NULL; for (i=0;iout.num_addrs;i++) { @@ -150,8 +150,8 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, state->queries[i]->async.private = c; } - c->state = SMBCLI_REQUEST_SEND; - c->private = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = state; c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx); return c; @@ -172,7 +172,7 @@ NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c, status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); + struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state); *reply_addr = talloc_steal(mem_ctx, state->reply_addr); } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index c21b29b57f..c9e2fa503b 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -28,7 +28,7 @@ struct resolve_state { struct nbt_name name; const char **methods; - struct composite_context *req; + struct composite_context *creq; const char *reply_addr; }; @@ -65,26 +65,26 @@ static const struct resolve_method *find_method(const char *name) /* handle completion of one name resolve method */ -static void resolve_handler(struct composite_context *req) +static void resolve_handler(struct composite_context *creq) { - struct composite_context *c = req->async.private; - struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); + struct composite_context *c = creq->async.private_data; + struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state); const struct resolve_method *method = find_method(state->methods[0]); - c->status = method->recv_fn(req, state, &state->reply_addr); + c->status = method->recv_fn(creq, state, &state->reply_addr); if (!NT_STATUS_IS_OK(c->status)) { state->methods++; - state->req = setup_next_method(c); - if (state->req != NULL) { + state->creq = setup_next_method(c); + if (state->creq != NULL) { return; } } if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; + c->state = COMPOSITE_STATE_ERROR; } else { - c->state = SMBCLI_REQUEST_DONE; + c->state = COMPOSITE_STATE_DONE; } if (c->async.fn) { c->async.fn(c); @@ -94,23 +94,23 @@ static void resolve_handler(struct composite_context *req) static struct composite_context *setup_next_method(struct composite_context *c) { - struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); - struct composite_context *req = NULL; + struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state); + struct composite_context *creq = NULL; do { const struct resolve_method *method = find_method(state->methods[0]); if (method) { - req = method->send_fn(&state->name, c->event_ctx); + creq = method->send_fn(&state->name, c->event_ctx); } - if (req == NULL && state->methods[0]) state->methods++; - } while (!req && state->methods[0]); + if (creq == NULL && state->methods[0]) state->methods++; + } while (!creq && state->methods[0]); - if (req) { - req->async.fn = resolve_handler; - req->async.private = c; + if (creq) { + creq->async.fn = resolve_handler; + creq->async.private_data = c; } - return req; + return creq; } /* @@ -136,8 +136,8 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ state->methods = str_list_copy(state, methods); if (state->methods == NULL) goto failed; - c->state = SMBCLI_REQUEST_SEND; - c->private = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = state; if (event_ctx == NULL) { c->event_ctx = event_context_init(c); if (c->event_ctx == NULL) goto failed; @@ -154,8 +154,8 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ return c; } - state->req = setup_next_method(c); - if (state->req == NULL) goto failed; + state->creq = setup_next_method(c); + if (state->creq == NULL) goto failed; return c; @@ -175,7 +175,7 @@ NTSTATUS resolve_name_recv(struct composite_context *c, status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { - struct resolve_state *state = talloc_get_type(c->private, struct resolve_state); + struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state); *reply_addr = talloc_steal(mem_ctx, state->reply_addr); } diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c new file mode 100644 index 0000000000..b47a41a43b --- /dev/null +++ b/source4/libcli/smb_composite/appendacl.c @@ -0,0 +1,312 @@ +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum appendacl_stage {APPENDACL_OPENPATH, APPENDACL_GET, + APPENDACL_SET, APPENDACL_GETAGAIN, APPENDACL_CLOSEPATH}; + +static void appendacl_handler(struct smbcli_request *req); + +struct appendacl_state { + enum appendacl_stage stage; + struct smb_composite_appendacl *io; + + union smb_open *io_open; + union smb_setfileinfo *io_setfileinfo; + union smb_fileinfo *io_fileinfo; + + struct smbcli_request *req; +}; + + +static NTSTATUS appendacl_open(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + + status = smb_raw_open_recv(state->req, c, state->io_open); + NT_STATUS_NOT_OK_RETURN(status); + + /* setup structures for getting fileinfo */ + state->io_fileinfo = talloc(c, union smb_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); + + state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; + state->io_fileinfo->query_secdesc.in.fnum = state->io_open->ntcreatex.out.fnum; + state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; + + state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* set the handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_GET; + + talloc_free (state->io_open); + + return NT_STATUS_OK; +} + +static NTSTATUS appendacl_get(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + int i; + NTSTATUS status; + + status = smb_raw_fileinfo_recv(state->req, state->io_fileinfo, state->io_fileinfo); + NT_STATUS_NOT_OK_RETURN(status); + + /* setup structures for setting fileinfo */ + state->io_setfileinfo = talloc(c, union smb_setfileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo); + + state->io_setfileinfo->set_secdesc.level = RAW_SFILEINFO_SEC_DESC; + state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.in.fnum; + + state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL; + state->io_setfileinfo->set_secdesc.in.sd = state->io_fileinfo->query_secdesc.out.sd; + talloc_steal(state->io_setfileinfo, state->io_setfileinfo->set_secdesc.in.sd); + + /* append all aces from io->in.sd->dacl to new security descriptor */ + if (io->in.sd->dacl != NULL) { + for (i = 0; i < io->in.sd->dacl->num_aces; i++) { + security_descriptor_dacl_add(state->io_setfileinfo->set_secdesc.in.sd, + &(io->in.sd->dacl->aces[i])); + } + } + + status = smb_raw_setfileinfo(tree, state->io_setfileinfo); + NT_STATUS_NOT_OK_RETURN(status); + + state->req = smb_raw_setfileinfo_send(tree, state->io_setfileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call handler when done setting new security descriptor on file */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_SET; + + talloc_free (state->io_fileinfo); + + return NT_STATUS_OK; +} + +static NTSTATUS appendacl_set(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + + status = smbcli_request_simple_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + /* setup structures for getting fileinfo */ + state->io_fileinfo = talloc(c, union smb_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); + + + state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; + state->io_fileinfo->query_secdesc.in.fnum = state->io_setfileinfo->set_secdesc.file.fnum; + state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; + + state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* set the handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_GETAGAIN; + + talloc_free (state->io_setfileinfo); + + return NT_STATUS_OK; +} + + +static NTSTATUS appendacl_getagain(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + struct smbcli_tree *tree = state->req->tree; + union smb_close *io_close; + NTSTATUS status; + + status = smb_raw_fileinfo_recv(state->req, c, state->io_fileinfo); + NT_STATUS_NOT_OK_RETURN(status); + + io->out.sd = state->io_fileinfo->query_secdesc.out.sd; + + /* setup structures for close */ + io_close = talloc(c, union smb_close); + NT_STATUS_HAVE_NO_MEMORY(io_close); + + io_close->close.level = RAW_CLOSE_CLOSE; + io_close->close.in.fnum = state->io_fileinfo->query_secdesc.in.fnum; + io_close->close.in.write_time = 0; + + state->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_CLOSEPATH; + + talloc_free (state->io_fileinfo); + + return NT_STATUS_OK; +} + + + +static NTSTATUS appendacl_close(struct composite_context *c, + struct smb_composite_appendacl *io) +{ + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + NTSTATUS status; + + status = smbcli_request_simple_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + c->state = COMPOSITE_STATE_DONE; + + return NT_STATUS_OK; +} + +/* + handler for completion of a sub-request in appendacl +*/ +static void appendacl_handler(struct smbcli_request *req) +{ + struct composite_context *c = req->async.private; + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case APPENDACL_OPENPATH: + c->status = appendacl_open(c, state->io); + break; + + case APPENDACL_GET: + c->status = appendacl_get(c, state->io); + break; + + case APPENDACL_SET: + c->status = appendacl_set(c, state->io); + break; + + case APPENDACL_GETAGAIN: + c->status = appendacl_getagain(c, state->io); + break; + + case APPENDACL_CLOSEPATH: + c->status = appendacl_close(c, state->io); + break; + } + + /* We should get here if c->state >= SMBCLI_REQUEST_DONE */ + if (!NT_STATUS_IS_OK(c->status)) { + c->state = COMPOSITE_STATE_ERROR; + } + + if (c->state >= COMPOSITE_STATE_DONE && + c->async.fn) { + c->async.fn(c); + } +} + + +/* + composite appendacl call - does an open followed by a number setfileinfo, + after that new acls are read with fileinfo, followed by a close +*/ +struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree, + struct smb_composite_appendacl *io) +{ + struct composite_context *c; + struct appendacl_state *state; + + c = talloc_zero(tree, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct appendacl_state); + if (state == NULL) goto failed; + + state->io = io; + + c->private_data = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = tree->session->transport->socket->event.ctx; + + /* setup structures for opening file */ + state->io_open = talloc_zero(c, union smb_open); + if (state->io_open == NULL) goto failed; + + state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + state->io_open->ntcreatex.in.root_fid = 0; + state->io_open->ntcreatex.in.flags = 0; + state->io_open->ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + state->io_open->ntcreatex.in.security_flags = 0; + state->io_open->ntcreatex.in.fname = io->in.fname; + + /* send the open on its way */ + state->req = smb_raw_open_send(tree, state->io_open); + if (state->req == NULL) goto failed; + + /* setup the callback handler */ + state->req->async.fn = appendacl_handler; + state->req->async.private = c; + state->stage = APPENDACL_OPENPATH; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + composite appendacl call - recv side +*/ +NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); + state->io->out.sd = security_descriptor_copy (mem_ctx, state->io->out.sd); + } + + talloc_free(c); + return status; +} + + +/* + composite appendacl call - sync interface +*/ +NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_composite_appendacl *io) +{ + struct composite_context *c = smb_composite_appendacl_send(tree, io); + return smb_composite_appendacl_recv(c, mem_ctx); +} + diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c new file mode 100644 index 0000000000..56d9d988c3 --- /dev/null +++ b/source4/libcli/smb_composite/connect.c @@ -0,0 +1,396 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for making a full SMB connection +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" + +/* the stages of this call */ +enum connect_stage {CONNECT_RESOLVE, + CONNECT_SOCKET, + CONNECT_SESSION_REQUEST, + CONNECT_NEGPROT, + CONNECT_SESSION_SETUP, + CONNECT_TCON}; + +struct connect_state { + enum connect_stage stage; + struct smbcli_socket *sock; + struct smbcli_transport *transport; + struct smbcli_session *session; + struct smb_composite_connect *io; + union smb_tcon *io_tcon; + struct smb_composite_sesssetup *io_setup; + struct smbcli_request *req; + struct composite_context *creq; +}; + + +static void request_handler(struct smbcli_request *); +static void composite_handler(struct composite_context *); + +/* + setup a negprot send +*/ +static NTSTATUS connect_send_negprot(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + + state->req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + state->req->async.fn = request_handler; + state->req->async.private = c; + state->stage = CONNECT_NEGPROT; + + return NT_STATUS_OK; +} + + +/* + a tree connect request has competed +*/ +static NTSTATUS connect_tcon(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + + status = smb_raw_tcon_recv(state->req, c, state->io_tcon); + NT_STATUS_NOT_OK_RETURN(status); + + io->out.tree->tid = state->io_tcon->tconx.out.tid; + if (state->io_tcon->tconx.out.dev_type) { + io->out.tree->device = talloc_strdup(io->out.tree, + state->io_tcon->tconx.out.dev_type); + } + if (state->io_tcon->tconx.out.fs_type) { + io->out.tree->fs_type = talloc_strdup(io->out.tree, + state->io_tcon->tconx.out.fs_type); + } + + /* all done! */ + c->state = COMPOSITE_STATE_DONE; + + return NT_STATUS_OK; +} + + +/* + a session setup request has competed +*/ +static NTSTATUS connect_session_setup(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + + status = smb_composite_sesssetup_recv(state->creq); + NT_STATUS_NOT_OK_RETURN(status); + + state->session->vuid = state->io_setup->out.vuid; + + /* setup for a tconx */ + io->out.tree = smbcli_tree_init(state->session, state, True); + NT_STATUS_HAVE_NO_MEMORY(io->out.tree); + + state->io_tcon = talloc(c, union smb_tcon); + NT_STATUS_HAVE_NO_MEMORY(state->io_tcon); + + /* connect to a share using a tree connect */ + state->io_tcon->generic.level = RAW_TCON_TCONX; + state->io_tcon->tconx.in.flags = 0; + state->io_tcon->tconx.in.password = data_blob(NULL, 0); + + state->io_tcon->tconx.in.path = talloc_asprintf(state->io_tcon, + "\\\\%s\\%s", + io->in.called_name, + io->in.service); + NT_STATUS_HAVE_NO_MEMORY(state->io_tcon->tconx.in.path); + if (!io->in.service_type) { + state->io_tcon->tconx.in.device = "?????"; + } else { + state->io_tcon->tconx.in.device = io->in.service_type; + } + + state->req = smb_raw_tcon_send(io->out.tree, state->io_tcon); + NT_STATUS_HAVE_NO_MEMORY(state->req); + if (state->req->state == SMBCLI_REQUEST_ERROR) { + return state->req->status; + } + + state->req->async.fn = request_handler; + state->req->async.private = c; + state->stage = CONNECT_TCON; + + return NT_STATUS_OK; +} + +/* + a negprot request has competed +*/ +static NTSTATUS connect_negprot(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + + status = smb_raw_negotiate_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + /* next step is a session setup */ + state->session = smbcli_session_init(state->transport, state, True); + NT_STATUS_HAVE_NO_MEMORY(state->session); + + state->io_setup = talloc(c, struct smb_composite_sesssetup); + NT_STATUS_HAVE_NO_MEMORY(state->io_setup); + + /* prepare a session setup to establish a security context */ + state->io_setup->in.sesskey = state->transport->negotiate.sesskey; + state->io_setup->in.capabilities = state->transport->negotiate.capabilities; + state->io_setup->in.credentials = io->in.credentials; + state->io_setup->in.workgroup = io->in.workgroup; + + state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); + NT_STATUS_HAVE_NO_MEMORY(state->creq); + if (state->creq->state == COMPOSITE_STATE_ERROR) { + return state->creq->status; + } + + state->creq->async.fn = composite_handler; + state->creq->async.private_data = c; + state->stage = CONNECT_SESSION_SETUP; + + return NT_STATUS_OK; +} + + +/* + a session request operation has competed +*/ +static NTSTATUS connect_session_request(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + + status = smbcli_transport_connect_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + /* next step is a negprot */ + return connect_send_negprot(c, io); +} + +/* + a socket connection operation has competed +*/ +static NTSTATUS connect_socket(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + struct nbt_name calling, called; + + status = smbcli_sock_connect_recv(state->creq); + NT_STATUS_NOT_OK_RETURN(status); + + /* the socket is up - we can initialise the smbcli transport layer */ + state->transport = smbcli_transport_init(state->sock, state, True); + NT_STATUS_HAVE_NO_MEMORY(state->transport); + + make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials)); + + nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); + + /* we have a connected socket - next step is a session + request, if needed. Port 445 doesn't need it, so it goes + straight to the negprot */ + if (state->sock->port == 445) { + status = nbt_name_dup(state->transport, &called, + &state->transport->called); + NT_STATUS_NOT_OK_RETURN(status); + return connect_send_negprot(c, io); + } + + state->req = smbcli_transport_connect_send(state->transport, &calling, &called); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + state->req->async.fn = request_handler; + state->req->async.private = c; + state->stage = CONNECT_SESSION_REQUEST; + + return NT_STATUS_OK; +} + + +/* + called when name resolution is finished +*/ +static NTSTATUS connect_resolve(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + const char *address; + + status = resolve_name_recv(state->creq, state, &address); + NT_STATUS_NOT_OK_RETURN(status); + + state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port, io->in.dest_host); + NT_STATUS_HAVE_NO_MEMORY(state->creq); + + state->stage = CONNECT_SOCKET; + state->creq->async.private_data = c; + state->creq->async.fn = composite_handler; + + return NT_STATUS_OK; +} + + +/* + handle and dispatch state transitions +*/ +static void state_handler(struct composite_context *c) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + + switch (state->stage) { + case CONNECT_RESOLVE: + c->status = connect_resolve(c, state->io); + break; + case CONNECT_SOCKET: + c->status = connect_socket(c, state->io); + break; + case CONNECT_SESSION_REQUEST: + c->status = connect_session_request(c, state->io); + break; + case CONNECT_NEGPROT: + c->status = connect_negprot(c, state->io); + break; + case CONNECT_SESSION_SETUP: + c->status = connect_session_setup(c, state->io); + break; + case CONNECT_TCON: + c->status = connect_tcon(c, state->io); + break; + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = COMPOSITE_STATE_ERROR; + } + + if (c->state >= COMPOSITE_STATE_DONE && + c->async.fn) { + c->async.fn(c); + } +} + + +/* + handler for completion of a smbcli_request sub-request +*/ +static void request_handler(struct smbcli_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + state_handler(c); +} + +/* + handler for completion of a smbcli_composite sub-request +*/ +static void composite_handler(struct composite_context *creq) +{ + struct composite_context *c = talloc_get_type(creq->async.private_data, + struct composite_context); + state_handler(c); +} + +/* + a function to establish a smbcli_tree from scratch +*/ +struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io, + struct event_context *event_ctx) +{ + struct composite_context *c; + struct connect_state *state; + struct nbt_name name; + + c = talloc_zero(NULL, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct connect_state); + if (state == NULL) goto failed; + + state->sock = smbcli_sock_init(state, event_ctx); + if (state->sock == NULL) goto failed; + + state->io = io; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = talloc_reference(c, state->sock->event.ctx); + c->private_data = state; + + state->stage = CONNECT_RESOLVE; + make_nbt_name_server(&name, io->in.dest_host); + state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); + + if (state->creq == NULL) goto failed; + state->creq->async.private_data = c; + state->creq->async.fn = composite_handler; + + return c; +failed: + talloc_free(c); + return NULL; +} + +/* + recv half of async composite connect code +*/ +NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + talloc_steal(mem_ctx, state->io->out.tree); + } + + talloc_free(c); + return status; +} + +/* + sync version of smb_composite_connect +*/ +NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, + struct event_context *ev) +{ + struct composite_context *c = smb_composite_connect_send(io, ev); + return smb_composite_connect_recv(c, mem_ctx); +} diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c new file mode 100644 index 0000000000..9e88fb669d --- /dev/null +++ b/source4/libcli/smb_composite/fetchfile.c @@ -0,0 +1,187 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Volker Lendecke 2005 + + 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. +*/ +/* + a composite API for loading a whole file into memory +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" + +enum fetchfile_stage {FETCHFILE_CONNECT, + FETCHFILE_READ}; + +struct fetchfile_state { + enum fetchfile_stage stage; + struct smb_composite_fetchfile *io; + struct composite_context *creq; + struct smb_composite_connect *connect; + struct smb_composite_loadfile *loadfile; +}; + +static void fetchfile_composite_handler(struct composite_context *req); + +static NTSTATUS fetchfile_connect(struct composite_context *c, + struct smb_composite_fetchfile *io) +{ + NTSTATUS status; + struct fetchfile_state *state; + state = talloc_get_type(c->private_data, struct fetchfile_state); + + status = smb_composite_connect_recv(state->creq, c); + NT_STATUS_NOT_OK_RETURN(status); + + state->loadfile = talloc(state, struct smb_composite_loadfile); + NT_STATUS_HAVE_NO_MEMORY(state->loadfile); + + state->loadfile->in.fname = io->in.filename; + + state->creq = smb_composite_loadfile_send(state->connect->out.tree, + state->loadfile); + NT_STATUS_HAVE_NO_MEMORY(state->creq); + + state->creq->async.private_data = c; + state->creq->async.fn = fetchfile_composite_handler; + + state->stage = FETCHFILE_READ; + c->event_ctx = talloc_reference(c, state->creq->event_ctx); + + return NT_STATUS_OK; +} + +static NTSTATUS fetchfile_read(struct composite_context *c, + struct smb_composite_fetchfile *io) +{ + NTSTATUS status; + struct fetchfile_state *state; + state = talloc_get_type(c->private_data, struct fetchfile_state); + + status = smb_composite_loadfile_recv(state->creq, NULL); + NT_STATUS_NOT_OK_RETURN(status); + + io->out.data = state->loadfile->out.data; + io->out.size = state->loadfile->out.size; + + c->state = COMPOSITE_STATE_DONE; + if (c->async.fn) + c->async.fn(c); + + return NT_STATUS_OK; +} + +static void fetchfile_state_handler(struct composite_context *c) +{ + struct fetchfile_state *state; + NTSTATUS status; + + state = talloc_get_type(c->private_data, struct fetchfile_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case FETCHFILE_CONNECT: + status = fetchfile_connect(c, state->io); + break; + case FETCHFILE_READ: + status = fetchfile_read(c, state->io); + break; + } + + if (!NT_STATUS_IS_OK(status)) { + c->status = status; + c->state = COMPOSITE_STATE_ERROR; + if (c->async.fn) { + c->async.fn(c); + } + } +} + +static void fetchfile_composite_handler(struct composite_context *creq) +{ + struct composite_context *c = talloc_get_type(creq->async.private_data, + struct composite_context); + fetchfile_state_handler(c); +} + +struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, + struct event_context *event_ctx) +{ + struct composite_context *c; + struct fetchfile_state *state; + + c = talloc_zero(NULL, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct fetchfile_state); + if (state == NULL) goto failed; + + state->connect = talloc(state, struct smb_composite_connect); + if (state->connect == NULL) goto failed; + + state->io = io; + + state->connect->in.dest_host = io->in.dest_host; + state->connect->in.port = io->in.port; + state->connect->in.called_name = io->in.called_name; + state->connect->in.service = io->in.service; + state->connect->in.service_type = io->in.service_type; + state->connect->in.credentials = io->in.credentials; + state->connect->in.workgroup = io->in.workgroup; + + state->creq = smb_composite_connect_send(state->connect, event_ctx); + if (state->creq == NULL) goto failed; + + state->creq->async.private_data = c; + state->creq->async.fn = fetchfile_composite_handler; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + state->stage = FETCHFILE_CONNECT; + c->event_ctx = talloc_reference(c, state->creq->event_ctx); + c->private_data = state; + + return c; + failed: + talloc_free(c); + return NULL; +} + +NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct fetchfile_state *state = talloc_get_type(c->private_data, struct fetchfile_state); + talloc_steal(mem_ctx, state->io->out.data); + } + + talloc_free(c); + return status; +} + +NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io, + TALLOC_CTX *mem_ctx) +{ + struct composite_context *c = smb_composite_fetchfile_send(io, NULL); + return smb_composite_fetchfile_recv(c, mem_ctx); +} diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c new file mode 100644 index 0000000000..e870225906 --- /dev/null +++ b/source4/libcli/smb_composite/fsinfo.c @@ -0,0 +1,201 @@ +/* + a composite API for quering file system information +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY}; + + +static void fsinfo_raw_handler(struct smbcli_request *req); +static void fsinfo_composite_handler(struct composite_context *c); +static void fsinfo_state_handler(struct composite_context *c); + +struct fsinfo_state { + enum fsinfo_stage stage; + struct composite_context *creq; + struct smb_composite_fsinfo *io; + struct smb_composite_connect *connect; + union smb_fsinfo *fsinfo; + struct smbcli_tree *tree; + struct smbcli_request *req; +}; + +static NTSTATUS fsinfo_connect(struct composite_context *c, + struct smb_composite_fsinfo *io) +{ + NTSTATUS status; + struct fsinfo_state *state; + state = talloc_get_type(c->private_data, struct fsinfo_state); + + status = smb_composite_connect_recv(state->creq, c); + NT_STATUS_NOT_OK_RETURN(status); + + state->fsinfo = talloc(state, union smb_fsinfo); + NT_STATUS_HAVE_NO_MEMORY(state->fsinfo); + + state->fsinfo->generic.level = io->in.level; + + state->req = smb_raw_fsinfo_send(state->connect->out.tree, + state, + state->fsinfo); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + state->req->async.private = c; + state->req->async.fn = fsinfo_raw_handler; + + state->stage = FSINFO_QUERY; + c->event_ctx = talloc_reference(c, state->req->session->transport->socket->event.ctx); + + return NT_STATUS_OK; +} + +static NTSTATUS fsinfo_query(struct composite_context *c, + struct smb_composite_fsinfo *io) +{ + NTSTATUS status; + struct fsinfo_state *state; + state = talloc_get_type(c->private_data, struct fsinfo_state); + + status = smb_raw_fsinfo_recv(state->req, state, state->fsinfo); + NT_STATUS_NOT_OK_RETURN(status); + + state->io->out.fsinfo = state->fsinfo; + + c->state = COMPOSITE_STATE_DONE; + + if (c->async.fn) + c->async.fn(c); + + return NT_STATUS_OK; + +} + +/* + handler for completion of a sub-request in fsinfo +*/ +static void fsinfo_state_handler(struct composite_context *creq) +{ + struct fsinfo_state *state = talloc_get_type(creq->private_data, struct fsinfo_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case FSINFO_CONNECT: + creq->status = fsinfo_connect(creq, state->io); + break; + + case FSINFO_QUERY: + creq->status = fsinfo_query(creq, state->io); + break; + } + + if (!NT_STATUS_IS_OK(creq->status)) { + creq->state = COMPOSITE_STATE_ERROR; + } + + if (creq->state >= COMPOSITE_STATE_DONE && creq->async.fn) { + creq->async.fn(creq); + } +} + +/* + As raw and composite handlers take different requests, we need to handlers + to adapt both for the same state machine in fsinfo_state_handler() +*/ +static void fsinfo_raw_handler(struct smbcli_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + fsinfo_state_handler(c); +} + +static void fsinfo_composite_handler(struct composite_context *creq) +{ + struct composite_context *c = talloc_get_type(creq->async.private_data, + struct composite_context); + fsinfo_state_handler(c); +} + +/* + composite fsinfo call - connects to a tree and queries a file system information +*/ +struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, + struct smb_composite_fsinfo *io) +{ + struct composite_context *c; + struct fsinfo_state *state; + + c = talloc_zero(tree, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct fsinfo_state); + if (state == NULL) goto failed; + + state->io = io; + + state->connect = talloc(state, struct smb_composite_connect); + + if (state->connect == NULL) goto failed; + + state->connect->in.dest_host = io->in.dest_host; + state->connect->in.port = io->in.port; + state->connect->in.called_name = io->in.called_name; + state->connect->in.service = io->in.service; + state->connect->in.service_type = io->in.service_type; + state->connect->in.credentials = io->in.credentials; + state->connect->in.workgroup = io->in.workgroup; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + state->stage = FSINFO_CONNECT; + c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); + c->private_data = state; + + state->creq = smb_composite_connect_send(state->connect, c->event_ctx); + + if (state->creq == NULL) goto failed; + + state->creq->async.private_data = c; + state->creq->async.fn = fsinfo_composite_handler; + + return c; +failed: + talloc_free(c); + return NULL; +} + +/* + composite fsinfo call - recv side +*/ +NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct fsinfo_state *state = talloc_get_type(c->private_data, struct fsinfo_state); + talloc_steal(mem_ctx, state->io->out.fsinfo); + } + + talloc_free(c); + return status; +} + + +/* + composite fsinfo call - sync interface +*/ +NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_composite_fsinfo *io) +{ + struct composite_context *c = smb_composite_fsinfo_send(tree, io); + return smb_composite_fsinfo_recv(c, mem_ctx); +} + diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c new file mode 100644 index 0000000000..93122e287f --- /dev/null +++ b/source4/libcli/smb_composite/loadfile.c @@ -0,0 +1,294 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for loading a whole file into memory +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE}; + + +static void loadfile_handler(struct smbcli_request *req); + +struct loadfile_state { + enum loadfile_stage stage; + struct smb_composite_loadfile *io; + struct smbcli_request *req; + union smb_open *io_open; + union smb_read *io_read; +}; + +/* + setup for the close +*/ +static NTSTATUS setup_close(struct composite_context *c, + struct smbcli_tree *tree, uint16_t fnum) +{ + struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); + union smb_close *io_close; + + /* nothing to read, setup the close */ + io_close = talloc(c, union smb_close); + NT_STATUS_HAVE_NO_MEMORY(io_close); + + io_close->close.level = RAW_CLOSE_CLOSE; + io_close->close.in.fnum = fnum; + io_close->close.in.write_time = 0; + + state->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler again when the close is done */ + state->req->async.fn = loadfile_handler; + state->req->async.private = c; + state->stage = LOADFILE_CLOSE; + + return NT_STATUS_OK; +} + +/* + called when the open is done - pull the results and setup for the + first readx, or close if the file is zero size +*/ +static NTSTATUS loadfile_open(struct composite_context *c, + struct smb_composite_loadfile *io) +{ + struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + + status = smb_raw_open_recv(state->req, c, state->io_open); + NT_STATUS_NOT_OK_RETURN(status); + + /* don't allow stupidly large loads */ + if (state->io_open->ntcreatex.out.size > 100*1000*1000) { + return NT_STATUS_INSUFFICIENT_RESOURCES; + } + + /* allocate space for the file data */ + io->out.size = state->io_open->ntcreatex.out.size; + io->out.data = talloc_array(c, uint8_t, io->out.size); + NT_STATUS_HAVE_NO_MEMORY(io->out.data); + + if (io->out.size == 0) { + return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); + } + + /* setup for the read */ + state->io_read = talloc(c, union smb_read); + NT_STATUS_HAVE_NO_MEMORY(state->io_read); + + state->io_read->readx.level = RAW_READ_READX; + state->io_read->readx.in.fnum = state->io_open->ntcreatex.out.fnum; + state->io_read->readx.in.offset = 0; + state->io_read->readx.in.mincnt = MIN(32768, io->out.size); + state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; + state->io_read->readx.in.remaining = 0; + state->io_read->readx.out.data = io->out.data; + + state->req = smb_raw_read_send(tree, state->io_read); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler again when the first read is done */ + state->req->async.fn = loadfile_handler; + state->req->async.private = c; + state->stage = LOADFILE_READ; + + talloc_free(state->io_open); + + return NT_STATUS_OK; +} + + +/* + called when a read is done - pull the results and setup for the + next read, or close if the file is all done +*/ +static NTSTATUS loadfile_read(struct composite_context *c, + struct smb_composite_loadfile *io) +{ + struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + + status = smb_raw_read_recv(state->req, state->io_read); + NT_STATUS_NOT_OK_RETURN(status); + + /* we might be done */ + if (state->io_read->readx.in.offset + + state->io_read->readx.out.nread == io->out.size) { + return setup_close(c, tree, state->io_read->readx.in.fnum); + } + + /* setup for the next read */ + state->io_read->readx.in.offset += state->io_read->readx.out.nread; + state->io_read->readx.in.mincnt = MIN(32768, io->out.size - state->io_read->readx.in.offset); + state->io_read->readx.out.data = io->out.data + state->io_read->readx.in.offset; + + state->req = smb_raw_read_send(tree, state->io_read); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler again when the read is done */ + state->req->async.fn = loadfile_handler; + state->req->async.private = c; + + return NT_STATUS_OK; +} + +/* + called when the close is done, check the status and cleanup +*/ +static NTSTATUS loadfile_close(struct composite_context *c, + struct smb_composite_loadfile *io) +{ + struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); + NTSTATUS status; + + status = smbcli_request_simple_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + c->state = COMPOSITE_STATE_DONE; + + return NT_STATUS_OK; +} + + +/* + handler for completion of a sub-request in loadfile +*/ +static void loadfile_handler(struct smbcli_request *req) +{ + struct composite_context *c = req->async.private; + struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case LOADFILE_OPEN: + c->status = loadfile_open(c, state->io); + break; + + case LOADFILE_READ: + c->status = loadfile_read(c, state->io); + break; + + case LOADFILE_CLOSE: + c->status = loadfile_close(c, state->io); + break; + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = COMPOSITE_STATE_ERROR; + } + + if (c->state >= COMPOSITE_STATE_DONE && + c->async.fn) { + c->async.fn(c); + } +} + +/* + composite loadfile call - does an openx followed by a number of readx calls, + followed by a close +*/ +struct composite_context *smb_composite_loadfile_send(struct smbcli_tree *tree, + struct smb_composite_loadfile *io) +{ + struct composite_context *c; + struct loadfile_state *state; + + c = talloc_zero(tree, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct loadfile_state); + if (state == NULL) goto failed; + + state->io = io; + + c->private_data = state; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = tree->session->transport->socket->event.ctx; + + /* setup for the open */ + state->io_open = talloc_zero(c, union smb_open); + if (state->io_open == NULL) goto failed; + + state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + state->io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + state->io_open->ntcreatex.in.access_mask = SEC_FILE_READ_DATA; + state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + state->io_open->ntcreatex.in.fname = io->in.fname; + + /* send the open on its way */ + state->req = smb_raw_open_send(tree, state->io_open); + if (state->req == NULL) goto failed; + + /* setup the callback handler */ + state->req->async.fn = loadfile_handler; + state->req->async.private = c; + state->stage = LOADFILE_OPEN; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + composite loadfile call - recv side +*/ +NTSTATUS smb_composite_loadfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); + talloc_steal(mem_ctx, state->io->out.data); + } + + talloc_free(c); + return status; +} + + +/* + composite loadfile call - sync interface +*/ +NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_composite_loadfile *io) +{ + struct composite_context *c = smb_composite_loadfile_send(tree, io); + return smb_composite_loadfile_recv(c, mem_ctx); +} + diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c new file mode 100644 index 0000000000..0e11031dab --- /dev/null +++ b/source4/libcli/smb_composite/savefile.c @@ -0,0 +1,289 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for saving a whole file from memory +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* the stages of this call */ +enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE}; + +static void savefile_handler(struct smbcli_request *req); + +struct savefile_state { + enum savefile_stage stage; + off_t total_written; + struct smb_composite_savefile *io; + union smb_open *io_open; + union smb_write *io_write; + struct smbcli_request *req; +}; + + +/* + setup for the close +*/ +static NTSTATUS setup_close(struct composite_context *c, + struct smbcli_tree *tree, uint16_t fnum) +{ + struct savefile_state *state = talloc_get_type(c->private_data, struct savefile_state); + union smb_close *io_close; + + /* nothing to write, setup the close */ + io_close = talloc(c, union smb_close); + NT_STATUS_HAVE_NO_MEMORY(io_close); + + io_close->close.level = RAW_CLOSE_CLOSE; + io_close->close.in.fnum = fnum; + io_close->close.in.write_time = 0; + + state->req = smb_raw_close_send(tree, io_close); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler again when the close is done */ + state->stage = SAVEFILE_CLOSE; + state->req->async.fn = savefile_handler; + state->req->async.private = c; + + return NT_STATUS_OK; +} + +/* + called when the open is done - pull the results and setup for the + first writex, or close if the file is zero size +*/ +static NTSTATUS savefile_open(struct composite_context *c, + struct smb_composite_savefile *io) +{ + struct savefile_state *state = talloc_get_type(c->private_data, struct savefile_state); + union smb_write *io_write; + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; + + status = smb_raw_open_recv(state->req, c, state->io_open); + NT_STATUS_NOT_OK_RETURN(status); + + if (io->in.size == 0) { + return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); + } + + /* setup for the first write */ + io_write = talloc(c, union smb_write); + NT_STATUS_HAVE_NO_MEMORY(io_write); + + io_write->writex.level = RAW_WRITE_WRITEX; + io_write->writex.in.fnum = state->io_open->ntcreatex.out.fnum; + io_write->writex.in.offset = 0; + io_write->writex.in.wmode = 0; + io_write->writex.in.remaining = 0; + io_write->writex.in.count = MIN(max_xmit - 100, io->in.size); + io_write->writex.in.data = io->in.data; + state->io_write = io_write; + + state->req = smb_raw_write_send(tree, io_write); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler again when the first write is done */ + state->stage = SAVEFILE_WRITE; + state->req->async.fn = savefile_handler; + state->req->async.private = c; + talloc_free(state->io_open); + + return NT_STATUS_OK; +} + + +/* + called when a write is done - pull the results and setup for the + next write, or close if the file is all done +*/ +static NTSTATUS savefile_write(struct composite_context *c, + struct smb_composite_savefile *io) +{ + struct savefile_state *state = talloc_get_type(c->private_data, struct savefile_state); + struct smbcli_tree *tree = state->req->tree; + NTSTATUS status; + uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; + + status = smb_raw_write_recv(state->req, state->io_write); + NT_STATUS_NOT_OK_RETURN(status); + + state->total_written += state->io_write->writex.out.nwritten; + + /* we might be done */ + if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count || + state->total_written == io->in.size) { + return setup_close(c, tree, state->io_write->writex.in.fnum); + } + + /* setup for the next write */ + state->io_write->writex.in.offset = state->total_written; + state->io_write->writex.in.count = MIN(max_xmit - 100, + io->in.size - state->total_written); + state->io_write->writex.in.data = io->in.data + state->total_written; + + state->req = smb_raw_write_send(tree, state->io_write); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + /* call the handler again when the write is done */ + state->req->async.fn = savefile_handler; + state->req->async.private = c; + + return NT_STATUS_OK; +} + +/* + called when the close is done, check the status and cleanup +*/ +static NTSTATUS savefile_close(struct composite_context *c, + struct smb_composite_savefile *io) +{ + struct savefile_state *state = talloc_get_type(c->private_data, struct savefile_state); + NTSTATUS status; + + status = smbcli_request_simple_recv(state->req); + NT_STATUS_NOT_OK_RETURN(status); + + if (state->total_written != io->in.size) { + return NT_STATUS_DISK_FULL; + } + + c->state = COMPOSITE_STATE_DONE; + + return NT_STATUS_OK; +} + + +/* + handler for completion of a sub-request in savefile +*/ +static void savefile_handler(struct smbcli_request *req) +{ + struct composite_context *c = req->async.private; + struct savefile_state *state = talloc_get_type(c->private_data, struct savefile_state); + + /* when this handler is called, the stage indicates what + call has just finished */ + switch (state->stage) { + case SAVEFILE_OPEN: + c->status = savefile_open(c, state->io); + break; + + case SAVEFILE_WRITE: + c->status = savefile_write(c, state->io); + break; + + case SAVEFILE_CLOSE: + c->status = savefile_close(c, state->io); + break; + } + + if (!NT_STATUS_IS_OK(c->status)) { + c->state = COMPOSITE_STATE_ERROR; + } + + if (c->state >= COMPOSITE_STATE_DONE && + c->async.fn) { + c->async.fn(c); + } +} + +/* + composite savefile call - does an openx followed by a number of writex calls, + followed by a close +*/ +struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree, + struct smb_composite_savefile *io) +{ + struct composite_context *c; + struct savefile_state *state; + union smb_open *io_open; + + c = talloc_zero(tree, struct composite_context); + if (c == NULL) goto failed; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = tree->session->transport->socket->event.ctx; + + state = talloc(c, struct savefile_state); + if (state == NULL) goto failed; + + state->stage = SAVEFILE_OPEN; + state->total_written = 0; + state->io = io; + + /* setup for the open */ + io_open = talloc_zero(c, union smb_open); + if (io_open == NULL) goto failed; + + io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; + io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io_open->ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; + io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io_open->ntcreatex.in.fname = io->in.fname; + state->io_open = io_open; + + /* send the open on its way */ + state->req = smb_raw_open_send(tree, io_open); + if (state->req == NULL) goto failed; + + /* setup the callback handler */ + state->req->async.fn = savefile_handler; + state->req->async.private = c; + c->private_data = state; + + return c; + +failed: + talloc_free(c); + return NULL; +} + + +/* + composite savefile call - recv side +*/ +NTSTATUS smb_composite_savefile_recv(struct composite_context *c) +{ + NTSTATUS status; + status = composite_wait(c); + talloc_free(c); + return status; +} + + +/* + composite savefile call - sync interface +*/ +NTSTATUS smb_composite_savefile(struct smbcli_tree *tree, + struct smb_composite_savefile *io) +{ + struct composite_context *c = smb_composite_savefile_send(tree, io); + return smb_composite_savefile_recv(c); +} diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c new file mode 100644 index 0000000000..2ca862fb2f --- /dev/null +++ b/source4/libcli/smb_composite/sesssetup.c @@ -0,0 +1,459 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ +/* + a composite API for making handling a generic async session setup +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" +#include "auth/auth.h" +#include "version.h" + +struct sesssetup_state { + union smb_sesssetup setup; + NTSTATUS gensec_status; + struct smb_composite_sesssetup *io; + struct smbcli_request *req; +}; + + +/* + form an encrypted lanman password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB lanman_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); + SMBencrypt(pass, challenge.data, blob.data); + return blob; +} + +/* + form an encrypted NT password from a plaintext password + and the server supplied challenge +*/ +static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const struct samr_Password *nt_hash, DATA_BLOB challenge) +{ + DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); + SMBOWFencrypt(nt_hash->hash, challenge.data, blob.data); + return blob; +} + +/* + store the user session key for a transport +*/ +static void set_user_session_key(struct smbcli_session *session, + const DATA_BLOB *session_key) +{ + session->user_session_key = data_blob_talloc(session, + session_key->data, + session_key->length); +} + +/* + handler for completion of a smbcli_request sub-request +*/ +static void request_handler(struct smbcli_request *req) +{ + struct composite_context *c = req->async.private; + struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); + struct smbcli_session *session = req->session; + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB null_data_blob = data_blob(NULL, 0); + NTSTATUS session_key_err; + + c->status = smb_raw_sesssetup_recv(req, state, &state->setup); + + switch (state->setup.old.level) { + case RAW_SESSSETUP_OLD: + state->io->out.vuid = state->setup.old.out.vuid; + break; + + case RAW_SESSSETUP_NT1: + state->io->out.vuid = state->setup.nt1.out.vuid; + break; + + case RAW_SESSSETUP_SPNEGO: + session->vuid = state->io->out.vuid = state->setup.spnego.out.vuid; + if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(c->status)) { + break; + } + if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + + /* The status value here, from the earlier pass at GENSEC is + * vital to the security of the system. Even if the other end + * accepts, if GENSEC claims 'MORE_PROCESSING_REQUIRED' then + * you must keep feeding it blobs, or else the remote + * host/attacker might avoid mutal authentication + * requirements */ + + state->gensec_status = gensec_update(session->gensec, state, + state->setup.spnego.out.secblob, + &state->setup.spnego.in.secblob); + c->status = state->gensec_status; + if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(c->status)) { + break; + } + } else { + state->setup.spnego.in.secblob = data_blob(NULL, 0); + } + + /* we need to do another round of session setup. We keep going until both sides + are happy */ + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { + set_user_session_key(session, &session_key); + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } + + if (state->setup.spnego.in.secblob.length) { + state->req = smb_raw_sesssetup_send(session, &state->setup); + state->req->async.fn = request_handler; + state->req->async.private = c; + return; + } + } + + /* enforce the local signing required flag */ + if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) { + if (!session->transport->negotiate.sign_info.doing_signing + && session->transport->negotiate.sign_info.mandatory_signing) { + DEBUG(0, ("SMB signing required, but server does not support it\n")); + c->status = NT_STATUS_ACCESS_DENIED; + } + } + + if (NT_STATUS_IS_OK(c->status)) { + c->state = COMPOSITE_STATE_DONE; + } else { + c->state = COMPOSITE_STATE_ERROR; + } + if (c->async.fn) { + c->async.fn(c); + } +} + + +/* + send a nt1 style session setup +*/ +static NTSTATUS session_setup_nt1(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req) +{ + struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); + const struct samr_Password *nt_hash = cli_credentials_get_nt_hash(io->in.credentials, state); + const char *password = cli_credentials_get_password(io->in.credentials); + + state->setup.nt1.level = RAW_SESSSETUP_NT1; + state->setup.nt1.in.bufsize = session->transport->options.max_xmit; + state->setup.nt1.in.mpx_max = session->transport->options.max_mux; + state->setup.nt1.in.vc_num = 1; + state->setup.nt1.in.sesskey = io->in.sesskey; + state->setup.nt1.in.capabilities = io->in.capabilities; + state->setup.nt1.in.os = "Unix"; + state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); + cli_credentials_get_ntlm_username_domain(io->in.credentials, state, + &state->setup.nt1.in.user, + &state->setup.nt1.in.domain); + + if (!password) { + state->setup.nt1.in.password1 = data_blob(NULL, 0); + state->setup.nt1.in.password2 = data_blob(NULL, 0); + } else if (session->transport->negotiate.sec_mode & + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + DATA_BLOB session_key; + if (lp_client_ntlmv2_auth()) { + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_netbios_name(), lp_workgroup()); + DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key; + + if (!SMBNTLMv2encrypt_hash(state, + state->setup.nt1.in.user, state->setup.nt1.in.domain, + nt_hash->hash, &session->transport->negotiate.secblob, + &names_blob, + &lmv2_response, &ntlmv2_response, + &lmv2_session_key, &session_key)) { + data_blob_free(&names_blob); + return NT_STATUS_NO_MEMORY; + } + data_blob_free(&names_blob); + state->setup.nt1.in.password1 = lmv2_response; + state->setup.nt1.in.password2 = ntlmv2_response; + + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&lmv2_session_key); + data_blob_free(&session_key); + } else { + + state->setup.nt1.in.password2 = nt_blob(state, nt_hash, + session->transport->negotiate.secblob); + if (lp_client_lanman_auth()) { + state->setup.nt1.in.password1 = lanman_blob(state, password, + session->transport->negotiate.secblob); + } else { + /* if not sending the LM password, send the NT password twice */ + state->setup.nt1.in.password1 = state->setup.nt1.in.password2; + } + + session_key = data_blob_talloc(session, NULL, 16); + SMBsesskeygen_ntv1(nt_hash->hash, session_key.data); + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&session_key); + } + + } else if (lp_client_plaintext_auth()) { + state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); + state->setup.nt1.in.password2 = data_blob(NULL, 0); + } else { + /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ + return NT_STATUS_INVALID_PARAMETER; + } + + *req = smb_raw_sesssetup_send(session, &state->setup); + if (!*req) { + return NT_STATUS_NO_MEMORY; + } + return (*req)->status; +} + + +/* + old style session setup (pre NT1 protocol level) +*/ +static NTSTATUS session_setup_old(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req) +{ + struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); + const char *password = cli_credentials_get_password(io->in.credentials); + + state->setup.old.level = RAW_SESSSETUP_OLD; + state->setup.old.in.bufsize = session->transport->options.max_xmit; + state->setup.old.in.mpx_max = session->transport->options.max_mux; + state->setup.old.in.vc_num = 1; + state->setup.old.in.sesskey = io->in.sesskey; + state->setup.old.in.os = "Unix"; + state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); + cli_credentials_get_ntlm_username_domain(io->in.credentials, state, + &state->setup.old.in.user, + &state->setup.old.in.domain); + + if (!password) { + state->setup.old.in.password = data_blob(NULL, 0); + } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + state->setup.old.in.password = lanman_blob(state, password, + session->transport->negotiate.secblob); + } else { + state->setup.old.in.password = data_blob_talloc(state, + password, + strlen(password)); + } + + *req = smb_raw_sesssetup_send(session, &state->setup); + if (!*req) { + return NT_STATUS_NO_MEMORY; + } + return (*req)->status; +} + + +/* + Modern, all singing, all dancing extended security (and possibly SPNEGO) request +*/ +static NTSTATUS session_setup_spnego(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req) +{ + struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); + NTSTATUS status, session_key_err; + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB null_data_blob = data_blob(NULL, 0); + const char *chosen_oid = NULL; + + state->setup.spnego.level = RAW_SESSSETUP_SPNEGO; + state->setup.spnego.in.bufsize = session->transport->options.max_xmit; + state->setup.spnego.in.mpx_max = session->transport->options.max_mux; + state->setup.spnego.in.vc_num = 1; + state->setup.spnego.in.sesskey = io->in.sesskey; + state->setup.spnego.in.capabilities = io->in.capabilities; + state->setup.spnego.in.os = "Unix"; + state->setup.spnego.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); + state->setup.spnego.in.workgroup = io->in.workgroup; + + state->setup.spnego.out.vuid = session->vuid; + + smbcli_temp_set_signing(session->transport); + + status = gensec_client_start(session, &session->gensec, c->event_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); + return status; + } + + gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); + + status = gensec_set_credentials(session->gensec, io->in.credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", + nt_errstr(status))); + return status; + } + + status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + return status; + } + + status = gensec_set_target_service(session->gensec, "cifs"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", + nt_errstr(status))); + return status; + } + + if (session->transport->negotiate.secblob.length) { + chosen_oid = GENSEC_OID_SPNEGO; + } else { + /* without a sec blob, means raw NTLMSSP */ + chosen_oid = GENSEC_OID_NTLMSSP; + } + + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + return status; + } + + status = gensec_update(session->gensec, state, + session->transport->negotiate.secblob, + &state->setup.spnego.in.secblob); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + return status; + } + state->gensec_status = status; + + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } + + *req = smb_raw_sesssetup_send(session, &state->setup); + if (!*req) { + return NT_STATUS_NO_MEMORY; + } + return (*req)->status; +} + + +/* + composite session setup function that hides the details of all the + different session setup varients, including the multi-pass nature of + the spnego varient +*/ +struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session, + struct smb_composite_sesssetup *io) +{ + struct composite_context *c; + struct sesssetup_state *state; + NTSTATUS status; + + c = talloc_zero(session, struct composite_context); + if (c == NULL) return NULL; + + state = talloc(c, struct sesssetup_state); + if (state == NULL) { + c->state = COMPOSITE_STATE_ERROR; + c->status = NT_STATUS_NO_MEMORY; + } + + state->io = io; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = state; + c->event_ctx = session->transport->socket->event.ctx; + + /* no session setup at all in earliest protocol varients */ + if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { + ZERO_STRUCT(io->out); + c->state = COMPOSITE_STATE_DONE; + return c; + } + + /* see what session setup interface we will use */ + if (session->transport->negotiate.protocol < PROTOCOL_NT1) { + status = session_setup_old(c, session, io, &state->req); + } else if (!session->transport->options.use_spnego || + !(io->in.capabilities & CAP_EXTENDED_SECURITY)) { + status = session_setup_nt1(c, session, io, &state->req); + } else { + status = session_setup_spnego(c, session, io, &state->req); + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || + NT_STATUS_IS_OK(status)) { + state->req->async.fn = request_handler; + state->req->async.private = c; + return c; + } + + c->state = COMPOSITE_STATE_ERROR; + c->status = status; + return c; +} + + +/* + receive a composite session setup reply +*/ +NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c) +{ + NTSTATUS status; + status = composite_wait(c); + talloc_free(c); + return status; +} + +/* + sync version of smb_composite_sesssetup +*/ +NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io) +{ + struct composite_context *c = smb_composite_sesssetup_send(session, io); + return smb_composite_sesssetup_recv(c); +} diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h new file mode 100644 index 0000000000..08031c2f4b --- /dev/null +++ b/source4/libcli/smb_composite/smb_composite.h @@ -0,0 +1,152 @@ +/* + Unix SMB/CIFS implementation. + + SMB composite request interfaces + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +/* + this defines the structures associated with "composite" + requests. Composite requests are libcli requests that are internally + implemented as multiple libcli/raw/ calls, but can be treated as a + single call via these composite calls. The composite calls are + particularly designed to be used in async applications +*/ + + +/* + a composite open/read(s)/close request that loads a whole file + into memory. Used as a demo of the composite system. +*/ +struct smb_composite_loadfile { + struct { + const char *fname; + } in; + struct { + uint8_t *data; + uint32_t size; + } out; +}; + +struct smb_composite_fetchfile { + struct { + const char *dest_host; + int port; + const char *called_name; + const char *service; + const char *service_type; + struct cli_credentials *credentials; + const char *workgroup; + const char *filename; + } in; + struct { + uint8_t *data; + uint32_t size; + } out; +}; + +/* + a composite open/write(s)/close request that saves a whole file from + memory. Used as a demo of the composite system. +*/ +struct smb_composite_savefile { + struct { + const char *fname; + uint8_t *data; + uint32_t size; + } in; +}; + + +/* + a composite request for a full connection to a remote server. Includes + + - socket establishment + - session request + - negprot + - session setup + - tree connect +*/ +struct smb_composite_connect { + struct { + const char *dest_host; + int port; + const char *called_name; + const char *service; + const char *service_type; + struct cli_credentials *credentials; + const char *workgroup; + } in; + struct { + struct smbcli_tree *tree; + } out; +}; + + +/* + generic session setup interface that takes care of which + session setup varient to use +*/ +struct smb_composite_sesssetup { + struct { + uint32_t sesskey; + uint32_t capabilities; + struct cli_credentials *credentials; + const char *workgroup; + } in; + struct { + uint16_t vuid; + } out; +}; + +/* + query file system info +*/ +struct smb_composite_fsinfo { + struct { + const char *dest_host; + int port; + const char *called_name; + const char *service; + const char *service_type; + struct cli_credentials *credentials; + const char *workgroup; + enum smb_fsinfo_level level; + } in; + + struct { + union smb_fsinfo *fsinfo; + } out; +}; + +/* + composite call for appending new acl to the file's security descriptor and get + new full acl +*/ + +struct smb_composite_appendacl { + struct { + const char *fname; + + const struct security_descriptor *sd; + } in; + + struct { + struct security_descriptor *sd; + } out; +}; -- cgit From 49839f356f493d0de1b719c8c3bfdee4713c0728 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Sep 2005 16:57:08 +0000 Subject: r10513: Reduce some use of pstring. The main reason some parts of the code still use pstring is next_token() now. (This used to be commit a5b88bcd420eb7ae42283293541519e142be36e3) --- source4/libcli/util/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 08cd844b3a..ca8605faea 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -835,7 +835,7 @@ const char *get_nt_error_c_code(NTSTATUS nt_code) /***************************************************************************** returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) *****************************************************************************/ -NTSTATUS nt_status_string_to_code(char *nt_status_str) +NTSTATUS nt_status_string_to_code(const char *nt_status_str) { int idx = 0; -- cgit From fa70d1d0c28ff8065ca40a3682dc50131b7a6ecf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Sep 2005 10:29:13 +0000 Subject: r10529: fix a crash bug in full async code the uses the composite_trigger_done() code the event subsystem wants to free timed_events! metze (This used to be commit dc5d5953b60662b895ad148525e84d82882d62a8) --- source4/libcli/composite/composite.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 4a5247c9ea..f6fc61d764 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -52,6 +52,12 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te, { struct composite_context *c = talloc_get_type(ptr, struct composite_context); if (c->async.fn) { + /* + * the event is a child of req, + * and req will be free'ed by the callback fn + * but the events code wants to free the event itself + */ + talloc_steal(ev, te); c->async.fn(c); } } -- cgit From 4d024ddfb52504644313dfcb4ab0f97d07f83c29 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Sep 2005 10:31:57 +0000 Subject: r10530: - fix some crash bugs when we lost the connection... metze (This used to be commit 0983452bf8b0922f6df7af4aa16b14835d39d036) --- source4/libcli/wrepl/winsrepl.c | 55 ++++++++++++++++++++++++++++++++++++++--- source4/libcli/wrepl/winsrepl.h | 3 +++ 2 files changed, 55 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 516c72ef29..945f4a4b4c 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -31,6 +31,8 @@ */ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket) { + wrepl_socket->dead = True; + event_set_fd_flags(wrepl_socket->fde, 0); while (wrepl_socket->send_queue) { @@ -118,7 +120,10 @@ static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) req->buffer.data + req->num_read, 4 - req->num_read, &nread, 0); - if (NT_STATUS_IS_ERR(req->status)) goto failed; + if (NT_STATUS_IS_ERR(req->status)) { + wrepl_socket_dead(wrepl_socket); + return; + } if (!NT_STATUS_IS_OK(req->status)) return; req->num_read += nread; @@ -140,7 +145,10 @@ static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) req->buffer.data + req->num_read, req->buffer.length - req->num_read, &nread, 0); - if (NT_STATUS_IS_ERR(req->status)) goto failed; + if (NT_STATUS_IS_ERR(req->status)) { + wrepl_socket_dead(wrepl_socket); + return; + } if (!NT_STATUS_IS_OK(req->status)) return; req->num_read += nread; @@ -275,6 +283,7 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, wrepl_socket->send_queue = NULL; wrepl_socket->recv_queue = NULL; + wrepl_socket->dead = False; wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, socket_get_fd(wrepl_socket->sock), @@ -368,6 +377,35 @@ NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *address) return wrepl_connect_recv(req); } +/* + callback from wrepl_request_trigger() +*/ +static void wrepl_request_trigger_handler(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); + if (req->async.fn) { + /* + * the event is a child of req, + * and req will be free'ed by the callback fn + * but the events code wants to free the event itself + */ + talloc_steal(ev, te); + req->async.fn(req); + } +} + +/* + trigger an immediate event on a wrepl_request +*/ +static void wrepl_request_trigger(struct wrepl_request *req) +{ + /* a zero timeout means immediate */ + event_add_timed(req->wrepl_socket->event_ctx, + req, timeval_zero(), + wrepl_request_trigger_handler, req); +} + /* send a generic wins replication request @@ -381,12 +419,20 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, req = talloc_zero(wrepl_socket, struct wrepl_request); if (req == NULL) goto failed; + if (wrepl_socket->dead) { + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_ERROR; + req->status = NT_STATUS_INVALID_CONNECTION; + wrepl_request_trigger(req); + return req; + } + req->wrepl_socket = wrepl_socket; req->state = WREPL_REQUEST_SEND; wrap.packet = *packet; req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, - (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); + (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); if (!NT_STATUS_IS_OK(req->status)) goto failed; if (DEBUGLVL(10)) { @@ -468,6 +514,7 @@ NTSTATUS wrepl_associate_recv(struct wrepl_request *req, struct wrepl_packet *packet=NULL; NTSTATUS status; status = wrepl_request_recv(req, req->wrepl_socket, &packet); + NT_STATUS_NOT_OK_RETURN(status); if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) { status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; } @@ -527,6 +574,7 @@ NTSTATUS wrepl_pull_table_recv(struct wrepl_request *req, int i; status = wrepl_request_recv(req, req->wrepl_socket, &packet); + NT_STATUS_NOT_OK_RETURN(status); if (packet->mess_type != WREPL_REPLICATION) { status = NT_STATUS_NETWORK_ACCESS_DENIED; } else if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) { @@ -630,6 +678,7 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, int i; status = wrepl_request_recv(req, req->wrepl_socket, &packet); + NT_STATUS_NOT_OK_RETURN(status); if (packet->mess_type != WREPL_REPLICATION || packet->message.replication.command != WREPL_REPL_SEND_REPLY) { status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 79b7f1fd70..a966cf5451 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -38,6 +38,9 @@ struct wrepl_socket { /* the fd event */ struct fd_event *fde; + + /* remember is the socket is dead */ + BOOL dead; }; enum wrepl_request_state { -- cgit From 38e43be7b89673282f8853ffedf726d84ef5ce30 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Sep 2005 12:54:08 +0000 Subject: r10537: - we now use a much nicer way to handle talloc_free(timed_event) the events code replaces a destructor to one that returns allways -1 while it's calling the event handler - we don't need the composite and winsrepl specific fixes any more - this also fixes the problem with smbcli, dcerpc, cldap, ldap and nbt request timeouts metze (This used to be commit 495996cfc49a1c6eefde6ff04fc75e0739be3aab) --- source4/libcli/composite/composite.c | 6 ------ source4/libcli/wrepl/winsrepl.c | 6 ------ 2 files changed, 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index f6fc61d764..4a5247c9ea 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -52,12 +52,6 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te, { struct composite_context *c = talloc_get_type(ptr, struct composite_context); if (c->async.fn) { - /* - * the event is a child of req, - * and req will be free'ed by the callback fn - * but the events code wants to free the event itself - */ - talloc_steal(ev, te); c->async.fn(c); } } diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 945f4a4b4c..853ee01d38 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -385,12 +385,6 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed { struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); if (req->async.fn) { - /* - * the event is a child of req, - * and req will be free'ed by the callback fn - * but the events code wants to free the event itself - */ - talloc_steal(ev, te); req->async.fn(req); } } -- cgit From 1c701527fff811ab7a60f38f91937d78509c1c01 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Sep 2005 13:31:17 +0000 Subject: r10542: if the transport is dead we need to return tridge: I think this is correct, comments? metze (This used to be commit e06ca726f3df013d869d943338bc6b7a151cdd3f) --- source4/libcli/raw/clitransport.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index d70d333039..7d4891da00 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -353,6 +353,7 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport) req->out.size, &nwritten); if (NT_STATUS_IS_ERR(status)) { smbcli_transport_dead(transport); + return; } if (!NT_STATUS_IS_OK(status)) { return; @@ -540,6 +541,7 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) &nread); if (NT_STATUS_IS_ERR(status)) { smbcli_transport_dead(transport); + return; } if (!NT_STATUS_IS_OK(status)) { return; @@ -571,6 +573,7 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) &nread); if (NT_STATUS_IS_ERR(status)) { smbcli_transport_dead(transport); + return; } if (!NT_STATUS_IS_OK(status)) { return; -- cgit From 5880f79f4f314b875d8cb2b72562f6cdf716ba67 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Sep 2005 16:20:17 +0000 Subject: r10545: map ECONNRESET to NT_STATUS_CONNECTION_RESET metze (This used to be commit e753114e863ff0ea32b35ef30a6f0056cfa7c902) --- source4/libcli/util/errormap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 95fac97428..99154d2cb0 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1277,6 +1277,9 @@ const struct unix_error_map unix_nt_errmap[] = { { ENOMEM, NT_STATUS_NO_MEMORY }, { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, +#ifdef ECONNRESET + { ECONNRESET, NT_STATUS_CONNECTION_RESET }, +#endif { EBUSY, NT_STATUS_SHARING_VIOLATION }, #ifdef ENOTSUP { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, -- cgit From 0b2c6aec9217c40324dddcc2fef376f5a8c5c27d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Sep 2005 16:53:08 +0000 Subject: r10547: - add wrepl_request timeout handling - when we got an unexpected READ event, we need to do a socket_recv() to find connection errors and we need to mark the socket as dead (and remove the fde_event) to prevent, endless loops on broken connections tridge: we should look carefull at other protocol, to handle broken connections without spinning metze (This used to be commit ff1272347739696dcdf2fd191b8f47ca82c205de) --- source4/libcli/wrepl/winsrepl.c | 75 ++++++++++++++++++++++++++++++++--------- source4/libcli/wrepl/winsrepl.h | 9 +++++ 2 files changed, 69 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 853ee01d38..4284c5cdbb 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -29,17 +29,28 @@ /* mark all pending requests as dead - called when a socket error happens */ -static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket) +static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status) { wrepl_socket->dead = True; - event_set_fd_flags(wrepl_socket->fde, 0); + if (wrepl_socket->fde) { + talloc_free(wrepl_socket->fde); + wrepl_socket->fde = NULL; + } + + if (wrepl_socket->sock) { + talloc_free(wrepl_socket->sock); + wrepl_socket->sock = NULL; + } + if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } while (wrepl_socket->send_queue) { struct wrepl_request *req = wrepl_socket->send_queue; DLIST_REMOVE(wrepl_socket->send_queue, req); req->state = WREPL_REQUEST_ERROR; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + req->status = status; if (req->async.fn) { req->async.fn(req); } @@ -48,13 +59,20 @@ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket) struct wrepl_request *req = wrepl_socket->recv_queue; DLIST_REMOVE(wrepl_socket->recv_queue, req); req->state = WREPL_REQUEST_ERROR; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + req->status = status; if (req->async.fn) { req->async.fn(req); } } } +static void wrepl_request_timeout_handler(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); + wrepl_socket_dead(req->wrepl_socket, NT_STATUS_IO_TIMEOUT); +} + /* handle send events */ @@ -67,7 +85,7 @@ static void wrepl_handler_send(struct wrepl_socket *wrepl_socket) status = socket_send(wrepl_socket->sock, &req->buffer, &nsent, 0); if (NT_STATUS_IS_ERR(status)) { - wrepl_socket_dead(wrepl_socket); + wrepl_socket_dead(wrepl_socket, status); return; } if (!NT_STATUS_IS_OK(status) || nsent == 0) return; @@ -99,7 +117,16 @@ static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) DATA_BLOB blob; if (req == NULL) { + NTSTATUS status; + EVENT_FD_NOT_READABLE(wrepl_socket->fde); + + status = socket_recv(wrepl_socket->sock, NULL, 0, &nread, 0); + if (NT_STATUS_EQUAL(NT_STATUS_END_OF_FILE,status)) return; + if (NT_STATUS_IS_ERR(status)) { + wrepl_socket_dead(wrepl_socket, status); + return; + } return; } @@ -121,7 +148,7 @@ static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) 4 - req->num_read, &nread, 0); if (NT_STATUS_IS_ERR(req->status)) { - wrepl_socket_dead(wrepl_socket); + wrepl_socket_dead(wrepl_socket, req->status); return; } if (!NT_STATUS_IS_OK(req->status)) return; @@ -146,7 +173,7 @@ static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) req->buffer.length - req->num_read, &nread, 0); if (NT_STATUS_IS_ERR(req->status)) { - wrepl_socket_dead(wrepl_socket); + wrepl_socket_dead(wrepl_socket, req->status); return; } if (!NT_STATUS_IS_OK(req->status)) return; @@ -225,7 +252,8 @@ static void wrepl_connect_handler(struct event_context *ev, struct fd_event *fde struct wrepl_socket); struct wrepl_request *req = wrepl_socket->recv_queue; - talloc_free(fde); + talloc_free(wrepl_socket->fde); + wrepl_socket->fde = NULL; if (req == NULL) return; @@ -255,6 +283,15 @@ failed: } } +/* + destroy a wrepl_socket destructor +*/ +static int wrepl_socket_destructor(void *ptr) +{ + struct wrepl_socket *sock = talloc_get_type(ptr, struct wrepl_socket); + wrepl_socket_dead(sock, NT_STATUS_CONNECTION_DISCONNECTED); + return 0; +} /* initialise a wrepl_socket. The event_ctx is optional, if provided then @@ -281,9 +318,10 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, talloc_steal(wrepl_socket, wrepl_socket->sock); - wrepl_socket->send_queue = NULL; - wrepl_socket->recv_queue = NULL; - wrepl_socket->dead = False; + wrepl_socket->send_queue = NULL; + wrepl_socket->recv_queue = NULL; + wrepl_socket->request_timeout = WREPL_SOCKET_REQUEST_TIMEOUT; + wrepl_socket->dead = False; wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, socket_get_fd(wrepl_socket->sock), @@ -291,6 +329,8 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, wrepl_connect_handler, wrepl_socket); set_blocking(socket_get_fd(wrepl_socket->sock), False); + + talloc_set_destructor(wrepl_socket, wrepl_socket_destructor); return wrepl_socket; @@ -299,7 +339,6 @@ failed: return NULL; } - /* destroy a wrepl_request */ @@ -438,6 +477,12 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, talloc_set_destructor(req, wrepl_request_destructor); + if (wrepl_socket->request_timeout > 0) { + req->te = event_add_timed(wrepl_socket->event_ctx, req, + timeval_current_ofs(wrepl_socket->request_timeout, 0), + wrepl_request_timeout_handler, req); + } + EVENT_FD_WRITEABLE(wrepl_socket->fde); return req; @@ -643,16 +688,16 @@ static NTSTATUS wrepl_extract_name(struct nbt_name *name, } if (len < 17) { - make_nbt_name_client(name, talloc_strndup(mem_ctx, namebuf, len)); + make_nbt_name_client(name, talloc_strndup(mem_ctx, (char *)namebuf, len)); return NT_STATUS_OK; } - s = talloc_strndup(mem_ctx, namebuf, 15); + s = talloc_strndup(mem_ctx, (char *)namebuf, 15); trim_string(s, NULL, " "); name->name = s; name->type = namebuf[15]; if (len > 18) { - name->scope = talloc_strndup(mem_ctx, namebuf+17, len-17); + name->scope = talloc_strndup(mem_ctx, (char *)(namebuf+17), len-17); } else { name->scope = NULL; } diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index a966cf5451..64e09d61c6 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -39,6 +39,13 @@ struct wrepl_socket { /* the fd event */ struct fd_event *fde; + /* the default timeout for requests, 0 means no timeout */ +#define WREPL_SOCKET_REQUEST_TIMEOUT (60) + uint32_t request_timeout; + + /* counter for request timeouts, after 2 timeouts the socket is marked as dead */ + uint32_t timeout_count; + /* remember is the socket is dead */ BOOL dead; }; @@ -64,6 +71,8 @@ struct wrepl_request { size_t num_read; + struct timed_event *te; + struct wrepl_packet *packet; struct { -- cgit From f7c5e5a3987ea773203f6052e9cac34ae8992131 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Sep 2005 09:58:58 +0000 Subject: r10569: add all info that we have to wrepl_name, as we need it for replication :-) metze (This used to be commit bfd548ca10134d5a17b87a0507917721aa251223) --- source4/libcli/wrepl/winsrepl.c | 21 +++++++++++++++------ source4/libcli/wrepl/winsrepl.h | 4 ++++ 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 4284c5cdbb..069ee29407 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -729,7 +729,7 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, status = NT_STATUS_NO_MEMORY; io->out.names = talloc_array(packet, struct wrepl_name, io->out.num_names); - if (io->out.names == NULL) goto failed; + if (io->out.names == NULL) goto nomem; /* convert the list of names and addresses to a sane format */ for (i=0;iout.num_names;i++) { @@ -739,6 +739,12 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, wname->name, wname->name_len); if (!NT_STATUS_IS_OK(status)) goto failed; + name->flags = wname->flags; + name->group_flag= wname->group_flag; + name->version_id= wname->id; + name->owner = talloc_strdup(io->out.names, io->in.partner.address); + if (name->owner == NULL) goto nomem; + /* trying to save 1 or 2 bytes on the wire isn't a good idea */ if (wname->flags & 2) { int j; @@ -747,7 +753,7 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, name->addresses = talloc_array(io->out.names, struct wrepl_address, name->num_addresses); - if (name->addresses == NULL) goto failed; + if (name->addresses == NULL) goto nomem; for (j=0;jnum_addresses;j++) { name->addresses[j].owner = talloc_steal(name->addresses, @@ -759,16 +765,19 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, } else { name->num_addresses = 1; name->addresses = talloc(io->out.names, struct wrepl_address); - if (name->addresses == NULL) goto failed; - name->addresses[0].owner = io->in.partner.address; + if (name->addresses == NULL) goto nomem; + name->addresses[0].owner = talloc_strdup(name->addresses,io->in.partner.address); + if (name->addresses[0].owner == NULL) goto nomem; name->addresses[0].address = talloc_steal(name->addresses, wname->addresses.ip); } } talloc_steal(mem_ctx, io->out.names); - status = NT_STATUS_OK; - + talloc_free(packet); + return NT_STATUS_OK; +nomem: + status = NT_STATUS_NO_MEMORY; failed: talloc_free(packet); return status; diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 64e09d61c6..2253fe181e 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -116,6 +116,10 @@ struct wrepl_pull_names { uint32_t num_names; struct wrepl_name { struct nbt_name name; + uint32_t flags; + uint32_t group_flag; + uint64_t version_id; + const char *owner; uint32_t num_addresses; struct wrepl_address { const char *owner; -- cgit From 5058f4b9e82ca8b9f2405930db3a46b8c37f06ed Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Sep 2005 18:18:09 +0000 Subject: r10586: Add MergedObject() builder. Default to Library() rather then StaticLibrary() (This used to be commit b53313dc517986c69a4e4cb8fe3885b696f8faa1) --- source4/libcli/SConscript | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index 76143b97cf..aa911d9838 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -2,41 +2,41 @@ Import('hostenv') proto_files = [] cli_utils_files = ['util/asn1.c', 'util/doserr.c','util/errormap.c','util/clierror.c', 'util/nterr.c','util/smbdes.c'] proto_files += cli_utils_files -hostenv.StaticLibrary('cli_utils', cli_utils_files) +hostenv.Library('cli_utils', cli_utils_files) -hostenv.StaticLibrary('cli_lsa', ['util/clilsa.c']) -hostenv.StaticLibrary('cli_composite_base', ['composite/composite.c']) +hostenv.Library('cli_lsa', ['util/clilsa.c']) +hostenv.Library('cli_composite_base', ['composite/composite.c']) -cli_composite_files = ['composite/loadfile.c','composite/savefile.c','composite/connect.c', - 'composite/sesssetup.c','composite/fetchfile.c','composite/appendacl.c', - 'composite/fsinfo.c'] +cli_composite_files = ['smb_composite/loadfile.c','smb_composite/savefile.c','smb_composite/connect.c', + 'smb_composite/sesssetup.c','smb_composite/fetchfile.c','smb_composite/appendacl.c', + 'smb_composite/fsinfo.c'] -hostenv.StaticLibrary('cli_composite', cli_composite_files) +hostenv.Library('cli_composite', cli_composite_files) proto_files += ['util/clilsa.c', 'composite/composite.c'] + cli_composite_files cli_nbt_files = ['nbt/nbtname.c','nbt/nbtsocket.c','nbt/namequery.c','nbt/nameregister.c', 'nbt/namerefresh.c','nbt/namerelease.c'] -hostenv.StaticLibrary('cli_nbt', cli_nbt_files) +hostenv.Library('cli_nbt', cli_nbt_files) proto_files += cli_nbt_files -hostenv.StaticLibrary('cli_dgram', +hostenv.Library('cli_dgram', [ 'dgram/dgramsocket.c','dgram/mailslot.c','dgram/netlogon.c', 'dgram/ntlogon.c','dgram/browse.c']) -hostenv.StaticLibrary('cli_cldap', ['cldap/cldap.c']) -hostenv.StaticLibrary('cli_wrepl', ['wrepl/winsrepl.c']) +hostenv.Library('cli_cldap', ['cldap/cldap.c']) +hostenv.Library('cli_wrepl', ['wrepl/winsrepl.c']) cli_resolve_files = ['resolve/resolve.c','resolve/nbtlist.c','resolve/bcast.c','resolve/wins.c', 'resolve/host.c'] -hostenv.StaticLibrary('cli_resolve', cli_resolve_files) +hostenv.Library('cli_resolve', cli_resolve_files) proto_files += cli_resolve_files smb_files = ['clireadwrite.c', 'cliconnect.c','clifile.c','clilist.c','clitrans2.c', 'climessage.c','clideltree.c'] -hostenv.StaticLibrary('smb', smb_files) +hostenv.Library('smb', smb_files) proto_files += smb_files cli_raw_files = ['raw/rawfile.c','raw/smb_signing.c','raw/clisocket.c', @@ -47,23 +47,23 @@ cli_raw_files = ['raw/rawfile.c','raw/smb_signing.c','raw/clisocket.c', 'raw/rawfileinfo.c','raw/rawnotify.c','raw/rawioctl.c', 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c'] -hostenv.StaticLibrary('cli_raw', cli_raw_files) +hostenv.Library('cli_raw', cli_raw_files) proto_files += cli_raw_files security_files = ['security/security_token.c','security/security_descriptor.c', 'security/dom_sid.c', 'security/access_check.c', 'security/privilege.c', '../librpc/ndr/ndr_sec_helper.c'] proto_files += security_files -hostenv.StaticLibrary('cli_security', security_files) +hostenv.Library('cli_security', security_files) auth_files = ['auth/credentials.c','auth/session.c','auth/smbencrypt.c'] proto_files += auth_files -hostenv.StaticLibrary('cli_auth',auth_files) +hostenv.Library('cli_auth',auth_files) ldap_files = ['ldap/ldap.c','ldap/ldap_client.c','ldap/ldap_bind.c', 'ldap/ldap_msg.c','ldap/ldap_ndr.c','ldap/ldap_ildap.c'] proto_files += ldap_files -cli_ldap = hostenv.StaticLibrary('cli_ldap',ldap_files) +cli_ldap = hostenv.Library('cli_ldap',ldap_files) Export('cli_ldap') -- cgit From f9fea8ba7786ef0b633d396c6ae56929325f312b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Sep 2005 00:28:46 +0000 Subject: r10598: Factor out common code, in preperation for a move elsewhere. Andrew Bartlett (This used to be commit 0d757b169a3d521a0d228bed51aa96cf199d5c42) --- source4/libcli/smb_composite/sesssetup.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 2ca862fb2f..700e4ef744 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -199,15 +199,10 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, return NT_STATUS_NO_MEMORY; } data_blob_free(&names_blob); + data_blob_free(&lmv2_session_key); state->setup.nt1.in.password1 = lmv2_response; state->setup.nt1.in.password2 = ntlmv2_response; - smbcli_transport_simple_set_signing(session->transport, session_key, - state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); - - data_blob_free(&lmv2_session_key); - data_blob_free(&session_key); } else { state->setup.nt1.in.password2 = nt_blob(state, nt_hash, @@ -222,13 +217,14 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, session_key = data_blob_talloc(session, NULL, 16); SMBsesskeygen_ntv1(nt_hash->hash, session_key.data); - smbcli_transport_simple_set_signing(session->transport, session_key, - state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); - - data_blob_free(&session_key); } + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&session_key); + } else if (lp_client_plaintext_auth()) { state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); -- cgit From 08f16292a0cfab57c484661c1f05e1a49ec06942 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Sep 2005 14:00:07 +0000 Subject: r10608: - fix hierachical memory handling in ndr_pull_nbt_name - add wrepl_nbt_name scalar type and do the pull/push in the ndr layer instead of the caller - give the flags and group_flag in the wrepl_name a meaning metze (This used to be commit b98efc2905e1147eb97111b46a877bdb9d8dd154) --- source4/libcli/nbt/nbtname.c | 126 +++++++++++++++++++++++++++++++++++++--- source4/libcli/wrepl/winsrepl.c | 47 +++------------ source4/libcli/wrepl/winsrepl.h | 16 ++++- 3 files changed, 140 insertions(+), 49 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index ae6df8a18d..86309b7f6b 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -294,7 +294,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name scope = strchr(s, '.'); if (scope) { *scope = 0; - r->scope = talloc_strdup(ndr, scope+1); + r->scope = talloc_strdup(ndr->current_mem_ctx, scope+1); NT_STATUS_HAVE_NO_MEMORY(r->scope); } else { r->scope = NULL; @@ -312,7 +312,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name status = decompress_name(cname, &r->type); NT_STATUS_NOT_OK_RETURN(status); - r->name = talloc_strdup(ndr, cname); + r->name = talloc_strdup(ndr->current_mem_ctx, cname); NT_STATUS_HAVE_NO_MEMORY(r->name); talloc_free(cname); @@ -344,12 +344,7 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt } status = ndr_push_nbt_string(ndr, ndr_flags, fullname); -#if 0 - /* this free conflicts with the use of pointers into strings - in the ndr_token_store() calls above. Metze, can you look - at this? */ - talloc_free(fullname); -#endif + return status; } @@ -476,3 +471,118 @@ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) return ret; } +/* + pull a nbt name, WINS Replication uses another on wire format for nbt name +*/ +NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) +{ + uint8_t *namebuf; + uint32_t namebuf_len; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &namebuf_len)); + if (namebuf_len < 1 || namebuf_len > 255) { + return ndr_pull_error(ndr, NDR_ERR_ALLOC, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); + + /* oh wow, what a nasty bug in windows ... */ + if (namebuf[0] == 0x1b && namebuf_len >= 16) { + namebuf[0] = namebuf[15]; + namebuf[15] = 0x1b; + } + + if (namebuf_len < 17) { + r->type = 0x00; + + r->name = talloc_strndup(ndr->current_mem_ctx, (char *)namebuf, namebuf_len); + if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); + + r->scope= NULL; + + talloc_free(namebuf); + return NT_STATUS_OK; + } + + r->type = namebuf[15]; + + namebuf[15] = '\0'; + trim_string((char *)namebuf, NULL, " "); + r->name = talloc_strdup(ndr->current_mem_ctx, (char *)namebuf); + if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); + + if (namebuf_len > 18) { + r->scope = talloc_strndup(ndr->current_mem_ctx, (char *)(namebuf+17), namebuf_len-17); + if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); + } else { + r->scope = NULL; + } + + talloc_free(namebuf); + return NT_STATUS_OK; +} + +/* + push a nbt name, WINS Replication uses another on wire format for nbt name +*/ +NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name r) +{ + uint8_t *namebuf; + uint32_t namebuf_len; + uint32_t name_len; + uint32_t scope_len = 0; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + name_len = strlen(r.name); + if (name_len > 15) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + if (r.scope) { + scope_len = strlen(r.scope); + } + if (scope_len > 238) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s", + r.name, 'X', + (r.scope?r.scope:"")); + if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory"); + + namebuf_len = strlen((char *)namebuf) + 1; + + /* + * we need to set the type here, and use a place-holder in the talloc_asprintf() + * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results + */ + namebuf[15] = r.type; + + /* oh wow, what a nasty bug in windows ... */ + if (r.type == 0x1b) { + namebuf[15] = namebuf[0]; + namebuf[0] = 0x1b; + } + + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, namebuf_len)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); + + talloc_free(namebuf); + return NT_STATUS_OK; +} + +void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name r) +{ + char *s = nbt_name_string(ndr, &r); + ndr_print_string(ndr, name, s); + talloc_free(s); +} diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 069ee29407..feeea321b1 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -671,40 +671,6 @@ struct wrepl_request *wrepl_pull_names_send(struct wrepl_socket *wrepl_socket, return req; } - -/* - extract a nbt_name from a WINS name buffer -*/ -static NTSTATUS wrepl_extract_name(struct nbt_name *name, - TALLOC_CTX *mem_ctx, - uint8_t *namebuf, uint32_t len) -{ - char *s; - - /* oh wow, what a nasty bug in windows ... */ - if (namebuf[0] == 0x1b && len >= 16) { - namebuf[0] = namebuf[15]; - namebuf[15] = 0x1b; - } - - if (len < 17) { - make_nbt_name_client(name, talloc_strndup(mem_ctx, (char *)namebuf, len)); - return NT_STATUS_OK; - } - - s = talloc_strndup(mem_ctx, (char *)namebuf, 15); - trim_string(s, NULL, " "); - name->name = s; - name->type = namebuf[15]; - if (len > 18) { - name->scope = talloc_strndup(mem_ctx, (char *)(namebuf+17), len-17); - } else { - name->scope = NULL; - } - - return NT_STATUS_OK; -} - /* fetch the names for a WINS partner - recv */ @@ -735,12 +701,15 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, for (i=0;iout.num_names;i++) { struct wrepl_wins_name *wname = &packet->message.replication.info.reply.names[i]; struct wrepl_name *name = &io->out.names[i]; - status = wrepl_extract_name(&name->name, io->out.names, - wname->name, wname->name_len); - if (!NT_STATUS_IS_OK(status)) goto failed; - name->flags = wname->flags; - name->group_flag= wname->group_flag; + name->name = wname->name; + talloc_steal(io->out.names, wname->name.name); + talloc_steal(io->out.names, wname->name.scope); + name->type = WREPL_NAME_TYPE(wname->flags); + name->state = WREPL_NAME_STATE(wname->flags); + name->node = WREPL_NBT_NODE(wname->flags); + name->is_static = WREPL_NAME_IS_STATIC(wname->flags); + name->raw_flags = wname->flags; name->version_id= wname->id; name->owner = talloc_strdup(io->out.names, io->in.partner.address); if (name->owner == NULL) goto nomem; diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 2253fe181e..9b9362e4b3 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -104,6 +104,15 @@ struct wrepl_pull_table { } out; }; +#define WREPL_NAME_TYPE(flags) (flags & WREPL_FLAGS_RECORD_TYPE) +#define WREPL_NAME_STATE(flags) ((flags & WREPL_FLAGS_RECORD_STATE)>>2) +#define WREPL_NBT_NODE(flags) ((flags & WREPL_FLAGS_NODE_TYPE)<<8) +#define WREPL_NAME_IS_STATIC(flags) ((flags & WREPL_FLAGS_IS_STATIC)?True:False) + +#define WREPL_NAME_FLAGS(type, state, node, is_static) \ + (type | (state << 2) | (node>>8) | \ + (is_static ? WREPL_FLAGS_IS_STATIC : 0)) + /* a full pull replication */ @@ -116,8 +125,11 @@ struct wrepl_pull_names { uint32_t num_names; struct wrepl_name { struct nbt_name name; - uint32_t flags; - uint32_t group_flag; + enum wrepl_name_type type; + enum wrepl_name_state state; + enum nbt_node_type node; + BOOL is_static; + uint32_t raw_flags; uint64_t version_id; const char *owner; uint32_t num_addresses; -- cgit From c2d7914428f73d1826dffa893418fa286a5e9ab8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Sep 2005 22:06:24 +0000 Subject: r10627: - use a wrepl specific enum for the node type - the unknown flag 0x10 seems to mean that this name was localy registered on this currently asked server, that flag is not present in replica records metze (This used to be commit ba3685c41dc934692bd653f4fe9c0ee451146c40) --- source4/libcli/wrepl/winsrepl.c | 2 +- source4/libcli/wrepl/winsrepl.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index feeea321b1..aae77feb29 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -707,7 +707,7 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, talloc_steal(io->out.names, wname->name.scope); name->type = WREPL_NAME_TYPE(wname->flags); name->state = WREPL_NAME_STATE(wname->flags); - name->node = WREPL_NBT_NODE(wname->flags); + name->node = WREPL_NAME_NODE(wname->flags); name->is_static = WREPL_NAME_IS_STATIC(wname->flags); name->raw_flags = wname->flags; name->version_id= wname->id; diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 9b9362e4b3..e78f0464e7 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -106,11 +106,11 @@ struct wrepl_pull_table { #define WREPL_NAME_TYPE(flags) (flags & WREPL_FLAGS_RECORD_TYPE) #define WREPL_NAME_STATE(flags) ((flags & WREPL_FLAGS_RECORD_STATE)>>2) -#define WREPL_NBT_NODE(flags) ((flags & WREPL_FLAGS_NODE_TYPE)<<8) +#define WREPL_NAME_NODE(flags) ((flags & WREPL_FLAGS_NODE_TYPE)>>5) #define WREPL_NAME_IS_STATIC(flags) ((flags & WREPL_FLAGS_IS_STATIC)?True:False) #define WREPL_NAME_FLAGS(type, state, node, is_static) \ - (type | (state << 2) | (node>>8) | \ + (type | (state << 2) | (node << 5) | \ (is_static ? WREPL_FLAGS_IS_STATIC : 0)) /* @@ -127,7 +127,7 @@ struct wrepl_pull_names { struct nbt_name name; enum wrepl_name_type type; enum wrepl_name_state state; - enum nbt_node_type node; + enum wrepl_name_node node; BOOL is_static; uint32_t raw_flags; uint64_t version_id; -- cgit From 65271095d0aaf3b4fb10ae5639b89ae31ba80774 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 29 Sep 2005 22:36:41 +0000 Subject: r10635: Formatting for better readability. rafal (This used to be commit 7b3a4096b5922e4a98ea0a74c0b92bc10d18cddd) --- source4/libcli/composite/composite.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 83857edd14..1e6e9f5dc8 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -32,10 +32,10 @@ /* a composite call moves between the following 3 states. */ -enum composite_state {COMPOSITE_STATE_INIT, /* we are creating the request */ - COMPOSITE_STATE_IN_PROGRESS, /* the request is in the outgoing socket Q */ - COMPOSITE_STATE_DONE, /* the request is received by the caller finished */ - COMPOSITE_STATE_ERROR}; /* a packet or transport level error has occurred */ +enum composite_state { COMPOSITE_STATE_INIT, /* we are creating the request */ + COMPOSITE_STATE_IN_PROGRESS, /* the request is in the outgoing socket Q */ + COMPOSITE_STATE_DONE, /* the request is received by the caller finished */ + COMPOSITE_STATE_ERROR }; /* a packet or transport level error has occurred */ /* the context of one "composite" call */ struct composite_context { -- cgit From 9bc38ce65f1907230618b3edccafb1d33f753fe0 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 29 Sep 2005 22:37:15 +0000 Subject: r10636: Formatting for better readability. rafal (This used to be commit ef29863d999089c47140bd37731c60659a200421) --- source4/libcli/resolve/nbtlist.c | 18 ++++++++++++------ source4/libcli/resolve/resolve.c | 3 +++ 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 4fb4ccbb20..f8fe5df9a1 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -51,6 +51,7 @@ static void nbtlist_handler(struct nbt_name_request *req) for (i=0;inum_queries;i++) { if (req == state->queries[i]) break; } + if (i == state->num_queries) { /* not for us?! */ c->status = NT_STATUS_INTERNAL_ERROR; @@ -61,15 +62,18 @@ static void nbtlist_handler(struct nbt_name_request *req) c->status = nbt_name_query_recv(req, state, &state->io_queries[i]); if (!NT_STATUS_IS_OK(c->status)) { c->state = COMPOSITE_STATE_ERROR; + } else { if (state->io_queries[i].out.num_addrs < 1) { c->state = COMPOSITE_STATE_ERROR; c->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } else { struct nbt_name_query *q = &state->io_queries[i]; c->state = COMPOSITE_STATE_DONE; /* favor a local address if possible */ state->reply_addr = NULL; + for (i=0;iout.num_addrs;i++) { if (iface_is_local(q->out.reply_addrs[i])) { state->reply_addr = talloc_steal(state, @@ -77,6 +81,7 @@ static void nbtlist_handler(struct nbt_name_request *req) break; } } + if (state->reply_addr == NULL) { state->reply_addr = talloc_steal(state, q->out.reply_addrs[0]); @@ -135,18 +140,19 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, if (!state->queries) goto failed; for (i=0;inum_queries;i++) { - state->io_queries[i].in.name = state->name; - state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); + state->io_queries[i].in.name = state->name; + state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); if (!state->io_queries[i].in.dest_addr) goto failed; - state->io_queries[i].in.broadcast = broadcast; + + state->io_queries[i].in.broadcast = broadcast; state->io_queries[i].in.wins_lookup = wins_lookup; - state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 1); + state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 1); + state->io_queries[i].in.retries = 2; - state->io_queries[i].in.retries = 2; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); if (!state->queries[i]) goto failed; - state->queries[i]->async.fn = nbtlist_handler; + state->queries[i]->async.fn = nbtlist_handler; state->queries[i]->async.private = c; } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index c9e2fa503b..db5aefeaeb 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -103,6 +103,7 @@ static struct composite_context *setup_next_method(struct composite_context *c) creq = method->send_fn(&state->name, c->event_ctx); } if (creq == NULL && state->methods[0]) state->methods++; + } while (!creq && state->methods[0]); if (creq) { @@ -138,9 +139,11 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ c->state = COMPOSITE_STATE_IN_PROGRESS; c->private_data = state; + if (event_ctx == NULL) { c->event_ctx = event_context_init(c); if (c->event_ctx == NULL) goto failed; + } else { c->event_ctx = talloc_reference(c, event_ctx); } -- cgit From bb77c2aa1e426dff40d8b7507bb562dcf9c779bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Sep 2005 01:55:29 +0000 Subject: r10638: - add wrepl_socket_merge() function that creates a wrepl_socket on top of an existing socket, that is needed to handle WREPL_REPL_UPDATE in the server, because we need to flig the connection and act as client on it metze (This used to be commit 131e5dfe695d427e992b840439743f880b14d82d) --- source4/libcli/wrepl/winsrepl.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index aae77feb29..aba3fc817e 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -327,9 +327,52 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, socket_get_fd(wrepl_socket->sock), EVENT_FD_WRITE, wrepl_connect_handler, wrepl_socket); + if (wrepl_socket->fde == NULL) { + goto failed; + } set_blocking(socket_get_fd(wrepl_socket->sock), False); + talloc_set_destructor(wrepl_socket, wrepl_socket_destructor); + + return wrepl_socket; + +failed: + talloc_free(wrepl_socket); + return NULL; +} + +/* + initialise a wrepl_socket from an already existing connection +*/ +struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct socket_context *socket) +{ + struct wrepl_socket *wrepl_socket; + + wrepl_socket = talloc(mem_ctx, struct wrepl_socket); + if (wrepl_socket == NULL) goto failed; + + wrepl_socket->event_ctx = talloc_reference(wrepl_socket, event_ctx); + if (wrepl_socket->event_ctx == NULL) goto failed; + + wrepl_socket->sock = socket; + talloc_steal(wrepl_socket, wrepl_socket->sock); + + wrepl_socket->send_queue = NULL; + wrepl_socket->recv_queue = NULL; + wrepl_socket->request_timeout = WREPL_SOCKET_REQUEST_TIMEOUT; + wrepl_socket->dead = False; + + wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + 0, + wrepl_handler, wrepl_socket); + if (wrepl_socket->fde == NULL) { + goto failed; + } + talloc_set_destructor(wrepl_socket, wrepl_socket_destructor); return wrepl_socket; -- cgit From cc8af00a93aa16c61a3446c76caf0d2b174b3017 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 30 Sep 2005 07:30:37 +0000 Subject: r10646: Hey Jelmer what do you think of this? The SConscript for the libcli directory now looks like the config.mk file but with different punctuation. The only weird bit is that it creates a proto.h file for each subsystem. (This used to be commit 09d4abecb01fa9159243cfcb33051092f92cef3b) --- source4/libcli/SConscript | 185 +++++++++++++++++++++++++++++----------------- 1 file changed, 117 insertions(+), 68 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index aa911d9838..5b600fdcff 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -1,70 +1,119 @@ Import('hostenv') -proto_files = [] -cli_utils_files = ['util/asn1.c', 'util/doserr.c','util/errormap.c','util/clierror.c', 'util/nterr.c','util/smbdes.c'] -proto_files += cli_utils_files -hostenv.Library('cli_utils', cli_utils_files) -hostenv.Library('cli_lsa', ['util/clilsa.c']) -hostenv.Library('cli_composite_base', ['composite/composite.c']) - -cli_composite_files = ['smb_composite/loadfile.c','smb_composite/savefile.c','smb_composite/connect.c', - 'smb_composite/sesssetup.c','smb_composite/fetchfile.c','smb_composite/appendacl.c', - 'smb_composite/fsinfo.c'] - -hostenv.Library('cli_composite', cli_composite_files) -proto_files += ['util/clilsa.c', 'composite/composite.c'] + cli_composite_files - -cli_nbt_files = ['nbt/nbtname.c','nbt/nbtsocket.c','nbt/namequery.c','nbt/nameregister.c', - 'nbt/namerefresh.c','nbt/namerelease.c'] - -hostenv.Library('cli_nbt', cli_nbt_files) -proto_files += cli_nbt_files - -hostenv.Library('cli_dgram', - [ 'dgram/dgramsocket.c','dgram/mailslot.c','dgram/netlogon.c', - 'dgram/ntlogon.c','dgram/browse.c']) - -hostenv.Library('cli_cldap', ['cldap/cldap.c']) -hostenv.Library('cli_wrepl', ['wrepl/winsrepl.c']) - -cli_resolve_files = ['resolve/resolve.c','resolve/nbtlist.c','resolve/bcast.c','resolve/wins.c', - 'resolve/host.c'] - -hostenv.Library('cli_resolve', cli_resolve_files) -proto_files += cli_resolve_files - -smb_files = ['clireadwrite.c', 'cliconnect.c','clifile.c','clilist.c','clitrans2.c', - 'climessage.c','clideltree.c'] - -hostenv.Library('smb', smb_files) -proto_files += smb_files - -cli_raw_files = ['raw/rawfile.c','raw/smb_signing.c','raw/clisocket.c', - 'raw/clitransport.c','raw/clisession.c','raw/clitree.c', - 'raw/rawrequest.c','raw/rawreadwrite.c','raw/rawsearch.c', - 'raw/rawsetfileinfo.c','raw/raweas.c','raw/rawtrans.c', - 'raw/clioplock.c','raw/rawnegotiate.c','raw/rawfsinfo.c', - 'raw/rawfileinfo.c','raw/rawnotify.c','raw/rawioctl.c', - 'raw/rawacl.c','raw/rawdate.c','raw/rawlpq.c'] - -hostenv.Library('cli_raw', cli_raw_files) -proto_files += cli_raw_files - -security_files = ['security/security_token.c','security/security_descriptor.c', - 'security/dom_sid.c', 'security/access_check.c', - 'security/privilege.c', '../librpc/ndr/ndr_sec_helper.c'] -proto_files += security_files -hostenv.Library('cli_security', security_files) - -auth_files = ['auth/credentials.c','auth/session.c','auth/smbencrypt.c'] -proto_files += auth_files -hostenv.Library('cli_auth',auth_files) - -ldap_files = ['ldap/ldap.c','ldap/ldap_client.c','ldap/ldap_bind.c', - 'ldap/ldap_msg.c','ldap/ldap_ndr.c','ldap/ldap_ildap.c'] -proto_files += ldap_files -cli_ldap = hostenv.Library('cli_ldap',ldap_files) - -Export('cli_ldap') - -hostenv.proto_headers += hostenv.CProtoHeader('proto.h', proto_files) +hostenv.Subsystem( + 'cli_utils', + ['util/asn1.c', + 'util/doserr.c', + 'util/errormap.c', + 'util/clierror.c', + 'util/nterr.c', + 'util/smbdes.c']) + +hostenv.Subsystem( + 'cli_lsa', + ['util/clilsa.c']) + +hostenv.Subsystem( + 'cli_composite_base', + ['composite/composite.c']) + +hostenv.Subsystem( + 'cli_composite', + ['smb_composite/loadfile.c', + 'smb_composite/savefile.c', + 'smb_composite/connect.c', + 'smb_composite/sesssetup.c', + 'smb_composite/fetchfile.c', + 'smb_composite/appendacl.c', + 'smb_composite/fsinfo.c']) + +hostenv.Subsystem( + 'cli_nbt', + ['nbt/nbtname.c', + 'nbt/nbtsocket.c', + 'nbt/namequery.c', + 'nbt/nameregister.c', + 'nbt/namerefresh.c', + 'nbt/namerelease.c']) + +hostenv.Subsystem( + 'cli_dgram', + ['dgram/dgramsocket.c', + 'dgram/mailslot.c', + 'dgram/netlogon.c', + 'dgram/ntlogon.c', + 'dgram/browse.c']) + +hostenv.Subsystem( + 'cli_cldap', + ['cldap/cldap.c']) + +hostenv.Subsystem( + 'cli_wrepl', + ['wrepl/winsrepl.c']) + +hostenv.Subsystem( + 'cli_resolve', + ['resolve/resolve.c', + 'resolve/nbtlist.c', + 'resolve/bcast.c', + 'resolve/wins.c', + 'resolve/host.c']) + +hostenv.Subsystem( + 'smb', + ['clireadwrite.c', + 'cliconnect.c', + 'clifile.c', + 'clilist.c', + 'clitrans2.c', + 'climessage.c', + 'clideltree.c']) + +hostenv.Subsystem( + 'cli_raw', + ['raw/rawfile.c', + 'raw/smb_signing.c', + 'raw/clisocket.c', + 'raw/clitransport.c', + 'raw/clisession.c', + 'raw/clitree.c', + 'raw/rawrequest.c', + 'raw/rawreadwrite.c', + 'raw/rawsearch.c', + 'raw/rawsetfileinfo.c', + 'raw/raweas.c', + 'raw/rawtrans.c', + 'raw/clioplock.c', + 'raw/rawnegotiate.c', + 'raw/rawfsinfo.c', + 'raw/rawfileinfo.c', + 'raw/rawnotify.c', + 'raw/rawioctl.c', + 'raw/rawacl.c', + 'raw/rawdate.c', + 'raw/rawlpq.c']) + +hostenv.Subsystem( + 'cli_security', + ['security/security_token.c', + 'security/security_descriptor.c', + 'security/dom_sid.c', + 'security/access_check.c', + 'security/privilege.c', + '../librpc/ndr/ndr_sec_helper.c']) + +hostenv.Subsystem( + 'cli_auth', + ['auth/credentials.c', + 'auth/session.c', + 'auth/smbencrypt.c']) + +hostenv.Subsystem( + 'cli_ldap', + ['ldap/ldap.c', + 'ldap/ldap_client.c', + 'ldap/ldap_bind.c', + 'ldap/ldap_msg.c', + 'ldap/ldap_ndr.c', + 'ldap/ldap_ildap.c']) -- cgit From 67762d7965d74e4534a9dcb06276786fa9a37713 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Sep 2005 23:56:54 +0000 Subject: r10668: added a ildap_search_bytree() function (This used to be commit fd6d895ebdb201ac6afaf5c8ec84d003765cdff6) --- source4/libcli/ldap/ldap_ildap.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 541797c25c..d85585bce8 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -154,10 +154,10 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) /* perform a ldap search */ -NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, - int scope, const char *expression, - const char * const *attrs, BOOL attributesonly, - struct ldap_message ***results) +NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, + int scope, struct ldb_parse_tree *tree, + const char * const *attrs, BOOL attributesonly, + struct ldap_message ***results) { struct ldap_message *msg; int n, i; @@ -178,7 +178,7 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, msg->r.SearchRequest.timelimit = 0; msg->r.SearchRequest.sizelimit = 0; msg->r.SearchRequest.attributesonly = attributesonly; - msg->r.SearchRequest.tree = ldb_parse_tree(msg, expression); + msg->r.SearchRequest.tree = tree; msg->r.SearchRequest.num_attributes = n; msg->r.SearchRequest.attributes = attrs; @@ -213,3 +213,18 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, return status; } + +/* + perform a ldap search +*/ +NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, + int scope, const char *expression, + const char * const *attrs, BOOL attributesonly, + struct ldap_message ***results) +{ + struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); + NTSTATUS status; + status = ildap_search(conn, basedn, scope, tree, attrs, attributesonly, results); + talloc_free(tree); + return status; +} -- cgit From 68c70ef396f84077dd08f97bf700f0c2963c8676 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 2 Oct 2005 10:02:35 +0000 Subject: r10677: Add smb_composite_connectmulti: Send out multiple SYN packets at once, use the first one that replies correctly. Add a talloc context to smb_composite_connect() Volker (This used to be commit 6b88de182e40cb00a833c085f801fd47c92bbe94) --- source4/libcli/config.mk | 1 + source4/libcli/smb_composite/connect.c | 44 +++++-- source4/libcli/smb_composite/connect_multi.c | 188 +++++++++++++++++++++++++++ source4/libcli/smb_composite/fetchfile.c | 2 +- source4/libcli/smb_composite/fsinfo.c | 3 +- source4/libcli/smb_composite/smb_composite.h | 18 +++ 6 files changed, 246 insertions(+), 10 deletions(-) create mode 100644 source4/libcli/smb_composite/connect_multi.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 62530ed64b..8b39207194 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -20,6 +20,7 @@ ADD_OBJ_FILES = \ libcli/smb_composite/loadfile.o \ libcli/smb_composite/savefile.o \ libcli/smb_composite/connect.o \ + libcli/smb_composite/connect_multi.o \ libcli/smb_composite/sesssetup.o \ libcli/smb_composite/fetchfile.o \ libcli/smb_composite/appendacl.o \ diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 56d9d988c3..53cc8a9ac0 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -25,6 +25,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" +#include "lib/events/events.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, @@ -39,6 +40,7 @@ struct connect_state { struct smbcli_socket *sock; struct smbcli_transport *transport; struct smbcli_session *session; + struct smb_composite_connectmulti *conn; struct smb_composite_connect *io; union smb_tcon *io_tcon; struct smb_composite_sesssetup *io_setup; @@ -213,9 +215,11 @@ static NTSTATUS connect_socket(struct composite_context *c, NTSTATUS status; struct nbt_name calling, called; - status = smbcli_sock_connect_recv(state->creq); + status = smb_composite_connectmulti_recv(state->creq, state); NT_STATUS_NOT_OK_RETURN(status); + state->sock = state->conn->out.socket; + /* the socket is up - we can initialise the smbcli transport layer */ state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); @@ -254,11 +258,33 @@ static NTSTATUS connect_resolve(struct composite_context *c, struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); NTSTATUS status; const char *address; + struct smb_composite_connectmulti *conn; status = resolve_name_recv(state->creq, state, &address); NT_STATUS_NOT_OK_RETURN(status); - state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port, io->in.dest_host); + conn = talloc(state, struct smb_composite_connectmulti); + NT_STATUS_HAVE_NO_MEMORY(conn); + state->conn = conn; + conn->in.num_dests = 1; + + conn->in.addresses = talloc_array(state->conn, const char *, 1); + NT_STATUS_HAVE_NO_MEMORY(conn->in.addresses); + conn->in.addresses[0] = address; + + conn->in.hostnames = talloc_array(state->conn, const char *, 1); + NT_STATUS_HAVE_NO_MEMORY(conn->in.hostnames); + conn->in.hostnames[0] = state->io->in.dest_host; + + conn->in.ports = NULL; + if (state->io->in.port != 0) { + conn->in.ports = talloc_array(state->conn, int, 1); + NT_STATUS_HAVE_NO_MEMORY(conn->in.ports); + conn->in.ports[0] = state->io->in.port; + } + + state->creq = smb_composite_connectmulti_send(conn, state, + c->event_ctx); NT_STATUS_HAVE_NO_MEMORY(state->creq); state->stage = CONNECT_SOCKET; @@ -332,25 +358,27 @@ static void composite_handler(struct composite_context *creq) a function to establish a smbcli_tree from scratch */ struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io, - struct event_context *event_ctx) + TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) { struct composite_context *c; struct connect_state *state; struct nbt_name name; - c = talloc_zero(NULL, struct composite_context); + c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) goto failed; state = talloc(c, struct connect_state); if (state == NULL) goto failed; - state->sock = smbcli_sock_init(state, event_ctx); - if (state->sock == NULL) goto failed; + if (event_ctx == NULL) { + event_ctx = event_context_init(mem_ctx); + } state->io = io; c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = talloc_reference(c, state->sock->event.ctx); + c->event_ctx = talloc_reference(c, event_ctx); c->private_data = state; state->stage = CONNECT_RESOLVE; @@ -391,6 +419,6 @@ NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, struct event_context *ev) { - struct composite_context *c = smb_composite_connect_send(io, ev); + struct composite_context *c = smb_composite_connect_send(io, mem_ctx, ev); return smb_composite_connect_recv(c, mem_ctx); } diff --git a/source4/libcli/smb_composite/connect_multi.c b/source4/libcli/smb_composite/connect_multi.c new file mode 100644 index 0000000000..a539ba4bc6 --- /dev/null +++ b/source4/libcli/smb_composite/connect_multi.c @@ -0,0 +1,188 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Volker Lendecke + + 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. +*/ +/* + a composite API to fire connect calls to multiple targets, picking the first + one. +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" + +struct connectmulti_state { + struct smb_composite_connectmulti *io; + struct composite_context *creq; + struct smbcli_socket *result; + int num_socks, socks_left; + struct smbcli_socket **socks; + struct composite_context **creqs; +}; + +static void connect_receive(struct composite_context *c) + +{ + struct connectmulti_state *state = + talloc_get_type(c->async.private_data, + struct connectmulti_state); + int i; + + for (i=0; inum_socks; i++) { + if (state->creqs[i] == c) { + break; + } + } + + if (i == state->num_socks) { + c->status = NT_STATUS_INTERNAL_ERROR; + c->state = COMPOSITE_STATE_ERROR; + if (state->creq->async.fn != NULL) { + state->creq->async.fn(state->creq); + } + return; + } + + state->creq->status = smbcli_sock_connect_recv(c); + if (!NT_STATUS_IS_OK(state->creq->status)) { + talloc_free(state->socks[i]); + state->socks[i] = NULL; + state->creqs[i] = NULL; + state->socks_left -= 1; + if (state->socks_left == 0) { + state->creq->state = COMPOSITE_STATE_ERROR; + if (state->creq->async.fn != NULL) { + state->creq->async.fn(state->creq); + } + } + return; + } + + state->result = talloc_steal(state, state->socks[i]); + talloc_free(state->socks); + + state->creq->state = COMPOSITE_STATE_DONE; + if (state->creq->async.fn != NULL) { + state->creq->async.fn(state->creq); + } +} + +struct composite_context *smb_composite_connectmulti_send(struct smb_composite_connectmulti *io, + TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) +{ + struct composite_context *c; + struct connectmulti_state *state; + int num_socks = io->in.num_dests; + const char **hostnames = io->in.hostnames; + const char **addresses = io->in.addresses; + int *ports = io->in.ports; + int i; + + c = talloc_zero(mem_ctx, struct composite_context); + if (c == NULL) goto failed; + + state = talloc(c, struct connectmulti_state); + if (state == NULL) goto failed; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = talloc_reference(c, event_ctx); + c->private_data = state; + + if (ports == NULL) { + int j, nports; + const char **smb_ports = lp_smb_ports(); + + for (nports=0; smb_ports[nports]; nports++) /* noop */; + + num_socks *= nports; + hostnames = talloc_array(state, const char *, num_socks); + if (hostnames == NULL) goto failed; + addresses = talloc_array(state, const char *, num_socks); + if (addresses == NULL) goto failed; + ports = talloc_array(state, int, num_socks); + if (ports == NULL) goto failed; + + for (i=0; iin.num_dests; i++) { + for (j=0; jin.hostnames[i]; + addresses[i*nports+j] = io->in.addresses[i]; + ports[i*nports+j] = atoi(smb_ports[j]); + } + } + } + + state->io = io; + state->creq = c; + state->num_socks = num_socks; + state->socks_left = num_socks; + state->socks = talloc_array(state, struct smbcli_socket *, num_socks); + state->creqs = talloc_array(state, struct composite_context *, + num_socks); + if ((state->socks == NULL) || (state->creqs == NULL)) goto failed; + + for (i=0; isocks[i] = smbcli_sock_init(state->socks, event_ctx); + if (state->socks[i] == NULL) goto failed; + + /* If the event_ctx we got given is NULL, the first socket + * creates one and all others need to refer to it. */ + event_ctx = state->socks[i]->event.ctx; + + state->creqs[i] = smbcli_sock_connect_send(state->socks[i], + addresses[i], + ports[i], + hostnames[i]); + if (state->creqs[i] == NULL) goto failed; + state->creqs[i]->async.fn = connect_receive; + state->creqs[i]->async.private_data = state; + } + + return c; + + failed: + talloc_free(c); + return NULL; +} + +NTSTATUS smb_composite_connectmulti_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct connectmulti_state *state = + talloc_get_type(c->private_data, + struct connectmulti_state); + state->io->out.socket = talloc_steal(mem_ctx, state->result); + } + + talloc_free(c); + return status; +} + +NTSTATUS smb_composite_connectmulti(struct smb_composite_connectmulti *io, + TALLOC_CTX *mem_ctx, + struct event_context *ev) +{ + struct composite_context *c = + smb_composite_connectmulti_send(io, mem_ctx, ev); + return smb_composite_connectmulti_recv(c, mem_ctx); +} diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 9e88fb669d..8aa91bf3a9 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -146,7 +146,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.credentials = io->in.credentials; state->connect->in.workgroup = io->in.workgroup; - state->creq = smb_composite_connect_send(state->connect, event_ctx); + state->creq = smb_composite_connect_send(state->connect, state, event_ctx); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index e870225906..fa9f18d132 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -156,7 +156,8 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); c->private_data = state; - state->creq = smb_composite_connect_send(state->connect, c->event_ctx); + state->creq = smb_composite_connect_send(state->connect, state, + c->event_ctx); if (state->creq == NULL) goto failed; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 08031c2f4b..ec3a7af22d 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -150,3 +150,21 @@ struct smb_composite_appendacl { struct security_descriptor *sd; } out; }; + +/* + a composite API to fire connect() calls to multiple targets, picking the + first one. +*/ + +struct smb_composite_connectmulti { + struct { + int num_dests; + const char **hostnames; + const char **addresses; + int *ports; /* Either NULL for lp_smb_ports() per + * destination or a list of explicit ports */ + } in; + struct { + struct smbcli_socket *socket; + } out; +}; -- cgit From 49dd5e4b1d8f0bcffa3fd8134e03d162a3507739 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 4 Oct 2005 12:04:10 +0000 Subject: r10712: Use data_blob_talloc, thanks to valgrind for finding the errors. Andrew Bartlett (This used to be commit 1f6fec8e6b0845ae6000eeda65641435fb18c9e3) --- source4/libcli/auth/smbencrypt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index a9a7bb9903..b031bf4886 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -348,7 +348,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - final_response = data_blob(out_mem_ctx, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); @@ -365,8 +365,8 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, const DATA_BLOB *server_chal) { uint8_t lmv2_response[16]; - DATA_BLOB lmv2_client_data = data_blob(mem_ctx, 8); - DATA_BLOB final_response = data_blob(mem_ctx, 24); + DATA_BLOB lmv2_client_data = data_blob_talloc(mem_ctx, NULL, 8); + DATA_BLOB final_response = data_blob_talloc(mem_ctx, NULL,24); /* LMv2 */ /* client-supplied random data */ @@ -408,7 +408,7 @@ BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, ntlm_v2_hash, server_chal, names_blob); if (user_session_key) { - *user_session_key = data_blob(mem_ctx, 16); + *user_session_key = data_blob_talloc(mem_ctx, NULL, 16); /* The NTLMv2 calculations also provide a session key, for signing etc later */ /* use only the first 16 bytes of nt_response for session key */ @@ -422,7 +422,7 @@ BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, *lm_response = LMv2_generate_response(mem_ctx, ntlm_v2_hash, server_chal); if (lm_session_key) { - *lm_session_key = data_blob(mem_ctx, 16); + *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16); /* The NTLMv2 calculations also provide a session key, for signing etc later */ /* use only the first 16 bytes of lm_response for session key */ -- cgit From 97e8c5bcecb1fe4ef551906540b3d299f7c9c682 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Oct 2005 05:25:35 +0000 Subject: r10754: fixed a valgrind error for unmatched SMB replies (This used to be commit b714ab64fd79d5cabc39779774fae7c3861a84da) --- source4/libcli/raw/clitransport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 7d4891da00..b07bd630e9 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -385,7 +385,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) { uint8_t *buffer, *hdr, *vwv; int len; - uint16_t wct=0, mid = 0; + uint16_t wct=0, mid = 0, op = 0; struct smbcli_request *req; buffer = transport->recv_buffer.buffer; @@ -424,6 +424,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) /* extract the mid for matching to pending requests */ mid = SVAL(hdr, HDR_MID); wct = CVAL(hdr, HDR_WCT); + op = CVAL(hdr, HDR_COM); } /* match the incoming request against the list of pending requests */ @@ -432,8 +433,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) } if (!req) { - DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", - mid, CVAL(hdr, HDR_COM))); + DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", mid, op)); goto error; } -- cgit From 03b634042f937a6085a6cb96a1eb1e302e27c991 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Oct 2005 07:26:05 +0000 Subject: r10761: we need to use a pointer to a nbt_name to fix compiler warnings, because we can only use a pointers to unknown types in proto.h metze (This used to be commit 2f46e54e1bcf43f1bee062ff9a21e646cc3676e9) --- source4/libcli/nbt/nbtname.c | 35 +++++++++++++++++++++-------------- source4/libcli/wrepl/winsrepl.c | 5 ++--- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 86309b7f6b..622d03c1f4 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -474,8 +474,9 @@ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) /* pull a nbt name, WINS Replication uses another on wire format for nbt name */ -NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) +NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r) { + struct nbt_name *r; uint8_t *namebuf; uint32_t namebuf_len; @@ -491,6 +492,8 @@ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len); NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); + NDR_PULL_ALLOC(ndr, r); + /* oh wow, what a nasty bug in windows ... */ if (namebuf[0] == 0x1b && namebuf_len >= 16) { namebuf[0] = namebuf[15]; @@ -500,12 +503,13 @@ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt if (namebuf_len < 17) { r->type = 0x00; - r->name = talloc_strndup(ndr->current_mem_ctx, (char *)namebuf, namebuf_len); + r->name = talloc_strndup(r, (char *)namebuf, namebuf_len); if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); r->scope= NULL; talloc_free(namebuf); + *_r = r; return NT_STATUS_OK; } @@ -513,49 +517,52 @@ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt namebuf[15] = '\0'; trim_string((char *)namebuf, NULL, " "); - r->name = talloc_strdup(ndr->current_mem_ctx, (char *)namebuf); + r->name = talloc_strdup(r, (char *)namebuf); if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); if (namebuf_len > 18) { - r->scope = talloc_strndup(ndr->current_mem_ctx, (char *)(namebuf+17), namebuf_len-17); + r->scope = talloc_strndup(r, (char *)(namebuf+17), namebuf_len-17); if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); } else { r->scope = NULL; } talloc_free(namebuf); + *_r = r; return NT_STATUS_OK; } /* push a nbt name, WINS Replication uses another on wire format for nbt name */ -NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name r) +NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) { uint8_t *namebuf; uint32_t namebuf_len; uint32_t name_len; uint32_t scope_len = 0; + if (r == NULL) return NT_STATUS_INVALID_PARAMETER_MIX; + if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - name_len = strlen(r.name); + name_len = strlen(r->name); if (name_len > 15) { return NT_STATUS_INVALID_PARAMETER_MIX; } - if (r.scope) { - scope_len = strlen(r.scope); + if (r->scope) { + scope_len = strlen(r->scope); } if (scope_len > 238) { return NT_STATUS_INVALID_PARAMETER_MIX; } namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s", - r.name, 'X', - (r.scope?r.scope:"")); + r->name, 'X', + (r->scope?r->scope:"")); if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory"); namebuf_len = strlen((char *)namebuf) + 1; @@ -564,10 +571,10 @@ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const stru * we need to set the type here, and use a place-holder in the talloc_asprintf() * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results */ - namebuf[15] = r.type; + namebuf[15] = r->type; /* oh wow, what a nasty bug in windows ... */ - if (r.type == 0x1b) { + if (r->type == 0x1b) { namebuf[15] = namebuf[0]; namebuf[0] = 0x1b; } @@ -580,9 +587,9 @@ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const stru return NT_STATUS_OK; } -void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name r) +void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r) { - char *s = nbt_name_string(ndr, &r); + char *s = nbt_name_string(ndr, r); ndr_print_string(ndr, name, s); talloc_free(s); } diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index aba3fc817e..297dccbf38 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -745,9 +745,8 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, struct wrepl_wins_name *wname = &packet->message.replication.info.reply.names[i]; struct wrepl_name *name = &io->out.names[i]; - name->name = wname->name; - talloc_steal(io->out.names, wname->name.name); - talloc_steal(io->out.names, wname->name.scope); + name->name = *wname->name; + talloc_steal(io->out.names, wname->name); name->type = WREPL_NAME_TYPE(wname->flags); name->state = WREPL_NAME_STATE(wname->flags); name->node = WREPL_NAME_NODE(wname->flags); -- cgit From 6799fde75d1ccf93171874fd33f9e89e4472fd81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Oct 2005 14:38:07 +0000 Subject: r10766: - make it possible to mark a wrepl_request as send only, used for WREPL_REPL_INFORM* messsages - make it possible to close the connection after a request was send used for WREPL_ASSOCIATION_STOP - fix the torture test that tests the assoc context handling between connections, you can issue a request and get the reply on another connection, I think we should not implement that in our server code, as I think it's a security hole, you can cause a windows server to send the replies to someone another client, that doesn't wait for data, and as there're no massage_id in the protocol the client would be confused by a replies that doesn't belong to a query metze (This used to be commit dfc95de8fa7ded8ea92cafe58cf86efcc7920156) --- source4/libcli/wrepl/winsrepl.c | 100 +++++++++++++++++++++++++++++++++++----- source4/libcli/wrepl/winsrepl.h | 14 ++++++ 2 files changed, 103 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 297dccbf38..31ef1ffbeb 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -31,6 +31,7 @@ */ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status) { + talloc_set_destructor(wrepl_socket, NULL); wrepl_socket->dead = True; if (wrepl_socket->fde) { @@ -96,9 +97,31 @@ static void wrepl_handler_send(struct wrepl_socket *wrepl_socket) return; } - DLIST_REMOVE(wrepl_socket->send_queue, req); - DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); - req->state = WREPL_REQUEST_RECV; + if (req->disconnect_after_send) { + DLIST_REMOVE(wrepl_socket->send_queue, req); + req->status = NT_STATUS_OK; + req->state = WREPL_REQUEST_DONE; + wrepl_socket_dead(wrepl_socket, NT_STATUS_LOCAL_DISCONNECT); + if (req->async.fn) { + req->async.fn(req); + } + return; + } + + if (req->send_only) { + DLIST_REMOVE(wrepl_socket->send_queue, req); + req->status = NT_STATUS_OK; + req->state = WREPL_REQUEST_DONE; + if (req->async.fn) { + EVENT_FD_READABLE(wrepl_socket->fde); + req->async.fn(req); + return; + } + } else { + DLIST_REMOVE(wrepl_socket->send_queue, req); + DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); + req->state = WREPL_REQUEST_RECV; + } EVENT_FD_READABLE(wrepl_socket->fde); } @@ -289,7 +312,7 @@ failed: static int wrepl_socket_destructor(void *ptr) { struct wrepl_socket *sock = talloc_get_type(ptr, struct wrepl_socket); - wrepl_socket_dead(sock, NT_STATUS_CONNECTION_DISCONNECTED); + wrepl_socket_dead(sock, NT_STATUS_LOCAL_DISCONNECT); return 0; } @@ -415,7 +438,7 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req) connect a wrepl_socket to a WINS server */ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, - const char *address) + const char *our_ip, const char *peer_ip) { struct wrepl_request *req; NTSTATUS status; @@ -429,8 +452,12 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, DLIST_ADD(wrepl_socket->recv_queue, req); talloc_set_destructor(req, wrepl_request_destructor); - - status = socket_connect(wrepl_socket->sock, iface_best_ip(address), 0, address, + + if (!our_ip) { + our_ip = iface_best_ip(peer_ip); + } + + status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip, WINS_REPLICATION_PORT, 0); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) goto failed; @@ -453,9 +480,9 @@ NTSTATUS wrepl_connect_recv(struct wrepl_request *req) /* connect a wrepl_socket to a WINS server - sync API */ -NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *address) +NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *our_ip, const char *peer_ip) { - struct wrepl_request *req = wrepl_connect_send(wrepl_socket, address); + struct wrepl_request *req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip); return wrepl_connect_recv(req); } @@ -618,6 +645,59 @@ NTSTATUS wrepl_associate(struct wrepl_socket *wrepl_socket, } +/* + stop an association - send +*/ +struct wrepl_request *wrepl_associate_stop_send(struct wrepl_socket *wrepl_socket, + struct wrepl_associate_stop *io) +{ + struct wrepl_packet *packet; + struct wrepl_request *req; + + packet = talloc_zero(wrepl_socket, struct wrepl_packet); + if (packet == NULL) return NULL; + + packet->opcode = WREPL_OPCODE_BITS; + packet->assoc_ctx = io->in.assoc_ctx; + packet->mess_type = WREPL_STOP_ASSOCIATION; + packet->message.stop.reason = io->in.reason; + + req = wrepl_request_send(wrepl_socket, packet); + + if (req && io->in.reason == 0) { + req->send_only = True; + req->disconnect_after_send = True; + } + + talloc_free(packet); + + return req; +} + +/* + stop an association - recv +*/ +NTSTATUS wrepl_associate_stop_recv(struct wrepl_request *req, + struct wrepl_associate_stop *io) +{ + struct wrepl_packet *packet=NULL; + NTSTATUS status; + status = wrepl_request_recv(req, req->wrepl_socket, &packet); + NT_STATUS_NOT_OK_RETURN(status); + talloc_free(packet); + return status; +} + +/* + setup an association - sync api +*/ +NTSTATUS wrepl_associate_stop(struct wrepl_socket *wrepl_socket, + struct wrepl_associate_stop *io) +{ + struct wrepl_request *req = wrepl_associate_stop_send(wrepl_socket, io); + return wrepl_associate_stop_recv(req, io); +} + /* fetch the partner tables - send */ @@ -735,8 +815,6 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req, io->out.num_names = packet->message.replication.info.reply.num_names; - status = NT_STATUS_NO_MEMORY; - io->out.names = talloc_array(packet, struct wrepl_name, io->out.num_names); if (io->out.names == NULL) goto nomem; diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index e78f0464e7..89a4c642b2 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -69,6 +69,10 @@ struct wrepl_request { DATA_BLOB buffer; + BOOL disconnect_after_send; + + BOOL send_only; + size_t num_read; struct timed_event *te; @@ -91,6 +95,16 @@ struct wrepl_associate { } out; }; +/* + setup an association +*/ +struct wrepl_associate_stop { + struct { + uint32_t assoc_ctx; + uint32_t reason; + } in; +}; + /* pull the partner table */ -- cgit From 1377cca5f4beb43cf67fcc65eed79f14178d6349 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Oct 2005 11:31:45 +0000 Subject: r10810: This adds the hooks required to communicate the current user from the authenticated session down into LDB. This associates a session info structure with the open LDB, allowing a future ldb_ntacl module to allow/deny operations on that basis. Along the way, I cleaned up a few things, and added new helper functions to assist. In particular the LSA pipe uses simpler queries for some of the setup. In ldap_server, I have removed the 'ldasrv:hacked' module, which hasn't been worked on (other than making it continue to compile) since January, and I think the features of this module are being put into ldb anyway. I have also changed the partitions in ldap_server to be initialised after the connection, with the private pointer used to associate the ldb with the incoming session. Andrew Bartlett (This used to be commit fd7203789a2c0929eecea8125b57b833a67fed71) --- source4/libcli/security/security_token.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index a23aa92bf3..8e52759e70 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -165,3 +165,28 @@ void security_token_debug(int dbg_lev, const struct security_token *token) talloc_free(mem_ctx); } + +/* These really should be cheaper... */ + +BOOL is_system_token(struct security_token *token) +{ + TALLOC_CTX *mem_ctx = talloc_new(token); + if (dom_sid_equal(token->user_sid, dom_sid_parse_talloc(mem_ctx, SID_NT_SYSTEM))) { + talloc_free(mem_ctx); + return True; + } + talloc_free(mem_ctx); + return False; +} + +BOOL is_anonymous_token(struct security_token *token) +{ + TALLOC_CTX *mem_ctx = talloc_new(token); + if (dom_sid_equal(token->user_sid, dom_sid_parse_talloc(mem_ctx, SID_NT_ANONYMOUS))) { + talloc_free(mem_ctx); + return True; + } + talloc_free(mem_ctx); + return False; +} + -- cgit From 846f4b304ce0f69ee11ddfe7519e5f024ccf4c11 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Oct 2005 16:35:33 +0000 Subject: r10836: giving NT_STATUS_NO_MEMORY, when the connection fails wasn't a good idea... metze (This used to be commit e7ee73a747a025a66ac6563172e51f160bc28e0a) --- source4/libcli/wrepl/winsrepl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 31ef1ffbeb..82abd76665 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -433,6 +433,7 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req) return req->status; } +static void wrepl_request_trigger(struct wrepl_request *req); /* connect a wrepl_socket to a WINS server @@ -459,7 +460,13 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip, WINS_REPLICATION_PORT, 0); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) goto failed; + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_ERROR; + req->status = status; + wrepl_request_trigger(req); + return req; + } return req; -- cgit From 8aff6e005e36c21ebc9dd5a0dcd41f1c0d5c9c2f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Oct 2005 12:38:23 +0000 Subject: r10845: Add new function to decrypt the session keys in samlogon responses. Andrew Bartlett (This used to be commit 6d24d8d12cdc64b180fd6277f0775e943f26e82b) --- source4/libcli/auth/credentials.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index bcb462ae9d..7cfccf446c 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -315,3 +315,47 @@ NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, return NT_STATUS_ACCESS_DENIED; } } + +void creds_decrypt_samlogon(struct creds_CredentialState *creds, + uint16_t validation_level, + union netr_Validation *validation) +{ + static const char zeros[16]; + + struct netr_SamBaseInfo *base; + switch (validation_level) { + case 2: + base = &validation->sam2->base; + break; + case 3: + base = &validation->sam3->base; + break; + case 6: + base = &validation->sam6->base; + break; + } + /* find and decyrpt the session keys, return in parameters above */ + if (validation_level == 6) { + /* they aren't encrypted! */ + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + if (memcmp(base->key.key, zeros, + sizeof(base->key.key)) != 0) { + creds_arcfour_crypt(creds, + base->key.key, + sizeof(base->key.key)); + } + + if (memcmp(base->LMSessKey.key, zeros, + sizeof(base->LMSessKey.key)) != 0) { + creds_arcfour_crypt(creds, + base->LMSessKey.key, + sizeof(base->LMSessKey.key)); + } + } else { + if (memcmp(base->LMSessKey.key, zeros, + sizeof(base->LMSessKey.key)) != 0) { + creds_des_decrypt_LMKey(creds, + &base->LMSessKey); + } + } +} -- cgit From 43adda56b6a175fa2a9e4c6f20ca921e0b1c5fab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Oct 2005 13:03:52 +0000 Subject: r10847: Fix up new 'decrypt samlogon reply' routine to be more robust, and use it in the RPC-SAMLOGON test. Andrew Bartlett (This used to be commit 675b7df2eedbcb7ea89c0411f76429d8e2357222) --- source4/libcli/auth/credentials.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 7cfccf446c..3f055a657d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -322,18 +322,32 @@ void creds_decrypt_samlogon(struct creds_CredentialState *creds, { static const char zeros[16]; - struct netr_SamBaseInfo *base; + struct netr_SamBaseInfo *base = NULL; switch (validation_level) { case 2: - base = &validation->sam2->base; + if (validation->sam2) { + base = &validation->sam2->base; + } break; case 3: - base = &validation->sam3->base; + if (validation->sam3) { + base = &validation->sam3->base; + } break; case 6: - base = &validation->sam6->base; + if (validation->sam6) { + base = &validation->sam6->base; + } break; + default: + /* If we can't find it, we can't very well decrypt it */ + return; } + + if (!base) { + return; + } + /* find and decyrpt the session keys, return in parameters above */ if (validation_level == 6) { /* they aren't encrypted! */ -- cgit From a1f60c9b0d3a86c356f4e642b9bcb32a8e03b28f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 9 Oct 2005 13:40:55 +0000 Subject: r10848: Fix warning (This used to be commit 48d22a991024f19eccaa63848566b311524260c8) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 622d03c1f4..b0424b430f 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -474,7 +474,7 @@ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) /* pull a nbt name, WINS Replication uses another on wire format for nbt name */ -NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r) +NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name **_r) { struct nbt_name *r; uint8_t *namebuf; -- cgit From 9e5d44d56733f598e0a25ad1e72eccf3267be51a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 Oct 2005 20:32:24 +0000 Subject: r10852: Continuation-based programming can become a bit spaghetti... Initialize a domain structure properly. Excerpt from wb_init_domain.c: /* * Initialize a domain: * * - With schannel credentials, try to open the SMB connection with the machine * creds. Fall back to anonymous. * * - If we have schannel creds, do the auth2 and open the schannel'ed netlogon * pipe. * * - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back * to schannel and then to anon bind. * * - With queryinfopolicy, verify that we're talking to the right domain * * A bit complex, but with all the combinations I think it's the best we can * get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we * have a signed&sealed lsa connection on all of them. * * Is this overkill? In particular the authenticated SMB connection seems a * bit overkill, given that we do schannel for netlogon and ntlmssp for * lsa later on w2k3, the others don't do this anyway. */ Thanks to Jeremy for his detective work, and to the Samba4 team for providing such a great infrastructure. Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr with all we have. Volker (This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7) --- source4/libcli/composite/composite.c | 74 +++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 4a5247c9ea..6458a971b4 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -25,7 +25,7 @@ #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" - +#include "lib/messaging/irpc.h" /* block until a composite function has completed, then return the status @@ -68,3 +68,75 @@ void composite_trigger_done(struct composite_context *c) /* a zero timeout means immediate */ event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); } + + +/* + * Some composite helpers that are handy if you write larger composite + * functions. + */ + +BOOL comp_is_ok(struct composite_context *ctx) +{ + if (NT_STATUS_IS_OK(ctx->status)) { + return True; + } + ctx->state = COMPOSITE_STATE_ERROR; + if (ctx->async.fn != NULL) { + ctx->async.fn(ctx); + } + return False; +} + +void comp_error(struct composite_context *ctx, NTSTATUS status) +{ + ctx->status = status; + SMB_ASSERT(!comp_is_ok(ctx)); +} + +BOOL comp_nomem(const void *p, struct composite_context *ctx) +{ + if (p != NULL) { + return False; + } + comp_error(ctx, NT_STATUS_NO_MEMORY); + return True; +} + +void comp_done(struct composite_context *ctx) +{ + ctx->state = COMPOSITE_STATE_DONE; + if (ctx->async.fn != NULL) { + ctx->async.fn(ctx); + } +} + +void comp_cont(struct composite_context *ctx, + struct composite_context *new_ctx, + void (*continuation)(struct composite_context *), + void *private_data) +{ + if (comp_nomem(new_ctx, ctx)) return; + new_ctx->async.fn = continuation; + new_ctx->async.private_data = private_data; +} + +void rpc_cont(struct composite_context *ctx, + struct rpc_request *new_req, + void (*continuation)(struct rpc_request *), + void *private_data) +{ + if (comp_nomem(new_req, ctx)) return; + new_req->async.callback = continuation; + new_req->async.private = private_data; +} + +void irpc_cont(struct composite_context *ctx, + struct irpc_request *new_req, + void (*continuation)(struct irpc_request *), + void *private_data) +{ + if (comp_nomem(new_req, ctx)) return; + new_req->async.fn = continuation; + new_req->async.private = private_data; +} + -- cgit From b0e342e389d19377ad6c1b4236e60306d662ddab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Oct 2005 11:21:02 +0000 Subject: r10867: add WERR_UNKNOWN_REVISION errorcode metze (This used to be commit b436206c498ea166b8b9fa47638d5f8f6f4752bf) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index eecf923bac..a32da5a880 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -69,6 +69,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_UNKNOWN_REVISION", WERR_UNKNOWN_REVISION }, { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, -- cgit From d617556ef50863d6a03c81a04f0f6b05848a250e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Oct 2005 19:57:55 +0000 Subject: r10878: Reply to some comments by tridge and metze: * rename the composite helper functions from comp_* to composite_* * Move the lsa initialization to wb_connect_lsa.c * Equip smb_composite_connect with a fallback_to_anonymous The latter two simplify wb_init_domain.c quite a bit. Volker (This used to be commit deb127e04ea01ae93394da5ebffb39d81caeb6d9) --- source4/libcli/composite/composite.c | 42 +++++++------- source4/libcli/raw/clitree.c | 1 + source4/libcli/smb_composite/connect.c | 83 +++++++++++++++++++++++++++- source4/libcli/smb_composite/fetchfile.c | 1 + source4/libcli/smb_composite/fsinfo.c | 1 + source4/libcli/smb_composite/smb_composite.h | 2 + 6 files changed, 107 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 6458a971b4..f5eed77300 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -75,7 +75,7 @@ void composite_trigger_done(struct composite_context *c) * functions. */ -BOOL comp_is_ok(struct composite_context *ctx) +BOOL composite_is_ok(struct composite_context *ctx) { if (NT_STATUS_IS_OK(ctx->status)) { return True; @@ -87,22 +87,22 @@ BOOL comp_is_ok(struct composite_context *ctx) return False; } -void comp_error(struct composite_context *ctx, NTSTATUS status) +void composite_error(struct composite_context *ctx, NTSTATUS status) { ctx->status = status; - SMB_ASSERT(!comp_is_ok(ctx)); + SMB_ASSERT(!composite_is_ok(ctx)); } -BOOL comp_nomem(const void *p, struct composite_context *ctx) +BOOL composite_nomem(const void *p, struct composite_context *ctx) { if (p != NULL) { return False; } - comp_error(ctx, NT_STATUS_NO_MEMORY); + composite_error(ctx, NT_STATUS_NO_MEMORY); return True; } -void comp_done(struct composite_context *ctx) +void composite_done(struct composite_context *ctx) { ctx->state = COMPOSITE_STATE_DONE; if (ctx->async.fn != NULL) { @@ -110,32 +110,32 @@ void comp_done(struct composite_context *ctx) } } -void comp_cont(struct composite_context *ctx, - struct composite_context *new_ctx, - void (*continuation)(struct composite_context *), - void *private_data) +void composite_continue(struct composite_context *ctx, + struct composite_context *new_ctx, + void (*continuation)(struct composite_context *), + void *private_data) { - if (comp_nomem(new_ctx, ctx)) return; + if (composite_nomem(new_ctx, ctx)) return; new_ctx->async.fn = continuation; new_ctx->async.private_data = private_data; } -void rpc_cont(struct composite_context *ctx, - struct rpc_request *new_req, - void (*continuation)(struct rpc_request *), - void *private_data) +void composite_continue_rpc(struct composite_context *ctx, + struct rpc_request *new_req, + void (*continuation)(struct rpc_request *), + void *private_data) { - if (comp_nomem(new_req, ctx)) return; + if (composite_nomem(new_req, ctx)) return; new_req->async.callback = continuation; new_req->async.private = private_data; } -void irpc_cont(struct composite_context *ctx, - struct irpc_request *new_req, - void (*continuation)(struct irpc_request *), - void *private_data) +void composite_continue_irpc(struct composite_context *ctx, + struct irpc_request *new_req, + void (*continuation)(struct irpc_request *), + void *private_data) { - if (comp_nomem(new_req, ctx)) return; + if (composite_nomem(new_req, ctx)) return; new_req->async.fn = continuation; new_req->async.private = private_data; } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index cae93bdbe2..990552d64f 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -179,6 +179,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service = service; io.in.service_type = service_type; io.in.credentials = credentials; + io.in.fallback_to_anonymous = False; io.in.workgroup = lp_workgroup(); status = smb_composite_connect(&io, parent_ctx, ev); diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 53cc8a9ac0..925d5ddb38 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -30,9 +30,10 @@ /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, CONNECT_SOCKET, - CONNECT_SESSION_REQUEST, + CONNECT_SESSION_REQUEST, CONNECT_NEGPROT, CONNECT_SESSION_SETUP, + CONNECT_SESSION_SETUP_ANON, CONNECT_TCON}; struct connect_state { @@ -101,7 +102,59 @@ static NTSTATUS connect_tcon(struct composite_context *c, /* - a session setup request has competed + a session setup request with anonymous fallback has completed +*/ +static NTSTATUS connect_session_setup_anon(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + NTSTATUS status; + + status = smb_composite_sesssetup_recv(state->creq); + NT_STATUS_NOT_OK_RETURN(status); + + io->out.anonymous_fallback_done = True; + + state->session->vuid = state->io_setup->out.vuid; + + /* setup for a tconx */ + io->out.tree = smbcli_tree_init(state->session, state, True); + NT_STATUS_HAVE_NO_MEMORY(io->out.tree); + + state->io_tcon = talloc(c, union smb_tcon); + NT_STATUS_HAVE_NO_MEMORY(state->io_tcon); + + /* connect to a share using a tree connect */ + state->io_tcon->generic.level = RAW_TCON_TCONX; + state->io_tcon->tconx.in.flags = 0; + state->io_tcon->tconx.in.password = data_blob(NULL, 0); + + state->io_tcon->tconx.in.path = talloc_asprintf(state->io_tcon, + "\\\\%s\\%s", + io->in.called_name, + io->in.service); + NT_STATUS_HAVE_NO_MEMORY(state->io_tcon->tconx.in.path); + if (!io->in.service_type) { + state->io_tcon->tconx.in.device = "?????"; + } else { + state->io_tcon->tconx.in.device = io->in.service_type; + } + + state->req = smb_raw_tcon_send(io->out.tree, state->io_tcon); + NT_STATUS_HAVE_NO_MEMORY(state->req); + if (state->req->state == SMBCLI_REQUEST_ERROR) { + return state->req->status; + } + + state->req->async.fn = request_handler; + state->req->async.private = c; + state->stage = CONNECT_TCON; + + return NT_STATUS_OK; +} + +/* + a session setup request has completed */ static NTSTATUS connect_session_setup(struct composite_context *c, struct smb_composite_connect *io) @@ -110,6 +163,29 @@ static NTSTATUS connect_session_setup(struct composite_context *c, NTSTATUS status; status = smb_composite_sesssetup_recv(state->creq); + + if (!NT_STATUS_IS_OK(status) && + !cli_credentials_is_anonymous(state->io->in.credentials) && + io->in.fallback_to_anonymous) { + + state->io_setup->in.credentials = cli_credentials_init(state); + NT_STATUS_HAVE_NO_MEMORY(state->io_setup->in.credentials); + cli_credentials_set_conf(state->io_setup->in.credentials); + cli_credentials_set_anonymous(state->io_setup->in.credentials); + + state->creq = smb_composite_sesssetup_send(state->session, + state->io_setup); + NT_STATUS_HAVE_NO_MEMORY(state->creq); + if (state->creq->state == COMPOSITE_STATE_ERROR) { + return state->creq->status; + } + state->creq->async.fn = composite_handler; + state->creq->async.private_data = c; + state->stage = CONNECT_SESSION_SETUP_ANON; + + return NT_STATUS_OK; + } + NT_STATUS_NOT_OK_RETURN(status); state->session->vuid = state->io_setup->out.vuid; @@ -318,6 +394,9 @@ static void state_handler(struct composite_context *c) case CONNECT_SESSION_SETUP: c->status = connect_session_setup(c, state->io); break; + case CONNECT_SESSION_SETUP_ANON: + c->status = connect_session_setup_anon(c, state->io); + break; case CONNECT_TCON: c->status = connect_tcon(c, state->io); break; diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 8aa91bf3a9..1891ee956c 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -144,6 +144,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; state->connect->in.credentials = io->in.credentials; + state->connect->in.fallback_to_anonymous = False; state->connect->in.workgroup = io->in.workgroup; state->creq = smb_composite_connect_send(state->connect, state, event_ctx); diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index fa9f18d132..1d3860e5c6 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -149,6 +149,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; state->connect->in.credentials = io->in.credentials; + state->connect->in.fallback_to_anonymous = False; state->connect->in.workgroup = io->in.workgroup; c->state = COMPOSITE_STATE_IN_PROGRESS; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index ec3a7af22d..7ab0127440 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -90,10 +90,12 @@ struct smb_composite_connect { const char *service; const char *service_type; struct cli_credentials *credentials; + BOOL fallback_to_anonymous; const char *workgroup; } in; struct { struct smbcli_tree *tree; + BOOL anonymous_fallback_done; } out; }; -- cgit From a599edf04cbdeef9014923ba0d3713b8ff84f266 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Oct 2005 06:10:23 +0000 Subject: r10913: This patch isn't as big as it looks ... most of the changes are fixes to make all the ldb code compile without warnings on gcc4. Unfortunately That required a lot of casts :-( I have also added the start of an 'operational' module, which will replace the timestamp module, plus add support for some other operational attributes In ldb_msg_*() I added some new utility functions to make the operational module sane, and remove the 'ldb' argument from the ldb_msg_add_*() functions. That argument was only needed back in the early days of ldb when we didn't use the hierarchical talloc and thus needed a place to get the allocation function from. Now its just a pain to pass around everywhere. Also added a ldb_debug_set() function that calls ldb_debug() plus sets the result using ldb_set_errstring(). That saves on some awkward coding in a few places. (This used to be commit f6818daecca95760c12f79fd307770cbe3346f57) --- source4/libcli/ldap/ldap.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 815d543038..043faabf2f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -79,7 +79,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree i = 0; if ( ! tree->u.substring.start_with_wildcard) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); asn1_pop_tag(data); i++; } @@ -93,7 +93,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree ctx = 1; } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); asn1_pop_tag(data); i++; } @@ -159,7 +159,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_LDAPString(data, tree->u.extended.value.data); + asn1_write_LDAPString(data, (char *)tree->u.extended.value.data); asn1_pop_tag(data); asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); asn1_write_uint8(data, tree->u.extended.dnAttributes); @@ -517,7 +517,7 @@ static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_va return NULL; } - chunks[chunk_num]->data = talloc_strdup(mem_ctx, value); + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); if (chunks[chunk_num]->data == NULL) { return NULL; } @@ -631,8 +631,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_memdup(ret, attr.data, attr.length + 1); - ret->u.substring.attr[attr.length] = '\0'; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); ret->u.substring.chunks = NULL; ret->u.substring.start_with_wildcard = 1; ret->u.substring.end_with_wildcard = 1; -- cgit From f7ff0540d2b2490b2ef502d02b422e74a298b43d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 14 Oct 2005 03:57:35 +0000 Subject: r10981: Pull code to decide between and implement NTLMv2, NTLM and LM authentication out of the various callers and into the kitchen sink.. err, credentials subsystem. This should ensure consistant logic, as well as get us one step closer to security=server operation in future. Andrew Bartlett (This used to be commit 09c95763301c0f7770d56462e8af4169b8c171fb) --- source4/libcli/smb_composite/sesssetup.c | 118 ++++++++++++------------------- 1 file changed, 47 insertions(+), 71 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 700e4ef744..0d0904b969 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -36,28 +36,6 @@ struct sesssetup_state { }; -/* - form an encrypted lanman password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB lanman_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBencrypt(pass, challenge.data, blob.data); - return blob; -} - -/* - form an encrypted NT password from a plaintext password - and the server supplied challenge -*/ -static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const struct samr_Password *nt_hash, DATA_BLOB challenge) -{ - DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBOWFencrypt(nt_hash->hash, challenge.data, blob.data); - return blob; -} - /* store the user session key for a transport */ @@ -163,9 +141,19 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, struct smb_composite_sesssetup *io, struct smbcli_request **req) { + NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); - const struct samr_Password *nt_hash = cli_credentials_get_nt_hash(io->in.credentials, state); const char *password = cli_credentials_get_password(io->in.credentials); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup()); + DATA_BLOB session_key; + int flags = CLI_CRED_NTLM_AUTH; + if (lp_client_lanman_auth()) { + flags |= CLI_CRED_LANMAN_AUTH; + } + + if (lp_client_ntlmv2_auth()) { + flags |= CLI_CRED_NTLMv2_AUTH; + } state->setup.nt1.level = RAW_SESSSETUP_NT1; state->setup.nt1.in.bufsize = session->transport->options.max_xmit; @@ -175,56 +163,26 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, state->setup.nt1.in.capabilities = io->in.capabilities; state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); + cli_credentials_get_ntlm_username_domain(io->in.credentials, state, &state->setup.nt1.in.user, &state->setup.nt1.in.domain); + - if (!password) { - state->setup.nt1.in.password1 = data_blob(NULL, 0); - state->setup.nt1.in.password2 = data_blob(NULL, 0); - } else if (session->transport->negotiate.sec_mode & - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - DATA_BLOB session_key; - if (lp_client_ntlmv2_auth()) { - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_netbios_name(), lp_workgroup()); - DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key; - - if (!SMBNTLMv2encrypt_hash(state, - state->setup.nt1.in.user, state->setup.nt1.in.domain, - nt_hash->hash, &session->transport->negotiate.secblob, - &names_blob, - &lmv2_response, &ntlmv2_response, - &lmv2_session_key, &session_key)) { - data_blob_free(&names_blob); - return NT_STATUS_NO_MEMORY; - } - data_blob_free(&names_blob); - data_blob_free(&lmv2_session_key); - state->setup.nt1.in.password1 = lmv2_response; - state->setup.nt1.in.password2 = ntlmv2_response; - - } else { - - state->setup.nt1.in.password2 = nt_blob(state, nt_hash, - session->transport->negotiate.secblob); - if (lp_client_lanman_auth()) { - state->setup.nt1.in.password1 = lanman_blob(state, password, - session->transport->negotiate.secblob); - } else { - /* if not sending the LM password, send the NT password twice */ - state->setup.nt1.in.password1 = state->setup.nt1.in.password2; - } - - session_key = data_blob_talloc(session, NULL, 16); - SMBsesskeygen_ntv1(nt_hash->hash, session_key.data); - } + if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, + &flags, + session->transport->negotiate.secblob, + names_blob, + &state->setup.nt1.in.password1, + &state->setup.nt1.in.password2, + NULL, &session_key); smbcli_transport_simple_set_signing(session->transport, session_key, state->setup.nt1.in.password2); set_user_session_key(session, &session_key); data_blob_free(&session_key); - } else if (lp_client_plaintext_auth()) { state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); @@ -249,8 +207,19 @@ static NTSTATUS session_setup_old(struct composite_context *c, struct smb_composite_sesssetup *io, struct smbcli_request **req) { + NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup()); + DATA_BLOB session_key; + int flags = 0; + if (lp_client_lanman_auth()) { + flags |= CLI_CRED_LANMAN_AUTH; + } + + if (lp_client_ntlmv2_auth()) { + flags |= CLI_CRED_NTLMv2_AUTH; + } state->setup.old.level = RAW_SESSSETUP_OLD; state->setup.old.in.bufsize = session->transport->options.max_xmit; @@ -263,15 +232,22 @@ static NTSTATUS session_setup_old(struct composite_context *c, &state->setup.old.in.user, &state->setup.old.in.domain); - if (!password) { - state->setup.old.in.password = data_blob(NULL, 0); - } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { - state->setup.old.in.password = lanman_blob(state, password, - session->transport->negotiate.secblob); + if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, + &flags, + session->transport->negotiate.secblob, + names_blob, + &state->setup.old.in.password, + NULL, + NULL, &session_key); + set_user_session_key(session, &session_key); + + data_blob_free(&session_key); + } else if (lp_client_plaintext_auth()) { + state->setup.old.in.password = data_blob_talloc(state, password, strlen(password)); } else { - state->setup.old.in.password = data_blob_talloc(state, - password, - strlen(password)); + /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ + return NT_STATUS_INVALID_PARAMETER; } *req = smb_raw_sesssetup_send(session, &state->setup); -- cgit From fccbbf354634b31c9c3cb2bca15843f13e3b77f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:22:15 +0000 Subject: r10997: r11980@SERNOX (orig r10037): metze | 2005-09-05 14:21:40 +0200 add struct nbt_peer_socket and use it instead of passing const char *addr, uint16 port everyhwere (tridge: can you review this please, (make test works) metze (This used to be commit a599d7a4ae881c94be2c2d908a398838549942bb) --- source4/libcli/dgram/browse.c | 9 ++++++--- source4/libcli/dgram/dgramsocket.c | 28 +++++++++++++-------------- source4/libcli/dgram/libdgram.h | 22 ++++++++------------- source4/libcli/dgram/mailslot.c | 12 ++++++------ source4/libcli/dgram/netlogon.c | 10 ++++++---- source4/libcli/dgram/ntlogon.c | 10 ++++++---- source4/libcli/nbt/libnbt.h | 16 ++++++++++------ source4/libcli/nbt/namequery.c | 18 ++++++++++++------ source4/libcli/nbt/namerefresh.c | 9 ++++++--- source4/libcli/nbt/nameregister.c | 9 ++++++--- source4/libcli/nbt/namerelease.c | 9 ++++++--- source4/libcli/nbt/nbtsocket.c | 39 +++++++++++++++++++------------------- 12 files changed, 104 insertions(+), 87 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index a304db9c9d..d6813b36b9 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -29,7 +29,7 @@ #include "librpc/gen_ndr/ndr_nbt.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, - struct nbt_name *dest_name, const char *dest_address, int dest_port, + struct nbt_name *dest_name, const struct nbt_peer_socket *dest, struct nbt_name *src_name, struct nbt_browse_packet *request) { NTSTATUS status; @@ -45,7 +45,7 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, NBT_MAILSLOT_BROWSE, - dest_name, dest_address, dest_port, + dest_name, dest, src_name, &blob); talloc_free(tmp_ctx); return status; @@ -59,6 +59,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; + struct nbt_peer_socket dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); @@ -69,10 +70,12 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); + dest.port = request->src_port; + dest.addr = request->src_addr; status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - request->source, request->src_port, + &dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index e66e5ed52e..decbc0225c 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -35,8 +35,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); NTSTATUS status; - const char *src_addr; - int src_port; + struct nbt_peer_socket src; DATA_BLOB blob; size_t nread, dsize; struct nbt_dgram_packet *packet; @@ -55,16 +54,16 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) } status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, 0, - &src_addr, &src_port); + &src.addr, &src.port); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src_addr); + talloc_steal(tmp_ctx, src.addr); blob.length = nread; DEBUG(2,("Received dgram packet of length %d from %s:%d\n", - (int)blob.length, src_addr, src_port)); + (int)blob.length, src.addr, src.port)); packet = talloc(tmp_ctx, struct nbt_dgram_packet); if (packet == NULL) { @@ -88,14 +87,14 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, src_addr, src_port); + dgmslot->handler(dgmslot, packet, &src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } } else { /* dispatch if there is a general handler */ if (dgmsock->incoming.handler) { - dgmsock->incoming.handler(dgmsock, packet, src_addr, src_port); + dgmsock->incoming.handler(dgmsock, packet, &src); } } @@ -116,10 +115,10 @@ static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) len = req->encoded.length; status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0, - req->dest_addr, req->dest_port); + req->dest.addr, req->dest.port); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send datagram of length %u to %s:%d\n", - (unsigned)req->encoded.length, req->dest_addr, req->dest_port)); + (unsigned)req->encoded.length, req->dest.addr, req->dest.port)); DLIST_REMOVE(dgmsock->send_queue, req); talloc_free(req); continue; @@ -201,7 +200,7 @@ failed: NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const char *, int ), + const struct nbt_peer_socket *), void *private) { dgmsock->incoming.handler = handler; @@ -216,8 +215,7 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, */ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const char *dest_addr, - int dest_port) + const struct nbt_peer_socket *dest) { struct nbt_dgram_request *req; NTSTATUS status = NT_STATUS_NO_MEMORY; @@ -225,9 +223,9 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, req = talloc(dgmsock, struct nbt_dgram_request); if (req == NULL) goto failed; - req->dest_addr = talloc_strdup(req, dest_addr); - if (req->dest_addr == NULL) goto failed; - req->dest_port = dest_port; + req->dest.port = dest->port; + req->dest.addr = talloc_strdup(req, dest->addr); + if (req->dest.addr == NULL) goto failed; status = ndr_push_struct_blob(&req->encoded, req, packet, (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 5bddd220d0..f913e90d88 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -22,7 +22,6 @@ #include "librpc/gen_ndr/ndr_nbt.h" - /* a datagram name request */ @@ -30,8 +29,7 @@ struct nbt_dgram_request { struct nbt_dgram_request *next, *prev; /* where to send the request */ - const char *dest_addr; - int dest_port; + struct nbt_peer_socket dest; /* the encoded request */ DATA_BLOB encoded; @@ -56,7 +54,7 @@ struct nbt_dgram_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const char *, int ); + const struct nbt_peer_socket *src); void *private; } incoming; }; @@ -72,7 +70,7 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, - const char *, int ); + const struct nbt_peer_socket *src); struct dgram_mailslot_handler { struct dgram_mailslot_handler *next, *prev; @@ -88,12 +86,11 @@ struct dgram_mailslot_handler { /* prototypes */ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const char *dest_addr, - int dest_port); + const struct nbt_peer_socket *dest); NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const char *, int ), + const struct nbt_peer_socket *), void *private); struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); @@ -116,15 +113,13 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - const char *dest_address, - int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name *src_name, DATA_BLOB *request); NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, - const char *dest_address, - int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name *src_name, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, @@ -139,8 +134,7 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, struct nbt_name *dest_name, - const char *dest_address, - int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name *src_name, struct nbt_ntlogon_packet *request); NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 14e7e49fc1..d521484422 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -152,27 +152,27 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - const char *dest_address, - int dest_port, + const struct nbt_peer_socket *_dest, struct nbt_name *src_name, DATA_BLOB *request) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_dgram_packet packet; + struct nbt_peer_socket dest = *_dest; struct dgram_message *msg; struct dgram_smb_packet *smb; struct smb_trans_body *trans; NTSTATUS status; - if (dest_port == 0) { - dest_port = lp_dgram_port(); + if (dest.port == 0) { + dest.port = lp_dgram_port(); } ZERO_STRUCT(packet); packet.msg_type = msg_type; packet.flags = DGRAM_FLAG_FIRST | DGRAM_NODE_NBDD; packet.dgram_id = generate_random() % UINT16_MAX; - packet.source = socket_get_my_addr(dgmsock->sock, tmp_ctx); + packet.src_addr = socket_get_my_addr(dgmsock->sock, tmp_ctx); packet.src_port = socket_get_my_port(dgmsock->sock); msg = &packet.data.msg; @@ -199,7 +199,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, trans->mailslot_name = mailslot_name; trans->data = *request; - status = nbt_dgram_send(dgmsock, &packet, dest_address, dest_port); + status = nbt_dgram_send(dgmsock, &packet, &dest); talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index dda77689de..0627fe900c 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -33,8 +33,7 @@ */ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, - const char *dest_address, - int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -52,7 +51,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, NBT_MAILSLOT_NETLOGON, - dest_name, dest_address, dest_port, + dest_name, dest, src_name, &blob); talloc_free(tmp_ctx); return status; @@ -71,6 +70,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; + struct nbt_peer_socket dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); @@ -81,10 +81,12 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); + dest.port = request->src_port; + dest.addr = request->src_addr; status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - request->source, request->src_port, + &dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index efa5d4ab9e..2bdce6f853 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -34,8 +34,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, struct nbt_name *dest_name, - const char *dest_address, - int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name *src_name, struct nbt_ntlogon_packet *request) { @@ -53,7 +52,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, msg_type, NBT_MAILSLOT_NTLOGON, - dest_name, dest_address, dest_port, + dest_name, dest, src_name, &blob); talloc_free(tmp_ctx); return status; @@ -72,6 +71,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; + struct nbt_peer_socket dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); @@ -82,10 +82,12 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); + dest.port = request->src_port; + dest.addr = request->src_addr; status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - request->source, request->src_port, + &dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 5a53510ccf..218b5e5921 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -31,6 +31,12 @@ enum nbt_request_state {NBT_REQUEST_SEND, NBT_REQUEST_TIMEOUT, NBT_REQUEST_ERROR}; +/* where to send the request/replies */ +struct nbt_peer_socket { + const char *addr; + int port; +}; + /* a nbt name request */ @@ -45,8 +51,7 @@ struct nbt_name_request { struct nbt_name_socket *nbtsock; /* where to send the request */ - const char *dest_addr; - int dest_port; + struct nbt_peer_socket dest; /* timeout between retries */ int timeout; @@ -75,8 +80,7 @@ struct nbt_name_request { uint_t num_replies; struct nbt_name_reply { struct nbt_name_packet *packet; - const char *reply_addr; - int reply_port; + struct nbt_peer_socket dest; } *replies; /* information on what to do on completion */ @@ -110,14 +114,14 @@ struct nbt_name_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const char *, int ); + const struct nbt_peer_socket *); void *private; } incoming; /* what to do with unexpected replies */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const char *, int ); + const struct nbt_peer_socket *); void *private; } unexpected; }; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index f222148f4d..c0a1e274e2 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -31,6 +31,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; + struct nbt_peer_socket dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -50,8 +51,10 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, packet->questions[0].name = io->in.name; packet->questions[0].question_type = NBT_QTYPE_NETBIOS; packet->questions[0].question_class = NBT_QCLASS_IP; - - req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + + dest.port = lp_nbt_port(); + dest.addr = io->in.dest_addr; + req = nbt_name_request_send(nbtsock, &dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -81,7 +84,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); if ((packet->operation & NBT_RCODE) != 0) { status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); @@ -137,6 +140,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; + struct nbt_peer_socket dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -150,8 +154,10 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, packet->questions[0].name = io->in.name; packet->questions[0].question_type = NBT_QTYPE_STATUS; packet->questions[0].question_class = NBT_QCLASS_IP; - - req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + + dest.port = lp_nbt_port(); + dest.addr = io->in.dest_addr; + req = nbt_name_request_send(nbtsock, &dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -181,7 +187,7 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); if ((packet->operation & NBT_RCODE) != 0) { status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index d9f2070d4c..e6464885f7 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -32,6 +32,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; + struct nbt_peer_socket dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -64,8 +65,10 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - - req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + + dest.port = lp_nbt_port(); + dest.addr = io->in.dest_addr; + req = nbt_name_request_send(nbtsock, &dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -94,7 +97,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 4dac500780..4f3e046274 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -32,6 +32,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; + struct nbt_peer_socket dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -72,8 +73,10 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; - - req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + + dest.port = lp_nbt_port(); + dest.addr = io->in.dest_addr; + req = nbt_name_request_send(nbtsock, &dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -102,7 +105,7 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index 208c73d386..0a0cd45276 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -31,6 +31,7 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; + struct nbt_peer_socket dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -63,8 +64,10 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - - req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, + + dest.port = lp_nbt_port(); + dest.addr = io->in.dest_addr; + req = nbt_name_request_send(nbtsock, &dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -93,7 +96,7 @@ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index f40ec84e77..905541e74a 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -73,7 +73,7 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) len = req->encoded.length; status = socket_sendto(nbtsock->sock, &req->encoded, &len, 0, - req->dest_addr, req->dest_port); + req->dest.addr, req->dest.port); if (NT_STATUS_IS_ERR(status)) goto failed; if (!NT_STATUS_IS_OK(status)) { @@ -153,8 +153,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) { TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); NTSTATUS status; - const char *src_addr; - int src_port; + struct nbt_peer_socket src; DATA_BLOB blob; size_t nread, dsize; struct nbt_name_packet *packet; @@ -173,12 +172,12 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, - &src_addr, &src_port); + &src.addr, &src.port); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src_addr); + talloc_steal(tmp_ctx, src.addr); blob.length = nread; packet = talloc(tmp_ctx, struct nbt_name_packet); @@ -199,7 +198,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) if (DEBUGLVL(10)) { DEBUG(10,("Received nbt packet of length %d from %s:%d\n", - (int)blob.length, src_addr, src_port)); + (int)blob.length, src.addr, src.port)); NDR_PRINT_DEBUG(nbt_name_packet, packet); } @@ -207,7 +206,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) handler, if any */ if (!(packet->operation & NBT_FLAG_REPLY)) { if (nbtsock->incoming.handler) { - nbtsock->incoming.handler(nbtsock, packet, src_addr, src_port); + nbtsock->incoming.handler(nbtsock, packet, &src); } talloc_free(tmp_ctx); return; @@ -217,7 +216,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req = idr_find(nbtsock->idr, packet->name_trn_id); if (req == NULL) { if (nbtsock->unexpected.handler) { - nbtsock->unexpected.handler(nbtsock, packet, src_addr, src_port); + nbtsock->unexpected.handler(nbtsock, packet, &src); } else { DEBUG(2,("Failed to match request for incoming name packet id 0x%04x on %p\n", packet->name_trn_id, nbtsock)); @@ -259,8 +258,8 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) goto done; } - req->replies[req->num_replies].reply_addr = talloc_steal(req, src_addr); - req->replies[req->num_replies].reply_port = src_port; + req->replies[req->num_replies].dest.addr = talloc_steal(req, src.addr); + req->replies[req->num_replies].dest.port = src.port; req->replies[req->num_replies].packet = talloc_steal(req, packet); req->num_replies++; @@ -349,7 +348,7 @@ failed: send off a nbt name request */ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, - const char *dest_addr, int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name_packet *request, int timeout, int retries, BOOL allow_multiple_replies) @@ -362,14 +361,14 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, if (req == NULL) goto failed; req->nbtsock = nbtsock; - req->dest_port = dest_port; req->allow_multiple_replies = allow_multiple_replies; req->state = NBT_REQUEST_SEND; req->is_reply = False; req->timeout = timeout; req->num_retries = retries; - req->dest_addr = talloc_strdup(req, dest_addr); - if (req->dest_addr == NULL) goto failed; + req->dest.port = dest->port; + req->dest.addr = talloc_strdup(req, dest->addr); + if (req->dest.addr == NULL) goto failed; /* we select a random transaction id unless the user supplied one */ if (request->name_trn_id == 0) { @@ -398,7 +397,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, if (DEBUGLVL(10)) { DEBUG(10,("Queueing nbt packet to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest.addr, req->dest.port)); NDR_PRINT_DEBUG(nbt_name_packet, request); } @@ -416,7 +415,7 @@ failed: send off a nbt name reply */ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - const char *dest_addr, int dest_port, + const struct nbt_peer_socket *dest, struct nbt_name_packet *request) { struct nbt_name_request *req; @@ -426,9 +425,9 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, NT_STATUS_HAVE_NO_MEMORY(req); req->nbtsock = nbtsock; - req->dest_addr = talloc_strdup(req, dest_addr); - if (req->dest_addr == NULL) goto failed; - req->dest_port = dest_port; + req->dest.port = dest->port; + req->dest.addr = talloc_strdup(req, dest->addr); + if (req->dest.addr == NULL) goto failed; req->state = NBT_REQUEST_SEND; req->is_reply = True; @@ -481,7 +480,7 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) */ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const char *, int ), + const struct nbt_peer_socket *), void *private) { nbtsock->incoming.handler = handler; -- cgit From 2ecb46d595b880c533e2dafea43baf02f009bec6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:54:52 +0000 Subject: r11037: (This used to be commit 6913e338405a5aca5c70cf6e022532c596ed0a36) --- source4/libcli/SConscript | 1 - source4/libcli/auth/SConscript | 3 +++ source4/libcli/ldap/SConscript | 5 +++++ source4/libcli/security/SConscript | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/auth/SConscript create mode 100644 source4/libcli/ldap/SConscript create mode 100644 source4/libcli/security/SConscript (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index 5b600fdcff..98847d9336 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -1,5 +1,4 @@ Import('hostenv') - hostenv.Subsystem( 'cli_utils', ['util/asn1.c', diff --git a/source4/libcli/auth/SConscript b/source4/libcli/auth/SConscript new file mode 100644 index 0000000000..d527faac30 --- /dev/null +++ b/source4/libcli/auth/SConscript @@ -0,0 +1,3 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_auth',['credentials.c','session.c','smbencrypt.c']) diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript new file mode 100644 index 0000000000..eef9a9f41c --- /dev/null +++ b/source4/libcli/ldap/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_ldap', + ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', + 'ldap_ildap.c']) diff --git a/source4/libcli/security/SConscript b/source4/libcli/security/SConscript new file mode 100644 index 0000000000..e81051e07e --- /dev/null +++ b/source4/libcli/security/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_security', + ['security_token.c','security_descriptor.c','dom_sid.c', + 'access_check.c','privilege.c']) -- cgit From cffd522b5c806508dfacfb10234e4c0a115c0a98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 14:02:47 +0000 Subject: r11052: bring samba4 uptodate with the samba4-winsrepl branch, before the bad merge metze (This used to be commit 471c0ca4abb17fb5f73c0efed195c67628c1c06e) --- source4/libcli/SConscript | 1 + source4/libcli/auth/SConscript | 3 --- source4/libcli/ldap/SConscript | 5 ----- source4/libcli/security/SConscript | 5 ----- 4 files changed, 1 insertion(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript index 98847d9336..5b600fdcff 100644 --- a/source4/libcli/SConscript +++ b/source4/libcli/SConscript @@ -1,4 +1,5 @@ Import('hostenv') + hostenv.Subsystem( 'cli_utils', ['util/asn1.c', diff --git a/source4/libcli/auth/SConscript b/source4/libcli/auth/SConscript index d527faac30..e69de29bb2 100644 --- a/source4/libcli/auth/SConscript +++ b/source4/libcli/auth/SConscript @@ -1,3 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_auth',['credentials.c','session.c','smbencrypt.c']) diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript index eef9a9f41c..e69de29bb2 100644 --- a/source4/libcli/ldap/SConscript +++ b/source4/libcli/ldap/SConscript @@ -1,5 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_ldap', - ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', - 'ldap_ildap.c']) diff --git a/source4/libcli/security/SConscript b/source4/libcli/security/SConscript index e81051e07e..e69de29bb2 100644 --- a/source4/libcli/security/SConscript +++ b/source4/libcli/security/SConscript @@ -1,5 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_security', - ['security_token.c','security_descriptor.c','dom_sid.c', - 'access_check.c','privilege.c']) -- cgit From 42ef193dd22518b50e0af27b963078440f02b510 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 15 Oct 2005 12:23:33 +0000 Subject: r11090: we need this to run correct under socket_wrapper metze (This used to be commit 3f7b09a3086a8b6d255bc3fc5cd8882e12f05d10) --- source4/libcli/wrepl/winsrepl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 82abd76665..61cf633b54 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -287,7 +287,7 @@ static void wrepl_connect_handler(struct event_context *ev, struct fd_event *fde wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, socket_get_fd(wrepl_socket->sock), - 0, + EVENT_FD_WRITE, wrepl_handler, wrepl_socket); if (wrepl_socket->fde == NULL) { req->status = NT_STATUS_NO_MEMORY; -- cgit From d68319431e62e43c0ecb23328e3162128d823958 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 16 Oct 2005 12:43:09 +0000 Subject: r11095: Implement wb_getuserdomgroups. Tridge, if you have the time, you might want to look at a problem I'm having with unix domain stream sockets. From a comment in this commit: /* Using composite_trigger_error here causes problems with the client * socket. Linux 2.6.8 gives me a ECONNRESET on the next read after * writing the reply when I don't wait the 100 milliseconds. */ This is in winbind/wb_cmd_userdomgroups.c:93. The problem I have is that I can not *immediately* send an error reply to the client because the next receive fails. Waiting 100 milliseconds helps. It might also be a problem with epoll(), I don't really know. I'd appreciate if you took a brief look at this, maybe I'm doing something wrong. Thanks, Volker (This used to be commit 3e535cce743710a68a4264e4f66e9c0c4d6770c6) --- source4/libcli/composite/composite.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index f5eed77300..c78d039905 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -69,6 +69,13 @@ void composite_trigger_done(struct composite_context *c) event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); } +void composite_trigger_error(struct composite_context *c) +{ + c->state = COMPOSITE_STATE_ERROR; + /* a zero timeout means immediate */ + event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); +} + /* * Some composite helpers that are handy if you write larger composite -- cgit From d73bd8f01aefe97f007a59f49698a5c7c9e97c29 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Oct 2005 11:50:34 +0000 Subject: r11114: - fixed error handling on bad bind in ildap client - added nicer error display, giving a string version of the error code (This used to be commit 5ec486bb81536b38a5f40cae7555cbcbbfa52263) --- source4/libcli/ldap/ldap_bind.c | 3 +- source4/libcli/ldap/ldap_client.c | 63 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 738222da86..c08ffabc22 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -240,7 +240,8 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr result = response->r.BindResponse.response.resultcode; if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { - status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + status = ldap_check_response(conn, + &response->r.BindResponse.response); break; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 800e523eb4..6b4e73d44b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -555,11 +555,63 @@ NTSTATUS ldap_request_wait(struct ldap_request *req) } +/* + a mapping of ldap response code to strings +*/ +static const struct { + enum ldap_result_code code; + const char *str; +} ldap_code_map[] = { +#define _LDAP_MAP_CODE(c) { c, #c } + _LDAP_MAP_CODE(LDAP_SUCCESS), + _LDAP_MAP_CODE(LDAP_OPERATIONS_ERROR), + _LDAP_MAP_CODE(LDAP_PROTOCOL_ERROR), + _LDAP_MAP_CODE(LDAP_TIME_LIMIT_EXCEEDED), + _LDAP_MAP_CODE(LDAP_SIZE_LIMIT_EXCEEDED), + _LDAP_MAP_CODE(LDAP_COMPARE_FALSE), + _LDAP_MAP_CODE(LDAP_COMPARE_TRUE), + _LDAP_MAP_CODE(LDAP_AUTH_METHOD_NOT_SUPPORTED), + _LDAP_MAP_CODE(LDAP_STRONG_AUTH_REQUIRED), + _LDAP_MAP_CODE(LDAP_REFERRAL), + _LDAP_MAP_CODE(LDAP_ADMIN_LIMIT_EXCEEDED), + _LDAP_MAP_CODE(LDAP_UNAVAILABLE_CRITICAL_EXTENSION), + _LDAP_MAP_CODE(LDAP_CONFIDENTIALITY_REQUIRED), + _LDAP_MAP_CODE(LDAP_SASL_BIND_IN_PROGRESS), + _LDAP_MAP_CODE(LDAP_NO_SUCH_ATTRIBUTE), + _LDAP_MAP_CODE(LDAP_UNDEFINED_ATTRIBUTE_TYPE), + _LDAP_MAP_CODE(LDAP_INAPPROPRIATE_MATCHING), + _LDAP_MAP_CODE(LDAP_CONSTRAINT_VIOLATION), + _LDAP_MAP_CODE(LDAP_ATTRIBUTE_OR_VALUE_EXISTS), + _LDAP_MAP_CODE(LDAP_INVALID_ATTRIBUTE_SYNTAX), + _LDAP_MAP_CODE(LDAP_NO_SUCH_OBJECT), + _LDAP_MAP_CODE(LDAP_ALIAS_PROBLEM), + _LDAP_MAP_CODE(LDAP_INVALID_DN_SYNTAX), + _LDAP_MAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), + _LDAP_MAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), + _LDAP_MAP_CODE(LDAP_INVALID_CREDENTIALS), + _LDAP_MAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTs), + _LDAP_MAP_CODE(LDAP_BUSY), + _LDAP_MAP_CODE(LDAP_UNAVAILABLE), + _LDAP_MAP_CODE(LDAP_UNWILLING_TO_PERFORM), + _LDAP_MAP_CODE(LDAP_LOOP_DETECT), + _LDAP_MAP_CODE(LDAP_NAMING_VIOLATION), + _LDAP_MAP_CODE(LDAP_OBJECT_CLASS_VIOLATION), + _LDAP_MAP_CODE(LDAP_NOT_ALLOWED_ON_NON_LEAF), + _LDAP_MAP_CODE(LDAP_NOT_ALLOWED_ON_RDN), + _LDAP_MAP_CODE(LDAP_ENTRY_ALREADY_EXISTS), + _LDAP_MAP_CODE(LDAP_OBJECT_CLASS_MODS_PROHIBITED), + _LDAP_MAP_CODE(LDAP_AFFECTS_MULTIPLE_DSAS), + _LDAP_MAP_CODE(LDAP_OTHER) +}; + /* used to setup the status code from a ldap response */ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) { + int i; + const char *codename = "unknown"; + if (r->resultcode == LDAP_SUCCESS) { return NT_STATUS_OK; } @@ -567,8 +619,17 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r if (conn->last_error) { talloc_free(conn->last_error); } - conn->last_error = talloc_asprintf(conn, "LDAP error %u - %s <%s> <%s>", + + for (i=0;iresultcode == ldap_code_map[i].code) { + codename = ldap_code_map[i].str; + break; + } + } + + conn->last_error = talloc_asprintf(conn, "LDAP error %u %s - %s <%s> <%s>", r->resultcode, + codename, r->dn?r->dn:"(NULL)", r->errormessage?r->errormessage:"", r->referral?r->referral:""); -- cgit From bf38a5e7c59defc19781ceee05b0287e00a24364 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 20 Oct 2005 03:34:49 +0000 Subject: r11198: The recent changes to netlogon changed this from a RID to a SID. Andrew Bartlett (This used to be commit 24dbf3435277a51dd49c5e2189fc6655260eddf4) --- source4/libcli/auth/credentials.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 6ce3288b01..27c5a4e689 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -33,7 +33,7 @@ struct creds_CredentialState { const char *domain; const char *computer_name; const char *account_name; - uint32_t rid; + struct dom_sid *sid; }; /* for the timebeing, use the same neg flags as Samba3. */ -- cgit From f4d590662effeb80c2b55ae5ad869b4b7810cf08 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Oct 2005 10:04:57 +0000 Subject: r11214: Remove scons files (see http://lists.samba.org/archive/samba-technical/2005-October/043443.html) (This used to be commit 7fffc5c9178158249be632ac0ca179c13bd1f98f) --- source4/libcli/SConscript | 119 ------------------------------------- source4/libcli/auth/SConscript | 0 source4/libcli/ldap/SConscript | 0 source4/libcli/security/SConscript | 0 4 files changed, 119 deletions(-) delete mode 100644 source4/libcli/SConscript delete mode 100644 source4/libcli/auth/SConscript delete mode 100644 source4/libcli/ldap/SConscript delete mode 100644 source4/libcli/security/SConscript (limited to 'source4/libcli') diff --git a/source4/libcli/SConscript b/source4/libcli/SConscript deleted file mode 100644 index 5b600fdcff..0000000000 --- a/source4/libcli/SConscript +++ /dev/null @@ -1,119 +0,0 @@ -Import('hostenv') - -hostenv.Subsystem( - 'cli_utils', - ['util/asn1.c', - 'util/doserr.c', - 'util/errormap.c', - 'util/clierror.c', - 'util/nterr.c', - 'util/smbdes.c']) - -hostenv.Subsystem( - 'cli_lsa', - ['util/clilsa.c']) - -hostenv.Subsystem( - 'cli_composite_base', - ['composite/composite.c']) - -hostenv.Subsystem( - 'cli_composite', - ['smb_composite/loadfile.c', - 'smb_composite/savefile.c', - 'smb_composite/connect.c', - 'smb_composite/sesssetup.c', - 'smb_composite/fetchfile.c', - 'smb_composite/appendacl.c', - 'smb_composite/fsinfo.c']) - -hostenv.Subsystem( - 'cli_nbt', - ['nbt/nbtname.c', - 'nbt/nbtsocket.c', - 'nbt/namequery.c', - 'nbt/nameregister.c', - 'nbt/namerefresh.c', - 'nbt/namerelease.c']) - -hostenv.Subsystem( - 'cli_dgram', - ['dgram/dgramsocket.c', - 'dgram/mailslot.c', - 'dgram/netlogon.c', - 'dgram/ntlogon.c', - 'dgram/browse.c']) - -hostenv.Subsystem( - 'cli_cldap', - ['cldap/cldap.c']) - -hostenv.Subsystem( - 'cli_wrepl', - ['wrepl/winsrepl.c']) - -hostenv.Subsystem( - 'cli_resolve', - ['resolve/resolve.c', - 'resolve/nbtlist.c', - 'resolve/bcast.c', - 'resolve/wins.c', - 'resolve/host.c']) - -hostenv.Subsystem( - 'smb', - ['clireadwrite.c', - 'cliconnect.c', - 'clifile.c', - 'clilist.c', - 'clitrans2.c', - 'climessage.c', - 'clideltree.c']) - -hostenv.Subsystem( - 'cli_raw', - ['raw/rawfile.c', - 'raw/smb_signing.c', - 'raw/clisocket.c', - 'raw/clitransport.c', - 'raw/clisession.c', - 'raw/clitree.c', - 'raw/rawrequest.c', - 'raw/rawreadwrite.c', - 'raw/rawsearch.c', - 'raw/rawsetfileinfo.c', - 'raw/raweas.c', - 'raw/rawtrans.c', - 'raw/clioplock.c', - 'raw/rawnegotiate.c', - 'raw/rawfsinfo.c', - 'raw/rawfileinfo.c', - 'raw/rawnotify.c', - 'raw/rawioctl.c', - 'raw/rawacl.c', - 'raw/rawdate.c', - 'raw/rawlpq.c']) - -hostenv.Subsystem( - 'cli_security', - ['security/security_token.c', - 'security/security_descriptor.c', - 'security/dom_sid.c', - 'security/access_check.c', - 'security/privilege.c', - '../librpc/ndr/ndr_sec_helper.c']) - -hostenv.Subsystem( - 'cli_auth', - ['auth/credentials.c', - 'auth/session.c', - 'auth/smbencrypt.c']) - -hostenv.Subsystem( - 'cli_ldap', - ['ldap/ldap.c', - 'ldap/ldap_client.c', - 'ldap/ldap_bind.c', - 'ldap/ldap_msg.c', - 'ldap/ldap_ndr.c', - 'ldap/ldap_ildap.c']) diff --git a/source4/libcli/auth/SConscript b/source4/libcli/auth/SConscript deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/source4/libcli/security/SConscript b/source4/libcli/security/SConscript deleted file mode 100644 index e69de29bb2..0000000000 -- cgit From 4c5a4a7e0288e9ac0b2f795befd5684059e4c429 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Oct 2005 16:29:54 +0000 Subject: r11244: Relative path names in .mk files (This used to be commit 24e10300906c380919d2d631bfb3b8fd6b3f54ba) --- source4/libcli/auth/config.mk | 6 +- source4/libcli/config.mk | 128 ++++++++++++++++++++------------------ source4/libcli/ldap/config.mk | 12 ++-- source4/libcli/security/config.mk | 16 ++--- 4 files changed, 83 insertions(+), 79 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 0c2e5f9d14..c97bcd1e73 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,9 +1,9 @@ ################################# # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] -ADD_OBJ_FILES = libcli/auth/credentials.o \ - libcli/auth/session.o \ - libcli/auth/smbencrypt.o +ADD_OBJ_FILES = credentials.o \ + session.o \ + smbencrypt.o REQUIRED_SUBSYSTEMS = \ AUTH SCHANNELDB GENSEC # End SUBSYSTEM LIBCLI_AUTH diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 8b39207194..cf9695ec11 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -1,71 +1,75 @@ +include auth/config.mk +include ldap/config.mk +include security/config.mk + [SUBSYSTEM::LIBCLI_UTILS] -ADD_OBJ_FILES = libcli/util/asn1.o \ - libcli/util/doserr.o \ - libcli/util/errormap.o \ - libcli/util/clierror.o \ - libcli/util/nterr.o \ - libcli/util/smbdes.o +ADD_OBJ_FILES = util/asn1.o \ + util/doserr.o \ + util/errormap.o \ + util/clierror.o \ + util/nterr.o \ + util/smbdes.o [SUBSYSTEM::LIBCLI_LSA] -ADD_OBJ_FILES = libcli/util/clilsa.o +ADD_OBJ_FILES = util/clilsa.o REQUIRED_SUBSYSTEMS = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_COMPOSITE] ADD_OBJ_FILES = \ - libcli/composite/composite.o + composite/composite.o REQUIRED_SUBSYSTEMS = LIBEVENTS [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] ADD_OBJ_FILES = \ - libcli/smb_composite/loadfile.o \ - libcli/smb_composite/savefile.o \ - libcli/smb_composite/connect.o \ - libcli/smb_composite/connect_multi.o \ - libcli/smb_composite/sesssetup.o \ - libcli/smb_composite/fetchfile.o \ - libcli/smb_composite/appendacl.o \ - libcli/smb_composite/fsinfo.o + smb_composite/loadfile.o \ + smb_composite/savefile.o \ + smb_composite/connect.o \ + smb_composite/connect_multi.o \ + smb_composite/sesssetup.o \ + smb_composite/fetchfile.o \ + smb_composite/appendacl.o \ + smb_composite/fsinfo.o REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE [SUBSYSTEM::LIBCLI_NBT] ADD_OBJ_FILES = \ - libcli/nbt/nbtname.o \ - libcli/nbt/nbtsocket.o \ - libcli/nbt/namequery.o \ - libcli/nbt/nameregister.o \ - libcli/nbt/namerefresh.o \ - libcli/nbt/namerelease.o + nbt/nbtname.o \ + nbt/nbtsocket.o \ + nbt/namequery.o \ + nbt/nameregister.o \ + nbt/namerefresh.o \ + nbt/namerelease.o REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ LIB_SECURITY_NDR [SUBSYSTEM::LIBCLI_DGRAM] ADD_OBJ_FILES = \ - libcli/dgram/dgramsocket.o \ - libcli/dgram/mailslot.o \ - libcli/dgram/netlogon.o \ - libcli/dgram/ntlogon.o \ - libcli/dgram/browse.o + dgram/dgramsocket.o \ + dgram/mailslot.o \ + dgram/netlogon.o \ + dgram/ntlogon.o \ + dgram/browse.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI_CLDAP] ADD_OBJ_FILES = \ - libcli/cldap/cldap.o + cldap/cldap.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP [SUBSYSTEM::LIBCLI_WREPL] ADD_OBJ_FILES = \ - libcli/wrepl/winsrepl.o + wrepl/winsrepl.o REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] ADD_OBJ_FILES = \ - libcli/resolve/resolve.o \ - libcli/resolve/nbtlist.o \ - libcli/resolve/bcast.o \ - libcli/resolve/wins.o \ - libcli/resolve/host.o + resolve/resolve.o \ + resolve/nbtlist.o \ + resolve/bcast.o \ + resolve/wins.o \ + resolve/host.o REQUIRED_SUBSYSTEMS = LIBCLI_NBT [SUBSYSTEM::LIBCLI] @@ -75,34 +79,34 @@ REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI SOCKET -ADD_OBJ_FILES = libcli/clireadwrite.o \ - libcli/cliconnect.o \ - libcli/clifile.o \ - libcli/clilist.o \ - libcli/clitrans2.o \ - libcli/climessage.o \ - libcli/clideltree.o +ADD_OBJ_FILES = clireadwrite.o \ + cliconnect.o \ + clifile.o \ + clilist.o \ + clitrans2.o \ + climessage.o \ + clideltree.o [SUBSYSTEM::LIBCLI_RAW] REQUIRED_SUBSYSTEMS = LIBCLI_RAW_KRB5 -OBJ_FILES = libcli/raw/rawfile.o \ - libcli/raw/smb_signing.o \ - libcli/raw/clisocket.o \ - libcli/raw/clitransport.o \ - libcli/raw/clisession.o \ - libcli/raw/clitree.o \ - libcli/raw/rawrequest.o \ - libcli/raw/rawreadwrite.o \ - libcli/raw/rawsearch.o \ - libcli/raw/rawsetfileinfo.o \ - libcli/raw/raweas.o \ - libcli/raw/rawtrans.o \ - libcli/raw/clioplock.o \ - libcli/raw/rawnegotiate.o \ - libcli/raw/rawfsinfo.o \ - libcli/raw/rawfileinfo.o \ - libcli/raw/rawnotify.o \ - libcli/raw/rawioctl.o \ - libcli/raw/rawacl.o \ - libcli/raw/rawdate.o \ - libcli/raw/rawlpq.o +OBJ_FILES = raw/rawfile.o \ + raw/smb_signing.o \ + raw/clisocket.o \ + raw/clitransport.o \ + raw/clisession.o \ + raw/clitree.o \ + raw/rawrequest.o \ + raw/rawreadwrite.o \ + raw/rawsearch.o \ + raw/rawsetfileinfo.o \ + raw/raweas.o \ + raw/rawtrans.o \ + raw/clioplock.o \ + raw/rawnegotiate.o \ + raw/rawfsinfo.o \ + raw/rawfileinfo.o \ + raw/rawnotify.o \ + raw/rawioctl.o \ + raw/rawacl.o \ + raw/rawdate.o \ + raw/rawlpq.o diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a92e733493..face7caa66 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,12 +1,12 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -ADD_OBJ_FILES = libcli/ldap/ldap.o \ - libcli/ldap/ldap_client.o \ - libcli/ldap/ldap_bind.o \ - libcli/ldap/ldap_msg.o \ - libcli/ldap/ldap_ndr.o \ - libcli/ldap/ldap_ildap.o +ADD_OBJ_FILES = ldap.o \ + ldap_client.o \ + ldap_bind.o \ + ldap_msg.o \ + ldap_ndr.o \ + ldap_ildap.o REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR LIBTLS # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 40987e37e2..d7492038d3 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,14 +1,14 @@ ################################# # Start SUBSYSTEM LIB_SECURITY_NDR_HELPER [SUBSYSTEM::LIB_SECURITY_NDR_HELPER] -ADD_OBJ_FILES = librpc/ndr/ndr_sec_helper.o +ADD_OBJ_FILES = ../../librpc/ndr/ndr_sec_helper.o # End SUBSYSTEM LIB_SECURITY_NDR_HELPER ################################# ################################# # Start SUBSYSTEM LIB_SECURITY_NDR [SUBSYSTEM::LIB_SECURITY_NDR] -ADD_OBJ_FILES = librpc/gen_ndr/ndr_security.o +ADD_OBJ_FILES = ../../librpc/gen_ndr/ndr_security.o NOPROTO = YES REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR_HELPER # End SUBSYSTEM LIB_SECURITY_NDR @@ -17,12 +17,12 @@ REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR_HELPER ################################# # Start SUBSYSTEM LIB_SECURITY [SUBSYSTEM::LIB_SECURITY] -ADD_OBJ_FILES = libcli/security/security_token.o \ - libcli/security/security_descriptor.o \ - libcli/security/dom_sid.o \ - libcli/security/access_check.o \ - libcli/security/privilege.o \ - librpc/ndr/ndr_sec.o +ADD_OBJ_FILES = security_token.o \ + security_descriptor.o \ + dom_sid.o \ + access_check.o \ + privilege.o \ + ../../librpc/ndr/ndr_sec.o REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR # End SUBSYSTEM LIB_SECURITY ################################# -- cgit From df30ef140d24863b849eaa81624509fabd663ee7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 21 Oct 2005 19:31:36 +0000 Subject: r11248: Fix anon fallback with spnego (This used to be commit 13ebdea11532f4810d01095a54d430c36c91d826) --- source4/libcli/smb_composite/connect.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 925d5ddb38..466d86233a 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -173,6 +173,11 @@ static NTSTATUS connect_session_setup(struct composite_context *c, cli_credentials_set_conf(state->io_setup->in.credentials); cli_credentials_set_anonymous(state->io_setup->in.credentials); + /* If the preceding attempt was with extended security, we + * have been given a uid in the NTLMSSP_CHALLENGE reply. This + * would lead to an invalid uid in the anonymous fallback */ + state->session->vuid = 0; + state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); NT_STATUS_HAVE_NO_MEMORY(state->creq); -- cgit From 3608b6af426c99eaa99f366d556018193a1aaa2d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Oct 2005 11:23:55 +0000 Subject: r11264: Winbind does not rely on the hostname resolution mechanisms of composite_connect, so in io.in.dest_host I'm setting the IP address. Gensec does not like that as a target hostname, so if a called name is present, use that. So we can session setup using kerberos now. Volker (This used to be commit c26b432c27954c8dc6ac8e702bd5e34a351d15bd) --- source4/libcli/smb_composite/connect.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 466d86233a..4e9ee48cb7 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -355,7 +355,11 @@ static NTSTATUS connect_resolve(struct composite_context *c, conn->in.hostnames = talloc_array(state->conn, const char *, 1); NT_STATUS_HAVE_NO_MEMORY(conn->in.hostnames); - conn->in.hostnames[0] = state->io->in.dest_host; + if (state->io->in.called_name != NULL) { + conn->in.hostnames[0] = state->io->in.called_name; + } else { + conn->in.hostnames[0] = state->io->in.dest_host; + } conn->in.ports = NULL; if (state->io->in.port != 0) { -- cgit From ca40d0a6fea0dbf2a9962ed125f420bea3ca0269 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 24 Oct 2005 04:19:27 +0000 Subject: r11271: Fix a warning and an infinite recursion (This used to be commit 7bc855359a82010fefa9fd1d4c719292bfc83528) --- source4/libcli/ldap/ldap_ildap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index d85585bce8..666cc02536 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -180,7 +180,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, msg->r.SearchRequest.attributesonly = attributesonly; msg->r.SearchRequest.tree = tree; msg->r.SearchRequest.num_attributes = n; - msg->r.SearchRequest.attributes = attrs; + msg->r.SearchRequest.attributes = discard_const(attrs); req = ldap_request_send(conn, msg); talloc_steal(msg, req); @@ -224,7 +224,8 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, { struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); NTSTATUS status; - status = ildap_search(conn, basedn, scope, tree, attrs, attributesonly, results); + status = ildap_search_bytree(conn, basedn, scope, tree, attrs, + attributesonly, results); talloc_free(tree); return status; } -- cgit From d6e070b74af8891c5e6ee15d57f8c0db3aac2f14 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 24 Oct 2005 09:34:12 +0000 Subject: r11274: Start a connection attempt to the DC's port 389. To do this properly, make socket_connect and ldap_connect properly async. Volker (This used to be commit bcc71fc1deeed443d7cf00220ce264011ddf588d) --- source4/libcli/ldap/ldap_client.c | 97 +++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6b4e73d44b..d7cfd7c7e5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -31,6 +31,7 @@ #include "lib/tls/tls.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" +#include "libcli/composite/composite.h" /* @@ -393,45 +394,105 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, /* connect to a ldap server */ -NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) + +struct ldap_connect_state { + struct composite_context *ctx; + struct ldap_connection *conn; +}; + +static void ldap_connect_recv_conn(struct composite_context *ctx); + +struct composite_context *ldap_connect_send(struct ldap_connection *conn, + const char *url) { - NTSTATUS status; + struct composite_context *result, *ctx; + struct ldap_connect_state *state; - status = ldap_parse_basic_url(conn, url, &conn->host, - &conn->port, &conn->ldaps); - NT_STATUS_NOT_OK_RETURN(status); + result = talloc_zero(NULL, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = conn->event.event_ctx; - status = socket_create("ipv4", SOCKET_TYPE_STREAM, &conn->sock, 0); - NT_STATUS_NOT_OK_RETURN(status); + state = talloc(result, struct ldap_connect_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; - talloc_steal(conn, conn->sock); + state->conn = conn; - /* connect in a event friendly way */ - status = socket_connect_ev(conn->sock, NULL, 0, conn->host, conn->port, 0, - conn->event.event_ctx); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(conn->sock); - return status; + state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_trigger_error(state->ctx); + return result; } + state->ctx->status = socket_create("ipv4", SOCKET_TYPE_STREAM, + &conn->sock, 0); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_trigger_error(state->ctx); + return result; + } + + talloc_steal(conn, conn->sock); + + ctx = socket_connect_send(conn->sock, NULL, 0, conn->host, + conn->port, 0, conn->event.event_ctx); + if (ctx == NULL) goto failed; + + ctx->async.fn = ldap_connect_recv_conn; + ctx->async.private_data = state; + return result; + + failed: + talloc_free(result); + return NULL; +} + +static void ldap_connect_recv_conn(struct composite_context *ctx) +{ + struct ldap_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct ldap_connect_state); + struct ldap_connection *conn = state->conn; + + state->ctx->status = socket_connect_recv(ctx); + if (!composite_is_ok(state->ctx)) return; + /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, socket_get_fd(conn->sock), EVENT_FD_READ, ldap_io_handler, conn); if (conn->event.fde == NULL) { - talloc_free(conn->sock); - return NT_STATUS_INTERNAL_ERROR; + composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); + return; } conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); if (conn->tls == NULL) { talloc_free(conn->sock); - return NT_STATUS_INTERNAL_ERROR; + return; } talloc_steal(conn, conn->tls); talloc_steal(conn->tls, conn->sock); - return NT_STATUS_OK; + composite_done(state->ctx); + + return; +} + +NTSTATUS ldap_connect_recv(struct composite_context *ctx) +{ + NTSTATUS status = composite_wait(ctx); + talloc_free(ctx); + return status; +} + +NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) +{ + struct composite_context *ctx = ldap_connect_send(conn, url); + return ldap_connect_recv(ctx); } /* destroy an open ldap request */ -- cgit From 8ee1ee66edb1c98b63cbc26741080932995156a4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Oct 2005 14:18:27 +0000 Subject: r11303: Support defining and installing public headers for libraries. Support installing libraries. Get rid of pkg-config file (will be autogenerated later on). (This used to be commit b4745032a2c55752c527026feb221ccc3dce10c8) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index cf9695ec11..5ed4cff199 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -39,7 +39,7 @@ ADD_OBJ_FILES = \ nbt/nameregister.o \ nbt/namerefresh.o \ nbt/namerelease.o -REQUIRED_SUBSYSTEMS = NDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ +REQUIRED_SUBSYSTEMS = LIBNDR NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ LIB_SECURITY_NDR [SUBSYSTEM::LIBCLI_DGRAM] -- cgit From 22d867fb1d0247a7b74776e65a0dd5eac5dcc0d4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Oct 2005 14:33:12 +0000 Subject: r11334: Print error status in debug. Andrew Bartlett (This used to be commit 3b5ef4208d8e9492fbed1b68251bc62063909854) --- source4/libcli/dgram/dgramsocket.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index decbc0225c..6c6a45f48e 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -117,8 +117,9 @@ static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0, req->dest.addr, req->dest.port); if (NT_STATUS_IS_ERR(status)) { - DEBUG(3,("Failed to send datagram of length %u to %s:%d\n", - (unsigned)req->encoded.length, req->dest.addr, req->dest.port)); + DEBUG(3,("Failed to send datagram of length %u to %s:%d: %s\n", + (unsigned)req->encoded.length, req->dest.addr, req->dest.port, + nt_errstr(status))); DLIST_REMOVE(dgmsock->send_queue, req); talloc_free(req); continue; -- cgit From 134b2488c82ae13392121f71e4960178a38f3e01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Oct 2005 11:02:42 +0000 Subject: r11369: Implement socket_connect_multi: Connect to multiple ipv4 tcp ports in sequence, with a 2-millisecond timeout between firing the syn packets. Build smbcli_sock_connect_send upon that. Volker (This used to be commit 5718df44d90d113304c5deed1e2e7f82ff9e928f) --- source4/libcli/cliconnect.c | 8 +- source4/libcli/config.mk | 1 - source4/libcli/ldap/ldap_client.c | 17 +- source4/libcli/raw/clisocket.c | 324 ++++++++++++--------------- source4/libcli/smb_composite/connect.c | 42 +--- source4/libcli/smb_composite/connect_multi.c | 188 ---------------- 6 files changed, 154 insertions(+), 426 deletions(-) delete mode 100644 source4/libcli/smb_composite/connect_multi.c (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 00c5012074..c344ece385 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -32,13 +32,9 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) { struct smbcli_socket *sock; - sock = smbcli_sock_init(cli, NULL); - if (!sock) return False; + sock = smbcli_sock_connect_byname(server, 0, NULL, NULL); - if (!smbcli_sock_connect_byname(sock, server, 0)) { - talloc_free(sock); - return False; - } + if (sock == NULL) return False; cli->transport = smbcli_transport_init(sock, cli, True); if (!cli->transport) { diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 5ed4cff199..c1747b5b17 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -24,7 +24,6 @@ ADD_OBJ_FILES = \ smb_composite/loadfile.o \ smb_composite/savefile.o \ smb_composite/connect.o \ - smb_composite/connect_multi.o \ smb_composite/sesssetup.o \ smb_composite/fetchfile.o \ smb_composite/appendacl.o \ diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index d7cfd7c7e5..3b801ca225 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -428,17 +428,8 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, return result; } - state->ctx->status = socket_create("ipv4", SOCKET_TYPE_STREAM, - &conn->sock, 0); - if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_trigger_error(state->ctx); - return result; - } - - talloc_steal(conn, conn->sock); - - ctx = socket_connect_send(conn->sock, NULL, 0, conn->host, - conn->port, 0, conn->event.event_ctx); + ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, + conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_conn; @@ -456,8 +447,10 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) talloc_get_type(ctx->async.private_data, struct ldap_connect_state); struct ldap_connection *conn = state->conn; + uint16_t port; - state->ctx->status = socket_connect_recv(ctx); + state->ctx->status = socket_connect_multi_recv(ctx, state, &conn->sock, + &port); if (!composite_is_ok(state->ctx)) return; /* setup a handler for events on this socket */ diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 688ee8a78b..8b8a0b0faf 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -27,206 +27,130 @@ #include "libcli/composite/composite.h" #include "lib/socket/socket.h" -/* - this private structure is used during async connection handling -*/ -struct clisocket_connect { - int port_num; - int *iports; - struct smbcli_socket *sock; - const char *dest_host_addr; - const char *dest_hostname; +struct sock_connect_state { + struct composite_context *ctx; + const char *host_name; + int num_ports; + uint16_t *ports; + struct smbcli_socket *result; }; - /* - create a smbcli_socket context - The event_ctx is optional - if not supplied one will be created + connect a smbcli_socket context to an IP/port pair + if port is 0 then choose 445 then 139 */ -struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) + +static void smbcli_sock_connect_recv_conn(struct composite_context *ctx); + +struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, + const char *host_addr, + int port, + const char *host_name, + struct event_context *event_ctx) { - struct smbcli_socket *sock; + struct composite_context *result, *ctx; + struct sock_connect_state *state; - sock = talloc_zero(mem_ctx, struct smbcli_socket); - if (!sock) { - return NULL; - } + result = talloc_zero(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; - if (event_ctx) { - sock->event.ctx = talloc_reference(sock, event_ctx); + if (event_ctx != NULL) { + result->event_ctx = talloc_reference(result, event_ctx); } else { - sock->event.ctx = event_context_init(sock); - } - if (sock->event.ctx == NULL) { - talloc_free(sock); - return NULL; + result->event_ctx = event_context_init(result); } - /* ensure we don't get SIGPIPE */ - BlockSignals(True,SIGPIPE); + if (result->event_ctx == NULL) goto failed; - return sock; -} + state = talloc(result, struct sock_connect_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; -static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, - const char *hostaddr, int port, - struct composite_context *c); + state->host_name = talloc_strdup(state, host_name); + if (state->host_name == NULL) goto failed; -/* - handle socket write events during an async connect. These happen when the OS - has either completed the connect() or has returned an error -*/ -static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private_data) -{ - struct composite_context *c = talloc_get_type(private_data, struct composite_context); - struct clisocket_connect *conn = talloc_get_type(c->private_data, struct clisocket_connect); - int i; - - c->status = socket_connect_complete(conn->sock->sock, 0); - if (NT_STATUS_IS_OK(c->status)) { - socket_set_option(conn->sock->sock, lp_socket_options(), NULL); - conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_hostname); - c->state = COMPOSITE_STATE_DONE; - if (c->async.fn) { - c->async.fn(c); - } - return; - } + if (port == 0) { + const char **ports = lp_smb_ports(); + int i; - /* that port failed - try the next port */ - for (i=conn->port_num+1;conn->iports[i];i++) { - conn->port_num = i; - c->status = smbcli_sock_connect_one(conn->sock, - conn->dest_host_addr, - conn->iports[i], c); - if (NT_STATUS_IS_OK(c->status) || - NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return; + for (i=0;ports[i];i++) /* noop */ ; + if (i == 0) { + DEBUG(3, ("no smb ports defined\n")); + goto failed; } + state->num_ports = i; + state->ports = talloc_array(state, uint16_t, i); + if (state->ports == NULL) goto failed; + for (i=0;ports[i];i++) { + state->ports[i] = atoi(ports[i]); + } + } else { + state->ports = talloc_array(state, uint16_t, 1); + if (state->ports == NULL) goto failed; + state->num_ports = 1; + state->ports[0] = port; } - c->state = COMPOSITE_STATE_ERROR; - if (c->async.fn) { - c->async.fn(c); - } -} - - -/* - try to connect to the given address/port -*/ -static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock, - const char *hostaddr, int port, - struct composite_context *c) -{ - NTSTATUS status; - - if (sock->sock) { - talloc_free(sock->sock); - sock->sock = NULL; - } - talloc_free(sock->event.fde); - - status = socket_create("ip", SOCKET_TYPE_STREAM, &sock->sock, 0); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - talloc_steal(sock, sock->sock); - - /* we initially look for write - see the man page on - non-blocking connect */ - sock->event.fde = event_add_fd(sock->event.ctx, sock, socket_get_fd(sock->sock), - EVENT_FD_WRITE, smbcli_sock_connect_handler, c); + ctx = socket_connect_multi_send(state, host_addr, + state->num_ports, state->ports, + state->ctx->event_ctx); + if (ctx == NULL) goto failed; + ctx->async.fn = smbcli_sock_connect_recv_conn; + ctx->async.private_data = state; + return result; - sock->port = port; - set_blocking(socket_get_fd(sock->sock), False); - - return socket_connect(sock->sock, NULL, 0, hostaddr, port, 0); +failed: + talloc_free(result); + return NULL; } - -/* - connect a smbcli_socket context to an IP/port pair - if port is 0 then choose 445 then 139 - - this is the async send side of the interface -*/ -struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, - const char *host_addr, int port, - const char *host_name) +static void smbcli_sock_connect_recv_conn(struct composite_context *ctx) { - struct composite_context *c; - struct clisocket_connect *conn; - int i; + struct sock_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct sock_connect_state); + struct socket_context *sock; + uint16_t port; - c = talloc_zero(sock, struct composite_context); - if (c == NULL) return NULL; + state->ctx->status = socket_connect_multi_recv(ctx, state, &sock, + &port); + if (!composite_is_ok(state->ctx)) return; - c->event_ctx = sock->event.ctx; + state->ctx->status = + socket_set_option(sock, lp_socket_options(), NULL); + if (!composite_is_ok(state->ctx)) return; - conn = talloc(c, struct clisocket_connect); - if (conn == NULL) goto failed; - conn->sock = sock; + state->result = talloc_zero(state, struct smbcli_socket); + if (composite_nomem(state->result, state->ctx)) return; - /* work out what ports we will try */ - if (port == 0) { - const char **ports = lp_smb_ports(); - for (i=0;ports[i];i++) /* noop */ ; - conn->iports = talloc_array(c, int, i+1); - if (conn->iports == NULL) goto failed; - for (i=0;ports[i];i++) { - conn->iports[i] = atoi(ports[i]); - } - conn->iports[i] = 0; - } else { - conn->iports = talloc_array(c, int, 2); - if (conn->iports == NULL) goto failed; - conn->iports[0] = port; - conn->iports[1] = 0; - } + state->result->sock = talloc_steal(state->result, sock); + state->result->port = port; + state->result->hostname = talloc_steal(sock, state->host_name); - conn->dest_host_addr = talloc_strdup(c, host_addr); - if (conn->dest_host_addr == NULL) goto failed; - - conn->dest_hostname = talloc_strdup(c, host_name); - if (conn->dest_hostname == NULL) goto failed; - - c->private_data = conn; - c->state = COMPOSITE_STATE_IN_PROGRESS; - - /* startup the connect process for each port in turn until one - succeeds or tells us that it is pending */ - for (i=0;conn->iports[i];i++) { - conn->port_num = i; - conn->sock->port = conn->iports[i]; - c->status = smbcli_sock_connect_one(sock, - conn->dest_host_addr, - conn->iports[i], c); - if (NT_STATUS_IS_OK(c->status) || - NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return c; - } - } + state->result->event.ctx = + talloc_reference(state->result, state->ctx->event_ctx); + if (composite_nomem(state->result->event.ctx, state->ctx)) return; - c->state = COMPOSITE_STATE_ERROR; - return c; - -failed: - talloc_free(c); - return NULL; + composite_done(state->ctx); } /* finish a smbcli_sock_connect_send() operation */ -NTSTATUS smbcli_sock_connect_recv(struct composite_context *c) +NTSTATUS smbcli_sock_connect_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx, + struct smbcli_socket **result) { - NTSTATUS status; - status = composite_wait(c); + NTSTATUS status = composite_wait(c); + if (NT_STATUS_IS_OK(status)) { + struct sock_connect_state *state = + talloc_get_type(c->private_data, + struct sock_connect_state); + *result = talloc_steal(mem_ctx, state->result); + } talloc_free(c); return status; } @@ -237,17 +161,16 @@ NTSTATUS smbcli_sock_connect_recv(struct composite_context *c) sync version of the function */ -NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port, - const char *host_name) +NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx, + const char *host_addr, int port, + const char *host_name, + struct event_context *event_ctx, + struct smbcli_socket **result) { - struct composite_context *c; - - c = smbcli_sock_connect_send(sock, host_addr, port, host_name); - if (c == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return smbcli_sock_connect_recv(c); + struct composite_context *c = + smbcli_sock_connect_send(mem_ctx, host_addr, port, host_name, + event_ctx); + return smbcli_sock_connect_recv(c, mem_ctx, result); } @@ -306,15 +229,39 @@ NTSTATUS smbcli_sock_read(struct smbcli_socket *sock, uint8_t *data, /**************************************************************************** resolve a hostname and connect ****************************************************************************/ -BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, int port) +struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, + TALLOC_CTX *mem_ctx, + struct event_context *event_ctx) { int name_type = NBT_NAME_SERVER; const char *address; NTSTATUS status; struct nbt_name nbt_name; char *name, *p; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + struct smbcli_socket *result; + + if (tmp_ctx == NULL) { + DEBUG(0, ("talloc_new failed\n")); + return NULL; + } + + name = talloc_strdup(tmp_ctx, host); + if (name == NULL) { + DEBUG(0, ("talloc_strdup failed\n")); + talloc_free(tmp_ctx); + return NULL; + } + + if (event_ctx == NULL) { + event_ctx = event_context_init(mem_ctx); + } - name = talloc_strdup(sock, host); + if (event_ctx == NULL) { + DEBUG(0, ("event_context_init failed\n")); + talloc_free(tmp_ctx); + return NULL; + } /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(name, '#'))) { @@ -322,16 +269,25 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in *p = 0; } - nbt_name.name = name; - nbt_name.type = name_type; - nbt_name.scope = NULL; + make_nbt_name(&nbt_name, host, name_type); - status = resolve_name(&nbt_name, sock, &address, sock->event.ctx); + status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx); if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); return False; } - status = smbcli_sock_connect(sock, address, port, name); + status = smbcli_sock_connect(mem_ctx, address, port, name, event_ctx, + &result); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(9, ("smbcli_sock_connect failed: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return NULL; + } + + talloc_free(tmp_ctx); - return NT_STATUS_IS_OK(status); + return result; } diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 4e9ee48cb7..643871a8c4 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -41,7 +41,6 @@ struct connect_state { struct smbcli_socket *sock; struct smbcli_transport *transport; struct smbcli_session *session; - struct smb_composite_connectmulti *conn; struct smb_composite_connect *io; union smb_tcon *io_tcon; struct smb_composite_sesssetup *io_setup; @@ -73,7 +72,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, /* - a tree connect request has competed + a tree connect request has completed */ static NTSTATUS connect_tcon(struct composite_context *c, struct smb_composite_connect *io) @@ -232,7 +231,7 @@ static NTSTATUS connect_session_setup(struct composite_context *c, } /* - a negprot request has competed + a negprot request has completed */ static NTSTATUS connect_negprot(struct composite_context *c, struct smb_composite_connect *io) @@ -271,7 +270,7 @@ static NTSTATUS connect_negprot(struct composite_context *c, /* - a session request operation has competed + a session request operation has completed */ static NTSTATUS connect_session_request(struct composite_context *c, struct smb_composite_connect *io) @@ -287,7 +286,7 @@ static NTSTATUS connect_session_request(struct composite_context *c, } /* - a socket connection operation has competed + a socket connection operation has completed */ static NTSTATUS connect_socket(struct composite_context *c, struct smb_composite_connect *io) @@ -296,11 +295,9 @@ static NTSTATUS connect_socket(struct composite_context *c, NTSTATUS status; struct nbt_name calling, called; - status = smb_composite_connectmulti_recv(state->creq, state); + status = smbcli_sock_connect_recv(state->creq, state, &state->sock); NT_STATUS_NOT_OK_RETURN(status); - state->sock = state->conn->out.socket; - /* the socket is up - we can initialise the smbcli transport layer */ state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); @@ -339,37 +336,12 @@ static NTSTATUS connect_resolve(struct composite_context *c, struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); NTSTATUS status; const char *address; - struct smb_composite_connectmulti *conn; status = resolve_name_recv(state->creq, state, &address); NT_STATUS_NOT_OK_RETURN(status); - conn = talloc(state, struct smb_composite_connectmulti); - NT_STATUS_HAVE_NO_MEMORY(conn); - state->conn = conn; - conn->in.num_dests = 1; - - conn->in.addresses = talloc_array(state->conn, const char *, 1); - NT_STATUS_HAVE_NO_MEMORY(conn->in.addresses); - conn->in.addresses[0] = address; - - conn->in.hostnames = talloc_array(state->conn, const char *, 1); - NT_STATUS_HAVE_NO_MEMORY(conn->in.hostnames); - if (state->io->in.called_name != NULL) { - conn->in.hostnames[0] = state->io->in.called_name; - } else { - conn->in.hostnames[0] = state->io->in.dest_host; - } - - conn->in.ports = NULL; - if (state->io->in.port != 0) { - conn->in.ports = talloc_array(state->conn, int, 1); - NT_STATUS_HAVE_NO_MEMORY(conn->in.ports); - conn->in.ports[0] = state->io->in.port; - } - - state->creq = smb_composite_connectmulti_send(conn, state, - c->event_ctx); + state->creq = smbcli_sock_connect_send(state, address, io->in.port, + io->in.dest_host, c->event_ctx); NT_STATUS_HAVE_NO_MEMORY(state->creq); state->stage = CONNECT_SOCKET; diff --git a/source4/libcli/smb_composite/connect_multi.c b/source4/libcli/smb_composite/connect_multi.c deleted file mode 100644 index a539ba4bc6..0000000000 --- a/source4/libcli/smb_composite/connect_multi.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Volker Lendecke - - 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. -*/ -/* - a composite API to fire connect calls to multiple targets, picking the first - one. -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "libcli/smb_composite/smb_composite.h" - -struct connectmulti_state { - struct smb_composite_connectmulti *io; - struct composite_context *creq; - struct smbcli_socket *result; - int num_socks, socks_left; - struct smbcli_socket **socks; - struct composite_context **creqs; -}; - -static void connect_receive(struct composite_context *c) - -{ - struct connectmulti_state *state = - talloc_get_type(c->async.private_data, - struct connectmulti_state); - int i; - - for (i=0; inum_socks; i++) { - if (state->creqs[i] == c) { - break; - } - } - - if (i == state->num_socks) { - c->status = NT_STATUS_INTERNAL_ERROR; - c->state = COMPOSITE_STATE_ERROR; - if (state->creq->async.fn != NULL) { - state->creq->async.fn(state->creq); - } - return; - } - - state->creq->status = smbcli_sock_connect_recv(c); - if (!NT_STATUS_IS_OK(state->creq->status)) { - talloc_free(state->socks[i]); - state->socks[i] = NULL; - state->creqs[i] = NULL; - state->socks_left -= 1; - if (state->socks_left == 0) { - state->creq->state = COMPOSITE_STATE_ERROR; - if (state->creq->async.fn != NULL) { - state->creq->async.fn(state->creq); - } - } - return; - } - - state->result = talloc_steal(state, state->socks[i]); - talloc_free(state->socks); - - state->creq->state = COMPOSITE_STATE_DONE; - if (state->creq->async.fn != NULL) { - state->creq->async.fn(state->creq); - } -} - -struct composite_context *smb_composite_connectmulti_send(struct smb_composite_connectmulti *io, - TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) -{ - struct composite_context *c; - struct connectmulti_state *state; - int num_socks = io->in.num_dests; - const char **hostnames = io->in.hostnames; - const char **addresses = io->in.addresses; - int *ports = io->in.ports; - int i; - - c = talloc_zero(mem_ctx, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct connectmulti_state); - if (state == NULL) goto failed; - - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = talloc_reference(c, event_ctx); - c->private_data = state; - - if (ports == NULL) { - int j, nports; - const char **smb_ports = lp_smb_ports(); - - for (nports=0; smb_ports[nports]; nports++) /* noop */; - - num_socks *= nports; - hostnames = talloc_array(state, const char *, num_socks); - if (hostnames == NULL) goto failed; - addresses = talloc_array(state, const char *, num_socks); - if (addresses == NULL) goto failed; - ports = talloc_array(state, int, num_socks); - if (ports == NULL) goto failed; - - for (i=0; iin.num_dests; i++) { - for (j=0; jin.hostnames[i]; - addresses[i*nports+j] = io->in.addresses[i]; - ports[i*nports+j] = atoi(smb_ports[j]); - } - } - } - - state->io = io; - state->creq = c; - state->num_socks = num_socks; - state->socks_left = num_socks; - state->socks = talloc_array(state, struct smbcli_socket *, num_socks); - state->creqs = talloc_array(state, struct composite_context *, - num_socks); - if ((state->socks == NULL) || (state->creqs == NULL)) goto failed; - - for (i=0; isocks[i] = smbcli_sock_init(state->socks, event_ctx); - if (state->socks[i] == NULL) goto failed; - - /* If the event_ctx we got given is NULL, the first socket - * creates one and all others need to refer to it. */ - event_ctx = state->socks[i]->event.ctx; - - state->creqs[i] = smbcli_sock_connect_send(state->socks[i], - addresses[i], - ports[i], - hostnames[i]); - if (state->creqs[i] == NULL) goto failed; - state->creqs[i]->async.fn = connect_receive; - state->creqs[i]->async.private_data = state; - } - - return c; - - failed: - talloc_free(c); - return NULL; -} - -NTSTATUS smb_composite_connectmulti_recv(struct composite_context *c, - TALLOC_CTX *mem_ctx) -{ - NTSTATUS status; - status = composite_wait(c); - - if (NT_STATUS_IS_OK(status)) { - struct connectmulti_state *state = - talloc_get_type(c->private_data, - struct connectmulti_state); - state->io->out.socket = talloc_steal(mem_ctx, state->result); - } - - talloc_free(c); - return status; -} - -NTSTATUS smb_composite_connectmulti(struct smb_composite_connectmulti *io, - TALLOC_CTX *mem_ctx, - struct event_context *ev) -{ - struct composite_context *c = - smb_composite_connectmulti_send(io, mem_ctx, ev); - return smb_composite_connectmulti_recv(c, mem_ctx); -} -- cgit From 93fd08168fdc881fdef099991bd7a22448841dc4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Oct 2005 18:26:26 +0000 Subject: r11377: Add support for building LIBRARY elements as shared libraries: - Adds -rpath bin/ so you don't have to install Samba in order to use compiled binaries. - Writes out pkg-config files when building shared libs - Supports automatic fallback to MERGEDOBJ (which is the default) or OBJ_LIST (if ld -r is not supported) Building with shared libs reduces the size of the Samba binaries from 197 Mb to 60 Mb (including libraries) on my system (GCC4, with debugging). To build with shared libraries support enabled, run: LIBRARY_OUTPUT_TYPE=SHARED_LIBRARY ./config.status init functions don't get called correctly yet when using shared libs, so you won't be able to actually run anything with success :-) Once init functions are done, I'll look at support for loading shared modules once again. Based on a patch by Peter Novodvorsky (nidd on IRC). (This used to be commit 0b54405685674a2b19a28d77aae5b1136b5a4728) --- source4/libcli/config.mk | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c1747b5b17..a7a2862da5 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -30,7 +30,10 @@ ADD_OBJ_FILES = \ smb_composite/fsinfo.o REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE -[SUBSYSTEM::LIBCLI_NBT] +[LIBRARY::LIBCLI_NBT] +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 ADD_OBJ_FILES = \ nbt/nbtname.o \ nbt/nbtsocket.o \ @@ -51,13 +54,19 @@ ADD_OBJ_FILES = \ NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT -[SUBSYSTEM::LIBCLI_CLDAP] +[LIBRARY::LIBCLI_CLDAP] +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 ADD_OBJ_FILES = \ cldap/cldap.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP -[SUBSYSTEM::LIBCLI_WREPL] +[LIBRARY::LIBCLI_WREPL] +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 ADD_OBJ_FILES = \ wrepl/winsrepl.o REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS @@ -71,7 +80,10 @@ ADD_OBJ_FILES = \ resolve/host.o REQUIRED_SUBSYSTEMS = LIBCLI_NBT -[SUBSYSTEM::LIBCLI] +[LIBRARY::LIBCLI] +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM -- cgit From b1d3d75c681d99f84aa2c60863597e32cdd24e66 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Oct 2005 02:46:15 +0000 Subject: r11404: Another torture test and a new WERR. Andrew Bartlett (This used to be commit de83b8cd187b28ecb30550c44f9f84e373df692e) --- source4/libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index a32da5a880..e1ef9d930a 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -72,6 +72,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_UNKNOWN_REVISION", WERR_UNKNOWN_REVISION }, { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, + { "WERR_INVALID_COMPUTERNAME", WERR_INVALID_COMPUTERNAME }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, -- cgit From 8f91998e0437b3481c095c7fcb6fca79d8b405df Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Oct 2005 21:37:36 +0000 Subject: r11424: Fix an uninitialized variable warning (This used to be commit fed26bc4fdb47b5bd1aaa6374b09252c239bbac4) --- source4/libcli/smb_composite/fetchfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 1891ee956c..a885aaa911 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -90,7 +90,7 @@ static NTSTATUS fetchfile_read(struct composite_context *c, static void fetchfile_state_handler(struct composite_context *c) { struct fetchfile_state *state; - NTSTATUS status; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; state = talloc_get_type(c->private_data, struct fetchfile_state); -- cgit From 827cbb480c6de7471554c97cb4cef13e5db7b2b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Nov 2005 03:08:52 +0000 Subject: r11466: Clear up some memory leaks in smbclient. Andrew Bartlett (This used to be commit 6535959fd7dfddd6bafb77a266ec3a641025f880) --- source4/libcli/raw/clitree.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 990552d64f..96d36c569c 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -172,10 +172,14 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, { struct smb_composite_connect io; NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(parent_ctx); + if (!tmp_ctx) { + return NT_STATUS_NO_MEMORY; + } io.in.dest_host = dest_host; io.in.port = port; - io.in.called_name = strupper_talloc(parent_ctx, dest_host); + io.in.called_name = strupper_talloc(tmp_ctx, dest_host); io.in.service = service; io.in.service_type = service_type; io.in.credentials = credentials; @@ -186,6 +190,6 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, if (NT_STATUS_IS_OK(status)) { *ret_tree = io.out.tree; } - + talloc_free(tmp_ctx); return status; } -- cgit From 536e68dbee1fcb404230b0fd6a9a050b7e4e9ee8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 3 Nov 2005 16:24:57 +0000 Subject: r11485: prevent us from calling the request handler recursiv when the handler calls talloc_free(wrepl_socket) metze (This used to be commit bf0b96f057c7f4ac39409c8710ec0cfb55d9fb04) --- source4/libcli/wrepl/winsrepl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 61cf633b54..bf894c6ad0 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -500,6 +500,9 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed struct timeval t, void *ptr) { struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); + struct wrepl_socket *wrepl_socket = req->wrepl_socket; + DLIST_REMOVE(wrepl_socket->send_queue, req); + DLIST_REMOVE(wrepl_socket->recv_queue, req); if (req->async.fn) { req->async.fn(req); } -- cgit From 6dafef03011865b9452736a417cbc5938714c13b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 3 Nov 2005 18:38:41 +0000 Subject: r11487: thanks to make test I noticed a dead lock bug, in the last change, this only happens with socket_wrapper as socket_connect() returns NT_STATUS_OK instead of NT_STATUS_MORE_PROCESSING_REQUIRED, and we missed to replace the fde event handler... metze (This used to be commit f04001f28007ad6bbecdcdf0d1d5887e378d2467) --- source4/libcli/wrepl/winsrepl.c | 58 +++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index bf894c6ad0..5658a2cc03 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -433,7 +433,7 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req) return req->status; } -static void wrepl_request_trigger(struct wrepl_request *req); +static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status); /* connect a wrepl_socket to a WINS server @@ -450,7 +450,7 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, req->wrepl_socket = wrepl_socket; req->state = WREPL_REQUEST_RECV; - DLIST_ADD(wrepl_socket->recv_queue, req); + DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); talloc_set_destructor(req, wrepl_request_destructor); @@ -460,11 +460,21 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip, WINS_REPLICATION_PORT, 0); + if (NT_STATUS_IS_OK(status)) { + talloc_free(wrepl_socket->fde); + + wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + EVENT_FD_WRITE, + wrepl_handler, wrepl_socket); + if (wrepl_socket->fde == NULL) { + status = NT_STATUS_NO_MEMORY; + } + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_ERROR; - req->status = status; - wrepl_request_trigger(req); + wrepl_request_trigger(req, status); return req; } @@ -500,9 +510,6 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed struct timeval t, void *ptr) { struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); - struct wrepl_socket *wrepl_socket = req->wrepl_socket; - DLIST_REMOVE(wrepl_socket->send_queue, req); - DLIST_REMOVE(wrepl_socket->recv_queue, req); if (req->async.fn) { req->async.fn(req); } @@ -511,8 +518,23 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed /* trigger an immediate event on a wrepl_request */ -static void wrepl_request_trigger(struct wrepl_request *req) +static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status) { + if (req->state == WREPL_REQUEST_SEND) { + DLIST_REMOVE(req->wrepl_socket->send_queue, req); + } + if (req->state == WREPL_REQUEST_RECV) { + DLIST_REMOVE(req->wrepl_socket->recv_queue, req); + } + + if (!NT_STATUS_IS_OK(status)) { + req->state = WREPL_REQUEST_ERROR; + } else { + req->state = WREPL_REQUEST_DONE; + } + + req->status = status; + /* a zero timeout means immediate */ event_add_timed(req->wrepl_socket->event_ctx, req, timeval_zero(), @@ -532,17 +554,19 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, req = talloc_zero(wrepl_socket, struct wrepl_request); if (req == NULL) goto failed; + req->wrepl_socket = wrepl_socket; + req->state = WREPL_REQUEST_SEND; + + DLIST_ADD_END(wrepl_socket->send_queue, req, struct wrepl_request *); + + talloc_set_destructor(req, wrepl_request_destructor); + if (wrepl_socket->dead) { req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_ERROR; - req->status = NT_STATUS_INVALID_CONNECTION; - wrepl_request_trigger(req); + wrepl_request_trigger(req, NT_STATUS_INVALID_CONNECTION); return req; } - req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_SEND; - wrap.packet = *packet; req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); @@ -553,10 +577,6 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); } - DLIST_ADD(wrepl_socket->send_queue, req); - - talloc_set_destructor(req, wrepl_request_destructor); - if (wrepl_socket->request_timeout > 0) { req->te = event_add_timed(wrepl_socket->event_ctx, req, timeval_current_ofs(wrepl_socket->request_timeout, 0), -- cgit From 72820aaf9281acc2acec869793a95f3353c1034c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 11:02:37 +0000 Subject: r11521: Add in client support for checking supportedSASLmechanisms, and then determining a mechanism to use. Currently it doesn't to fallbacks like SPNEGO does, but this could be added (to GENSEC, not to here). This also adds a new function to GENSEC, which returns a list of SASL names in our preference order (currently determined by the build system of all things...). Also make the similar function used for OIDs in SPNEGO do the same. This is all a very long-winded way of moving from a hard-coded NTLM to GSS-SPNEGO in our SASL client... Andrew Bartlett (This used to be commit 130eb9bb9a37957614c87e0e6846a812abb51e00) --- source4/libcli/ldap/ldap_bind.c | 57 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c08ffabc22..81e0c8b4e6 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -145,6 +145,18 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr DATA_BLOB input = data_blob(NULL, 0); DATA_BLOB output = data_blob(NULL, 0); + struct ldap_message **sasl_mechs_msgs; + struct ldap_SearchResEntry *search; + int count, i; + + const char **sasl_names; + const struct gensec_security_ops **mechs; + + static const char *supported_sasl_mech_attrs[] = { + "supportedSASLMechanisms", + NULL + }; + status = gensec_client_start(conn, &conn->gensec, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); @@ -174,16 +186,57 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } - status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); + status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, + False, &sasl_mechs_msgs); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set GENSEC client SPNEGO mechanism: %s\n", + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", nt_errstr(status))); goto failed; } + + count = ildap_count_entries(conn, sasl_mechs_msgs); + if (count != 1) { + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", + count)); + goto failed; + } tmp_ctx = talloc_new(conn); if (tmp_ctx == NULL) goto failed; + search = &sasl_mechs_msgs[0]->r.SearchResultEntry; + if (search->num_attributes != 1) { + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d\n", + search->num_attributes)); + goto failed; + } + + sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); + if (!sasl_names) { + DEBUG(1, ("talloc_arry(char *, %d) failed\n", + count)); + goto failed; + } + + for (i=0; iattributes[0].num_values; i++) { + sasl_names[i] = (const char *)search->attributes[0].values[i].data; + } + sasl_names[i] = NULL; + + mechs = gensec_security_by_sasl(tmp_ctx, sasl_names); + if (!mechs || !mechs[0]) { + DEBUG(1, ("None of the %d proposed SASL mechs were acceptable\n", + count)); + goto failed; + } + + status = gensec_start_mech_by_ops(conn->gensec, mechs[0]); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC client mechanism: %s/%s %s\n", + mechs[0]->name, mechs[0]->sasl_name, nt_errstr(status))); + goto failed; + } + while (1) { NTSTATUS gensec_status; struct ldap_message *response; -- cgit From 75ec65597cd9b0008876bbb5967f822f65985d0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 11:24:10 +0000 Subject: r11523: Working towards having Samba3 join Samba4, this allows the SASL credentials to be NULL, where the client is requesting a CIFS style server-first negTokenInit. Andrew Bartlett (This used to be commit eba652ecc89766304fdad14463072dc311693701) --- source4/libcli/ldap/ldap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 043faabf2f..7d1758a8fa 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -933,9 +933,13 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT(3)); r->mechanism = LDAP_AUTH_MECH_SASL; asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - asn1_read_OctetString(data, &r->creds.SASL.secblob); - if (r->creds.SASL.secblob.data) { - talloc_steal(msg, r->creds.SASL.secblob.data); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + asn1_read_OctetString(data, &r->creds.SASL.secblob); + if (r->creds.SASL.secblob.data) { + talloc_steal(msg, r->creds.SASL.secblob.data); + } + } else { + r->creds.SASL.secblob = data_blob(NULL, 0); } asn1_end_tag(data); } -- cgit From 69307693dc47cdaa931551c99914e85273037886 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 5 Nov 2005 23:46:57 +0000 Subject: r11528: Separate finding dcs from initializing a domain. Makes it easier to possibly support cldap and other stuff in the future. This temporarily disables wbinfo -t, but that will come back soon. Try an ldap bind using gss-spnego. This got me krb5 binds against "our" w2k3 and a trusted w2k, although with some memleaks from krb5 and a BAD_OPTION tgs-rep error. Volker (This used to be commit d14948fdf687c8f70ef9ec35445b7eb04da84253) --- source4/libcli/ldap/ldap_client.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index b61f765b40..38e043da1f 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -21,6 +21,8 @@ */ +#include "libcli/ldap/ldap.h" + enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE}; /* this is the handle that the caller gets when an async ldap message -- cgit From 08964b9de8e3e28ae15000f03c2a9f5223ff8007 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Nov 2005 12:19:34 +0000 Subject: r11532: Enable kerberos session setup for winbind smb connections (This used to be commit f0e4075db5e913d2262058bb7234c446160823d9) --- source4/libcli/smb_composite/connect.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 643871a8c4..81a82ad427 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -302,6 +302,15 @@ static NTSTATUS connect_socket(struct composite_context *c, state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); + if (state->io->in.called_name != NULL) { + /* If connecting to an IP address, we might want the real name + * of the host for later kerberos. The called name is a better + * approximation */ + state->sock->hostname = + talloc_strdup(state->sock, io->in.called_name); + NT_STATUS_HAVE_NO_MEMORY(state->sock->hostname); + } + make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials)); nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); -- cgit From 0ed6a35f000c3cc0856adce126d08d7a26d138e3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Nov 2005 12:24:33 +0000 Subject: r11533: Be a bit less intrusive (This used to be commit f341c8b4c8e8b8096c604b5842b9b7f7c4c9653c) --- source4/libcli/smb_composite/connect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 81a82ad427..785b0d076b 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -302,7 +302,8 @@ static NTSTATUS connect_socket(struct composite_context *c, state->transport = smbcli_transport_init(state->sock, state, True); NT_STATUS_HAVE_NO_MEMORY(state->transport); - if (state->io->in.called_name != NULL) { + if (is_ipaddress(state->sock->hostname) && + (state->io->in.called_name != NULL)) { /* If connecting to an IP address, we might want the real name * of the host for later kerberos. The called name is a better * approximation */ -- cgit From c4a0e36143fed4ca2ba29ddc1b52dd6e22d713fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Nov 2005 11:44:08 +0000 Subject: r11546: add more errno ntstatus mappings, to get more usefull errors from socket_wrapper metze (This used to be commit 6375a9a95da1eb2d5fd60b265047d98b264ff93f) --- source4/libcli/util/errormap.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 99154d2cb0..526e9085c9 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1319,6 +1319,21 @@ const struct unix_error_map unix_nt_errmap[] = { #endif #ifdef EFBIG { EFBIG, NT_STATUS_DISK_FULL }, +#endif +#ifdef EADDRNOTAVAIL + { EADDRNOTAVAIL,NT_STATUS_ADDRESS_NOT_ASSOCIATED }, +#endif +#ifdef ESOCKTNOSUPPORT + { ESOCKTNOSUPPORT,NT_STATUS_INVALID_PARAMETER_MIX }, +#endif +#ifdef EAFNOSUPPORT + { EAFNOSUPPORT, NT_STATUS_INVALID_PARAMETER_MIX }, +#endif +#ifdef ENOPROTOOPT + { ENOPROTOOPT, NT_STATUS_INVALID_PARAMETER_MIX }, +#endif +#ifdef ENODEV + { ENODEV, NT_STATUS_NO_SUCH_DEVICE }, #endif { 0, NT_STATUS_UNSUCCESSFUL } }; -- cgit From 1c07c25322802eef7b57dda3975baca6c9114c83 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Nov 2005 08:13:41 +0000 Subject: r11596: switched the libcli/raw/ code over to using the lib/stream/ generic packet parsing code. This simplifies the logic in the raw client library a fair bit (This used to be commit f8d43f1f67876360e1295d85a3c3702d1d60ed7b) --- source4/libcli/config.mk | 1 + source4/libcli/raw/clitransport.c | 122 +++++++++++++++----------------------- source4/libcli/raw/libcliraw.h | 9 +-- 3 files changed, 50 insertions(+), 82 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index a7a2862da5..ea93b12a03 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -121,3 +121,4 @@ OBJ_FILES = raw/rawfile.o \ raw/rawacl.o \ raw/rawdate.o \ raw/rawlpq.o +REQUIRED_SUBSYSTEMS = LIBPACKET diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index b07bd630e9..15959ce272 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -25,9 +25,9 @@ #include "lib/socket/socket.h" #include "dlinklist.h" #include "lib/events/events.h" +#include "lib/stream/packet.h" -static void smbcli_transport_process_recv(struct smbcli_transport *transport); static void smbcli_transport_process_send(struct smbcli_transport *transport); /* @@ -40,7 +40,7 @@ static void smbcli_transport_event_handler(struct event_context *ev, struct smbcli_transport *transport = talloc_get_type(private, struct smbcli_transport); if (flags & EVENT_FD_READ) { - smbcli_transport_process_recv(transport); + packet_recv(transport->packet); return; } if (flags & EVENT_FD_WRITE) { @@ -59,6 +59,18 @@ static int transport_destructor(void *ptr) return 0; } + +/* + handle receive errors +*/ +static void smbcli_transport_error(void *private, NTSTATUS status) +{ + struct smbcli_transport *transport = talloc_get_type(private, struct smbcli_transport); + smbcli_transport_dead(transport); +} + +static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob); + /* create a transport structure based on an established socket */ @@ -82,7 +94,20 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->options.request_timeout = SMB_REQUEST_TIMEOUT; transport->negotiate.max_xmit = transport->options.max_xmit; - + + /* setup the stream -> packet parser */ + transport->packet = packet_init(transport); + if (transport->packet == NULL) { + talloc_free(transport); + return NULL; + } + packet_set_private(transport->packet, transport); + packet_set_socket(transport->packet, transport->socket->sock); + packet_set_callback(transport->packet, smbcli_transport_finish_recv); + packet_set_full_request(transport->packet, packet_full_request_nbt); + packet_set_error_handler(transport->packet, smbcli_transport_error); + packet_set_event_context(transport->packet, transport->socket->event.ctx); + smbcli_init_signing(transport); ZERO_STRUCT(transport->called); @@ -381,17 +406,17 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport) we have a full request in our receive buffer - match it to a pending request and process */ -static void smbcli_transport_finish_recv(struct smbcli_transport *transport) +static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob) { + struct smbcli_transport *transport = talloc_get_type(private, + struct smbcli_transport); uint8_t *buffer, *hdr, *vwv; int len; uint16_t wct=0, mid = 0, op = 0; struct smbcli_request *req; - buffer = transport->recv_buffer.buffer; - len = transport->recv_buffer.req_size; - - ZERO_STRUCT(transport->recv_buffer); + buffer = blob.data; + len = blob.length; hdr = buffer+NBT_HDR_SIZE; vwv = hdr + HDR_VWV; @@ -399,7 +424,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport) /* see if it could be an oplock break request */ if (handle_oplock_break(transport, len, hdr, vwv)) { talloc_free(buffer); - return; + return NT_STATUS_OK; } /* at this point we need to check for a readbraw reply, as @@ -514,77 +539,14 @@ async: if (req->async.fn) { req->async.fn(req); } - return; + return NT_STATUS_OK; error: if (req) { DLIST_REMOVE(transport->pending_recv, req); req->state = SMBCLI_REQUEST_ERROR; } -} - -/* - process some pending receives -*/ -static void smbcli_transport_process_recv(struct smbcli_transport *transport) -{ - /* a incoming packet goes through 2 stages - first we read the - 4 byte header, which tells us how much more is coming. Then - we read the rest */ - if (transport->recv_buffer.received < NBT_HDR_SIZE) { - NTSTATUS status; - size_t nread; - status = smbcli_sock_read(transport->socket, - transport->recv_buffer.header + - transport->recv_buffer.received, - NBT_HDR_SIZE - transport->recv_buffer.received, - &nread); - if (NT_STATUS_IS_ERR(status)) { - smbcli_transport_dead(transport); - return; - } - if (!NT_STATUS_IS_OK(status)) { - return; - } - - transport->recv_buffer.received += nread; - - if (transport->recv_buffer.received == NBT_HDR_SIZE) { - /* we've got a full header */ - transport->recv_buffer.req_size = smb_len(transport->recv_buffer.header) + NBT_HDR_SIZE; - transport->recv_buffer.buffer = talloc_size(transport, - NBT_HDR_SIZE+transport->recv_buffer.req_size); - if (transport->recv_buffer.buffer == NULL) { - smbcli_transport_dead(transport); - return; - } - memcpy(transport->recv_buffer.buffer, transport->recv_buffer.header, NBT_HDR_SIZE); - } - } - - if (transport->recv_buffer.received < transport->recv_buffer.req_size) { - NTSTATUS status; - size_t nread; - status = smbcli_sock_read(transport->socket, - transport->recv_buffer.buffer + - transport->recv_buffer.received, - transport->recv_buffer.req_size - - transport->recv_buffer.received, - &nread); - if (NT_STATUS_IS_ERR(status)) { - smbcli_transport_dead(transport); - return; - } - if (!NT_STATUS_IS_OK(status)) { - return; - } - transport->recv_buffer.received += nread; - } - - if (transport->recv_buffer.received != 0 && - transport->recv_buffer.received == transport->recv_buffer.req_size) { - smbcli_transport_finish_recv(transport); - } + return NT_STATUS_OK; } /* @@ -593,8 +555,18 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport) */ BOOL smbcli_transport_process(struct smbcli_transport *transport) { + NTSTATUS status; + size_t npending; + smbcli_transport_process_send(transport); - smbcli_transport_process_recv(transport); + if (transport->socket->sock == NULL) { + return False; + } + + status = socket_pending(transport->socket->sock, &npending); + if (NT_STATUS_IS_OK(status) && npending > 0) { + packet_recv(transport->packet); + } if (transport->socket->sock == NULL) { return False; } diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index bb13210e74..a853bd177c 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -154,13 +154,8 @@ struct smbcli_transport { know the server name */ struct nbt_name called; - /* a buffer for partially received SMB packets. */ - struct { - uint8_t header[NBT_HDR_SIZE]; - size_t req_size; - size_t received; - uint8_t *buffer; - } recv_buffer; + /* context of the stream -> packet parser */ + struct packet_context *packet; }; /* this is the context for the user */ -- cgit From dce04d193eb0d195eb000c766921c51260d65f0e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Nov 2005 13:34:36 +0000 Subject: r11606: use the generic packet send code in libcli/raw/ (This used to be commit 0bcea45b15b08cb42d7f6fbbb3a25f73b95f362c) --- source4/libcli/raw/clitransport.c | 100 +++++++++----------------------------- 1 file changed, 23 insertions(+), 77 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 15959ce272..aafdfca74c 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -28,8 +28,6 @@ #include "lib/stream/packet.h" -static void smbcli_transport_process_send(struct smbcli_transport *transport); - /* an event has happened on the socket */ @@ -44,7 +42,7 @@ static void smbcli_transport_event_handler(struct event_context *ev, return; } if (flags & EVENT_FD_WRITE) { - smbcli_transport_process_send(transport); + packet_queue_run(transport->packet); } } @@ -122,6 +120,8 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, smbcli_transport_event_handler, transport); + packet_set_serialise(transport->packet, transport->socket->event.fde); + talloc_set_destructor(transport, transport_destructor); return transport; @@ -134,18 +134,7 @@ void smbcli_transport_dead(struct smbcli_transport *transport) { smbcli_sock_dead(transport->socket); - /* all pending sends become errors */ - while (transport->pending_send) { - struct smbcli_request *req = transport->pending_send; - req->state = SMBCLI_REQUEST_ERROR; - req->status = NT_STATUS_NET_WRITE_FAULT; - DLIST_REMOVE(transport->pending_send, req); - if (req->async.fn) { - req->async.fn(req); - } - } - - /* as do all pending receives */ + /* kill all pending receives */ while (transport->pending_recv) { struct smbcli_request *req = transport->pending_recv; req->state = SMBCLI_REQUEST_ERROR; @@ -158,24 +147,6 @@ void smbcli_transport_dead(struct smbcli_transport *transport) } -/* - enable select for write on a transport -*/ -static void smbcli_transport_write_enable(struct smbcli_transport *transport) -{ - struct fd_event *fde = transport->socket->event.fde; - EVENT_FD_WRITEABLE(fde); -} - -/* - disable select for write on a transport -*/ -static void smbcli_transport_write_disable(struct smbcli_transport *transport) -{ - struct fd_event *fde = transport->socket->event.fde; - EVENT_FD_NOT_WRITEABLE(fde); -} - /* send a session request */ @@ -364,44 +335,6 @@ void smbcli_transport_idle_handler(struct smbcli_transport *transport, idle_handler, transport); } -/* - process some pending sends -*/ -static void smbcli_transport_process_send(struct smbcli_transport *transport) -{ - while (transport->pending_send) { - struct smbcli_request *req = transport->pending_send; - NTSTATUS status; - size_t nwritten; - - status = smbcli_sock_write(transport->socket, req->out.buffer, - req->out.size, &nwritten); - if (NT_STATUS_IS_ERR(status)) { - smbcli_transport_dead(transport); - return; - } - if (!NT_STATUS_IS_OK(status)) { - return; - } - req->out.buffer += nwritten; - req->out.size -= nwritten; - if (req->out.size == 0) { - DLIST_REMOVE(transport->pending_send, req); - if (req->one_way_request) { - req->state = SMBCLI_REQUEST_DONE; - smbcli_request_destroy(req); - } else { - req->state = SMBCLI_REQUEST_RECV; - DLIST_ADD(transport->pending_recv, req); - } - } - } - - /* we're out of requests to send, so don't wait for write - events any more */ - smbcli_transport_write_disable(transport); -} - /* we have a full request in our receive buffer - match it to a pending request and process @@ -558,7 +491,7 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) NTSTATUS status; size_t npending; - smbcli_transport_process_send(transport); + packet_queue_run(transport->packet); if (transport->socket->sock == NULL) { return False; } @@ -616,6 +549,9 @@ static int smbcli_request_destructor(void *ptr) */ void smbcli_transport_send(struct smbcli_request *req) { + DATA_BLOB blob; + NTSTATUS status; + /* check if the transport is dead */ if (req->transport->socket->sock == NULL) { req->state = SMBCLI_REQUEST_ERROR; @@ -623,12 +559,22 @@ void smbcli_transport_send(struct smbcli_request *req) return; } - /* put it on the outgoing socket queue */ - req->state = SMBCLI_REQUEST_SEND; - DLIST_ADD_END(req->transport->pending_send, req, struct smbcli_request *); + /* put it on the socket queue */ + blob = data_blob_const(req->out.buffer, req->out.size); + status = packet_send(req->transport->packet, blob); + if (!NT_STATUS_IS_OK(status)) { + req->state = SMBCLI_REQUEST_ERROR; + req->status = status; + return; + } - /* make sure we look for write events */ - smbcli_transport_write_enable(req->transport); + if (req->one_way_request) { + req->state = SMBCLI_REQUEST_DONE; + smbcli_request_destroy(req); + } else { + req->state = SMBCLI_REQUEST_RECV; + DLIST_ADD(req->transport->pending_recv, req); + } /* add a timeout */ if (req->transport->options.request_timeout) { -- cgit From ac842774e4538d3e25159f1ff0bc273bc3c5faeb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Nov 2005 14:00:31 +0000 Subject: r11609: fixed handling of one way requests with new send code (This used to be commit d2b568a1114015839ca59c6f32bde4b06ea81ef9) --- source4/libcli/raw/clitransport.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index aafdfca74c..bc00b19ef5 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -571,11 +571,12 @@ void smbcli_transport_send(struct smbcli_request *req) if (req->one_way_request) { req->state = SMBCLI_REQUEST_DONE; smbcli_request_destroy(req); - } else { - req->state = SMBCLI_REQUEST_RECV; - DLIST_ADD(req->transport->pending_recv, req); + return; } + req->state = SMBCLI_REQUEST_RECV; + DLIST_ADD(req->transport->pending_recv, req); + /* add a timeout */ if (req->transport->options.request_timeout) { event_add_timed(req->transport->socket->event.ctx, req, -- cgit From 65baaafc34b2befac50541c5aef86e5d906d2797 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Nov 2005 00:28:02 +0000 Subject: r11620: switch the ldap client code over to using the generic packet code (This used to be commit 1d29ad2a27d89454e5e3c4a3cf05cc5edde0208c) --- source4/libcli/ldap/ldap.c | 8 ++ source4/libcli/ldap/ldap_client.c | 286 ++++++++++++++++---------------------- source4/libcli/ldap/ldap_client.h | 8 +- source4/libcli/util/asn1.c | 27 ++++ 4 files changed, 156 insertions(+), 173 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7d1758a8fa..3cfbe3a1e1 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1289,3 +1289,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 3b801ca225..503016e896 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -32,6 +32,7 @@ #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" +#include "lib/stream/packet.h" /* @@ -82,20 +83,20 @@ static void ldap_connection_dead(struct ldap_connection *conn) } } - while (conn->send_queue) { - req = conn->send_queue; - DLIST_REMOVE(req->conn->send_queue, req); - req->state = LDAP_REQUEST_DONE; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - if (req->async.fn) { - req->async.fn(req); - } - } - talloc_free(conn->tls); conn->tls = NULL; } +/* + handle packet errors +*/ +static void ldap_error_handler(void *private, NTSTATUS status) +{ + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); + ldap_connection_dead(conn); +} + /* match up with a pending message, adding to the replies list @@ -149,184 +150,99 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message } } + /* - try and decode/process plain data + check if a blob is a complete ldap packet + handle wrapper or unwrapped connections */ -static void ldap_try_decode_plain(struct ldap_connection *conn) +NTSTATUS ldap_complete_packet(void *private, DATA_BLOB blob, size_t *size) { - struct asn1_data asn1; - - if (!asn1_load(&asn1, conn->partial)) { - ldap_connection_dead(conn); - return; - } - - /* try and decode - this will fail if we don't have a full packet yet */ - while (asn1.ofs < asn1.length) { - struct ldap_message *msg = talloc(conn, struct ldap_message); - off_t saved_ofs = asn1.ofs; - - if (msg == NULL) { - ldap_connection_dead(conn); - return; - } - - if (ldap_decode(&asn1, msg)) { - ldap_match_message(conn, msg); - } else { - asn1.ofs = saved_ofs; - talloc_free(msg); - break; - } - } - - /* keep any remaining data in conn->partial */ - data_blob_free(&conn->partial); - if (asn1.ofs != asn1.length) { - conn->partial = data_blob_talloc(conn, - asn1.data + asn1.ofs, - asn1.length - asn1.ofs); + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); + if (conn->enable_wrap) { + return packet_full_request_u32(private, blob, size); } - asn1_free(&asn1); + return ldap_full_packet(private, blob, size); } /* - try and decode/process wrapped data + decode/process plain data */ -static void ldap_try_decode_wrapped(struct ldap_connection *conn) +static NTSTATUS ldap_decode_plain(struct ldap_connection *conn, DATA_BLOB blob) { - uint32_t len; - - /* keep decoding while we have a full wrapped packet */ - while (conn->partial.length >= 4 && - (len=RIVAL(conn->partial.data, 0)) <= conn->partial.length-4) { - DATA_BLOB wrapped, unwrapped; - struct asn1_data asn1; - struct ldap_message *msg = talloc(conn, struct ldap_message); - NTSTATUS status; - - if (msg == NULL) { - ldap_connection_dead(conn); - return; - } + struct asn1_data asn1; + struct ldap_message *msg = talloc(conn, struct ldap_message); - wrapped.data = conn->partial.data+4; - wrapped.length = len; + if (msg == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } - status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); - if (!NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); - return; - } + if (!asn1_load(&asn1, blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode(&asn1, msg)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } - if (!asn1_load(&asn1, unwrapped)) { - ldap_connection_dead(conn); - return; - } + ldap_match_message(conn, msg); - while (ldap_decode(&asn1, msg)) { - ldap_match_message(conn, msg); - msg = talloc(conn, struct ldap_message); - } - - talloc_free(msg); - asn1_free(&asn1); - - if (conn->partial.length == len + 4) { - data_blob_free(&conn->partial); - } else { - memmove(conn->partial.data, conn->partial.data+len+4, - conn->partial.length - (len+4)); - conn->partial.length -= len + 4; - } - } + data_blob_free(&blob); + asn1_free(&asn1); + return NT_STATUS_OK; } - /* - handle ldap recv events + decode/process wrapped data */ -static void ldap_recv_handler(struct ldap_connection *conn) +static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob) { + DATA_BLOB wrapped, unwrapped; + struct asn1_data asn1; + struct ldap_message *msg = talloc(conn, struct ldap_message); NTSTATUS status; - size_t npending=0, nread; - /* work out how much data is pending */ - status = tls_socket_pending(conn->tls, &npending); - if (!NT_STATUS_IS_OK(status) || npending == 0) { - ldap_connection_dead(conn); - return; + if (msg == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - conn->partial.data = talloc_realloc_size(conn, conn->partial.data, - conn->partial.length + npending); - if (conn->partial.data == NULL) { - ldap_connection_dead(conn); - return; - } + wrapped = data_blob_const(blob.data+4, blob.length-4); - /* receive the pending data */ - status = tls_socket_recv(conn->tls, conn->partial.data + conn->partial.length, - npending, &nread); - if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - return; - } + status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); if (!NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); - return; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - conn->partial.length += nread; - /* see if we can decode what we have */ - if (conn->enable_wrap) { - ldap_try_decode_wrapped(conn); - } else { - ldap_try_decode_plain(conn); + data_blob_free(&blob); + + if (!asn1_load(&asn1, unwrapped)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } + + while (ldap_decode(&asn1, msg)) { + ldap_match_message(conn, msg); + msg = talloc(conn, struct ldap_message); + } + + talloc_free(msg); + asn1_free(&asn1); + + return NT_STATUS_OK; } /* - handle ldap send events + handle ldap recv events */ -static void ldap_send_handler(struct ldap_connection *conn) +static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob) { - while (conn->send_queue) { - struct ldap_request *req = conn->send_queue; - size_t nsent; - NTSTATUS status; - - status = tls_socket_send(conn->tls, &req->data, &nsent); - if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - break; - } - if (!NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); - return; - } - - req->data.data += nsent; - req->data.length -= nsent; - if (req->data.length == 0) { - req->state = LDAP_REQUEST_PENDING; - DLIST_REMOVE(conn->send_queue, req); - - /* some types of requests don't expect a reply */ - if (req->type == LDAP_TAG_AbandonRequest || - req->type == LDAP_TAG_UnbindRequest) { - req->status = NT_STATUS_OK; - req->state = LDAP_REQUEST_DONE; - if (req->async.fn) { - req->async.fn(req); - } - } else { - DLIST_ADD(conn->pending, req); - } - } - } - if (conn->send_queue == NULL) { - EVENT_FD_NOT_WRITEABLE(conn->event.fde); + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); + if (conn->enable_wrap) { + return ldap_decode_wrapped(conn, blob); } + + return ldap_decode_plain(conn, blob); } @@ -336,13 +252,14 @@ static void ldap_send_handler(struct ldap_connection *conn) static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *private) { - struct ldap_connection *conn = talloc_get_type(private, struct ldap_connection); + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); if (flags & EVENT_FD_WRITE) { - ldap_send_handler(conn); + packet_queue_run(conn->packet); if (conn->tls == NULL) return; } if (flags & EVENT_FD_READ) { - ldap_recv_handler(conn); + packet_recv(conn->packet); } } @@ -470,6 +387,19 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) talloc_steal(conn, conn->tls); talloc_steal(conn->tls, conn->sock); + conn->packet = packet_init(conn); + if (conn->packet == NULL) { + talloc_free(conn->sock); + return; + } + packet_set_private(conn->packet, conn); + packet_set_tls(conn->packet, conn->tls); + packet_set_callback(conn->packet, ldap_recv_handler); + packet_set_full_request(conn->packet, ldap_complete_packet); + packet_set_error_handler(conn->packet, ldap_error_handler); + packet_set_event_context(conn->packet, conn->event.event_ctx); + packet_set_serialise(conn->packet, conn->event.fde); + composite_done(state->ctx); return; @@ -492,9 +422,6 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) static int ldap_request_destructor(void *ptr) { struct ldap_request *req = talloc_get_type(ptr, struct ldap_request); - if (req->state == LDAP_REQUEST_SEND) { - DLIST_REMOVE(req->conn->send_queue, req); - } if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); } @@ -509,9 +436,6 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t { struct ldap_request *req = talloc_get_type(private, struct ldap_request); req->status = NT_STATUS_IO_TIMEOUT; - if (req->state == LDAP_REQUEST_SEND) { - DLIST_REMOVE(req->conn->send_queue, req); - } if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); } @@ -521,6 +445,19 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t } } + +/* + called on completion of a one-way ldap request +*/ +static void ldap_request_complete(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct ldap_request *req = talloc_get_type(private, struct ldap_request); + if (req->async.fn) { + req->async.fn(req); + } +} + /* send a ldap message - async interface */ @@ -528,6 +465,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; + NTSTATUS status; if (conn->tls == NULL) { return NULL; @@ -558,7 +496,6 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, /* possibly encrypt/sign the request */ if (conn->enable_wrap) { DATA_BLOB wrapped; - NTSTATUS status; status = gensec_wrap(conn->gensec, req, &req->data, &wrapped); if (!NT_STATUS_IS_OK(status)) { @@ -574,11 +511,26 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, data_blob_free(&wrapped); } + status = packet_send(conn->packet, req->data); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } - if (conn->send_queue == NULL) { - EVENT_FD_WRITEABLE(conn->event.fde); + /* some requests don't expect a reply, so don't add those to the + pending queue */ + if (req->type == LDAP_TAG_AbandonRequest || + req->type == LDAP_TAG_UnbindRequest) { + req->status = NT_STATUS_OK; + req->state = LDAP_REQUEST_DONE; + /* we can't call the async callback now, as it isn't setup, so + call it as next event */ + event_add_timed(conn->event.event_ctx, req, timeval_zero(), + ldap_request_complete, req); + return req; } - DLIST_ADD_END(conn->send_queue, req, struct ldap_request *); + + req->state = LDAP_REQUEST_PENDING; + DLIST_ADD(conn->pending, req); /* put a timeout on the request */ event_add_timed(conn->event.event_ctx, req, diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 38e043da1f..ee458dc5b0 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -61,9 +61,6 @@ struct ldap_connection { /* next message id to assign */ unsigned next_messageid; - /* outgoing send queue */ - struct ldap_request *send_queue; - /* Outstanding LDAP requests that have not yet been replied to */ struct ldap_request *pending; @@ -73,9 +70,6 @@ struct ldap_connection { /* set if we are wrapping requests */ BOOL enable_wrap; - /* partially received packet */ - DATA_BLOB partial; - /* the default timeout for messages */ int timeout; @@ -86,4 +80,6 @@ struct ldap_connection { struct event_context *event_ctx; struct fd_event *fde; } event; + + struct packet_context *packet; }; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 6ca2221b1a..0dceb1bba6 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -607,3 +607,30 @@ BOOL asn1_write_enumerated(struct asn1_data *data, uint8_t v) asn1_pop_tag(data); return !data->has_error; } + +/* + check if a ASN.1 blob is a full tag +*/ +NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) +{ + struct asn1_data asn1; + int size; + + ZERO_STRUCT(asn1); + asn1.data = blob.data; + asn1.length = blob.length; + asn1_start_tag(&asn1, tag); + if (asn1.has_error) { + talloc_free(asn1.nesting); + return STATUS_MORE_ENTRIES; + } + size = asn1_tag_remaining(&asn1) + asn1.ofs; + talloc_free(asn1.nesting); + + if (size > blob.length) { + return STATUS_MORE_ENTRIES; + } + + *packet_size = size; + return NT_STATUS_OK; +} -- cgit From 0eeedb97a5b28c20edcf13d37e52b8e8b98567f6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 10 Nov 2005 03:48:56 +0000 Subject: r11626: Fix unhandled enum in case statement warnings by noting appropriately that some values aren't handled. The remaining warnings I think are actual bugs or required functionality that is missing (mostly lack of server side Unix extensions). (This used to be commit 03c7da27a06736f2a27d76e6a00a24ab54453af9) --- source4/libcli/raw/rawsetfileinfo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 7934171ab0..5e780757e8 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -124,6 +124,18 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, NEED_BLOB(4); SIVAL(blob->data, 0, parms->mode_information.in.mode); return True; + + /* Unhandled levels */ + + case RAW_SFILEINFO_UNIX_LINK: + case RAW_SFILEINFO_UNIX_HLINK: + case RAW_SFILEINFO_1023: + case RAW_SFILEINFO_1025: + case RAW_SFILEINFO_1029: + case RAW_SFILEINFO_1032: + case RAW_SFILEINFO_1039: + case RAW_SFILEINFO_1040: + break; } return False; -- cgit From 4c9ba2ffa13ebfe7e8a289ad3d27864fef7917d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Nov 2005 05:26:53 +0000 Subject: r11632: removed 2 unused functions (This used to be commit fa904afed93a350dd0dcd3cddc1521a4a1ad6711) --- source4/libcli/raw/clisocket.c | 33 --------------------------------- 1 file changed, 33 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 8b8a0b0faf..be25b36007 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -193,39 +193,6 @@ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) socket_set_option(sock->sock, options, NULL); } -/**************************************************************************** - Write to socket. Return amount written. -****************************************************************************/ -NTSTATUS smbcli_sock_write(struct smbcli_socket *sock, const uint8_t *data, - size_t len, size_t *nsent) -{ - DATA_BLOB blob; - - if (sock->sock == NULL) { - return NT_STATUS_CONNECTION_DISCONNECTED; - } - - blob.data = discard_const(data); - blob.length = len; - - return socket_send(sock->sock, &blob, nsent, 0); -} - - -/**************************************************************************** - Read from socket. return amount read -****************************************************************************/ -NTSTATUS smbcli_sock_read(struct smbcli_socket *sock, uint8_t *data, - size_t len, size_t *nread) -{ - if (sock->sock == NULL) { - return NT_STATUS_CONNECTION_DISCONNECTED; - } - - return socket_recv(sock->sock, data, len, nread, 0); -} - - /**************************************************************************** resolve a hostname and connect ****************************************************************************/ -- cgit From 7118df6df0970ce3403056a2ee073c18d0b06bd7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Nov 2005 09:12:36 +0000 Subject: r11635: fix a handling of packet_send in the smb client lib this was cause of the PANIC on the build farm on metze01 as we use req->out.buffer from the old request in the smb_raw_ntcancel() and send a 0 TID, that causes our server code to crash (a fix for the server code will follow) metze (This used to be commit 97cd824e44b03178706b108c7a78753faf412e8f) --- source4/libcli/raw/clitransport.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index bc00b19ef5..6bf79ecfb0 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -559,7 +559,16 @@ void smbcli_transport_send(struct smbcli_request *req) return; } - /* put it on the socket queue */ + /* put it on the socket queue + * - as the buffer is a part of the smbcli_request struct + * we need to reference it here, because packet_queue_run() + * will call talloc_free() on it + */ + if (!talloc_reference(req, req->out.buffer)) { + req->state = SMBCLI_REQUEST_ERROR; + req->status = NT_STATUS_NO_MEMORY; + return; + } blob = data_blob_const(req->out.buffer, req->out.size); status = packet_send(req->transport->packet, blob); if (!NT_STATUS_IS_OK(status)) { -- cgit From 872b821fca36bf543f2c3baf1296f25d1cb7e5a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Nov 2005 11:10:40 +0000 Subject: r11636: a bit neater solution to the nt_cancel problem (This used to be commit ba7864b07eebecd4d4eb2ce515412a49964ae179) --- source4/libcli/raw/clitransport.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 6bf79ecfb0..1cd706f11e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -105,6 +105,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, packet_set_full_request(transport->packet, packet_full_request_nbt); packet_set_error_handler(transport->packet, smbcli_transport_error); packet_set_event_context(transport->packet, transport->socket->event.ctx); + packet_set_nofree(transport->packet); smbcli_init_signing(transport); @@ -559,16 +560,6 @@ void smbcli_transport_send(struct smbcli_request *req) return; } - /* put it on the socket queue - * - as the buffer is a part of the smbcli_request struct - * we need to reference it here, because packet_queue_run() - * will call talloc_free() on it - */ - if (!talloc_reference(req, req->out.buffer)) { - req->state = SMBCLI_REQUEST_ERROR; - req->status = NT_STATUS_NO_MEMORY; - return; - } blob = data_blob_const(req->out.buffer, req->out.size); status = packet_send(req->transport->packet, blob); if (!NT_STATUS_IS_OK(status)) { -- cgit From aecff39aacbc7d033330bb25c5a3a39cb65ea2c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Nov 2005 14:16:50 +0000 Subject: r11644: free the buffer when it's not used metze (This used to be commit 16f2d92618a55188d260cadd144281b325cdacda) --- source4/libcli/raw/clitransport.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 1cd706f11e..4fed2ed9a0 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -479,6 +479,8 @@ error: if (req) { DLIST_REMOVE(transport->pending_recv, req); req->state = SMBCLI_REQUEST_ERROR; + } else { + talloc_free(buffer); } return NT_STATUS_OK; } -- cgit From 507286dbcdeeba77e630852257489129e7211b46 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Nov 2005 15:27:27 +0000 Subject: r11647: add smbcli_ prefix metze (This used to be commit 356e7d037cf3fc24844b2efa5071917ea03e6163) --- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 4fed2ed9a0..f579457252 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -356,7 +356,7 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob) vwv = hdr + HDR_VWV; /* see if it could be an oplock break request */ - if (handle_oplock_break(transport, len, hdr, vwv)) { + if (smbcli_handle_oplock_break(transport, len, hdr, vwv)) { talloc_free(buffer); return NT_STATUS_OK; } diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index e01626a15c..33ac9c55b1 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -360,7 +360,7 @@ BOOL smbcli_request_receive_more(struct smbcli_request *req) handle oplock break requests from the server - return True if the request was an oplock break */ -BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const uint8_t *hdr, const uint8_t *vwv) +BOOL smbcli_handle_oplock_break(struct smbcli_transport *transport, uint_t len, const uint8_t *hdr, const uint8_t *vwv) { /* we must be very fussy about what we consider an oplock break to avoid matching readbraw replies */ -- cgit From 3b42d207efccbb31f94626f8fd98379e4a32cc35 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Nov 2005 16:09:44 +0000 Subject: r11649: - add support for ntcancel replies (they only happen in error cases, e.g when you supply an invalid TID or VUID) - as we don't yet understand how to check the smb_signing of this replies, we just ignore the whole packet abartlet,jra,tridge: can someone try to find out how to create and verify the signatures for this replies. what I noticed is that still use the increment by one for the request, and later requests are still generated fine, only the generating and verifying of the ntcancel replies make problems metze (This used to be commit e6eb0fd2c2f45d6f612d74c6b527c7b17094c907) --- source4/libcli/raw/clitransport.c | 3 +++ source4/libcli/raw/libcliraw.h | 3 +++ source4/libcli/raw/rawnotify.c | 43 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index f579457252..2580df4aeb 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -391,6 +391,9 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob) if (req->mid == mid) break; } + /* see if it's a ntcancel reply for the current MID */ + req = smbcli_handle_ntcancel_reply(req, len, hdr); + if (!req) { DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", mid, op)); goto error; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index a853bd177c..dfc4dc37b5 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -231,6 +231,9 @@ struct smbcli_request { /* the sequence number of this packet - used for signing */ uint_t seq_num; + /* list of ntcancel request for this requests */ + struct smbcli_request *ntcancel; + /* set if this is a one-way request, meaning we are not expecting a reply from the server. */ uint_t one_way_request:1; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index e48545419f..1215a93f59 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "dlinklist.h" /**************************************************************************** change notify (async send) @@ -89,6 +90,37 @@ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, return NT_STATUS_OK; } +/**************************************************************************** + handle ntcancel replies from the server, + as the MID of the real reply and the ntcancel reply is the same + we need to do find out to what request the reply belongs +****************************************************************************/ +struct smbcli_request *smbcli_handle_ntcancel_reply(struct smbcli_request *req, + uint_t len, const uint8_t *hdr) +{ + struct smbcli_request *ntcancel; + + if (!req) return req; + + if (!req->ntcancel) return req; + + if (len >= MIN_SMB_SIZE + NBT_HDR_SIZE && + (CVAL(hdr, HDR_FLG) & FLAG_REPLY) && + CVAL(hdr,HDR_COM) == SMBntcancel) { + ntcancel = req->ntcancel; + DLIST_REMOVE(req->ntcancel, ntcancel); + + /* + * TODO: untill we understand how the + * smb_signing works for this case we + * return NULL, to just ignore the packet + */ + /*return ntcancel;*/ + return NULL; + } + + return req; +} /**************************************************************************** Send a NT Cancel request - used to hurry along a pending request. Usually @@ -111,7 +143,18 @@ NTSTATUS smb_raw_ntcancel(struct smbcli_request *oldreq) req->sign_single_increment = 1; req->one_way_request = 1; + /* + * smbcli_request_send() free's oneway requests + * but we want to keep it under oldreq->ntcancel + */ + if (!talloc_reference(oldreq, req)) { + talloc_free(req); + return NT_STATUS_NO_MEMORY; + } + smbcli_request_send(req); + DLIST_ADD_END(oldreq->ntcancel, req, struct smbcli_request *); + return NT_STATUS_OK; } -- cgit From b18ed75a75c111f23701295f31ecf3a117488e00 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 01:38:39 +0000 Subject: r11660: - the libcli/raw/ lib no longer uses the SMBCLI_REQUEST_SEND state, or the associated send queue - fixed negnowait to not watch for the SMBCLI_REQUEST_SEND state (This used to be commit d19235ede5d352d0b0373d204f4357dddde5946f) --- source4/libcli/raw/clitransport.c | 6 ------ source4/libcli/raw/libcliraw.h | 4 ---- 2 files changed, 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 2580df4aeb..2aebb92790 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -520,9 +520,6 @@ static void smbcli_timeout_handler(struct event_context *ev, struct timed_event { struct smbcli_request *req = talloc_get_type(private, struct smbcli_request); - if (req->state == SMBCLI_REQUEST_SEND) { - DLIST_REMOVE(req->transport->pending_send, req); - } if (req->state == SMBCLI_REQUEST_RECV) { DLIST_REMOVE(req->transport->pending_recv, req); } @@ -540,9 +537,6 @@ static void smbcli_timeout_handler(struct event_context *ev, struct timed_event static int smbcli_request_destructor(void *ptr) { struct smbcli_request *req = talloc_get_type(ptr, struct smbcli_request); - if (req->state == SMBCLI_REQUEST_SEND) { - DLIST_REMOVE(req->transport->pending_send, req); - } if (req->state == SMBCLI_REQUEST_RECV) { DLIST_REMOVE(req->transport->pending_recv, req); } diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index dfc4dc37b5..decee83eb7 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -144,9 +144,6 @@ struct smbcli_transport { void *private; } oplock; - /* a list of async requests that are pending for send on this connection */ - struct smbcli_request *pending_send; - /* a list of async requests that are pending for receive on this connection */ struct smbcli_request *pending_recv; @@ -199,7 +196,6 @@ struct smbcli_tree { a client request moves between the following 4 states. */ enum smbcli_request_state {SMBCLI_REQUEST_INIT, /* we are creating the request */ - SMBCLI_REQUEST_SEND, /* the request is in the outgoing socket Q */ SMBCLI_REQUEST_RECV, /* we are waiting for a matching reply */ SMBCLI_REQUEST_DONE, /* the request is finished */ SMBCLI_REQUEST_ERROR}; /* a packet or transport level error has occurred */ -- cgit From ac293f85342a77777c2164a53c8ec43ddc1c1aed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 04:45:38 +0000 Subject: r11662: the beginnings of a SMB2 client library. Very hackish, meant for experimentation (This used to be commit 68422dc73f6ea51bf906f3db223ae8abf077aba1) --- source4/libcli/config.mk | 2 + source4/libcli/smb2/config.mk | 6 + source4/libcli/smb2/negprot.c | 82 ++++++++++++ source4/libcli/smb2/request.c | 171 +++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 154 ++++++++++++++++++++++ source4/libcli/smb2/transport.c | 274 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 689 insertions(+) create mode 100644 source4/libcli/smb2/config.mk create mode 100644 source4/libcli/smb2/negprot.c create mode 100644 source4/libcli/smb2/request.c create mode 100644 source4/libcli/smb2/smb2.h create mode 100644 source4/libcli/smb2/transport.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index ea93b12a03..8417d770b6 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -122,3 +122,5 @@ OBJ_FILES = raw/rawfile.o \ raw/rawdate.o \ raw/rawlpq.o REQUIRED_SUBSYSTEMS = LIBPACKET + +include smb2/config.mk diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk new file mode 100644 index 0000000000..9840876c2f --- /dev/null +++ b/source4/libcli/smb2/config.mk @@ -0,0 +1,6 @@ +[SUBSYSTEM::LIBCLI_SMB2] +OBJ_FILES = \ + transport.o \ + request.o \ + negprot.o +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c new file mode 100644 index 0000000000..6b35373807 --- /dev/null +++ b/source4/libcli/smb2/negprot.c @@ -0,0 +1,82 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client negprot handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" + +/* + send a negprot request +*/ +struct smb2_request *smb2_negprot_send(struct smb2_transport *transport) +{ + struct smb2_request *req; + + req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26); + if (req == NULL) return NULL; + + memset(req->out.body, 0, 0x26); + SIVAL(req->out.body, 0, 0x00010024); /* unknown */ + + smb2_transport_send(req); + + return req; +} + +/* + recv a negprot reply +*/ +NTSTATUS smb2_negprot_recv(struct smb2_request *req) +{ + NTTIME t1, t2; + DATA_BLOB secblob; + struct GUID guid; + NTSTATUS status; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + t1 = smbcli_pull_nttime(req->in.body, 0x28); + t2 = smbcli_pull_nttime(req->in.body, 0x30); + + secblob = smb2_pull_blob(req, req->in.body+0x40, req->in.body_size - 0x40); + status = smb2_pull_guid(req, req->in.body+0x08, &guid); + NT_STATUS_NOT_OK_RETURN(status); + + printf("Negprot reply:\n"); + printf("t1 =%s\n", nt_time_string(req, t1)); + printf("t2 =%s\n", nt_time_string(req, t2)); + printf("guid=%s\n", GUID_string(req, &guid)); + + return smb2_request_destroy(req); +} + +/* + sync negprot request +*/ +NTSTATUS smb2_negprot(struct smb2_transport *transport) +{ + struct smb2_request *req = smb2_negprot_send(transport); + return smb2_negprot_recv(req); +} diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c new file mode 100644 index 0000000000..1b2dc5e64c --- /dev/null +++ b/source4/libcli/smb2/request.c @@ -0,0 +1,171 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client request handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "include/dlinklist.h" +#include "lib/events/events.h" +#include "librpc/gen_ndr/ndr_misc.h" + +/* + initialise a smb2 request +*/ +struct smb2_request *smb2_request_init(struct smb2_transport *transport, + uint16_t opcode, uint32_t body_size) +{ + struct smb2_request *req; + + req = talloc(transport, struct smb2_request); + if (req == NULL) return NULL; + + req->state = SMB2_REQUEST_INIT; + req->transport = transport; + req->seqnum = transport->seqnum++; + req->status = NT_STATUS_OK; + req->async.fn = NULL; + req->next = req->prev = NULL; + + ZERO_STRUCT(req->in); + + req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_size; + req->out.buffer = talloc_size(req, req->out.allocated); + if (req->out.buffer == NULL) { + talloc_free(req); + return NULL; + } + + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE + body_size; + req->out.hdr = req->out.buffer + NBT_HDR_SIZE; + req->out.body = req->out.hdr + SMB2_HDR_BODY; + req->out.body_size = body_size; + req->out.ptr = req->out.body; + + SIVAL(req->out.hdr, 0, SMB2_MAGIC); + SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); + SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); + SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); + SSVAL(req->out.hdr, SMB2_HDR_PAD2, 0); + SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); + SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN, 0); + SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_PID, 0); + SIVAL(req->out.hdr, SMB2_HDR_TID, 0); + SIVAL(req->out.hdr, SMB2_HDR_UID, 0); + SIVAL(req->out.hdr, SMB2_HDR_UID2, 0); + memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + + return req; +} + +/* destroy a request structure and return final status */ +NTSTATUS smb2_request_destroy(struct smb2_request *req) +{ + NTSTATUS status; + + /* this is the error code we give the application for when a + _send() call fails completely */ + if (!req) return NT_STATUS_UNSUCCESSFUL; + + if (req->transport) { + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_recv, req); + } + + if (req->state == SMBCLI_REQUEST_ERROR && + NT_STATUS_IS_OK(req->status)) { + req->status = NT_STATUS_INTERNAL_ERROR; + } + + status = req->status; + talloc_free(req); + return status; +} + +/* + receive a response to a packet +*/ +BOOL smb2_request_receive(struct smb2_request *req) +{ + /* req can be NULL when a send has failed. This eliminates lots of NULL + checks in each module */ + if (!req) return False; + + /* keep receiving packets until this one is replied to */ + while (req->state <= SMB2_REQUEST_RECV) { + if (event_loop_once(req->transport->socket->event.ctx) != 0) { + return False; + } + } + + return req->state == SMB2_REQUEST_DONE; +} + +/* Return true if the last packet was in error */ +BOOL smb2_request_is_error(struct smb2_request *req) +{ + return NT_STATUS_IS_ERR(req->status); +} + +/* + check if a range in the reply body is out of bounds +*/ +BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size) +{ + /* be careful with wraparound! */ + if (ptr < req->in.body || + ptr >= req->in.body + req->in.body_size || + size > req->in.body_size || + ptr + size > req->in.body + req->in.body_size) { + return True; + } + return False; +} + +/* + pull a data blob from the body of a reply +*/ +DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) +{ + if (smb2_oob(req, ptr, size)) { + return data_blob(NULL, 0); + } + return data_blob_talloc(req, ptr, size); +} + +/* + pull a guid from the reply body +*/ +NTSTATUS smb2_pull_guid(struct smb2_request *req, uint8_t *ptr, struct GUID *guid) +{ + NTSTATUS status; + DATA_BLOB blob = smb2_pull_blob(req, ptr, 16); + if (blob.data == NULL) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + status = ndr_pull_struct_blob(&blob, req, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + data_blob_free(&blob); + return status; +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h new file mode 100644 index 0000000000..2e01159355 --- /dev/null +++ b/source4/libcli/smb2/smb2.h @@ -0,0 +1,154 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client library header + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +struct smb2_options { + uint32_t timeout; +}; + +/* + information returned from the negotiate response +*/ +struct smb2_negotiate { + DATA_BLOB secblob; + +}; + +/* this is the context for the smb2 transport layer */ +struct smb2_transport { + /* socket level info */ + struct smbcli_socket *socket; + + struct smb2_options options; + struct smb2_negotiate negotiate; + + /* next seqnum to allocate */ + uint64_t seqnum; + + /* a list of requests that are pending for receive on this + connection */ + struct smb2_request *pending_recv; + + /* context of the stream -> packet parser */ + struct packet_context *packet; +}; + + +struct smb2_request_buffer { + /* the raw SMB2 buffer, including the 4 byte length header */ + uint8_t *buffer; + + /* the size of the raw buffer, including 4 byte header */ + uint_t size; + + /* how much has been allocated - on reply the buffer is over-allocated to + prevent too many realloc() calls + */ + uint_t allocated; + + /* the start of the SMB2 header - this is always buffer+4 */ + uint8_t *hdr; + + /* the packet body */ + uint8_t *body; + uint_t body_size; + + /* ptr is used as a moving pointer into the data area + * of the packet. The reason its here and not a local + * variable in each function is that when a realloc of + * a send packet is done we need to move this + * pointer */ + uint8_t *ptr; +}; + + +/* + a client request moves between the following 4 states. +*/ +enum smb2_request_state {SMB2_REQUEST_INIT, /* we are creating the request */ + SMB2_REQUEST_RECV, /* we are waiting for a matching reply */ + SMB2_REQUEST_DONE, /* the request is finished */ + SMB2_REQUEST_ERROR}; /* a packet or transport level error has occurred */ + +/* the context for a single SMB2 request */ +struct smb2_request { + /* allow a request to be part of a list of requests */ + struct smb2_request *next, *prev; + + /* each request is in one of 3 possible states */ + enum smb2_request_state state; + + struct smb2_transport *transport; + + uint64_t seqnum; + + /* the NT status for this request. Set by packet receive code + or code detecting error. */ + NTSTATUS status; + + struct smb2_request_buffer in; + struct smb2_request_buffer out; + + /* information on what to do with a reply when it is received + asyncronously. If this is not setup when a reply is received then + the reply is discarded + + The private pointer is private to the caller of the client + library (the application), not private to the library + */ + struct { + void (*fn)(struct smb2_request *); + void *private; + } async; +}; + + +#define SMB2_MIN_SIZE 0x40 + +/* offsets into header elements */ +#define SMB2_HDR_LENGTH 0x04 +#define SMB2_HDR_PAD1 0x06 +#define SMB2_HDR_STATUS 0x08 +#define SMB2_HDR_OPCODE 0x0c +#define SMB2_HDR_PAD2 0x0e +#define SMB2_HDR_FLAGS 0x10 +#define SMB2_HDR_UNKNOWN 0x14 +#define SMB2_HDR_SEQNUM 0x18 +#define SMB2_HDR_PID 0x20 +#define SMB2_HDR_TID 0x24 +#define SMB2_HDR_UID 0x28 +#define SMB2_HDR_UID2 0x2c /* whats this? */ +#define SMB2_HDR_SIG 0x30 /* guess ... */ +#define SMB2_HDR_BODY 0x40 + +/* SMB2 opcodes */ +#define SMB2_OP_NEGPROT 0x00 +#define SMB2_OP_SESSSETUP 0x01 +#define SMB2_OP_TCON 0x03 +#define SMB2_OP_TDIS 0x04 +#define SMB2_OP_CREATE 0x05 +#define SMB2_OP_CLOSE 0x06 +#define SMB2_OP_READ 0x08 +#define SMB2_OP_WRITE 0x09 +#define SMB2_OP_FIND 0x0e + +#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ + diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c new file mode 100644 index 0000000000..a178b35f93 --- /dev/null +++ b/source4/libcli/smb2/transport.c @@ -0,0 +1,274 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client transport context management functions + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "lib/socket/socket.h" +#include "lib/events/events.h" +#include "lib/stream/packet.h" +#include "include/dlinklist.h" + + +/* + an event has happened on the socket +*/ +static void smb2_transport_event_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, void *private) +{ + struct smb2_transport *transport = talloc_get_type(private, + struct smb2_transport); + if (flags & EVENT_FD_READ) { + packet_recv(transport->packet); + return; + } + if (flags & EVENT_FD_WRITE) { + packet_queue_run(transport->packet); + } +} + +/* + destroy a transport + */ +static int transport_destructor(void *ptr) +{ + struct smb2_transport *transport = ptr; + smb2_transport_dead(transport); + return 0; +} + + +/* + handle receive errors +*/ +static void smb2_transport_error(void *private, NTSTATUS status) +{ + struct smb2_transport *transport = talloc_get_type(private, + struct smb2_transport); + smb2_transport_dead(transport); +} + +static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob); + +/* + create a transport structure based on an established socket +*/ +struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, + TALLOC_CTX *parent_ctx) +{ + struct smb2_transport *transport; + + transport = talloc_zero(parent_ctx, struct smb2_transport); + if (!transport) return NULL; + + transport->socket = talloc_steal(transport, sock); + + /* setup the stream -> packet parser */ + transport->packet = packet_init(transport); + if (transport->packet == NULL) { + talloc_free(transport); + return NULL; + } + packet_set_private(transport->packet, transport); + packet_set_socket(transport->packet, transport->socket->sock); + packet_set_callback(transport->packet, smb2_transport_finish_recv); + packet_set_full_request(transport->packet, packet_full_request_nbt); + packet_set_error_handler(transport->packet, smb2_transport_error); + packet_set_event_context(transport->packet, transport->socket->event.ctx); + packet_set_nofree(transport->packet); + + /* take over event handling from the socket layer - it only + handles events up until we are connected */ + talloc_free(transport->socket->event.fde); + transport->socket->event.fde = event_add_fd(transport->socket->event.ctx, + transport->socket, + socket_get_fd(transport->socket->sock), + EVENT_FD_READ, + smb2_transport_event_handler, + transport); + + packet_set_serialise(transport->packet, transport->socket->event.fde); + + talloc_set_destructor(transport, transport_destructor); + + transport->options.timeout = 30; + + return transport; +} + +/* + mark the transport as dead +*/ +void smb2_transport_dead(struct smb2_transport *transport) +{ + smbcli_sock_dead(transport->socket); + + /* kill all pending receives */ + while (transport->pending_recv) { + struct smb2_request *req = transport->pending_recv; + req->state = SMB2_REQUEST_ERROR; + req->status = NT_STATUS_NET_WRITE_FAULT; + DLIST_REMOVE(transport->pending_recv, req); + if (req->async.fn) { + req->async.fn(req); + } + } +} + +/* + we have a full request in our receive buffer - match it to a pending request + and process + */ +static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) +{ + struct smb2_transport *transport = talloc_get_type(private, + struct smb2_transport); + uint8_t *buffer, *hdr; + int len; + struct smb2_request *req; + uint64_t seqnum; + + buffer = blob.data; + len = blob.length; + + hdr = buffer+NBT_HDR_SIZE; + + if (len < SMB2_MIN_SIZE) { + DEBUG(1,("Discarding smb2 reply of size %d\n", len)); + goto error; + } + + seqnum = BVAL(hdr, SMB2_HDR_SEQNUM); + + /* match the incoming request against the list of pending requests */ + for (req=transport->pending_recv; req; req=req->next) { + if (req->seqnum == seqnum) break; + } + + if (!req) { + DEBUG(1,("Discarding unmatched reply with seqnum 0x%llx op %d\n", + seqnum, SVAL(hdr, SMB2_HDR_OPCODE))); + goto error; + } + + /* fill in the 'in' portion of the matching request */ + req->in.buffer = buffer; + talloc_steal(req, buffer); + req->in.size = len; + req->in.allocated = req->in.size; + + req->in.hdr = hdr; + req->in.body = hdr+SMB2_HDR_BODY; + req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); + req->in.ptr = req->in.body; + req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); + + /* if this request has an async handler then call that to + notify that the reply has been received. This might destroy + the request so it must happen last */ + DLIST_REMOVE(transport->pending_recv, req); + req->state = SMB2_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + return NT_STATUS_OK; + +error: + if (req) { + DLIST_REMOVE(transport->pending_recv, req); + req->state = SMB2_REQUEST_ERROR; + } + dump_data(0, blob.data, blob.length); + data_blob_free(&blob); + return NT_STATUS_UNSUCCESSFUL; +} + +/* + handle timeouts of individual smb requests +*/ +static void smb2_timeout_handler(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct smb2_request *req = talloc_get_type(private, struct smb2_request); + + if (req->state == SMB2_REQUEST_RECV) { + DLIST_REMOVE(req->transport->pending_recv, req); + } + req->status = NT_STATUS_IO_TIMEOUT; + req->state = SMB2_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + destroy a request +*/ +static int smb2_request_destructor(void *ptr) +{ + struct smb2_request *req = talloc_get_type(ptr, struct smb2_request); + if (req->state == SMB2_REQUEST_RECV) { + DLIST_REMOVE(req->transport->pending_recv, req); + } + return 0; +} + + +/* + put a request into the send queue +*/ +void smb2_transport_send(struct smb2_request *req) +{ + DATA_BLOB blob; + NTSTATUS status; + + _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); + + /* check if the transport is dead */ + if (req->transport->socket->sock == NULL) { + req->state = SMB2_REQUEST_ERROR; + req->status = NT_STATUS_NET_WRITE_FAULT; + return; + } + + blob = data_blob_const(req->out.buffer, req->out.size); + status = packet_send(req->transport->packet, blob); + if (!NT_STATUS_IS_OK(status)) { + req->state = SMB2_REQUEST_ERROR; + req->status = status; + return; + } + + req->state = SMB2_REQUEST_RECV; + DLIST_ADD(req->transport->pending_recv, req); + + /* add a timeout */ + if (req->transport->options.timeout) { + event_add_timed(req->transport->socket->event.ctx, req, + timeval_current_ofs(req->transport->options.timeout, 0), + smb2_timeout_handler, req); + } + + talloc_set_destructor(req, smb2_request_destructor); +} -- cgit From 555b45e12c281eb3980d15b12728c59c6b73c302 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 05:53:54 +0000 Subject: r11665: started to put some meat on the structure used for the SMB2 library the call definitions will be in smb2_calls.h, which will play a similar role that smb_interfaces.h plays for the old SMB protocol (This used to be commit 4ef3902a8a99a0b8caa81a07ba07830d7cbbc32c) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/negprot.c | 53 +++++++++++++++++++-------------- source4/libcli/smb2/request.c | 16 ---------- source4/libcli/smb2/session.c | 47 ++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 8 ++++- source4/libcli/smb2/smb2_calls.h | 63 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/transport.c | 2 ++ 7 files changed, 153 insertions(+), 39 deletions(-) create mode 100644 source4/libcli/smb2/session.c create mode 100644 source4/libcli/smb2/smb2_calls.h (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 9840876c2f..4879dfb5df 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -2,5 +2,6 @@ OBJ_FILES = \ transport.o \ request.o \ - negprot.o + negprot.o \ + session.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 6b35373807..ffddf8a2f0 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -23,19 +23,23 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* send a negprot request */ -struct smb2_request *smb2_negprot_send(struct smb2_transport *transport) +struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, + struct smb2_negprot *io) { struct smb2_request *req; + req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26); if (req == NULL) return NULL; - memset(req->out.body, 0, 0x26); - SIVAL(req->out.body, 0, 0x00010024); /* unknown */ + SIVAL(req->out.body, 0x00, io->in.unknown1); + SSVAL(req->out.body, 0x04, io->in.unknown2); + memcpy(req->out.body+0x06, io->in.unknown3, 32); smb2_transport_send(req); @@ -45,29 +49,35 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport) /* recv a negprot reply */ -NTSTATUS smb2_negprot_recv(struct smb2_request *req) +NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + struct smb2_negprot *io) { - NTTIME t1, t2; - DATA_BLOB secblob; - struct GUID guid; - NTSTATUS status; + uint16_t blobsize; if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } - t1 = smbcli_pull_nttime(req->in.body, 0x28); - t2 = smbcli_pull_nttime(req->in.body, 0x30); - - secblob = smb2_pull_blob(req, req->in.body+0x40, req->in.body_size - 0x40); - status = smb2_pull_guid(req, req->in.body+0x08, &guid); - NT_STATUS_NOT_OK_RETURN(status); + if (req->in.body_size < 0x40) { + return NT_STATUS_BUFFER_TOO_SMALL; + } - printf("Negprot reply:\n"); - printf("t1 =%s\n", nt_time_string(req, t1)); - printf("t2 =%s\n", nt_time_string(req, t2)); - printf("guid=%s\n", GUID_string(req, &guid)); + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = IVAL(req->in.body, 0x04); + memcpy(io->out.sessid, req->in.body + 0x08, 16); + io->out.unknown3 = IVAL(req->in.body, 0x18); + io->out.unknown4 = SVAL(req->in.body, 0x1C); + io->out.unknown5 = IVAL(req->in.body, 0x1E); + io->out.unknown6 = IVAL(req->in.body, 0x22); + io->out.unknown7 = SVAL(req->in.body, 0x26); + io->out.current_time = smbcli_pull_nttime(req->in.body, 0x28); + io->out.boot_time = smbcli_pull_nttime(req->in.body, 0x30); + io->out.unknown8 = SVAL(req->in.body, 0x38); + blobsize = SVAL(req->in.body, 0x3A); + io->out.unknown9 = IVAL(req->in.body, 0x3C); + io->out.secblob = smb2_pull_blob(req, req->in.body+0x40, blobsize); + talloc_steal(mem_ctx, io->out.secblob.data); return smb2_request_destroy(req); } @@ -75,8 +85,9 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req) /* sync negprot request */ -NTSTATUS smb2_negprot(struct smb2_transport *transport) +NTSTATUS smb2_negprot(struct smb2_transport *transport, + TALLOC_CTX *mem_ctx, struct smb2_negprot *io) { - struct smb2_request *req = smb2_negprot_send(transport); - return smb2_negprot_recv(req); + struct smb2_request *req = smb2_negprot_send(transport, io); + return smb2_negprot_recv(req, mem_ctx, io); } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1b2dc5e64c..e71fc84471 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -25,7 +25,6 @@ #include "libcli/smb2/smb2.h" #include "include/dlinklist.h" #include "lib/events/events.h" -#include "librpc/gen_ndr/ndr_misc.h" /* initialise a smb2 request @@ -154,18 +153,3 @@ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) return data_blob_talloc(req, ptr, size); } -/* - pull a guid from the reply body -*/ -NTSTATUS smb2_pull_guid(struct smb2_request *req, uint8_t *ptr, struct GUID *guid) -{ - NTSTATUS status; - DATA_BLOB blob = smb2_pull_blob(req, ptr, 16); - if (blob.data == NULL) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - status = ndr_pull_struct_blob(&blob, req, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - data_blob_free(&blob); - return status; -} diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c new file mode 100644 index 0000000000..23fed70e17 --- /dev/null +++ b/source4/libcli/smb2/session.c @@ -0,0 +1,47 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client session handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" + +/* + initialise a smb2_session structure + */ +struct smb2_session *smb2_session_init(struct smb2_transport *transport, + TALLOC_CTX *parent_ctx, BOOL primary) +{ + struct smb2_session *session; + + session = talloc_zero(parent_ctx, struct smb2_session); + if (!session) { + return NULL; + } + if (primary) { + session->transport = talloc_steal(session, transport); + } else { + session->transport = talloc_reference(session, transport); + } + + return session; +} + diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 2e01159355..79b983206a 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -29,7 +29,6 @@ struct smb2_options { */ struct smb2_negotiate { DATA_BLOB secblob; - }; /* this is the context for the smb2 transport layer */ @@ -52,6 +51,13 @@ struct smb2_transport { }; +/* + SMB2 session context +*/ +struct smb2_session { + struct smb2_transport *transport; +}; + struct smb2_request_buffer { /* the raw SMB2 buffer, including the 4 byte length header */ uint8_t *buffer; diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h new file mode 100644 index 0000000000..ef0abc3e45 --- /dev/null +++ b/source4/libcli/smb2/smb2_calls.h @@ -0,0 +1,63 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client calls + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + + +struct smb2_negprot { + struct { + uint32_t unknown1; /* 0x00010024 */ + uint16_t unknown2; /* 0x00 */ + uint8_t unknown3[32]; /* all zero */ + } in; + struct { + uint32_t unknown1; /* 0x41 */ + uint32_t unknown2; /* 0x06 */ + uint8_t sessid[16]; + uint32_t unknown3; /* 0x0d */ + uint16_t unknown4; /* 0x00 */ + uint32_t unknown5; /* 0x01 */ + uint32_t unknown6; /* 0x01 */ + uint16_t unknown7; /* 0x01 */ + NTTIME current_time; + NTTIME boot_time; + uint16_t unknown8; /* 0x80 */ + /* uint16_t secblob size here */ + uint32_t unknown9; /* 0x204d4c20 */ + DATA_BLOB secblob; + } out; +}; + +struct smb2_session_setup { + struct { + uint32_t unknown1; /* 0x11 */ + uint32_t unknown2; /* 0xF */ + uint32_t unknown3; /* 0x00 */ + uint16_t unknown4; /* 0x50 */ + /* uint16_t secblob size here */ + DATA_BLOB secblob; + } in; + struct { + uint32_t unknown1; /* 0x09 */ + uint16_t unknown2; /* 0x48 */ + /* uint16_t secblob size here */ + DATA_BLOB secblob; + } out; +}; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index a178b35f93..dd05eed1dd 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -183,6 +183,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.ptr = req->in.body; req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); + dump_data(0, req->in.body, req->in.body_size); + /* if this request has an async handler then call that to notify that the reply has been received. This might destroy the request so it must happen last */ -- cgit From 86c1370cb03a244fd5644d30732a1fbda762fe6a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 06:26:42 +0000 Subject: r11666: filled in the basic session setup. Vista happily accepts the first stage of the session setup, and waits for more. (This used to be commit 804c229c3ba7f866a7f3d66684e268d5ddc820ce) --- source4/libcli/smb2/session.c | 70 +++++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 1 + 2 files changed, 71 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 23fed70e17..2f9a979fea 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* initialise a smb2_session structure @@ -31,6 +32,7 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, TALLOC_CTX *parent_ctx, BOOL primary) { struct smb2_session *session; + NTSTATUS status; session = talloc_zero(parent_ctx, struct smb2_session); if (!session) { @@ -42,6 +44,74 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, session->transport = talloc_reference(session, transport); } + /* prepare a gensec context for later use */ + status = gensec_client_start(session, &session->gensec, + session->transport->socket->event.ctx); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(session); + return NULL; + } + return session; } +/* + send a session setup request +*/ +struct smb2_request *smb2_session_setup_send(struct smb2_session *session, + struct smb2_session_setup *io) +{ + struct smb2_request *req; + + req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, + 0x10 + io->in.secblob.length); + if (req == NULL) return NULL; + + SIVAL(req->out.body, 0x00, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.unknown2); + SIVAL(req->out.body, 0x08, io->in.unknown3); + SSVAL(req->out.body, 0x0C, io->in.unknown4); + SSVAL(req->out.body, 0x0E, io->in.secblob.length); + memcpy(req->out.body+0x10, io->in.secblob.data, io->in.secblob.length); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a session setup reply +*/ +NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + struct smb2_session_setup *io) +{ + uint16_t blobsize; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x08) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = SVAL(req->in.body, 0x04); + blobsize = SVAL(req->in.body, 0x06); + io->out.secblob = smb2_pull_blob(req, req->in.body+0x08, blobsize); + talloc_steal(mem_ctx, io->out.secblob.data); + + return smb2_request_destroy(req); +} + +/* + sync session setup request +*/ +NTSTATUS smb2_session_setup(struct smb2_session *session, + TALLOC_CTX *mem_ctx, struct smb2_session_setup *io) +{ + struct smb2_request *req = smb2_session_setup_send(session, io); + return smb2_session_setup_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 79b983206a..2262040b51 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -56,6 +56,7 @@ struct smb2_transport { */ struct smb2_session { struct smb2_transport *transport; + struct gensec_security *gensec; }; struct smb2_request_buffer { -- cgit From 7a78d2d6b083fbd408c766116693d01b57628f28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 07:23:45 +0000 Subject: r11668: yay! we get a successful session setup with SMB2, and get back a 64bit uid (This used to be commit 72b34a7c1b66af6be02f66639efc55a19c73e387) --- source4/libcli/smb2/negprot.c | 1 - source4/libcli/smb2/request.c | 56 ++++++++++++++++++++++++++++++++++++++-- source4/libcli/smb2/session.c | 28 +++++++++++++------- source4/libcli/smb2/smb2.h | 4 +-- source4/libcli/smb2/smb2_calls.h | 7 +++-- source4/libcli/smb2/transport.c | 8 ++++-- 6 files changed, 84 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index ffddf8a2f0..5cd4810909 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -33,7 +33,6 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, { struct smb2_request *req; - req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26); if (req == NULL) return NULL; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index e71fc84471..93f8043d0c 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -130,7 +130,7 @@ BOOL smb2_request_is_error(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size) +BOOL smb2_oob_in(struct smb2_request *req, const uint8_t *ptr, uint_t size) { /* be careful with wraparound! */ if (ptr < req->in.body || @@ -142,14 +142,66 @@ BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size) return False; } +/* + check if a range in the outgoing body is out of bounds +*/ +BOOL smb2_oob_out(struct smb2_request *req, const uint8_t *ptr, uint_t size) +{ + /* be careful with wraparound! */ + if (ptr < req->out.body || + ptr >= req->out.body + req->out.body_size || + size > req->out.body_size || + ptr + size > req->out.body + req->out.body_size) { + return True; + } + return False; +} + /* pull a data blob from the body of a reply */ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) { - if (smb2_oob(req, ptr, size)) { + if (smb2_oob_in(req, ptr, size)) { return data_blob(NULL, 0); } return data_blob_talloc(req, ptr, size); } +/* + pull a ofs/length/blob triple into a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob) +{ + uint16_t ofs, size; + if (smb2_oob_in(req, ptr, 4)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = SVAL(ptr, 0); + size = SVAL(ptr, 2); + if (smb2_oob_in(req, req->in.hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(req, req->in.hdr+ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; +} + +/* + push a ofs/length/blob triple into a data blob + the ptr points to the start of the offset/length pair + + NOTE: assumes blob goes immediately after the offset/length pair. Needs + to be generalised +*/ +NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB blob) +{ + if (smb2_oob_out(req, ptr, 4+blob.length)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + SSVAL(ptr, 0, 4 + (ptr - req->out.hdr)); + SSVAL(ptr, 2, blob.length); + memcpy(ptr+4, blob.data, blob.length); + return NT_STATUS_OK; +} diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 2f9a979fea..031360fcb9 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -62,17 +62,22 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, struct smb2_session_setup *io) { struct smb2_request *req; + NTSTATUS status; req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, 0x10 + io->in.secblob.length); if (req == NULL) return NULL; + SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); SIVAL(req->out.body, 0x00, io->in.unknown1); SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3); - SSVAL(req->out.body, 0x0C, io->in.unknown4); - SSVAL(req->out.body, 0x0E, io->in.secblob.length); - memcpy(req->out.body+0x10, io->in.secblob.data, io->in.secblob.length); + + status = smb2_push_ofs_blob(req, req->out.body+0x0C, io->in.secblob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } smb2_transport_send(req); @@ -86,10 +91,11 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_session_setup *io) { - uint16_t blobsize; + NTSTATUS status; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + (smb2_request_is_error(req) && + !NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { return smb2_request_destroy(req); } @@ -97,10 +103,14 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = SVAL(req->in.body, 0x04); - blobsize = SVAL(req->in.body, 0x06); - io->out.secblob = smb2_pull_blob(req, req->in.body+0x08, blobsize); + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); + + status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } talloc_steal(mem_ctx, io->out.secblob.data); return smb2_request_destroy(req); diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 2262040b51..8ed51b2351 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -57,6 +57,7 @@ struct smb2_transport { struct smb2_session { struct smb2_transport *transport; struct gensec_security *gensec; + uint64_t uid; }; struct smb2_request_buffer { @@ -141,8 +142,7 @@ struct smb2_request { #define SMB2_HDR_SEQNUM 0x18 #define SMB2_HDR_PID 0x20 #define SMB2_HDR_TID 0x24 -#define SMB2_HDR_UID 0x28 -#define SMB2_HDR_UID2 0x2c /* whats this? */ +#define SMB2_HDR_UID 0x28 /* 64 bit */ #define SMB2_HDR_SIG 0x30 /* guess ... */ #define SMB2_HDR_BODY 0x40 diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index ef0abc3e45..3ee8f90bc9 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -50,14 +50,13 @@ struct smb2_session_setup { uint32_t unknown1; /* 0x11 */ uint32_t unknown2; /* 0xF */ uint32_t unknown3; /* 0x00 */ - uint16_t unknown4; /* 0x50 */ - /* uint16_t secblob size here */ + /* uint16_t secblob ofs/size here */ DATA_BLOB secblob; } in; struct { uint32_t unknown1; /* 0x09 */ - uint16_t unknown2; /* 0x48 */ - /* uint16_t secblob size here */ + /* uint16_t secblob ofs/size here */ DATA_BLOB secblob; + uint64_t uid; /* returned in header */ } out; }; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index dd05eed1dd..97408b2ae3 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -183,7 +183,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.ptr = req->in.body; req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); - dump_data(0, req->in.body, req->in.body_size); + DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", req->seqnum)); + dump_data(2, req->in.body, req->in.body_size); /* if this request has an async handler then call that to notify that the reply has been received. This might destroy @@ -200,7 +201,7 @@ error: DLIST_REMOVE(transport->pending_recv, req); req->state = SMB2_REQUEST_ERROR; } - dump_data(0, blob.data, blob.length); + dump_data(2, blob.data, blob.length); data_blob_free(&blob); return NT_STATUS_UNSUCCESSFUL; } @@ -247,6 +248,9 @@ void smb2_transport_send(struct smb2_request *req) _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); + DEBUG(2, ("SMB2 send seqnum=0x%llx\n", req->seqnum)); + dump_data(2, req->out.body, req->out.body_size); + /* check if the transport is dead */ if (req->transport->socket->sock == NULL) { req->state = SMB2_REQUEST_ERROR; -- cgit From 3015c6ba0435c9e99c202890e50187db891d761d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Nov 2005 07:38:25 +0000 Subject: r11669: - make sure req is initialized - call async callback on error metze (This used to be commit 43aa5cffd3fd8bf07b236a039f5146e1e44296c6) --- source4/libcli/raw/clitransport.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 2aebb92790..fba6c36bbe 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -347,7 +347,7 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob) uint8_t *buffer, *hdr, *vwv; int len; uint16_t wct=0, mid = 0, op = 0; - struct smbcli_request *req; + struct smbcli_request *req = NULL; buffer = blob.data; len = blob.length; @@ -482,6 +482,9 @@ error: if (req) { DLIST_REMOVE(transport->pending_recv, req); req->state = SMBCLI_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } } else { talloc_free(buffer); } -- cgit From d9d90e105b493cfb7676eb65af4456dfb572a5b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Nov 2005 08:00:05 +0000 Subject: r11670: fix the build metze (This used to be commit c0eebe293f341dcf35229c2cbbc3029f6f853abb) --- source4/libcli/smb2/request.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 93f8043d0c..28e7018ecc 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -70,8 +70,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SIVAL(req->out.hdr, SMB2_HDR_UID, 0); - SIVAL(req->out.hdr, SMB2_HDR_UID2, 0); + SBVAL(req->out.hdr, SMB2_HDR_UID, (uint64_t)0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); return req; -- cgit From 5f58c67b8265adaeb386d718c8f7fe86807115fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Nov 2005 08:00:51 +0000 Subject: r11671: - make sure req is initialized - only free the buffer when there's no request - call async callback on error metze (This used to be commit 2084d62dd54c230c6494e482cb346b3ea959e6fb) --- source4/libcli/smb2/transport.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 97408b2ae3..9940379f98 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -145,7 +145,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) struct smb2_transport); uint8_t *buffer, *hdr; int len; - struct smb2_request *req; + struct smb2_request *req = NULL; uint64_t seqnum; buffer = blob.data; @@ -197,12 +197,16 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) return NT_STATUS_OK; error: + dump_data(2, buffer, len); if (req) { DLIST_REMOVE(transport->pending_recv, req); req->state = SMB2_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } else { + talloc_free(buffer); } - dump_data(2, blob.data, blob.length); - data_blob_free(&blob); return NT_STATUS_UNSUCCESSFUL; } @@ -210,7 +214,7 @@ error: handle timeouts of individual smb requests */ static void smb2_timeout_handler(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) + struct timeval t, void *private) { struct smb2_request *req = talloc_get_type(private, struct smb2_request); -- cgit From 3e54c36fa459ec6f5e721b90ce4e4c1d0e31d85c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 09:11:51 +0000 Subject: r11674: SMB2 tree connect now works. We do 2 session setups and 2 tree connects, giving the following output: Running SMB2-CONNECT Negprot reply: current_time = Fri Nov 11 20:10:42 2005 EST boot_time = Sat Nov 12 10:34:33 2005 EST Session setup gave UID 0x40000000071 Session setup gave UID 0x140000000075 Tree connect gave tid = 0x7500000001 Tree connect gave tid = 0x7500000005 SMB2-CONNECT took 0.049024 secs (This used to be commit a24a4c311005dec4c5638e9c7c10e5e2f9872f4d) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/request.c | 37 +++++++++++++ source4/libcli/smb2/smb2.h | 9 ++++ source4/libcli/smb2/smb2_calls.h | 14 +++++ source4/libcli/smb2/tcon.c | 112 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/tcon.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 4879dfb5df..63cb6c6140 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -3,5 +3,6 @@ OBJ_FILES = \ transport.o \ request.o \ negprot.o \ - session.o + session.o \ + tcon.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 28e7018ecc..deadd1794f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -204,3 +204,40 @@ NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB bl memcpy(ptr+4, blob.data, blob.length); return NT_STATUS_OK; } + +/* + pull a string in a ofs/length/blob format +*/ +NTSTATUS smb2_pull_ofs_string(struct smb2_request *req, uint8_t *ptr, + const char **str) +{ + DATA_BLOB blob; + NTSTATUS status; + ssize_t size; + void *vstr; + status = smb2_pull_ofs_blob(req, ptr, &blob); + NT_STATUS_NOT_OK_RETURN(status); + size = convert_string_talloc(req, CH_UTF16, CH_UNIX, + blob.data, blob.length, &vstr); + data_blob_free(&blob); + (*str) = vstr; + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + return NT_STATUS_OK; +} + +/* + create a UTF16 string in a blob from a char* +*/ +NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) +{ + ssize_t size; + size = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, + str, strlen(str), (void **)&blob->data); + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + blob->length = size; + return NT_STATUS_OK; +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 8ed51b2351..353f9687d7 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -51,6 +51,14 @@ struct smb2_transport { }; +/* + SMB2 tree context +*/ +struct smb2_tree { + struct smb2_session *session; + uint64_t tid; +}; + /* SMB2 session context */ @@ -60,6 +68,7 @@ struct smb2_session { uint64_t uid; }; + struct smb2_request_buffer { /* the raw SMB2 buffer, including the 4 byte length header */ uint8_t *buffer; diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 3ee8f90bc9..523f314cbf 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -60,3 +60,17 @@ struct smb2_session_setup { uint64_t uid; /* returned in header */ } out; }; + +struct smb2_tree_connect { + struct { + uint32_t unknown1; /* 0x09 */ + const char *path; + } in; + struct { + uint32_t unknown1; /* 0x00020010 */ + uint32_t unknown2; /* 0x00 */ + uint32_t unknown3; /* 0x00 */ + uint32_t unknown4; /* 0x1f01ff */ /* capabilities?? */ + uint64_t tid; + } out; +}; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c new file mode 100644 index 0000000000..7b13750cfe --- /dev/null +++ b/source4/libcli/smb2/tcon.c @@ -0,0 +1,112 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client tree handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + initialise a smb2_session structure + */ +struct smb2_tree *smb2_tree_init(struct smb2_session *session, + TALLOC_CTX *parent_ctx, BOOL primary) +{ + struct smb2_tree *tree; + + tree = talloc_zero(parent_ctx, struct smb2_tree); + if (!session) { + return NULL; + } + if (primary) { + tree->session = talloc_steal(tree, session); + } else { + tree->session = talloc_reference(tree, session); + } + return tree; +} + +/* + send a tree connect +*/ +struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, + struct smb2_tree_connect *io) +{ + struct smb2_request *req; + NTSTATUS status; + DATA_BLOB path; + + status = smb2_string_blob(tree, io->in.path, &path); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + + req = smb2_request_init(tree->session->transport, SMB2_OP_TCON, + 0x8 + path.length); + if (req == NULL) return NULL; + + SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SIVAL(req->out.body, 0x00, io->in.unknown1); + status = smb2_push_ofs_blob(req, req->out.body+0x04, path); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + + smb2_transport_send(req); + + return req; +} + + +/* + recv a tree connect reply +*/ +NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_connect *io) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x10) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.tid = BVAL(req->in.hdr, SMB2_HDR_TID); + + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.unknown3 = IVAL(req->in.body, 0x08); + io->out.unknown4 = IVAL(req->in.body, 0x0C); + + return smb2_request_destroy(req); +} + +/* + sync session setup request +*/ +NTSTATUS smb2_tree_connect(struct smb2_tree *tree, struct smb2_tree_connect *io) +{ + struct smb2_request *req = smb2_tree_connect_send(tree, io); + return smb2_tree_connect_recv(req, io); +} -- cgit From 7935df168f4e98e5d3da352ea555883b0be8bbd3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Nov 2005 10:46:31 +0000 Subject: r11675: a more general way of getting rid of compiler warnings and errors metze (This used to be commit 653f5ccd61f2555bbd49b81c5cc660962b31aa68) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index deadd1794f..7e25de99a8 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -70,7 +70,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SBVAL(req->out.hdr, SMB2_HDR_UID, (uint64_t)0); + SBVAL(req->out.hdr, SMB2_HDR_UID, 0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); return req; -- cgit From 2e753f851885930000eadbd4b69660d85124c716 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 12:37:16 +0000 Subject: r11679: opening/creating files in SMB2 now works. Lots of unknown parameters in the call tho. (This used to be commit 548fbd86b3b114493943b50669bdcba2f4ed87f2) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/create.c | 124 +++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/request.c | 16 +++++ source4/libcli/smb2/smb2.h | 2 +- source4/libcli/smb2/smb2_calls.h | 47 ++++++++++++++- source4/libcli/smb2/tcon.c | 5 +- 6 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 source4/libcli/smb2/create.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 63cb6c6140..f3acd06955 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -4,5 +4,6 @@ OBJ_FILES = \ request.o \ negprot.o \ session.o \ - tcon.o + tcon.o \ + create.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c new file mode 100644 index 0000000000..dbb4d4b974 --- /dev/null +++ b/source4/libcli/smb2/create.c @@ -0,0 +1,124 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client tree handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a create request +*/ +struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create *io) +{ + struct smb2_request *req; + NTSTATUS status; + DATA_BLOB path; + uint8_t *ptr; + + status = smb2_string_blob(tree, io->in.fname, &path); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length); + if (req == NULL) return NULL; + + SIVAL(req->out.body, 0x00, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.unknown2); + SIVAL(req->out.body, 0x08, io->in.unknown3[0]); + SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); + SIVAL(req->out.body, 0x10, io->in.unknown3[2]); + SIVAL(req->out.body, 0x14, io->in.unknown3[3]); + SIVAL(req->out.body, 0x18, io->in.access_mask); + SIVAL(req->out.body, 0x1C, io->in.file_attr); + SIVAL(req->out.body, 0x20, io->in.unknown4); + SIVAL(req->out.body, 0x24, io->in.open_disposition); + SIVAL(req->out.body, 0x28, io->in.unknown5); + + SSVAL(req->out.body, 0x2C, 0x40+0x38); /* offset to fname */ + SSVAL(req->out.body, 0x2E, path.length); + SIVAL(req->out.body, 0x30, 0x40+0x38+path.length); /* offset to 2nd buffer? */ + + SIVAL(req->out.body, 0x34, io->in.unknown6); + + memcpy(req->out.body+0x38, path.data, path.length); + + ptr = req->out.body+0x38+path.length; + + SIVAL(ptr, 0x00, io->in.unknown7); + SIVAL(ptr, 0x04, io->in.unknown8); + SIVAL(ptr, 0x08, io->in.unknown9); + SIVAL(ptr, 0x0C, io->in.unknown10); + SIVAL(ptr, 0x10, io->in.unknown11); + + data_blob_free(&path); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a create reply +*/ +NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) +{ + int i; + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x54) { + printf("body size %d\n", req->in.body_size); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); + io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); + io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); + io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); + io->out.unknown3 = IVAL(req->in.body, 0x24); + io->out.unknown4 = IVAL(req->in.body, 0x28); + io->out.unknown5 = IVAL(req->in.body, 0x2C); + io->out.unknown6 = IVAL(req->in.body, 0x30); + io->out.unknown7 = IVAL(req->in.body, 0x34); + memcpy(io->out.handle.data, req->in.body+0x38, 20); + for (i=0;i<2;i++) { + io->out.unknown8[i] = IVAL(req->in.body, 0x4C + i*4); + } + + return smb2_request_destroy(req); +} + +/* + sync create request +*/ +NTSTATUS smb2_create(struct smb2_tree *tree, struct smb2_create *io) +{ + struct smb2_request *req = smb2_create_send(tree, io); + return smb2_create_recv(req, io); +} diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 7e25de99a8..108cf0ca55 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -76,6 +76,22 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, return req; } +/* + initialise a smb2 request for tree operations +*/ +struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, + uint16_t opcode, uint32_t body_size) +{ + struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, + body_size); + if (req == NULL) return NULL; + + SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid); + + return req; +} + /* destroy a request structure and return final status */ NTSTATUS smb2_request_destroy(struct smb2_request *req) { diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 353f9687d7..76f00cc573 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -56,7 +56,7 @@ struct smb2_transport { */ struct smb2_tree { struct smb2_session *session; - uint64_t tid; + uint32_t tid; }; /* diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 523f314cbf..8b68751df3 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -71,6 +71,51 @@ struct smb2_tree_connect { uint32_t unknown2; /* 0x00 */ uint32_t unknown3; /* 0x00 */ uint32_t unknown4; /* 0x1f01ff */ /* capabilities?? */ - uint64_t tid; + uint32_t tid; } out; }; + +/* + file handles in SMB2 are 20 bytes, like RPC handles +*/ +struct smb2_handle { + uint8_t data[20]; +}; + +struct smb2_create { + struct { + uint32_t unknown1; /* 0x09000039 */ + uint32_t unknown2; /* 2 */ + uint32_t unknown3[4]; + uint32_t access_mask; + uint32_t file_attr; + uint32_t unknown4; + uint32_t open_disposition; + uint32_t unknown5; + /* ofs/len of name here, 16 bits */ + uint32_t unknown6; + const char *fname; + uint32_t unknown7; + uint32_t unknown8; + uint32_t unknown9; + uint32_t unknown10; + uint64_t unknown11; + } in; + + struct { + uint32_t unknown1; + uint32_t unknown2; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t unknown3; + uint32_t unknown4; + uint32_t unknown5; + uint32_t unknown6; + uint32_t unknown7; + struct smb2_handle handle; + uint32_t unknown8[2]; + } out; +}; + diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 7b13750cfe..b339d6473e 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -67,6 +67,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); SIVAL(req->out.body, 0x00, io->in.unknown1); status = smb2_push_ofs_blob(req, req->out.body+0x04, path); + data_blob_free(&path); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -92,7 +93,7 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.tid = BVAL(req->in.hdr, SMB2_HDR_TID); + io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID); io->out.unknown1 = IVAL(req->in.body, 0x00); io->out.unknown2 = IVAL(req->in.body, 0x04); @@ -103,7 +104,7 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne } /* - sync session setup request + sync tree connect request */ NTSTATUS smb2_tree_connect(struct smb2_tree *tree, struct smb2_tree_connect *io) { -- cgit From 1b2e8caad3fb01ea3b61bda63965d324de61c815 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 13:08:31 +0000 Subject: r11680: added smb2_close(). This also demonstrates that file handles are 16 bytes, not 20 bytes (metze, you were right!) (This used to be commit d3bcc6628cde9ddedf0fd408cbee573f133ce582) --- source4/libcli/smb2/close.c | 85 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/create.c | 11 +++--- source4/libcli/smb2/smb2_calls.h | 31 +++++++++++++-- 4 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 source4/libcli/smb2/close.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c new file mode 100644 index 0000000000..87220a4200 --- /dev/null +++ b/source4/libcli/smb2/close.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client tree handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a close request +*/ +struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18); + if (req == NULL) return NULL; + + SIVAL(req->out.body, 0x00, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.unknown2); + SBVAL(req->out.body, 0x08, io->in.handle.data[0]); + SBVAL(req->out.body, 0x10, io->in.handle.data[1]); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a close reply +*/ +NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x3C) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); + io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); + io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); + io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); + io->out.unknown3 = IVAL(req->in.body, 0x24); + io->out.unknown4 = IVAL(req->in.body, 0x28); + io->out.unknown5 = IVAL(req->in.body, 0x2C); + io->out.unknown6 = IVAL(req->in.body, 0x30); + io->out.unknown7 = IVAL(req->in.body, 0x34); + + return smb2_request_destroy(req); +} + +/* + sync close request +*/ +NTSTATUS smb2_close(struct smb2_tree *tree, struct smb2_close *io) +{ + struct smb2_request *req = smb2_close_send(tree, io); + return smb2_close_recv(req, io); +} diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index f3acd06955..a180768694 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -5,5 +5,6 @@ OBJ_FILES = \ negprot.o \ session.o \ tcon.o \ - create.o + create.o \ + close.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index dbb4d4b974..dc602ca71c 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -84,14 +84,12 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create */ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) { - int i; if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } if (req->in.body_size < 0x54) { - printf("body size %d\n", req->in.body_size); return NT_STATUS_BUFFER_TOO_SMALL; } @@ -106,10 +104,11 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.unknown5 = IVAL(req->in.body, 0x2C); io->out.unknown6 = IVAL(req->in.body, 0x30); io->out.unknown7 = IVAL(req->in.body, 0x34); - memcpy(io->out.handle.data, req->in.body+0x38, 20); - for (i=0;i<2;i++) { - io->out.unknown8[i] = IVAL(req->in.body, 0x4C + i*4); - } + io->out.unknown8 = IVAL(req->in.body, 0x38); + io->out.unknown9 = IVAL(req->in.body, 0x3C); + io->out.handle.data[0] = BVAL(req->in.body, 0x40); + io->out.handle.data[1] = BVAL(req->in.body, 0x48); + io->out.unknown10 = IVAL(req->in.body, 0x50); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 8b68751df3..7d41a06153 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -76,10 +76,10 @@ struct smb2_tree_connect { }; /* - file handles in SMB2 are 20 bytes, like RPC handles + file handles in SMB2 are 16 bytes */ struct smb2_handle { - uint8_t data[20]; + uint64_t data[2]; }; struct smb2_create { @@ -114,8 +114,33 @@ struct smb2_create { uint32_t unknown5; uint32_t unknown6; uint32_t unknown7; + uint32_t unknown8; + uint32_t unknown9; struct smb2_handle handle; - uint32_t unknown8[2]; + uint32_t unknown10; + } out; +}; + + +struct smb2_close { + struct { + uint32_t unknown1; + uint32_t unknown2; + struct smb2_handle handle; + } in; + + struct { + uint32_t unknown1; + uint32_t unknown2; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t unknown3; + uint32_t unknown4; + uint32_t unknown5; + uint32_t unknown6; + uint32_t unknown7; } out; }; -- cgit From 461ccc557b7cc4ed8b0a3f9fc9aa5f03eccbc656 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 14:04:46 +0000 Subject: r11681: filled in a few more smb2_create() fields (This used to be commit a95413568f1e45691524dfd8e9159a3bafe358ea) --- source4/libcli/smb2/create.c | 15 ++++++--------- source4/libcli/smb2/smb2_calls.h | 15 ++++++--------- 2 files changed, 12 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index dc602ca71c..53476ad056 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -51,9 +51,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(req->out.body, 0x14, io->in.unknown3[3]); SIVAL(req->out.body, 0x18, io->in.access_mask); SIVAL(req->out.body, 0x1C, io->in.file_attr); - SIVAL(req->out.body, 0x20, io->in.unknown4); + SIVAL(req->out.body, 0x20, io->in.share_access); SIVAL(req->out.body, 0x24, io->in.open_disposition); - SIVAL(req->out.body, 0x28, io->in.unknown5); + SIVAL(req->out.body, 0x28, io->in.create_options); SSVAL(req->out.body, 0x2C, 0x40+0x38); /* offset to fname */ SSVAL(req->out.body, 0x2E, path.length); @@ -99,13 +99,10 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); - io->out.unknown3 = IVAL(req->in.body, 0x24); - io->out.unknown4 = IVAL(req->in.body, 0x28); - io->out.unknown5 = IVAL(req->in.body, 0x2C); - io->out.unknown6 = IVAL(req->in.body, 0x30); - io->out.unknown7 = IVAL(req->in.body, 0x34); - io->out.unknown8 = IVAL(req->in.body, 0x38); - io->out.unknown9 = IVAL(req->in.body, 0x3C); + io->out.alloc_size = BVAL(req->in.body, 0x28); + io->out.size = BVAL(req->in.body, 0x30); + io->out.file_attr = IVAL(req->in.body, 0x38); + io->out.unknown8 = IVAL(req->in.body, 0x3C); io->out.handle.data[0] = BVAL(req->in.body, 0x40); io->out.handle.data[1] = BVAL(req->in.body, 0x48); io->out.unknown10 = IVAL(req->in.body, 0x50); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 7d41a06153..639a9c47c3 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -89,9 +89,9 @@ struct smb2_create { uint32_t unknown3[4]; uint32_t access_mask; uint32_t file_attr; - uint32_t unknown4; + uint32_t share_access; uint32_t open_disposition; - uint32_t unknown5; + uint32_t create_options; /* ofs/len of name here, 16 bits */ uint32_t unknown6; const char *fname; @@ -109,15 +109,12 @@ struct smb2_create { NTTIME access_time; NTTIME write_time; NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t file_attr; uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; struct smb2_handle handle; - uint32_t unknown10; + uint32_t unknown4; } out; }; -- cgit From b034156bd5920557ac175236dab113b971d72baf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 14:13:24 +0000 Subject: r11682: filled in access_mask in tcon reply (This used to be commit 173a213f915aa929cc2a6bfef06954e665b3d694) --- source4/libcli/smb2/smb2_calls.h | 2 +- source4/libcli/smb2/tcon.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 639a9c47c3..bb27716a34 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -70,7 +70,7 @@ struct smb2_tree_connect { uint32_t unknown1; /* 0x00020010 */ uint32_t unknown2; /* 0x00 */ uint32_t unknown3; /* 0x00 */ - uint32_t unknown4; /* 0x1f01ff */ /* capabilities?? */ + uint32_t access_mask; uint32_t tid; } out; }; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index b339d6473e..88a2d0a67d 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -95,10 +95,10 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID); - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = IVAL(req->in.body, 0x04); - io->out.unknown3 = IVAL(req->in.body, 0x08); - io->out.unknown4 = IVAL(req->in.body, 0x0C); + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.unknown3 = IVAL(req->in.body, 0x08); + io->out.access_mask = IVAL(req->in.body, 0x0C); return smb2_request_destroy(req); } -- cgit From be77dac05f22b93345aa7b6f8ba42615d74b19a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 14:14:22 +0000 Subject: r11683: fixed create call (This used to be commit 02d733190340fbb611443b0cc484813ba026eafe) --- source4/libcli/smb2/create.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 53476ad056..f234e6cb35 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -102,10 +102,10 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.alloc_size = BVAL(req->in.body, 0x28); io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); - io->out.unknown8 = IVAL(req->in.body, 0x3C); + io->out.unknown3 = IVAL(req->in.body, 0x3C); io->out.handle.data[0] = BVAL(req->in.body, 0x40); io->out.handle.data[1] = BVAL(req->in.body, 0x48); - io->out.unknown10 = IVAL(req->in.body, 0x50); + io->out.unknown4 = IVAL(req->in.body, 0x50); return smb2_request_destroy(req); } -- cgit From 222e197b848e2f1e58602d1e709f057a1f8833fd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 21:22:15 +0000 Subject: r11687: filled in 3 more fields in the close reply (This used to be commit 3a0abb3ff0b532179780ed95f8fcb4bca6e040b1) --- source4/libcli/smb2/close.c | 8 +++----- source4/libcli/smb2/smb2_calls.h | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 87220a4200..4429cd557b 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -66,11 +66,9 @@ NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); - io->out.unknown3 = IVAL(req->in.body, 0x24); - io->out.unknown4 = IVAL(req->in.body, 0x28); - io->out.unknown5 = IVAL(req->in.body, 0x2C); - io->out.unknown6 = IVAL(req->in.body, 0x30); - io->out.unknown7 = IVAL(req->in.body, 0x34); + io->out.alloc_size = BVAL(req->in.body, 0x28); + io->out.size = BVAL(req->in.body, 0x30); + io->out.file_attr = IVAL(req->in.body, 0x38); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index bb27716a34..f3d158dadd 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -133,11 +133,9 @@ struct smb2_close { NTTIME access_time; NTTIME write_time; NTTIME change_time; - uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; + uint64_t alloc_size; + uint64_t size; + uint32_t file_attr; } out; }; -- cgit From 91e1893741741de04b73a098495c697434105803 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 23:27:47 +0000 Subject: r11691: added reply buffer code checks and oplock flags for create request/reply (This used to be commit 26ed781375c03958241d8c93324e04e948944d01) --- source4/libcli/smb2/close.c | 10 ++++++---- source4/libcli/smb2/create.c | 28 +++++++++++++++++----------- source4/libcli/smb2/negprot.c | 4 +++- source4/libcli/smb2/session.c | 4 +++- source4/libcli/smb2/smb2.h | 11 +++++++++++ source4/libcli/smb2/smb2_calls.h | 40 ++++++++++++++++++++++++++++------------ source4/libcli/smb2/tcon.c | 4 +++- 7 files changed, 71 insertions(+), 30 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 4429cd557b..b60c1b3071 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -35,8 +35,9 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18); if (req == NULL) return NULL; - SIVAL(req->out.body, 0x00, io->in.unknown1); - SIVAL(req->out.body, 0x04, io->in.unknown2); + SSVAL(req->out.body, 0x00, io->in.buffer_code); + SSVAL(req->out.body, 0x02, io->in.flags); + SIVAL(req->out.body, 0x04, io->in._pad); SBVAL(req->out.body, 0x08, io->in.handle.data[0]); SBVAL(req->out.body, 0x10, io->in.handle.data[1]); @@ -60,8 +61,9 @@ NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.buffer_code = SVAL(req->in.body, 0x00); + io->out.flags = SVAL(req->in.body, 0x02); + io->out._pad = IVAL(req->in.body, 0x04); io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index f234e6cb35..e4b0773758 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -43,7 +43,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length); if (req == NULL) return NULL; - SIVAL(req->out.body, 0x00, io->in.unknown1); + SSVAL(req->out.body, 0x00, io->in.buffer_code); + SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); @@ -84,6 +85,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create */ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) { + smb2_request_receive(req); + dump_data(0, req->in.body, req->in.body_size); + if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); @@ -93,16 +97,18 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = IVAL(req->in.body, 0x04); - io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); - io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); - io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); - io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); - io->out.alloc_size = BVAL(req->in.body, 0x28); - io->out.size = BVAL(req->in.body, 0x30); - io->out.file_attr = IVAL(req->in.body, 0x38); - io->out.unknown3 = IVAL(req->in.body, 0x3C); + SMB2_CHECK_BUFFER_CODE(req, 0x59); + + io->out.oplock_flags = SVAL(req->in.body, 0x02); + io->out.create_action = IVAL(req->in.body, 0x04); + io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); + io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); + io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); + io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); + io->out.alloc_size = BVAL(req->in.body, 0x28); + io->out.size = BVAL(req->in.body, 0x30); + io->out.file_attr = IVAL(req->in.body, 0x38); + io->out._pad = IVAL(req->in.body, 0x3C); io->out.handle.data[0] = BVAL(req->in.body, 0x40); io->out.handle.data[1] = BVAL(req->in.body, 0x48); io->out.unknown4 = IVAL(req->in.body, 0x50); diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 5cd4810909..758b06fcae 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -62,7 +62,9 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.unknown1 = IVAL(req->in.body, 0x00); + SMB2_CHECK_BUFFER_CODE(req, 0x41); + + io->out._pad = SVAL(req->in.body, 0x02); io->out.unknown2 = IVAL(req->in.body, 0x04); memcpy(io->out.sessid, req->in.body + 0x08, 16); io->out.unknown3 = IVAL(req->in.body, 0x18); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 031360fcb9..9d945243d2 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -103,7 +103,9 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.unknown1 = IVAL(req->in.body, 0x00); + SMB2_CHECK_BUFFER_CODE(req, 0x09); + + io->out._pad = SVAL(req->in.body, 0x02); io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob); diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 76f00cc573..f6847bfc9b 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -168,3 +168,14 @@ struct smb2_request { #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ +/* + check that a buffer code matches the expected value +*/ +#define SMB2_CHECK_BUFFER_CODE(req, code) do { \ + io->out.buffer_code = SVAL(req->in.body, 0); \ + if (io->out.buffer_code != (code)) { \ + DEBUG(0,("Unexpected buffer code 0x%x. Expected 0x%x\n", \ + io->out.buffer_code, code)); \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ +} while (0) diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index f3d158dadd..859655355d 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -28,7 +28,8 @@ struct smb2_negprot { uint8_t unknown3[32]; /* all zero */ } in; struct { - uint32_t unknown1; /* 0x41 */ + uint16_t buffer_code; + uint16_t _pad; uint32_t unknown2; /* 0x06 */ uint8_t sessid[16]; uint32_t unknown3; /* 0x0d */ @@ -54,7 +55,8 @@ struct smb2_session_setup { DATA_BLOB secblob; } in; struct { - uint32_t unknown1; /* 0x09 */ + uint16_t buffer_code; + uint16_t _pad; /* uint16_t secblob ofs/size here */ DATA_BLOB secblob; uint64_t uid; /* returned in header */ @@ -67,7 +69,8 @@ struct smb2_tree_connect { const char *path; } in; struct { - uint32_t unknown1; /* 0x00020010 */ + uint16_t buffer_code; + uint16_t unknown1; /* 0x02 */ uint32_t unknown2; /* 0x00 */ uint32_t unknown3; /* 0x00 */ uint32_t access_mask; @@ -82,10 +85,17 @@ struct smb2_handle { uint64_t data[2]; }; + +#define SMB2_CREATE_FLAG_REQUEST_OPLOCK 0x0100 +#define SMB2_CREATE_FLAG_REQUEST_EXCLUSIVE_OPLOCK 0x0800 +#define SMB2_CREATE_FLAG_GRANT_OPLOCK 0x0001 +#define SMB2_CREATE_FLAG_GRANT_EXCLUSIVE_OPLOCK 0x0080 + struct smb2_create { struct { - uint32_t unknown1; /* 0x09000039 */ - uint32_t unknown2; /* 2 */ + uint16_t buffer_code; /* 0x39 */ + uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint32_t unknown2; uint32_t unknown3[4]; uint32_t access_mask; uint32_t file_attr; @@ -103,8 +113,9 @@ struct smb2_create { } in; struct { - uint32_t unknown1; - uint32_t unknown2; + uint16_t buffer_code; /* 0x59 */ + uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint32_t create_action; NTTIME create_time; NTTIME access_time; NTTIME write_time; @@ -112,23 +123,28 @@ struct smb2_create { uint64_t alloc_size; uint64_t size; uint32_t file_attr; - uint32_t unknown3; + uint32_t _pad; struct smb2_handle handle; uint32_t unknown4; + uint32_t unknown5; } out; }; +#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0) + struct smb2_close { struct { - uint32_t unknown1; - uint32_t unknown2; + uint16_t buffer_code; + uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ + uint32_t _pad; struct smb2_handle handle; } in; struct { - uint32_t unknown1; - uint32_t unknown2; + uint16_t buffer_code; + uint16_t flags; + uint32_t _pad; NTTIME create_time; NTTIME access_time; NTTIME write_time; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 88a2d0a67d..f68987acf7 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -93,9 +93,11 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne return NT_STATUS_BUFFER_TOO_SMALL; } + SMB2_CHECK_BUFFER_CODE(req, 0x10); + io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID); - io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown1 = SVAL(req->in.body, 0x02); io->out.unknown2 = IVAL(req->in.body, 0x04); io->out.unknown3 = IVAL(req->in.body, 0x08); io->out.access_mask = IVAL(req->in.body, 0x0C); -- cgit From 2b7ee2ceee0a1b2be596a602997908f72a3af14d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 01:08:43 +0000 Subject: r11692: added a full composite (async) spnego session setup for SMB2. This simplies the torture code a lot. (This used to be commit 7bf1046fbb7fd83fecb2fa645628ba9a17aab037) --- source4/libcli/smb2/request.c | 4 + source4/libcli/smb2/session.c | 146 +++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 2 + source4/libcli/smb_composite/sesssetup.c | 4 +- 4 files changed, 154 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 108cf0ca55..ccffef9b88 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -39,6 +39,8 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, req->state = SMB2_REQUEST_INIT; req->transport = transport; + req->session = NULL; + req->tree = NULL; req->seqnum = transport->seqnum++; req->status = NT_STATUS_OK; req->async.fn = NULL; @@ -88,6 +90,8 @@ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid); + req->session = tree->session; + req->tree = tree; return req; } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 9d945243d2..baa706cf8b 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -24,6 +24,8 @@ #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "libcli/composite/composite.h" +#include "auth/gensec/gensec.h" /* initialise a smb2_session structure @@ -73,6 +75,8 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3); + req->session = session; + status = smb2_push_ofs_blob(req, req->out.body+0x0C, io->in.secblob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -127,3 +131,145 @@ NTSTATUS smb2_session_setup(struct smb2_session *session, struct smb2_request *req = smb2_session_setup_send(session, io); return smb2_session_setup_recv(req, mem_ctx, io); } + + +struct smb2_session_state { + struct smb2_session_setup io; + struct smb2_request *req; + NTSTATUS gensec_status; +}; + +/* + handle continuations of the spnego session setup +*/ +static void session_request_handler(struct smb2_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + struct smb2_session_state *state = talloc_get_type(c->private_data, + struct smb2_session_state); + struct smb2_session *session = req->session; + + c->status = smb2_session_setup_recv(req, c, &state->io); + if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) || + (NT_STATUS_IS_OK(c->status) && + NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { + c->status = gensec_update(req->session->gensec, c, + state->io.out.secblob, + &state->io.in.secblob); + state->gensec_status = c->status; + } + + session->uid = state->io.out.uid; + + if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + state->req = smb2_session_setup_send(session, &state->io); + if (state->req == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + } + + state->req->async.fn = session_request_handler; + state->req->async.private = c; + return; + } + + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + + composite_done(c); +} + +/* + a composite function that does a full SPNEGO session setup + */ +struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *session, + struct cli_credentials *credentials) +{ + struct composite_context *c; + struct smb2_session_state *state; + + c = talloc_zero(session, struct composite_context); + if (c == NULL) return NULL; + + state = talloc(c, struct smb2_session_state); + if (state == NULL) { + c->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = state; + c->event_ctx = session->transport->socket->event.ctx; + + ZERO_STRUCT(state->io); + state->io.in.unknown1 = 0x11; + state->io.in.unknown2 = 0xF; + state->io.in.unknown3 = 0x00; + + c->status = gensec_set_credentials(session->gensec, credentials); + if (!NT_STATUS_IS_OK(c->status)) { + goto failed; + } + + c->status = gensec_set_target_hostname(session->gensec, + session->transport->socket->hostname); + if (!NT_STATUS_IS_OK(c->status)) { + goto failed; + } + + c->status = gensec_set_target_service(session->gensec, "cifs"); + if (!NT_STATUS_IS_OK(c->status)) { + goto failed; + } + + c->status = gensec_start_mech_by_oid(session->gensec, GENSEC_OID_SPNEGO); + if (!NT_STATUS_IS_OK(c->status)) { + goto failed; + } + + c->status = gensec_update(session->gensec, c, + session->transport->negotiate.secblob, + &state->io.in.secblob); + if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto failed; + } + state->gensec_status = c->status; + + state->req = smb2_session_setup_send(session, &state->io); + if (state->req == NULL) { + c->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + state->req->async.fn = session_request_handler; + state->req->async.private = c; + + return c; + +failed: + composite_trigger_error(c); + return c; +} + +/* + receive a composite session setup reply +*/ +NTSTATUS smb2_session_setup_spnego_recv(struct composite_context *c) +{ + NTSTATUS status; + status = composite_wait(c); + talloc_free(c); + return status; +} + +/* + sync version of smb2_session_setup_spnego +*/ +NTSTATUS smb2_session_setup_spnego(struct smb2_session *session, + struct cli_credentials *credentials) +{ + struct composite_context *c = smb2_session_setup_spnego_send(session, credentials); + return smb2_session_setup_spnego_recv(c); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index f6847bfc9b..f452852cf9 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -114,6 +114,8 @@ struct smb2_request { enum smb2_request_state state; struct smb2_transport *transport; + struct smb2_session *session; + struct smb2_tree *tree; uint64_t seqnum; diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 0d0904b969..4cdc4c5e6b 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -370,8 +370,8 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se state = talloc(c, struct sesssetup_state); if (state == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; + talloc_free(c); + return NULL; } state->io = io; -- cgit From e27ba5e4c6f684c0fc0f0db9a84164384ff3c0fd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 02:12:51 +0000 Subject: r11693: added a full async composite function for SMB2 that does: - name resolution - socket connect - negprot - multi-stage session setup - tcon (This used to be commit c1a8e866fe6a0544b7b26da451ea093cdcacdd8f) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/connect.c | 280 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/connect.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index a180768694..097ed6df12 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -6,5 +6,6 @@ OBJ_FILES = \ session.o \ tcon.o \ create.o \ - close.o + close.o \ + connect.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c new file mode 100644 index 0000000000..18f28539ea --- /dev/null +++ b/source4/libcli/smb2/connect.c @@ -0,0 +1,280 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 composite connection setup + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" +#include "libcli/composite/composite.h" + +struct smb2_connect_state { + struct smb2_request *req; + struct composite_context *creq; + struct cli_credentials *credentials; + const char *host; + const char *share; + struct smb2_negprot negprot; + struct smb2_tree_connect tcon; + struct smb2_session *session; + struct smb2_tree *tree; +}; + +/* + continue after tcon reply +*/ +static void continue_tcon(struct smb2_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + struct smb2_connect_state *state = talloc_get_type(c->private_data, + struct smb2_connect_state); + + c->status = smb2_tree_connect_recv(req, &state->tcon); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + + state->tree->tid = state->tcon.out.tid; + + composite_done(c); +} + +/* + continue after a session setup +*/ +static void continue_session(struct composite_context *creq) +{ + struct composite_context *c = talloc_get_type(creq->async.private_data, + struct composite_context); + struct smb2_connect_state *state = talloc_get_type(c->private_data, + struct smb2_connect_state); + + c->status = smb2_session_setup_spnego_recv(creq); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + + state->tree = smb2_tree_init(state->session, state, True); + if (state->tree == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->tcon.in.unknown1 = 0x09; + state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s", + state->host, state->share); + if (state->tcon.in.path == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->req = smb2_tree_connect_send(state->tree, &state->tcon); + if (state->req == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->req->async.fn = continue_tcon; + state->req->async.private = c; +} + +/* + continue after negprot reply +*/ +static void continue_negprot(struct smb2_request *req) +{ + struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context); + struct smb2_connect_state *state = talloc_get_type(c->private_data, + struct smb2_connect_state); + struct smb2_transport *transport = req->transport; + + c->status = smb2_negprot_recv(req, c, &state->negprot); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + + state->session = smb2_session_init(transport, state, True); + if (state->session == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->creq = smb2_session_setup_spnego_send(state->session, state->credentials); + if (state->creq == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->creq->async.fn = continue_session; + state->creq->async.private_data = c; +} + +/* + continue after a socket connect completes +*/ +static void continue_socket(struct composite_context *creq) +{ + struct composite_context *c = talloc_get_type(creq->async.private_data, + struct composite_context); + struct smb2_connect_state *state = talloc_get_type(c->private_data, + struct smb2_connect_state); + struct smbcli_socket *sock; + struct smb2_transport *transport; + + c->status = smbcli_sock_connect_recv(creq, state, &sock); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + + transport = smb2_transport_init(sock, state); + if (transport == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + ZERO_STRUCT(state->negprot); + state->negprot.in.unknown1 = 0x010024; + + state->req = smb2_negprot_send(transport, &state->negprot); + if (state->req == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->req->async.fn = continue_negprot; + state->req->async.private = c; +} + + +/* + continue after a resolve finishes +*/ +static void continue_resolve(struct composite_context *creq) +{ + struct composite_context *c = talloc_get_type(creq->async.private_data, + struct composite_context); + struct smb2_connect_state *state = talloc_get_type(c->private_data, + struct smb2_connect_state); + const char *addr; + + c->status = resolve_name_recv(creq, state, &addr); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + + state->creq = smbcli_sock_connect_send(state, addr, 445, state->host, c->event_ctx); + if (state->creq == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return; + } + + state->creq->async.private_data = c; + state->creq->async.fn = continue_socket; +} + +/* + a composite function that does a full negprot/sesssetup/tcon, returning + a connected smb2_tree + */ +struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, + const char *host, + const char *share, + struct cli_credentials *credentials, + struct event_context *ev) +{ + struct composite_context *c; + struct smb2_connect_state *state; + struct nbt_name name; + + c = talloc_zero(mem_ctx, struct composite_context); + if (c == NULL) return NULL; + + state = talloc(c, struct smb2_connect_state); + if (state == NULL) { + c->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = state; + c->event_ctx = ev; + + state->credentials = credentials; + state->host = talloc_strdup(c, host); + state->share = talloc_strdup(c, share); + if (state->host == NULL || state->share == NULL) { + c->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + ZERO_STRUCT(name); + name.name = host; + + state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); + if (state->creq == NULL) goto failed; + + state->creq->async.private_data = c; + state->creq->async.fn = continue_resolve; + + return c; + +failed: + composite_trigger_error(c); + return c; +} + +/* + receive a connect reply +*/ +NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct smb2_tree **tree) +{ + NTSTATUS status; + struct smb2_connect_state *state = talloc_get_type(c->private_data, + struct smb2_connect_state); + status = composite_wait(c); + if (NT_STATUS_IS_OK(status)) { + *tree = talloc_steal(mem_ctx, state->tree); + } + talloc_free(c); + return status; +} + +/* + sync version of smb2_connect +*/ +NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, + const char *host, const char *share, + struct cli_credentials *credentials, + struct smb2_tree **tree, + struct event_context *ev) +{ + struct composite_context *c = smb2_connect_send(mem_ctx, host, share, + credentials, ev); + return smb2_connect_recv(c, mem_ctx, tree); +} -- cgit From 56712033d59212c8d72c8d60df885a5764601b7e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 02:16:19 +0000 Subject: r11694: fixed 2 valgrind errors (This used to be commit 6381fe72417a5cd231b63a87a6a0ba9c65030ce6) --- source4/libcli/smb2/create.c | 2 +- source4/libcli/smb2/session.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index e4b0773758..1316626432 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -70,7 +70,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(ptr, 0x04, io->in.unknown8); SIVAL(ptr, 0x08, io->in.unknown9); SIVAL(ptr, 0x0C, io->in.unknown10); - SIVAL(ptr, 0x10, io->in.unknown11); + SBVAL(ptr, 0x10, io->in.unknown11); data_blob_free(&path); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index baa706cf8b..257e754660 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -154,7 +154,7 @@ static void session_request_handler(struct smb2_request *req) if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) || (NT_STATUS_IS_OK(c->status) && NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { - c->status = gensec_update(req->session->gensec, c, + c->status = gensec_update(session->gensec, c, state->io.out.secblob, &state->io.in.secblob); state->gensec_status = c->status; -- cgit From a1562e23800caef20730db9d1e5006d3a9ea4298 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 02:45:49 +0000 Subject: r11696: added a few more opcode names (This used to be commit 2a45476e94a248733333df29da57513bd114f213) --- source4/libcli/smb2/smb2.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index f452852cf9..f77eab22d1 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -167,6 +167,9 @@ struct smb2_request { #define SMB2_OP_READ 0x08 #define SMB2_OP_WRITE 0x09 #define SMB2_OP_FIND 0x0e +#define SMB2_OP_GETINFO 0x10 +#define SMB2_OP_SETINFO 0x11 +#define SMB2_OP_BREAK 0x12 #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ -- cgit From 67a85b3f1bca7e0590ae97d07a6ef32c418e64d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 07:48:56 +0000 Subject: r11697: - added a generic SMB2 getinfo call - added a SMB2-SCANGETINFO test for scanning for available info levels - added names for the info levels I recognise to smb2.h (This used to be commit fe5986067e2aaca039d70393ccc8761434f18fe6) --- source4/libcli/smb2/close.c | 5 ++- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/create.c | 3 -- source4/libcli/smb2/getinfo.c | 90 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/request.c | 2 +- source4/libcli/smb2/smb2.h | 2 + source4/libcli/smb2/smb2_calls.h | 47 +++++++++++++++++++++ source4/libcli/smb2/transport.c | 6 +-- 8 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 source4/libcli/smb2/getinfo.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index b60c1b3071..2802e2f27e 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - SMB2 client tree handling + SMB2 client close handling Copyright (C) Andrew Tridgell 2005 @@ -61,7 +61,8 @@ NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.buffer_code = SVAL(req->in.body, 0x00); + SMB2_CHECK_BUFFER_CODE(req, 0x3C); + io->out.flags = SVAL(req->in.body, 0x02); io->out._pad = IVAL(req->in.body, 0x04); io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 097ed6df12..b7ecdcb98d 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -7,5 +7,6 @@ OBJ_FILES = \ tcon.o \ create.o \ close.o \ - connect.o + connect.o \ + getinfo.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 1316626432..9483f35ca1 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -85,9 +85,6 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create */ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) { - smb2_request_receive(req); - dump_data(0, req->in.body, req->in.body_size); - if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c new file mode 100644 index 0000000000..c8976e4230 --- /dev/null +++ b/source4/libcli/smb2/getinfo.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client getinfo calls + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a getinfo request +*/ +struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getinfo *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x00, io->in.buffer_code); + SSVAL(req->out.body, 0x02, io->in.level); + SIVAL(req->out.body, 0x04, io->in.max_response_size); + SIVAL(req->out.body, 0x08, io->in.unknown1); + SIVAL(req->out.body, 0x0C, io->in.unknown2); + SIVAL(req->out.body, 0x10, io->in.unknown3); + SIVAL(req->out.body, 0x14, io->in.unknown4); + SBVAL(req->out.body, 0x18, io->in.handle.data[0]); + SBVAL(req->out.body, 0x20, io->in.handle.data[1]); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a getinfo reply +*/ +NTSTATUS smb2_getinfo_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + struct smb2_getinfo *io) +{ + NTSTATUS status; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x08) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + SMB2_CHECK_BUFFER_CODE(req, 0x09); + + status = smb2_pull_ofs_blob(req, req->in.body+0x02, &io->out.blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + talloc_steal(mem_ctx, io->out.blob.data); + + return smb2_request_destroy(req); +} + +/* + sync getinfo request +*/ +NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + struct smb2_getinfo *io) +{ + struct smb2_request *req = smb2_getinfo_send(tree, io); + return smb2_getinfo_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index ccffef9b88..4b95d141a3 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -188,7 +188,7 @@ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) } /* - pull a ofs/length/blob triple into a data blob + pull a ofs/length/blob triple from a data blob the ptr points to the start of the offset/length pair */ NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob) diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index f77eab22d1..e99e8d3945 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -166,7 +166,9 @@ struct smb2_request { #define SMB2_OP_CLOSE 0x06 #define SMB2_OP_READ 0x08 #define SMB2_OP_WRITE 0x09 +#define SMB2_OP_CANCEL 0x0c #define SMB2_OP_FIND 0x0e +#define SMB2_OP_NOTIFY 0x0f #define SMB2_OP_GETINFO 0x10 #define SMB2_OP_SETINFO 0x11 #define SMB2_OP_BREAK 0x12 diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 859655355d..5e9efd2868 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -155,3 +155,50 @@ struct smb2_close { } out; }; +/* fs information levels */ +#define SMB2_GETINFO_FS_01 0x0102 +#define SMB2_GETINFO_FS_03 0x0302 +#define SMB2_GETINFO_FS_04 0x0402 +#define SMB2_GETINFO_FS_ATTRIB_INFO 0x0502 +#define SMB2_GETINFO_FS_06 0x0602 +#define SMB2_GETINFO_FS_07 0x0702 +#define SMB2_GETINFO_FS_08 0x0802 + +/* class 3 levels */ +#define SMB2_GETINFO_3_00 0x0003 + +/* file information levels */ +#define SMB2_GETINFO_FILE_BASIC_INFO 0x0401 +#define SMB2_GETINFO_FILE_05 0x0501 +#define SMB2_GETINFO_FILE_06 0x0601 +#define SMB2_GETINFO_FILE_07 0x0701 +#define SMB2_GETINFO_FILE_ACCESS_INFO 0x0801 +#define SMB2_GETINFO_FILE_0E 0x0e01 +#define SMB2_GETINFO_FILE_10 0x1001 +#define SMB2_GETINFO_FILE_11 0x1101 +#define SMB2_GETINFO_FILE_ALL_INFO 0x1201 +#define SMB2_GETINFO_FILE_NAME_INFO 0x1501 +#define SMB2_GETINFO_FILE_STREAM_INFO 0x1601 +#define SMB2_GETINFO_FILE_1C 0x1c01 +#define SMB2_GETINFO_FILE_STANDARD_INFO 0x2201 +#define SMB2_GETINFO_FILE_ATTRIB_INFO 0x2301 + + +struct smb2_getinfo { + struct { + uint16_t buffer_code; + uint16_t level; + uint32_t max_response_size; + uint32_t unknown1; + uint32_t unknown2; + uint32_t unknown3; + uint32_t unknown4; + struct smb2_handle handle; + } in; + + struct { + uint16_t buffer_code; + DATA_BLOB blob; + } out; +}; + diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 9940379f98..e87c7a68c0 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -184,7 +184,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", req->seqnum)); - dump_data(2, req->in.body, req->in.body_size); + dump_data(5, req->in.body, req->in.body_size); /* if this request has an async handler then call that to notify that the reply has been received. This might destroy @@ -197,7 +197,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) return NT_STATUS_OK; error: - dump_data(2, buffer, len); + dump_data(5, buffer, len); if (req) { DLIST_REMOVE(transport->pending_recv, req); req->state = SMB2_REQUEST_ERROR; @@ -253,7 +253,7 @@ void smb2_transport_send(struct smb2_request *req) _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); DEBUG(2, ("SMB2 send seqnum=0x%llx\n", req->seqnum)); - dump_data(2, req->out.body, req->out.body_size); + dump_data(5, req->out.body, req->out.body_size); /* check if the transport is dead */ if (req->transport->socket->sock == NULL) { -- cgit From 36e4374b1d047b4857db22421c2bcc67f13b55d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 08:18:52 +0000 Subject: r11698: added some more level names (This used to be commit 845bbef8038b776b32da0c9c55ae9375feee4961) --- source4/libcli/smb2/smb2_calls.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 5e9efd2868..df2aff75e6 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -169,17 +169,18 @@ struct smb2_close { /* file information levels */ #define SMB2_GETINFO_FILE_BASIC_INFO 0x0401 -#define SMB2_GETINFO_FILE_05 0x0501 +#define SMB2_GETINFO_FILE_SIZE_INFO 0x0501 #define SMB2_GETINFO_FILE_06 0x0601 -#define SMB2_GETINFO_FILE_07 0x0701 +#define SMB2_GETINFO_FILE_EA_SIZE 0x0701 #define SMB2_GETINFO_FILE_ACCESS_INFO 0x0801 #define SMB2_GETINFO_FILE_0E 0x0e01 +#define SMB2_GETINFO_FILE_EA_INFO 0x0f01 #define SMB2_GETINFO_FILE_10 0x1001 #define SMB2_GETINFO_FILE_11 0x1101 #define SMB2_GETINFO_FILE_ALL_INFO 0x1201 #define SMB2_GETINFO_FILE_NAME_INFO 0x1501 #define SMB2_GETINFO_FILE_STREAM_INFO 0x1601 -#define SMB2_GETINFO_FILE_1C 0x1c01 +#define SMB2_GETINFO_FILE_EOF_INFO 0x1c01 #define SMB2_GETINFO_FILE_STANDARD_INFO 0x2201 #define SMB2_GETINFO_FILE_ATTRIB_INFO 0x2301 -- cgit From 72565088bcb044bb790e25a0ea55f77cfa9fd9aa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 08:39:36 +0000 Subject: r11700: added structure definitions for many of the getinfo structures (This used to be commit 2919d4228636f1d61d930a37cddd5b1700bf2233) --- source4/libcli/smb2/smb2_calls.h | 101 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index df2aff75e6..22cdcef14f 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -178,7 +178,7 @@ struct smb2_close { #define SMB2_GETINFO_FILE_10 0x1001 #define SMB2_GETINFO_FILE_11 0x1101 #define SMB2_GETINFO_FILE_ALL_INFO 0x1201 -#define SMB2_GETINFO_FILE_NAME_INFO 0x1501 +#define SMB2_GETINFO_FILE_SHORT_INFO 0x1501 #define SMB2_GETINFO_FILE_STREAM_INFO 0x1601 #define SMB2_GETINFO_FILE_EOF_INFO 0x1c01 #define SMB2_GETINFO_FILE_STANDARD_INFO 0x2201 @@ -203,3 +203,102 @@ struct smb2_getinfo { } out; }; +union smb2_fileinfo { + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t file_attr; + uint32_t unknown; + } basic_info; + + struct { + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + uint32_t unknown; + } size_info; + + struct { + uint32_t unknown1; + uint32_t unknown2; + } unknown06; + + struct { + uint32_t ea_size; + } ea_info; + + struct { + uint32_t access_mask; + } access_info; + + struct { + uint32_t unknown1; + uint32_t unknown2; + } unknown0e; + + struct { + struct smb_ea_list all_eas; + } all_ea_info; + + struct { + uint32_t unknown; /* 2 */ + } unknown10; + + struct { + uint32_t unknown; + } unknown11; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t file_attr; + uint32_t unknown1; + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + uint32_t unknown2; + uint32_t unknown3; + uint32_t unknown4; + uint32_t ea_size; + uint32_t access_mask; + uint64_t unknown5; + uint64_t unknown6; + const char *fname; + } all_info; + + struct { + const char *short_name; + } short_info; + + struct { + uint32_t unknown; + uint64_t size; + uint64_t alloc_size; + const char *stream_name; + } stream_info; + + struct { + uint64_t size; + uint64_t unknown; + } eof_info; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t file_attr; + uint32_t unknown; + } standard_info; + + struct { + uint32_t file_attr; + uint32_t unknown; + } attrib_info; +}; -- cgit From 614950aed35353854019db5cccec5b3154643ca3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Nov 2005 03:45:57 +0000 Subject: r11713: separate out the setting of the fde in the packet context from the enabling of packet serialisation (This used to be commit 6a47cd65a8b588f9ddd375c57caaba08281e7cbb) --- source4/libcli/ldap/ldap_client.c | 3 ++- source4/libcli/raw/clitransport.c | 3 ++- source4/libcli/smb2/transport.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 503016e896..a5f647939f 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -398,7 +398,8 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) packet_set_full_request(conn->packet, ldap_complete_packet); packet_set_error_handler(conn->packet, ldap_error_handler); packet_set_event_context(conn->packet, conn->event.event_ctx); - packet_set_serialise(conn->packet, conn->event.fde); + packet_set_fde(conn->packet, conn->event.fde); + packet_set_serialise(conn->packet); composite_done(state->ctx); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index fba6c36bbe..b60ea1dc02 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -121,7 +121,8 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, smbcli_transport_event_handler, transport); - packet_set_serialise(transport->packet, transport->socket->event.fde); + packet_set_fde(transport->packet, transport->socket->event.fde); + packet_set_serialise(transport->packet); talloc_set_destructor(transport, transport_destructor); diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index e87c7a68c0..c6fc890e34 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -107,7 +107,8 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, smb2_transport_event_handler, transport); - packet_set_serialise(transport->packet, transport->socket->event.fde); + packet_set_fde(transport->packet, transport->socket->event.fde); + packet_set_serialise(transport->packet); talloc_set_destructor(transport, transport_destructor); -- cgit From 6f49a2404cde1e3e8a20e7ce270e28191ab9037e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Nov 2005 03:48:55 +0000 Subject: r11714: put in a workaround for a winbind problem volker asked me about. The problem is that winbind currently relies on being able to receive on a smb connection from within the same connections receive routine. This means it relies on a non-serialised connection, so disable the serialisation until winbind is fixed. The correct fix will be to get rid of full_request() in dcerpc.c so that bind requests can be fully async. (This used to be commit c4115293d83a4a6d103e049c5832d4bcdc0a9dbc) --- source4/libcli/raw/clitransport.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index b60ea1dc02..83b73f2e30 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -122,8 +122,11 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport); packet_set_fde(transport->packet, transport->socket->event.fde); +#if 0 + /* winbind relies on non-serialised connections for dcerpc bind. Once that is + fixed we can go back to serialised connections */ packet_set_serialise(transport->packet); - +#endif talloc_set_destructor(transport, transport_destructor); return transport; -- cgit From c6395a30b057c87de8ce410d5ea5ebe2e017093d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Nov 2005 05:09:26 +0000 Subject: r11715: added SMB2 read and write requests (This used to be commit d3556cbfa38447d2d385b697c1855b3c13d42744) --- source4/libcli/smb2/close.c | 3 +- source4/libcli/smb2/config.mk | 4 +- source4/libcli/smb2/getinfo.c | 149 ++++++++++++++++++++++++++++++++++++++- source4/libcli/smb2/read.c | 95 +++++++++++++++++++++++++ source4/libcli/smb2/request.c | 12 ++++ source4/libcli/smb2/smb2_calls.h | 60 ++++++++++++---- source4/libcli/smb2/write.c | 82 +++++++++++++++++++++ 7 files changed, 386 insertions(+), 19 deletions(-) create mode 100644 source4/libcli/smb2/read.c create mode 100644 source4/libcli/smb2/write.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 2802e2f27e..d5a2c4d422 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -38,8 +38,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * SSVAL(req->out.body, 0x00, io->in.buffer_code); SSVAL(req->out.body, 0x02, io->in.flags); SIVAL(req->out.body, 0x04, io->in._pad); - SBVAL(req->out.body, 0x08, io->in.handle.data[0]); - SBVAL(req->out.body, 0x10, io->in.handle.data[1]); + smb2_put_handle(req->out.body+0x08, io->in.handle); smb2_transport_send(req); diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index b7ecdcb98d..15f49ba88e 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -8,5 +8,7 @@ OBJ_FILES = \ create.o \ close.o \ connect.o \ - getinfo.o + getinfo.o \ + write.o \ + read.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index c8976e4230..a7935526e5 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -39,11 +39,10 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin SSVAL(req->out.body, 0x02, io->in.level); SIVAL(req->out.body, 0x04, io->in.max_response_size); SIVAL(req->out.body, 0x08, io->in.unknown1); - SIVAL(req->out.body, 0x0C, io->in.unknown2); + SIVAL(req->out.body, 0x0C, io->in.flags); SIVAL(req->out.body, 0x10, io->in.unknown3); SIVAL(req->out.body, 0x14, io->in.unknown4); - SBVAL(req->out.body, 0x18, io->in.handle.data[0]); - SBVAL(req->out.body, 0x20, io->in.handle.data[1]); + smb2_put_handle(req->out.body+0x18, io->in.handle); smb2_transport_send(req); @@ -88,3 +87,147 @@ NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_request *req = smb2_getinfo_send(tree, io); return smb2_getinfo_recv(req, mem_ctx, io); } + + +/* + parse a returned getinfo data blob +*/ +NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, + uint16_t level, + DATA_BLOB blob, + union smb2_fileinfo *io) +{ + switch (level) { + case SMB2_GETINFO_FILE_BASIC_INFO: + if (blob.length != 0x28) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->basic_info.create_time = smbcli_pull_nttime(blob.data, 0x00); + io->basic_info.access_time = smbcli_pull_nttime(blob.data, 0x08); + io->basic_info.write_time = smbcli_pull_nttime(blob.data, 0x10); + io->basic_info.change_time = smbcli_pull_nttime(blob.data, 0x18); + io->basic_info.file_attr = IVAL(blob.data, 0x20); + io->basic_info.unknown = IVAL(blob.data, 0x24); + break; + + case SMB2_GETINFO_FILE_SIZE_INFO: + if (blob.length != 0x18) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->size_info.alloc_size = BVAL(blob.data, 0x00); + io->size_info.size = BVAL(blob.data, 0x08); + io->size_info.nlink = IVAL(blob.data, 0x10); + io->size_info.unknown = IVAL(blob.data, 0x14); + break; + + case SMB2_GETINFO_FILE_06: + if (blob.length != 0x8) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown06.unknown1 = IVAL(blob.data, 0x00); + io->unknown06.unknown2 = IVAL(blob.data, 0x04); + break; + + case SMB2_GETINFO_FILE_EA_SIZE: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->ea_size.ea_size = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_ACCESS_INFO: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->access_info.access_mask = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_0E: + if (blob.length != 0x8) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown0e.unknown1 = IVAL(blob.data, 0x00); + io->unknown0e.unknown2 = IVAL(blob.data, 0x04); + break; + + case SMB2_GETINFO_FILE_ALL_EAS: + return ea_pull_list(&blob, mem_ctx, + &io->all_eas.eas.num_eas, + &io->all_eas.eas.eas); + + case SMB2_GETINFO_FILE_10: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown10.unknown = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_11: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown11.unknown = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_ALL_INFO: { + uint32_t nlen; + ssize_t size; + void *vstr; + if (blob.length != 0x60) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->all_info.create_time = smbcli_pull_nttime(blob.data, 0x00); + io->all_info.access_time = smbcli_pull_nttime(blob.data, 0x08); + io->all_info.write_time = smbcli_pull_nttime(blob.data, 0x10); + io->all_info.change_time = smbcli_pull_nttime(blob.data, 0x18); + io->all_info.file_attr = IVAL(blob.data, 0x20); + io->all_info.unknown1 = IVAL(blob.data, 0x24); + io->all_info.alloc_size = BVAL(blob.data, 0x28); + io->all_info.size = BVAL(blob.data, 0x30); + io->all_info.nlink = IVAL(blob.data, 0x38); + io->all_info.unknown2 = IVAL(blob.data, 0x3C); + io->all_info.unknown3 = IVAL(blob.data, 0x40); + io->all_info.unknown4 = IVAL(blob.data, 0x44); + io->all_info.ea_size = IVAL(blob.data, 0x48); + io->all_info.access_mask = IVAL(blob.data, 0x4C); + io->all_info.unknown5 = BVAL(blob.data, 0x50); + io->all_info.unknown6 = BVAL(blob.data, 0x58); + nlen = IVAL(blob.data, 0x5C); + if (nlen > blob.length - 0x60) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + blob.data+0x60, nlen, &vstr); + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + io->all_info.fname = vstr; + break; + } + + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + return NT_STATUS_OK; +} + + +/* + recv a getinfo reply and parse the level info +*/ +NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + uint16_t level, union smb2_fileinfo *io) +{ + struct smb2_getinfo b; + NTSTATUS status; + + status = smb2_getinfo_recv(req, mem_ctx, &b); + NT_STATUS_NOT_OK_RETURN(status); + + status = smb2_getinfo_parse(mem_ctx, level, b.out.blob, io); + data_blob_free(&b.out.blob); + + return status; +} + diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c new file mode 100644 index 0000000000..cbb3f74fa4 --- /dev/null +++ b/source4/libcli/smb2/read.c @@ -0,0 +1,95 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client read call + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a read request +*/ +struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x00, io->in.buffer_code); + SSVAL(req->out.body, 0x02, 0); + SIVAL(req->out.body, 0x04, io->in.length); + SBVAL(req->out.body, 0x08, io->in.offset); + smb2_put_handle(req->out.body+0x10, io->in.handle); + memcpy(req->out.body+0x20, io->in._pad, 17); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a read reply +*/ +NTSTATUS smb2_read_recv(struct smb2_request *req, + TALLOC_CTX *mem_ctx, struct smb2_read *io) +{ + uint16_t ofs; + uint32_t nread; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 16) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + SMB2_CHECK_BUFFER_CODE(req, 0x11); + + ofs = SVAL(req->in.body, 0x02); + + nread = IVAL(req->in.body, 0x04); + memcpy(io->out.unknown, req->in.body+0x08, 8); + + if (smb2_oob_in(req, req->in.hdr+ofs, nread)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.data = data_blob_talloc(mem_ctx, req->in.hdr+ofs, nread); + if (io->out.data.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return smb2_request_destroy(req); +} + +/* + sync read request +*/ +NTSTATUS smb2_read(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_read *io) +{ + struct smb2_request *req = smb2_read_send(tree, io); + return smb2_read_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 4b95d141a3..a06121df05 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" #include "include/dlinklist.h" #include "lib/events/events.h" @@ -261,3 +262,14 @@ NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) blob->length = size; return NT_STATUS_OK; } + + +/* + put a file handle into a buffer +*/ +void smb2_put_handle(uint8_t *data, struct smb2_handle h) +{ + SBVAL(data, 0, h.data[0]); + SBVAL(data, 8, h.data[1]); +} + diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 22cdcef14f..aa2fb717b2 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -156,16 +156,16 @@ struct smb2_close { }; /* fs information levels */ -#define SMB2_GETINFO_FS_01 0x0102 -#define SMB2_GETINFO_FS_03 0x0302 -#define SMB2_GETINFO_FS_04 0x0402 -#define SMB2_GETINFO_FS_ATTRIB_INFO 0x0502 -#define SMB2_GETINFO_FS_06 0x0602 -#define SMB2_GETINFO_FS_07 0x0702 -#define SMB2_GETINFO_FS_08 0x0802 +#define SMB2_GETINFO_FS_01 0x0102 +#define SMB2_GETINFO_FS_03 0x0302 +#define SMB2_GETINFO_FS_04 0x0402 +#define SMB2_GETINFO_FS_ATTRIB_INFO 0x0502 +#define SMB2_GETINFO_FS_06 0x0602 +#define SMB2_GETINFO_FS_07 0x0702 +#define SMB2_GETINFO_FS_08 0x0802 /* class 3 levels */ -#define SMB2_GETINFO_3_00 0x0003 +#define SMB2_GETINFO_SECURITY 0x0003 /* file information levels */ #define SMB2_GETINFO_FILE_BASIC_INFO 0x0401 @@ -174,7 +174,7 @@ struct smb2_close { #define SMB2_GETINFO_FILE_EA_SIZE 0x0701 #define SMB2_GETINFO_FILE_ACCESS_INFO 0x0801 #define SMB2_GETINFO_FILE_0E 0x0e01 -#define SMB2_GETINFO_FILE_EA_INFO 0x0f01 +#define SMB2_GETINFO_FILE_ALL_EAS 0x0f01 #define SMB2_GETINFO_FILE_10 0x1001 #define SMB2_GETINFO_FILE_11 0x1101 #define SMB2_GETINFO_FILE_ALL_INFO 0x1201 @@ -191,7 +191,7 @@ struct smb2_getinfo { uint16_t level; uint32_t max_response_size; uint32_t unknown1; - uint32_t unknown2; + uint32_t flags; /* level specific */ uint32_t unknown3; uint32_t unknown4; struct smb2_handle handle; @@ -227,7 +227,7 @@ union smb2_fileinfo { struct { uint32_t ea_size; - } ea_info; + } ea_size; struct { uint32_t access_mask; @@ -239,8 +239,8 @@ union smb2_fileinfo { } unknown0e; struct { - struct smb_ea_list all_eas; - } all_ea_info; + struct smb_ea_list eas; + } all_eas; struct { uint32_t unknown; /* 2 */ @@ -302,3 +302,37 @@ union smb2_fileinfo { uint32_t unknown; } attrib_info; }; + + +struct smb2_write { + struct { + uint16_t buffer_code; + uint64_t offset; + struct smb2_handle handle; + uint8_t _pad[16]; + DATA_BLOB data; + } in; + + struct { + uint16_t buffer_code; + uint16_t _pad; + uint32_t nwritten; + uint8_t unknown[9]; + } out; +}; + +struct smb2_read { + struct { + uint16_t buffer_code; + uint32_t length; + uint64_t offset; + struct smb2_handle handle; + uint8_t _pad[17]; + } in; + + struct { + uint16_t buffer_code; + uint8_t unknown[8]; + DATA_BLOB data; + } out; +}; diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c new file mode 100644 index 0000000000..f842969b93 --- /dev/null +++ b/source4/libcli/smb2/write.c @@ -0,0 +1,82 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client write call + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a write request +*/ +struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_WRITE, io->in.data.length + 0x30); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x00, io->in.buffer_code); + SSVAL(req->out.body, 0x02, req->out.body+0x30 - req->out.hdr); + SIVAL(req->out.body, 0x04, io->in.data.length); + SBVAL(req->out.body, 0x08, io->in.offset); + smb2_put_handle(req->out.body+0x10, io->in.handle); + memcpy(req->out.body+0x20, io->in._pad, 0x10); + memcpy(req->out.body+0x30, io->in.data.data, io->in.data.length); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a write reply +*/ +NTSTATUS smb2_write_recv(struct smb2_request *req, struct smb2_write *io) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 17) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + SMB2_CHECK_BUFFER_CODE(req, 0x11); + + io->out._pad = SVAL(req->in.body, 0x02); + io->out.nwritten = IVAL(req->in.body, 0x04); + memcpy(io->out.unknown, req->in.body+0x08, 9); + + return smb2_request_destroy(req); +} + +/* + sync write request +*/ +NTSTATUS smb2_write(struct smb2_tree *tree, struct smb2_write *io) +{ + struct smb2_request *req = smb2_write_send(tree, io); + return smb2_write_recv(req, io); +} -- cgit From 61317df8aab2fe2fd47baba8a137566df7b23395 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Nov 2005 07:06:16 +0000 Subject: r11721: Fix warnings (This used to be commit d760583e388157ff25e317da06c57e5a42f171bd) --- source4/libcli/smb2/close.c | 2 +- source4/libcli/smb2/getinfo.c | 2 +- source4/libcli/smb2/read.c | 2 +- source4/libcli/smb2/request.c | 6 +++--- source4/libcli/smb2/write.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index d5a2c4d422..cf1cdbef5f 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -38,7 +38,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * SSVAL(req->out.body, 0x00, io->in.buffer_code); SSVAL(req->out.body, 0x02, io->in.flags); SIVAL(req->out.body, 0x04, io->in._pad); - smb2_put_handle(req->out.body+0x08, io->in.handle); + smb2_put_handle(req->out.body+0x08, &io->in.handle); smb2_transport_send(req); diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index a7935526e5..ffc2a92daf 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -42,7 +42,7 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin SIVAL(req->out.body, 0x0C, io->in.flags); SIVAL(req->out.body, 0x10, io->in.unknown3); SIVAL(req->out.body, 0x14, io->in.unknown4); - smb2_put_handle(req->out.body+0x18, io->in.handle); + smb2_put_handle(req->out.body+0x18, &io->in.handle); smb2_transport_send(req); diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index cbb3f74fa4..0d63a6ba0a 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -39,7 +39,7 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io SSVAL(req->out.body, 0x02, 0); SIVAL(req->out.body, 0x04, io->in.length); SBVAL(req->out.body, 0x08, io->in.offset); - smb2_put_handle(req->out.body+0x10, io->in.handle); + smb2_put_handle(req->out.body+0x10, &io->in.handle); memcpy(req->out.body+0x20, io->in._pad, 17); smb2_transport_send(req); diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index a06121df05..4e40b1884a 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -267,9 +267,9 @@ NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) /* put a file handle into a buffer */ -void smb2_put_handle(uint8_t *data, struct smb2_handle h) +void smb2_put_handle(uint8_t *data, struct smb2_handle *h) { - SBVAL(data, 0, h.data[0]); - SBVAL(data, 8, h.data[1]); + SBVAL(data, 0, h->data[0]); + SBVAL(data, 8, h->data[1]); } diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index f842969b93..e458a540e8 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -39,7 +39,7 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * SSVAL(req->out.body, 0x02, req->out.body+0x30 - req->out.hdr); SIVAL(req->out.body, 0x04, io->in.data.length); SBVAL(req->out.body, 0x08, io->in.offset); - smb2_put_handle(req->out.body+0x10, io->in.handle); + smb2_put_handle(req->out.body+0x10, &io->in.handle); memcpy(req->out.body+0x20, io->in._pad, 0x10); memcpy(req->out.body+0x30, io->in.data.data, io->in.data.length); -- cgit From de5d71aebe4e415fcebbfacb852b190498cbf7bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Nov 2005 12:31:02 +0000 Subject: r11722: make the smb2_push/pull functions take a smb2_request_buffer and the pull ones also a TALLOC_CTX, then we can reuse this functions in the server later metze (This used to be commit 9b616516cae269f0870e9b9a9cecd8ee3f0a9095) --- source4/libcli/smb2/getinfo.c | 3 +-- source4/libcli/smb2/negprot.c | 3 +-- source4/libcli/smb2/read.c | 6 +---- source4/libcli/smb2/request.c | 59 ++++++++++++++++++++----------------------- source4/libcli/smb2/session.c | 5 ++-- source4/libcli/smb2/tcon.c | 2 +- source4/libcli/smb2/write.c | 7 ++++- 7 files changed, 39 insertions(+), 46 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index ffc2a92daf..9ad2b77310 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -69,11 +69,10 @@ NTSTATUS smb2_getinfo_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, SMB2_CHECK_BUFFER_CODE(req, 0x09); - status = smb2_pull_ofs_blob(req, req->in.body+0x02, &io->out.blob); + status = smb2_pull_ofs_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { return status; } - talloc_steal(mem_ctx, io->out.blob.data); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 758b06fcae..0dc8c8ca14 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -77,8 +77,7 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, io->out.unknown8 = SVAL(req->in.body, 0x38); blobsize = SVAL(req->in.body, 0x3A); io->out.unknown9 = IVAL(req->in.body, 0x3C); - io->out.secblob = smb2_pull_blob(req, req->in.body+0x40, blobsize); - talloc_steal(mem_ctx, io->out.secblob.data); + io->out.secblob = smb2_pull_blob(&req->in, mem_ctx, req->in.body+0x40, blobsize); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index 0d63a6ba0a..720d0bdbe0 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -73,11 +73,7 @@ NTSTATUS smb2_read_recv(struct smb2_request *req, nread = IVAL(req->in.body, 0x04); memcpy(io->out.unknown, req->in.body+0x08, 8); - if (smb2_oob_in(req, req->in.hdr+ofs, nread)) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - io->out.data = data_blob_talloc(mem_ctx, req->in.hdr+ofs, nread); + io->out.data = smb2_pull_blob(&req->in, mem_ctx, req->in.hdr+ofs, nread); if (io->out.data.data == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 4e40b1884a..457b7a4531 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -150,60 +150,57 @@ BOOL smb2_request_is_error(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob_in(struct smb2_request *req, const uint8_t *ptr, uint_t size) +BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) { /* be careful with wraparound! */ - if (ptr < req->in.body || - ptr >= req->in.body + req->in.body_size || - size > req->in.body_size || - ptr + size > req->in.body + req->in.body_size) { + if (ptr < buf->body || + ptr >= buf->body + buf->body_size || + size > buf->body_size || + ptr + size > buf->body + buf->body_size) { return True; } return False; } /* - check if a range in the outgoing body is out of bounds + pull a data blob from the body of a reply */ -BOOL smb2_oob_out(struct smb2_request *req, const uint8_t *ptr, uint_t size) +DATA_BLOB smb2_pull_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, uint_t size) { - /* be careful with wraparound! */ - if (ptr < req->out.body || - ptr >= req->out.body + req->out.body_size || - size > req->out.body_size || - ptr + size > req->out.body + req->out.body_size) { - return True; + if (smb2_oob(buf, ptr, size)) { + return data_blob(NULL, 0); } - return False; + return data_blob_talloc(mem_ctx, ptr, size); } /* - pull a data blob from the body of a reply + push a data blob from the body of a reply */ -DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) +NTSTATUS smb2_push_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) { - if (smb2_oob_in(req, ptr, size)) { - return data_blob(NULL, 0); + if (smb2_oob(buf, ptr, blob.length)) { + return NT_STATUS_BUFFER_TOO_SMALL; } - return data_blob_talloc(req, ptr, size); + memcpy(ptr, blob.data, blob.length); + return NT_STATUS_OK; } /* pull a ofs/length/blob triple from a data blob the ptr points to the start of the offset/length pair */ -NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob) +NTSTATUS smb2_pull_ofs_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { uint16_t ofs, size; - if (smb2_oob_in(req, ptr, 4)) { + if (smb2_oob(buf, ptr, 4)) { return NT_STATUS_BUFFER_TOO_SMALL; } ofs = SVAL(ptr, 0); size = SVAL(ptr, 2); - if (smb2_oob_in(req, req->in.hdr + ofs, size)) { + if (smb2_oob(buf, buf->hdr + ofs, size)) { return NT_STATUS_BUFFER_TOO_SMALL; } - *blob = data_blob_talloc(req, req->in.hdr+ofs, size); + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); return NT_STATUS_OK; } @@ -215,12 +212,12 @@ NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *b NOTE: assumes blob goes immediately after the offset/length pair. Needs to be generalised */ -NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_ofs_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) { - if (smb2_oob_out(req, ptr, 4+blob.length)) { + if (smb2_oob(buf, ptr, 4+blob.length)) { return NT_STATUS_BUFFER_TOO_SMALL; } - SSVAL(ptr, 0, 4 + (ptr - req->out.hdr)); + SSVAL(ptr, 0, 4 + (ptr - buf->hdr)); SSVAL(ptr, 2, blob.length); memcpy(ptr+4, blob.data, blob.length); return NT_STATUS_OK; @@ -229,16 +226,16 @@ NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB bl /* pull a string in a ofs/length/blob format */ -NTSTATUS smb2_pull_ofs_string(struct smb2_request *req, uint8_t *ptr, - const char **str) +NTSTATUS smb2_pull_ofs_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, + uint8_t *ptr, const char **str) { DATA_BLOB blob; NTSTATUS status; ssize_t size; void *vstr; - status = smb2_pull_ofs_blob(req, ptr, &blob); + status = smb2_pull_ofs_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); - size = convert_string_talloc(req, CH_UTF16, CH_UNIX, + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); (*str) = vstr; @@ -263,7 +260,6 @@ NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) return NT_STATUS_OK; } - /* put a file handle into a buffer */ @@ -272,4 +268,3 @@ void smb2_put_handle(uint8_t *data, struct smb2_handle *h) SBVAL(data, 0, h->data[0]); SBVAL(data, 8, h->data[1]); } - diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 257e754660..cb2797b9ad 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -77,7 +77,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, req->session = session; - status = smb2_push_ofs_blob(req, req->out.body+0x0C, io->in.secblob); + status = smb2_push_ofs_blob(&req->out, req->out.body+0x0C, io->in.secblob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -112,12 +112,11 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, io->out._pad = SVAL(req->in.body, 0x02); io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); - status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob); + status = smb2_pull_ofs_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); return status; } - talloc_steal(mem_ctx, io->out.secblob.data); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index f68987acf7..5e53e11634 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -66,7 +66,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); SIVAL(req->out.body, 0x00, io->in.unknown1); - status = smb2_push_ofs_blob(req, req->out.body+0x04, path); + status = smb2_push_ofs_blob(&req->out, req->out.body+0x04, path); data_blob_free(&path); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index e458a540e8..a8e644f2d1 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -30,6 +30,7 @@ */ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write *io) { + NTSTATUS status; struct smb2_request *req; req = smb2_request_init_tree(tree, SMB2_OP_WRITE, io->in.data.length + 0x30); @@ -41,7 +42,11 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * SBVAL(req->out.body, 0x08, io->in.offset); smb2_put_handle(req->out.body+0x10, &io->in.handle); memcpy(req->out.body+0x20, io->in._pad, 0x10); - memcpy(req->out.body+0x30, io->in.data.data, io->in.data.length); + + status = smb2_push_blob(&req->out, req->out.body+0x30, io->in.data); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } smb2_transport_send(req); -- cgit From b51703baf152c309ce325ce573c1683d7e503122 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Nov 2005 04:38:59 +0000 Subject: r11730: added parsing and tests for a bunch more SMB2 getinfo levels (This used to be commit ca65bf0235cbfab451e5d5ceac9f714acc0cd46c) --- source4/libcli/raw/rawfileinfo.c | 74 ++++++++++++-------- source4/libcli/smb2/getinfo.c | 142 +++++++++++++++++++++++++++++++-------- source4/libcli/smb2/smb2_calls.h | 30 ++++----- 3 files changed, 176 insertions(+), 70 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index ede4391824..f631522182 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -34,6 +34,51 @@ return NT_STATUS_INFO_LENGTH_MISMATCH; \ } +/* + parse a stream information structure +*/ +NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx, + struct stream_information *io) +{ + uint32_t ofs = 0; + io->num_streams = 0; + io->streams = NULL; + + while (blob.length - ofs >= 24) { + uint_t n = io->num_streams; + uint32_t nlen, len; + ssize_t size; + void *vstr; + io->streams = + talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1); + if (!io->streams) { + return NT_STATUS_NO_MEMORY; + } + nlen = IVAL(blob.data, ofs + 0x04); + io->streams[n].size = BVAL(blob.data, ofs + 0x08); + io->streams[n].alloc_size = BVAL(blob.data, ofs + 0x10); + if (nlen > blob.length - (ofs + 24)) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + size = convert_string_talloc(io->streams, CH_UTF16, CH_UNIX, + blob.data+ofs+24, nlen, &vstr); + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + io->streams[n].stream_name.s = vstr; + io->streams[n].stream_name.private_length = nlen; + io->num_streams++; + len = IVAL(blob.data, ofs); + if (len > blob.length - ofs) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + if (len == 0) break; + ofs += len; + } + + return NT_STATUS_OK; +} + /**************************************************************************** Handle qfileinfo/qpathinfo trans2 backend. ****************************************************************************/ @@ -42,8 +87,6 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, union smb_fileinfo *parms, DATA_BLOB *blob) { - uint_t len, ofs; - switch (parms->generic.level) { case RAW_FILEINFO_GENERIC: case RAW_FILEINFO_GETATTR: @@ -175,32 +218,7 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, case RAW_FILEINFO_STREAM_INFO: case RAW_FILEINFO_STREAM_INFORMATION: - ofs = 0; - parms->stream_info.out.num_streams = 0; - parms->stream_info.out.streams = NULL; - - while (blob->length - ofs >= 24) { - uint_t n = parms->stream_info.out.num_streams; - parms->stream_info.out.streams = - talloc_realloc(mem_ctx, - parms->stream_info.out.streams, - struct stream_struct, - n+1); - if (!parms->stream_info.out.streams) { - return NT_STATUS_NO_MEMORY; - } - parms->stream_info.out.streams[n].size = BVAL(blob->data, ofs + 8); - parms->stream_info.out.streams[n].alloc_size = BVAL(blob->data, ofs + 16); - smbcli_blob_pull_string(session, mem_ctx, blob, - &parms->stream_info.out.streams[n].stream_name, - ofs+4, ofs+24, STR_UNICODE); - parms->stream_info.out.num_streams++; - len = IVAL(blob->data, ofs); - if (len > blob->length - ofs) return NT_STATUS_INFO_LENGTH_MISMATCH; - if (len == 0) break; - ofs += len; - } - return NT_STATUS_OK; + return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out); case RAW_FILEINFO_INTERNAL_INFORMATION: FINFO_CHECK_SIZE(8); diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 9ad2b77310..7a362b24d9 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -113,18 +113,18 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, if (blob.length != 0x18) { return NT_STATUS_INFO_LENGTH_MISMATCH; } - io->size_info.alloc_size = BVAL(blob.data, 0x00); - io->size_info.size = BVAL(blob.data, 0x08); - io->size_info.nlink = IVAL(blob.data, 0x10); - io->size_info.unknown = IVAL(blob.data, 0x14); + io->size_info.alloc_size = BVAL(blob.data, 0x00); + io->size_info.size = BVAL(blob.data, 0x08); + io->size_info.nlink = IVAL(blob.data, 0x10); + io->size_info.delete_pending = CVAL(blob.data, 0x14); + io->size_info.directory = CVAL(blob.data, 0x15); break; - case SMB2_GETINFO_FILE_06: + case SMB2_GETINFO_FILE_ID: if (blob.length != 0x8) { return NT_STATUS_INFO_LENGTH_MISMATCH; } - io->unknown06.unknown1 = IVAL(blob.data, 0x00); - io->unknown06.unknown2 = IVAL(blob.data, 0x04); + io->file_id.file_id = BVAL(blob.data, 0x00); break; case SMB2_GETINFO_FILE_EA_SIZE: @@ -172,37 +172,105 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, uint32_t nlen; ssize_t size; void *vstr; - if (blob.length != 0x60) { + if (blob.length < 0x64) { return NT_STATUS_INFO_LENGTH_MISMATCH; } - io->all_info.create_time = smbcli_pull_nttime(blob.data, 0x00); - io->all_info.access_time = smbcli_pull_nttime(blob.data, 0x08); - io->all_info.write_time = smbcli_pull_nttime(blob.data, 0x10); - io->all_info.change_time = smbcli_pull_nttime(blob.data, 0x18); - io->all_info.file_attr = IVAL(blob.data, 0x20); - io->all_info.unknown1 = IVAL(blob.data, 0x24); - io->all_info.alloc_size = BVAL(blob.data, 0x28); - io->all_info.size = BVAL(blob.data, 0x30); - io->all_info.nlink = IVAL(blob.data, 0x38); - io->all_info.unknown2 = IVAL(blob.data, 0x3C); - io->all_info.unknown3 = IVAL(blob.data, 0x40); - io->all_info.unknown4 = IVAL(blob.data, 0x44); - io->all_info.ea_size = IVAL(blob.data, 0x48); - io->all_info.access_mask = IVAL(blob.data, 0x4C); - io->all_info.unknown5 = BVAL(blob.data, 0x50); - io->all_info.unknown6 = BVAL(blob.data, 0x58); - nlen = IVAL(blob.data, 0x5C); - if (nlen > blob.length - 0x60) { + io->all_info.create_time = smbcli_pull_nttime(blob.data, 0x00); + io->all_info.access_time = smbcli_pull_nttime(blob.data, 0x08); + io->all_info.write_time = smbcli_pull_nttime(blob.data, 0x10); + io->all_info.change_time = smbcli_pull_nttime(blob.data, 0x18); + io->all_info.file_attr = IVAL(blob.data, 0x20); + io->all_info.alloc_size = BVAL(blob.data, 0x28); + io->all_info.size = BVAL(blob.data, 0x30); + io->all_info.nlink = IVAL(blob.data, 0x38); + io->all_info.delete_pending = CVAL(blob.data, 0x3C); + io->all_info.directory = CVAL(blob.data, 0x3D); + io->all_info.file_id = BVAL(blob.data, 0x40); + io->all_info.ea_size = IVAL(blob.data, 0x48); + io->all_info.access_mask = IVAL(blob.data, 0x4C); + io->all_info.unknown5 = BVAL(blob.data, 0x50); + io->all_info.unknown6 = BVAL(blob.data, 0x58); + nlen = IVAL(blob.data, 0x60); + if (nlen > blob.length - 0x64) { return NT_STATUS_INFO_LENGTH_MISMATCH; } size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, - blob.data+0x60, nlen, &vstr); + blob.data+0x64, nlen, &vstr); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } io->all_info.fname = vstr; break; } + + case SMB2_GETINFO_FILE_SHORT_INFO: { + uint32_t nlen; + ssize_t size; + void *vstr; + if (blob.length < 0x04) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + nlen = IVAL(blob.data, 0x00); + if (nlen > blob.length - 0x04) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + blob.data+0x04, nlen, &vstr); + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + io->short_info.short_name = vstr; + break; + } + + case SMB2_GETINFO_FILE_STREAM_INFO: + return smbcli_parse_stream_info(blob, mem_ctx, &io->stream_info); + + case SMB2_GETINFO_FILE_EOF_INFO: + if (blob.length != 0x10) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->eof_info.size = BVAL(blob.data, 0x00); + io->eof_info.unknown = BVAL(blob.data, 0x08); + break; + + case SMB2_GETINFO_FILE_STANDARD_INFO: + if (blob.length != 0x38) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->standard_info.create_time = smbcli_pull_nttime(blob.data, 0x00); + io->standard_info.access_time = smbcli_pull_nttime(blob.data, 0x08); + io->standard_info.write_time = smbcli_pull_nttime(blob.data, 0x10); + io->standard_info.change_time = smbcli_pull_nttime(blob.data, 0x18); + io->standard_info.alloc_size = BVAL(blob.data, 0x20); + io->standard_info.size = BVAL(blob.data, 0x28); + io->standard_info.file_attr = IVAL(blob.data, 0x30); + io->standard_info.unknown = IVAL(blob.data, 0x34); + break; + + case SMB2_GETINFO_FILE_ATTRIB_INFO: + if (blob.length != 0x08) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->standard_info.file_attr = IVAL(blob.data, 0x00); + io->standard_info.unknown = IVAL(blob.data, 0x04); + break; + + case SMB2_GETINFO_SECURITY: { + struct ndr_pull *ndr; + NTSTATUS status; + ndr = ndr_pull_init_blob(&blob, mem_ctx); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + io->security.sd = talloc(mem_ctx, struct security_descriptor); + if (io->security.sd == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->security.sd); + talloc_free(ndr); + return status; + } default: return NT_STATUS_INVALID_INFO_CLASS; @@ -230,3 +298,23 @@ NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return status; } +/* + level specific getinfo call +*/ +NTSTATUS smb2_getinfo_level(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + struct smb2_handle handle, + uint16_t level, union smb2_fileinfo *io) +{ + struct smb2_getinfo b; + struct smb2_request *req; + + ZERO_STRUCT(b); + b.in.buffer_code = 0x29; + b.in.max_response_size = 0x10000; + b.in.handle = handle; + b.in.level = level; + + req = smb2_getinfo_send(tree, &b); + + return smb2_getinfo_level_recv(req, mem_ctx, level, io); +} diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index aa2fb717b2..127a9d229c 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -170,7 +170,7 @@ struct smb2_close { /* file information levels */ #define SMB2_GETINFO_FILE_BASIC_INFO 0x0401 #define SMB2_GETINFO_FILE_SIZE_INFO 0x0501 -#define SMB2_GETINFO_FILE_06 0x0601 +#define SMB2_GETINFO_FILE_ID 0x0601 #define SMB2_GETINFO_FILE_EA_SIZE 0x0701 #define SMB2_GETINFO_FILE_ACCESS_INFO 0x0801 #define SMB2_GETINFO_FILE_0E 0x0e01 @@ -217,13 +217,13 @@ union smb2_fileinfo { uint64_t alloc_size; uint64_t size; uint32_t nlink; - uint32_t unknown; + uint8_t delete_pending; + uint8_t directory; } size_info; struct { - uint32_t unknown1; - uint32_t unknown2; - } unknown06; + uint64_t file_id; + } file_id; struct { uint32_t ea_size; @@ -256,13 +256,14 @@ union smb2_fileinfo { NTTIME write_time; NTTIME change_time; uint32_t file_attr; - uint32_t unknown1; + /* uint32_t _pad; */ uint64_t alloc_size; uint64_t size; uint32_t nlink; - uint32_t unknown2; - uint32_t unknown3; - uint32_t unknown4; + uint8_t delete_pending; + uint8_t directory; + /* uint16_t _pad; */ + uint64_t file_id; uint32_t ea_size; uint32_t access_mask; uint64_t unknown5; @@ -274,12 +275,7 @@ union smb2_fileinfo { const char *short_name; } short_info; - struct { - uint32_t unknown; - uint64_t size; - uint64_t alloc_size; - const char *stream_name; - } stream_info; + struct stream_information stream_info; struct { uint64_t size; @@ -301,6 +297,10 @@ union smb2_fileinfo { uint32_t file_attr; uint32_t unknown; } attrib_info; + + struct { + struct security_descriptor *sd; + } security; }; -- cgit From 8dc40d68030396dd22844ff68b260645526e68f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Nov 2005 05:28:30 +0000 Subject: r11731: fixed typo noticed by metze (This used to be commit e51fb2b44ad524620451807cccb186dd4be704c7) --- source4/libcli/smb2/getinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 7a362b24d9..9599a6c48c 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -252,8 +252,8 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, if (blob.length != 0x08) { return NT_STATUS_INFO_LENGTH_MISMATCH; } - io->standard_info.file_attr = IVAL(blob.data, 0x00); - io->standard_info.unknown = IVAL(blob.data, 0x04); + io->attrib_info.file_attr = IVAL(blob.data, 0x00); + io->attrib_info.unknown = IVAL(blob.data, 0x04); break; case SMB2_GETINFO_SECURITY: { -- cgit From ab0d0f0623eed2990924580d73c05d6f0b6c8178 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Nov 2005 04:35:10 +0000 Subject: r11735: fixed the ALL_EAS smb2 level parsing (This used to be commit dd24c0e80cf07bda700a0abb84a7a053d817f903) --- source4/libcli/smb2/getinfo.c | 6 +++--- source4/libcli/smb2/smb2_calls.h | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 9599a6c48c..4817f09d68 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -150,9 +150,9 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, break; case SMB2_GETINFO_FILE_ALL_EAS: - return ea_pull_list(&blob, mem_ctx, - &io->all_eas.eas.num_eas, - &io->all_eas.eas.eas); + return ea_pull_list_chained(&blob, mem_ctx, + &io->all_eas.num_eas, + &io->all_eas.eas); case SMB2_GETINFO_FILE_10: if (blob.length != 0x4) { diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 127a9d229c..204ab7defb 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -238,12 +238,10 @@ union smb2_fileinfo { uint32_t unknown2; } unknown0e; - struct { - struct smb_ea_list eas; - } all_eas; + struct smb_ea_list all_eas; struct { - uint32_t unknown; /* 2 */ + uint32_t unknown; } unknown10; struct { -- cgit From b16543648e3cee12d6daf6d2d01c57fe1d13d6eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Nov 2005 06:36:08 +0000 Subject: r11737: use _smb_setlen2() to allow for 24 bit lengths in SMB2 packets (This used to be commit 54fda24379ca1a20d6de2edf64dd79b3fe80a37d) --- source4/libcli/smb2/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index c6fc890e34..083034a547 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -251,7 +251,7 @@ void smb2_transport_send(struct smb2_request *req) DATA_BLOB blob; NTSTATUS status; - _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); + _smb_setlen2(req->out.buffer, req->out.size - NBT_HDR_SIZE); DEBUG(2, ("SMB2 send seqnum=0x%llx\n", req->seqnum)); dump_data(5, req->out.body, req->out.body_size); -- cgit From 43fa1b6dbd5e03251572fb6c2ee7c7f59f413c7d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 10:16:14 +0000 Subject: r11740: add some EA error codes metze (This used to be commit b1afcced395812477365befad1ed37a7cdafa275) --- source4/libcli/util/nterr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index ca8605faea..45d0181103 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -35,7 +35,10 @@ static const nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, + { "STATUS_NO_MORE_EAS", STATUS_NO_MORE_EAS }, + { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME }, { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT }, + { "STATUS_INVALID_EA_FLAG", STATUS_INVALID_EA_FLAG }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, -- cgit From e9eb56068573d89f8ce45f08220ca870b3daa669 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 11:01:15 +0000 Subject: r11741: - the buffer code (first 2 bytes in the SMB2 body) seem to be the length of the fixed body part, and +1 if there's a dynamic part - there're 3 types of dynamic blobs with uint16_t offset/uint16_t size with uint16_t offset/uint32_t size with uint32_t offset/uint32_t size /* aligned to 8 bytes */ - strings are transmitted in UTF-16 with no termination and packet into a uint16/uint16 blob metze (This used to be commit 79103c51e5c752fbdb4d25a0047b65002828df89) --- source4/libcli/smb2/close.c | 11 +- source4/libcli/smb2/connect.c | 4 +- source4/libcli/smb2/create.c | 59 ++++---- source4/libcli/smb2/getinfo.c | 17 +-- source4/libcli/smb2/negprot.c | 31 +++-- source4/libcli/smb2/read.c | 34 ++--- source4/libcli/smb2/request.c | 290 +++++++++++++++++++++++++++++++++------ source4/libcli/smb2/session.c | 20 ++- source4/libcli/smb2/smb2.h | 31 +++-- source4/libcli/smb2/smb2_calls.h | 132 +++++++++++++----- source4/libcli/smb2/tcon.c | 18 +-- source4/libcli/smb2/transport.c | 1 - source4/libcli/smb2/write.c | 27 ++-- 13 files changed, 449 insertions(+), 226 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index cf1cdbef5f..c851d60be4 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -32,13 +32,12 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18); + req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x00, io->in.buffer_code); SSVAL(req->out.body, 0x02, io->in.flags); SIVAL(req->out.body, 0x04, io->in._pad); - smb2_put_handle(req->out.body+0x08, &io->in.handle); + smb2_push_handle(req->out.body+0x08, &io->in.handle); smb2_transport_send(req); @@ -56,11 +55,7 @@ NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) return smb2_request_destroy(req); } - if (req->in.body_size < 0x3C) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x3C); + SMB2_CHECK_PACKET_RECV(req, 0x3C, False); io->out.flags = SVAL(req->in.body, 0x02); io->out._pad = IVAL(req->in.body, 0x04); diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 18f28539ea..7b538dc2e6 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -157,8 +157,8 @@ static void continue_socket(struct composite_context *creq) } ZERO_STRUCT(state->negprot); - state->negprot.in.unknown1 = 0x010024; - + state->negprot.in.unknown1 = 0x0001; + state->req = smb2_negprot_send(transport, &state->negprot); if (state->req == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 9483f35ca1..79d3341bd0 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -32,18 +32,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create { struct smb2_request *req; NTSTATUS status; - DATA_BLOB path; - uint8_t *ptr; - status = smb2_string_blob(tree, io->in.fname, &path); - if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - - req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length); + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, 1); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x00, io->in.buffer_code); SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3[0]); @@ -56,23 +48,17 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(req->out.body, 0x24, io->in.open_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); - SSVAL(req->out.body, 0x2C, 0x40+0x38); /* offset to fname */ - SSVAL(req->out.body, 0x2E, path.length); - SIVAL(req->out.body, 0x30, 0x40+0x38+path.length); /* offset to 2nd buffer? */ - - SIVAL(req->out.body, 0x34, io->in.unknown6); - - memcpy(req->out.body+0x38, path.data, path.length); - - ptr = req->out.body+0x38+path.length; - - SIVAL(ptr, 0x00, io->in.unknown7); - SIVAL(ptr, 0x04, io->in.unknown8); - SIVAL(ptr, 0x08, io->in.unknown9); - SIVAL(ptr, 0x0C, io->in.unknown10); - SBVAL(ptr, 0x10, io->in.unknown11); + status = smb2_push_o16s16_string(&req->out, req->out.body+0x2C, io->in.fname); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } - data_blob_free(&path); + status = smb2_push_o32s32_blob(&req->out, req->out.body+0x30, io->in.blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } smb2_transport_send(req); @@ -83,18 +69,16 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* recv a create reply */ -NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) +NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io) { + NTSTATUS status; + if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } - if (req->in.body_size < 0x54) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x59); + SMB2_CHECK_PACKET_RECV(req, 0x58, True); io->out.oplock_flags = SVAL(req->in.body, 0x02); io->out.create_action = IVAL(req->in.body, 0x04); @@ -106,9 +90,12 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); io->out._pad = IVAL(req->in.body, 0x3C); - io->out.handle.data[0] = BVAL(req->in.body, 0x40); - io->out.handle.data[1] = BVAL(req->in.body, 0x48); - io->out.unknown4 = IVAL(req->in.body, 0x50); + smb2_pull_handle(req->in.body+0x40, &io->out.handle); + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } return smb2_request_destroy(req); } @@ -116,8 +103,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) /* sync create request */ -NTSTATUS smb2_create(struct smb2_tree *tree, struct smb2_create *io) +NTSTATUS smb2_create(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_create *io) { struct smb2_request *req = smb2_create_send(tree, io); - return smb2_create_recv(req, io); + return smb2_create_recv(req, mem_ctx, io); } diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 4817f09d68..1594b8c1b4 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -32,17 +32,19 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28); + req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x00, io->in.buffer_code); + /* this seems to be a bug, they use 0x29 but only send 0x28 bytes */ + SSVAL(req->out.body, 0x00, 0x29); + SSVAL(req->out.body, 0x02, io->in.level); SIVAL(req->out.body, 0x04, io->in.max_response_size); SIVAL(req->out.body, 0x08, io->in.unknown1); SIVAL(req->out.body, 0x0C, io->in.flags); SIVAL(req->out.body, 0x10, io->in.unknown3); SIVAL(req->out.body, 0x14, io->in.unknown4); - smb2_put_handle(req->out.body+0x18, &io->in.handle); + smb2_push_handle(req->out.body+0x18, &io->in.handle); smb2_transport_send(req); @@ -63,13 +65,9 @@ NTSTATUS smb2_getinfo_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - if (req->in.body_size < 0x08) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x09); + SMB2_CHECK_PACKET_RECV(req, 0x08, True); - status = smb2_pull_ofs_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); + status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -309,7 +307,6 @@ NTSTATUS smb2_getinfo_level(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_request *req; ZERO_STRUCT(b); - b.in.buffer_code = 0x29; b.in.max_response_size = 0x10000; b.in.handle = handle; b.in.level = level; diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 0dc8c8ca14..a3cf8eb018 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -33,12 +33,15 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, { struct smb2_request *req; - req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26); + req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26, 0); if (req == NULL) return NULL; - SIVAL(req->out.body, 0x00, io->in.unknown1); - SSVAL(req->out.body, 0x04, io->in.unknown2); - memcpy(req->out.body+0x06, io->in.unknown3, 32); + /* this seems to be a bug, they use 0x24 but the length is 0x26 */ + SSVAL(req->out.body, 0x00, 0x24); + + SSVAL(req->out.body, 0x02, io->in.unknown1); + memcpy(req->out.body+0x04, io->in.unknown2, 32); + SSVAL(req->out.body, 0x24, io->in.unknown3); smb2_transport_send(req); @@ -51,18 +54,14 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_negprot *io) { - uint16_t blobsize; + NTSTATUS status; - if (!smb2_request_receive(req) || + if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } - if (req->in.body_size < 0x40) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x41); + SMB2_CHECK_PACKET_RECV(req, 0x40, True); io->out._pad = SVAL(req->in.body, 0x02); io->out.unknown2 = IVAL(req->in.body, 0x04); @@ -74,10 +73,14 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, io->out.unknown7 = SVAL(req->in.body, 0x26); io->out.current_time = smbcli_pull_nttime(req->in.body, 0x28); io->out.boot_time = smbcli_pull_nttime(req->in.body, 0x30); - io->out.unknown8 = SVAL(req->in.body, 0x38); - blobsize = SVAL(req->in.body, 0x3A); + + status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x38, &io->out.secblob); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + io->out.unknown9 = IVAL(req->in.body, 0x3C); - io->out.secblob = smb2_pull_blob(&req->in, mem_ctx, req->in.body+0x40, blobsize); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index 720d0bdbe0..f598a78cba 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -32,15 +32,16 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31); + req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x00, io->in.buffer_code); - SSVAL(req->out.body, 0x02, 0); + SSVAL(req->out.body, 0x02, io->in._pad); SIVAL(req->out.body, 0x04, io->in.length); SBVAL(req->out.body, 0x08, io->in.offset); - smb2_put_handle(req->out.body+0x10, &io->in.handle); - memcpy(req->out.body+0x20, io->in._pad, 17); + smb2_push_handle(req->out.body+0x10, &io->in.handle); + SBVAL(req->out.body, 0x20, io->in.unknown1); + SBVAL(req->out.body, 0x28, io->in.unknown2); + SCVAL(req->out.body, 0x30, io->in._bug); smb2_transport_send(req); @@ -54,30 +55,23 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io NTSTATUS smb2_read_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_read *io) { - uint16_t ofs; - uint32_t nread; + NTSTATUS status; if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } - if (req->in.body_size < 16) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x11); - - ofs = SVAL(req->in.body, 0x02); + SMB2_CHECK_PACKET_RECV(req, 0x10, True); - nread = IVAL(req->in.body, 0x04); - memcpy(io->out.unknown, req->in.body+0x08, 8); - - io->out.data = smb2_pull_blob(&req->in, mem_ctx, req->in.hdr+ofs, nread); - if (io->out.data.data == NULL) { - return NT_STATUS_NO_MEMORY; + status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.data); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; } + io->out.unknown1 = BVAL(req->in.body, 0x08); + return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 457b7a4531..bb8ff06e2d 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -3,7 +3,8 @@ SMB2 client request handling - Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Stefan Metzmacher 2005 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 @@ -30,8 +31,8 @@ /* initialise a smb2 request */ -struct smb2_request *smb2_request_init(struct smb2_transport *transport, - uint16_t opcode, uint32_t body_size) +struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode, + uint16_t body_fixed_size, uint32_t body_dynamic_size) { struct smb2_request *req; @@ -49,18 +50,18 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, ZERO_STRUCT(req->in); - req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_size; + req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+body_dynamic_size; req->out.buffer = talloc_size(req, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); return NULL; } - req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE + body_size; + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+(body_dynamic_size?1:0); req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.body = req->out.hdr + SMB2_HDR_BODY; - req->out.body_size = body_size; - req->out.ptr = req->out.body; + req->out.body_size = body_fixed_size; + req->out.dynamic = (body_dynamic_size ? req->out.body + body_fixed_size : NULL); SIVAL(req->out.hdr, 0, SMB2_MAGIC); SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); @@ -76,17 +77,28 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, SBVAL(req->out.hdr, SMB2_HDR_UID, 0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + /* set the length of the fixed body part and +1 if there's a dynamic part also */ + SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0)); + + /* + * if we have a dynamic part, make sure the first byte + * which is always be part of the packet is initialized + */ + if (body_dynamic_size) { + SCVAL(req->out.dynamic, 0, 0); + } + return req; } /* initialise a smb2 request for tree operations */ -struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, - uint16_t opcode, uint32_t body_size) +struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode, + uint16_t body_fixed_size, uint32_t body_dynamic_size) { struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, - body_size); + body_fixed_size, body_dynamic_size); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); @@ -162,41 +174,123 @@ BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) return False; } +static size_t smb2_padding_size(uint32_t offset, size_t n) +{ + if ((offset & (n-1)) == 0) return 0; + return n - (offset & (n-1)); +} + +static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t n) +{ + size_t dynamic_ofs; + uint8_t *buffer_ptr; + + /* a packet size should be limited a bit */ + if (n >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW; + + if (n <= buf->allocated) return NT_STATUS_OK; + + dynamic_ofs = buf->dynamic - buf->buffer; + + buffer_ptr = talloc_realloc_size(buf, buf->buffer, n); + NT_STATUS_HAVE_NO_MEMORY(buffer_ptr); + + buf->buffer = buffer_ptr; + buf->hdr = buf->buffer + NBT_HDR_SIZE; + buf->body = buf->hdr + SMB2_HDR_BODY; + buf->dynamic = buf->buffer + dynamic_ofs; + buf->allocated = n; + + return NT_STATUS_OK; +} + /* - pull a data blob from the body of a reply + pull a uint16_t ofs/ uint16_t length/blob triple from a data blob + the ptr points to the start of the offset/length pair */ -DATA_BLOB smb2_pull_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, uint_t size) +NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { - if (smb2_oob(buf, ptr, size)) { - return data_blob(NULL, 0); + uint16_t ofs, size; + if (smb2_oob(buf, ptr, 4)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = SVAL(ptr, 0); + size = SVAL(ptr, 2); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; } - return data_blob_talloc(mem_ctx, ptr, size); + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; } /* - push a data blob from the body of a reply + push a uint16_t ofs/ uint16_t length/blob triple into a data blob + the ptr points to the start of the offset/length pair */ -NTSTATUS smb2_push_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) { - if (smb2_oob(buf, ptr, blob.length)) { + NTSTATUS status; + size_t offset; + size_t padding_length; + + if (!buf->dynamic) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* we have only 16 bit for the size */ + if (blob.length > 0xFFFF) { return NT_STATUS_BUFFER_TOO_SMALL; } - memcpy(ptr, blob.data, blob.length); + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 4)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 2); + offset += padding_length; + + SSVAL(ptr, 0, offset); + SSVAL(ptr, 2, blob.length); + + status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size = buf->dynamic - buf->buffer; + return NT_STATUS_OK; } /* - pull a ofs/length/blob triple from a data blob + pull a uint16_t ofs/ uint32_t length/blob triple from a data blob the ptr points to the start of the offset/length pair */ -NTSTATUS smb2_pull_ofs_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { - uint16_t ofs, size; - if (smb2_oob(buf, ptr, 4)) { + uint16_t ofs; + uint32_t size; + + if (smb2_oob(buf, ptr, 6)) { return NT_STATUS_BUFFER_TOO_SMALL; } ofs = SVAL(ptr, 0); - size = SVAL(ptr, 2); + size = IVAL(ptr, 2); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } if (smb2_oob(buf, buf->hdr + ofs, size)) { return NT_STATUS_BUFFER_TOO_SMALL; } @@ -206,35 +300,124 @@ NTSTATUS smb2_pull_ofs_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx } /* - push a ofs/length/blob triple into a data blob + push a uint16_t ofs/ uint32_t length/blob triple into a data blob the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +{ + NTSTATUS status; + size_t offset; + size_t padding_length; - NOTE: assumes blob goes immediately after the offset/length pair. Needs - to be generalised + if (!buf->dynamic) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 6)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 2); + offset += padding_length; + + SSVAL(ptr, 0, offset); + SIVAL(ptr, 2, blob.length); + + status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size = buf->dynamic - buf->buffer; + + return NT_STATUS_OK; +} + +/* + pull a uint32_t ofs/ uint32_t length/blob triple from a data blob + the ptr points to the start of the offset/length pair */ -NTSTATUS smb2_push_ofs_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { - if (smb2_oob(buf, ptr, 4+blob.length)) { + uint32_t ofs, size; + if (smb2_oob(buf, ptr, 8)) { return NT_STATUS_BUFFER_TOO_SMALL; } - SSVAL(ptr, 0, 4 + (ptr - buf->hdr)); - SSVAL(ptr, 2, blob.length); - memcpy(ptr+4, blob.data, blob.length); + ofs = IVAL(ptr, 0); + size = IVAL(ptr, 4); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); return NT_STATUS_OK; } /* - pull a string in a ofs/length/blob format + push a uint32_t ofs/ uint32_t length/blob triple into a data blob + the ptr points to the start of the offset/length pair */ -NTSTATUS smb2_pull_ofs_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, - uint8_t *ptr, const char **str) +NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +{ + NTSTATUS status; + size_t offset; + size_t padding_length; + + if (!buf->dynamic) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 8); + offset += padding_length; + + SIVAL(ptr, 0, offset); + SIVAL(ptr, 4, blob.length); + + status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size = buf->dynamic - buf->buffer; + + return NT_STATUS_OK; +} + +/* + pull a string in a uint16_t ofs/ uint16_t length/blob format + UTF-16 without termination +*/ +NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, + uint8_t *ptr, const char **str) { DATA_BLOB blob; NTSTATUS status; ssize_t size; void *vstr; - status = smb2_pull_ofs_blob(buf, mem_ctx, ptr, &blob); + + status = smb2_pull_o16s16_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); @@ -246,25 +429,44 @@ NTSTATUS smb2_pull_ofs_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_c } /* - create a UTF16 string in a blob from a char* + push a string in a uint16_t ofs/ uint16_t length/blob format + UTF-16 without termination */ -NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) +NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, + uint8_t *ptr, const char *str) { + DATA_BLOB blob; + NTSTATUS status; ssize_t size; - size = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, - str, strlen(str), (void **)&blob->data); + + size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, + str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } - blob->length = size; - return NT_STATUS_OK; + blob.length = size; + + status = smb2_push_o16s16_blob(buf, ptr, blob); + data_blob_free(&blob); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; } /* - put a file handle into a buffer + push a file handle into a buffer */ -void smb2_put_handle(uint8_t *data, struct smb2_handle *h) +void smb2_push_handle(uint8_t *data, struct smb2_handle *h) { SBVAL(data, 0, h->data[0]); SBVAL(data, 8, h->data[1]); } + +/* + pull a file handle from a buffer +*/ +void smb2_pull_handle(uint8_t *ptr, struct smb2_handle *h) +{ + h->data[0] = BVAL(ptr, 0); + h->data[1] = BVAL(ptr, 8); +} diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index cb2797b9ad..e572227a48 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -67,17 +67,17 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, NTSTATUS status; req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, - 0x10 + io->in.secblob.length); + 0x10, io->in.secblob.length); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); - SIVAL(req->out.body, 0x00, io->in.unknown1); + SSVAL(req->out.body, 0x02, io->in._pad); SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3); - + req->session = session; - - status = smb2_push_ofs_blob(&req->out, req->out.body+0x0C, io->in.secblob); + + status = smb2_push_o16s16_blob(&req->out, req->out.body+0x0C, io->in.secblob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -103,16 +103,12 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - if (req->in.body_size < 0x08) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x09); + SMB2_CHECK_PACKET_RECV(req, 0x08, True); io->out._pad = SVAL(req->in.body, 0x02); io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); - status = smb2_pull_ofs_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob); + status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); return status; @@ -203,7 +199,7 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se c->event_ctx = session->transport->socket->event.ctx; ZERO_STRUCT(state->io); - state->io.in.unknown1 = 0x11; + state->io.in._pad = 0x0; state->io.in.unknown2 = 0xF; state->io.in.unknown3 = 0x00; diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index e99e8d3945..47dd6fd272 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -87,13 +87,11 @@ struct smb2_request_buffer { /* the packet body */ uint8_t *body; uint_t body_size; - - /* ptr is used as a moving pointer into the data area - * of the packet. The reason its here and not a local - * variable in each function is that when a realloc of - * a send packet is done we need to move this - * pointer */ - uint8_t *ptr; + + /* this point to the next dynamic byte that can be used + * this will be moved when some dynamic data is pushed + */ + uint8_t *dynamic; }; @@ -176,13 +174,20 @@ struct smb2_request { #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ /* - check that a buffer code matches the expected value + check that a body has the expected size */ -#define SMB2_CHECK_BUFFER_CODE(req, code) do { \ - io->out.buffer_code = SVAL(req->in.body, 0); \ - if (io->out.buffer_code != (code)) { \ - DEBUG(0,("Unexpected buffer code 0x%x. Expected 0x%x\n", \ - io->out.buffer_code, code)); \ +#define SMB2_CHECK_PACKET_RECV(req, size, dynamic) do { \ + uint_t is_size = req->in.body_size; \ + uint16_t field_size = SVAL(req->in.body, 0); \ + uint16_t want_size = ((dynamic)?(size)+1:(size)); \ + if (is_size < (size)) { \ + DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \ + __location__, is_size, want_size)); \ + return NT_STATUS_BUFFER_TOO_SMALL; \ + }\ + if (field_size != want_size) { \ + DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \ + __location__, field_size, want_size)); \ return NT_STATUS_INVALID_PARAMETER; \ } \ } while (0) diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 204ab7defb..d0a1cb8905 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -23,12 +23,15 @@ struct smb2_negprot { struct { - uint32_t unknown1; /* 0x00010024 */ - uint16_t unknown2; /* 0x00 */ - uint8_t unknown3[32]; /* all zero */ + /* static body buffer 38 (0x26) bytes */ + /* uint16_t buffer_code; 0x24 (why?) */ + uint16_t unknown1; /* 0x0001 */ + uint8_t unknown2[32]; /* all zero */ + uint16_t unknown3; /* 0x00000 */ } in; struct { - uint16_t buffer_code; + /* static body buffer 64 (0x40) bytes */ + /* uint16_t buffer_code; 0x41 = 0x40 + 1 */ uint16_t _pad; uint32_t unknown2; /* 0x06 */ uint8_t sessid[16]; @@ -39,41 +42,63 @@ struct smb2_negprot { uint16_t unknown7; /* 0x01 */ NTTIME current_time; NTTIME boot_time; - uint16_t unknown8; /* 0x80 */ - /* uint16_t secblob size here */ + /* uint16_t secblob_ofs */ + /* uint16_t secblob_size */ uint32_t unknown9; /* 0x204d4c20 */ + + /* dynamic body buffer */ DATA_BLOB secblob; } out; }; struct smb2_session_setup { struct { - uint32_t unknown1; /* 0x11 */ + /* static body buffer 16 (0x10) bytes */ + /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ + uint16_t _pad; uint32_t unknown2; /* 0xF */ uint32_t unknown3; /* 0x00 */ - /* uint16_t secblob ofs/size here */ + /* uint16_t secblob_ofs */ + /* uint16_t secblob_size */ + + /* dynamic body */ DATA_BLOB secblob; } in; struct { - uint16_t buffer_code; + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 +1 */ uint16_t _pad; - /* uint16_t secblob ofs/size here */ + /* uint16_t secblob_ofs */ + /* uint16_t secblob_size */ + + /* dynamic body */ DATA_BLOB secblob; - uint64_t uid; /* returned in header */ + + /* extracted from the SMB2 header */ + uint64_t uid; } out; }; struct smb2_tree_connect { struct { - uint32_t unknown1; /* 0x09 */ - const char *path; + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + uint16_t unknown1; /* 0x0000 */ + /* uint16_t path_ofs */ + /* uint16_t path_size */ + + /* dynamic body */ + const char *path; /* as non-terminated UTF-16 on the wire */ } in; struct { - uint16_t buffer_code; + /* static body buffer 16 (0x10) bytes */ + /* uint16_t buffer_code; 0x10 */ uint16_t unknown1; /* 0x02 */ uint32_t unknown2; /* 0x00 */ uint32_t unknown3; /* 0x00 */ uint32_t access_mask; + + /* extracted from the SMB2 header */ uint32_t tid; } out; }; @@ -93,27 +118,32 @@ struct smb2_handle { struct smb2_create { struct { - uint16_t buffer_code; /* 0x39 */ + /* static body buffer 56 (0x38) bytes */ + /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ uint32_t unknown2; uint32_t unknown3[4]; uint32_t access_mask; + uint32_t file_attr; uint32_t share_access; uint32_t open_disposition; uint32_t create_options; - /* ofs/len of name here, 16 bits */ - uint32_t unknown6; + + /* uint16_t fname_ofs */ + /* uint16_t fname_size */ + /* uint32_t blob_ofs; */ + /* uint32_t blob_size; */ + + /* dynamic body */ const char *fname; - uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; - uint32_t unknown10; - uint64_t unknown11; + + DATA_BLOB blob; } in; struct { - uint16_t buffer_code; /* 0x59 */ + /* static body buffer 88 (0x58) bytes */ + /* uint16_t buffer_code; 0x59 = 0x58 + 1 */ uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ uint32_t create_action; NTTIME create_time; @@ -125,8 +155,11 @@ struct smb2_create { uint32_t file_attr; uint32_t _pad; struct smb2_handle handle; - uint32_t unknown4; - uint32_t unknown5; + /* uint32_t blob_ofs; */ + /* uint32_t blob_size; */ + + /* dynamic body */ + DATA_BLOB blob; } out; }; @@ -135,14 +168,16 @@ struct smb2_create { struct smb2_close { struct { - uint16_t buffer_code; + /* static body buffer 24 (0x18) bytes */ + /* uint16_t buffer_code; 0x18 */ uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ uint32_t _pad; struct smb2_handle handle; } in; struct { - uint16_t buffer_code; + /* static body buffer 60 (0x3C) bytes */ + /* uint16_t buffer_code; 0x3C */ uint16_t flags; uint32_t _pad; NTTIME create_time; @@ -187,7 +222,8 @@ struct smb2_close { struct smb2_getinfo { struct { - uint16_t buffer_code; + /* static body buffer 40 (0x28) bytes */ + /* uint16_t buffer_code; 0x29 = 0x28 + 1 (why???) */ uint16_t level; uint32_t max_response_size; uint32_t unknown1; @@ -198,7 +234,12 @@ struct smb2_getinfo { } in; struct { - uint16_t buffer_code; + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + /* uint16_t blob_ofs; */ + /* uint16_t blob_size; */ + + /* dynamic body */ DATA_BLOB blob; } out; }; @@ -304,33 +345,50 @@ union smb2_fileinfo { struct smb2_write { struct { - uint16_t buffer_code; + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ + /* uint16_t data_ofs; */ + /* uint32_t data_size; */ uint64_t offset; struct smb2_handle handle; - uint8_t _pad[16]; + uint64_t unknown1; /* 0xFFFFFFFFFFFFFFFF */ + uint64_t unknown2; /* 0xFFFFFFFFFFFFFFFF */ + + /* dynamic body */ DATA_BLOB data; } in; struct { - uint16_t buffer_code; + /* static body buffer 17 (0x11) bytes */ + /* uint16_t buffer_code; 0x11 */ uint16_t _pad; uint32_t nwritten; - uint8_t unknown[9]; + uint64_t unknown1; /* 0x0000000000000000 */ + uint8_t _bug; } out; }; struct smb2_read { struct { - uint16_t buffer_code; + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ + uint16_t _pad; uint32_t length; uint64_t offset; struct smb2_handle handle; - uint8_t _pad[17]; + uint64_t unknown1; /* 0x0000000000000000 */ + uint64_t unknown2; /* 0x0000000000000000 */ + uint8_t _bug; } in; struct { - uint16_t buffer_code; - uint8_t unknown[8]; + /* static body buffer 16 (0x10) bytes */ + /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ + /* uint16_t data_ofs; */ + /* uint32_t data_size; */ + uint64_t unknown1; /* 0x0000000000000000 */ + + /* dynamic body */ DATA_BLOB data; } out; }; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 5e53e11634..32ad05733e 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -53,21 +53,15 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, { struct smb2_request *req; NTSTATUS status; - DATA_BLOB path; - status = smb2_string_blob(tree, io->in.path, &path); - if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - req = smb2_request_init(tree->session->transport, SMB2_OP_TCON, - 0x8 + path.length); + 0x08, 1); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SIVAL(req->out.body, 0x00, io->in.unknown1); - status = smb2_push_ofs_blob(&req->out, req->out.body+0x04, path); - data_blob_free(&path); + status = smb2_push_o16s16_string(&req->out, req->out.body+0x04, io->in.path); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -89,11 +83,7 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne return smb2_request_destroy(req); } - if (req->in.body_size < 0x10) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x10); + SMB2_CHECK_PACKET_RECV(req, 0x10, False); io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID); diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 083034a547..04ebb88d4e 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -181,7 +181,6 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.hdr = hdr; req->in.body = hdr+SMB2_HDR_BODY; req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); - req->in.ptr = req->in.body; req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", req->seqnum)); diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index a8e644f2d1..0b28b820ec 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -33,21 +33,21 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_WRITE, io->in.data.length + 0x30); + req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, io->in.data.length); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x00, io->in.buffer_code); - SSVAL(req->out.body, 0x02, req->out.body+0x30 - req->out.hdr); - SIVAL(req->out.body, 0x04, io->in.data.length); - SBVAL(req->out.body, 0x08, io->in.offset); - smb2_put_handle(req->out.body+0x10, &io->in.handle); - memcpy(req->out.body+0x20, io->in._pad, 0x10); - - status = smb2_push_blob(&req->out, req->out.body+0x30, io->in.data); + status = smb2_push_o16s32_blob(&req->out, req->out.body+0x02, io->in.data); if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); return NULL; } + SBVAL(req->out.body, 0x08, io->in.offset); + smb2_push_handle(req->out.body+0x10, &io->in.handle); + + SBVAL(req->out.body, 0x20, io->in.unknown1); + SBVAL(req->out.body, 0x28, io->in.unknown2); + smb2_transport_send(req); return req; @@ -64,15 +64,12 @@ NTSTATUS smb2_write_recv(struct smb2_request *req, struct smb2_write *io) return smb2_request_destroy(req); } - if (req->in.body_size < 17) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x11); + SMB2_CHECK_PACKET_RECV(req, 0x11, False); io->out._pad = SVAL(req->in.body, 0x02); io->out.nwritten = IVAL(req->in.body, 0x04); - memcpy(io->out.unknown, req->in.body+0x08, 9); + io->out.unknown1 = BVAL(req->in.body, 0x08); + io->out._bug = CVAL(req->in.body, 0x10); return smb2_request_destroy(req); } -- cgit From ed069c1771843e0de0489bad7e0959c34fd260c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 13:34:56 +0000 Subject: r11742: fix pushing of 0 length blobs metze (This used to be commit e985ab117c6afb2ea575b55bfaa97b0795ec5745) --- source4/libcli/smb2/request.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index bb8ff06e2d..a9a7e6b71f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -252,6 +252,12 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA return NT_STATUS_BUFFER_TOO_SMALL; } + if (blob.length == 0) { + SSVAL(ptr, 0, 0); + SSVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; @@ -318,6 +324,12 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA return NT_STATUS_BUFFER_TOO_SMALL; } + if (blob.length == 0) { + SSVAL(ptr, 0, 0); + SIVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; @@ -382,6 +394,12 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA return NT_STATUS_BUFFER_TOO_SMALL; } + if (blob.length == 0) { + SIVAL(ptr, 0, 0); + SIVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 8); offset += padding_length; -- cgit From fb90bebab64c8eb02dc190d829b44eb592230302 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 15:47:44 +0000 Subject: r11743: - push the length at the correct offset - let us push empty strings metze (This used to be commit 17c4b6298d757f2e53fe764608504bf737005cbe) --- source4/libcli/smb2/request.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index a9a7e6b71f..bc278897a5 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -254,7 +254,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA if (blob.length == 0) { SSVAL(ptr, 0, 0); - SSVAL(ptr, 4, 0); + SSVAL(ptr, 2, 0); return NT_STATUS_OK; } @@ -326,7 +326,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA if (blob.length == 0) { SSVAL(ptr, 0, 0); - SIVAL(ptr, 4, 0); + SIVAL(ptr, 2, 0); return NT_STATUS_OK; } @@ -457,6 +457,13 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, NTSTATUS status; ssize_t size; + if (strcmp("", str) == 0) { + blob = data_blob(NULL, 0); + status = smb2_push_o16s16_blob(buf, ptr, blob); + NT_STATUS_NOT_OK_RETURN(status); + return NT_STATUS_OK; + } + size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { -- cgit From 1c71db99aa78f489a66d58e1116884c23b0c10f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 00:47:50 +0000 Subject: r11751: fixed the req->out.size calculation (it needs to be the complete request size, including dynamic portion) (This used to be commit 1b5cdf92cc7793b08d7c46ef00d4ff696b31c15e) --- source4/libcli/smb2/request.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index bc278897a5..3e80115e47 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -50,14 +50,16 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ ZERO_STRUCT(req->in); - req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+body_dynamic_size; + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+ + body_fixed_size+body_dynamic_size; + + req->out.allocated = req->out.size; req->out.buffer = talloc_size(req, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); return NULL; } - req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+(body_dynamic_size?1:0); req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.body = req->out.hdr + SMB2_HDR_BODY; req->out.body_size = body_fixed_size; -- cgit From 94ae534128a28e7a3f2f4124283bd8c1acbff6d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 00:48:24 +0000 Subject: r11752: setup the dynamic pointer for incoming packets too (This used to be commit 583f3c415ea33ddf5f4065a66f6fae49ab48455e) --- source4/libcli/smb2/smb2.h | 2 +- source4/libcli/smb2/transport.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 47dd6fd272..0ff8b87143 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -138,7 +138,7 @@ struct smb2_request { }; -#define SMB2_MIN_SIZE 0x40 +#define SMB2_MIN_SIZE 0x42 /* offsets into header elements */ #define SMB2_HDR_LENGTH 0x04 diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 04ebb88d4e..04767fa634 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -148,6 +148,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) int len; struct smb2_request *req = NULL; uint64_t seqnum; + uint16_t buffer_code; + uint32_t dynamic_size; buffer = blob.data; len = blob.length; @@ -183,6 +185,18 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); + buffer_code = SVAL(req->in.body, 0); + req->in.dynamic = NULL; + dynamic_size = req->in.body_size - (buffer_code & ~1); + if (dynamic_size != 0 && (buffer_code & 1)) { + req->in.dynamic = req->in.body + (buffer_code & ~1); + if (smb2_oob(&req->in, req->in.dynamic, dynamic_size)) { + DEBUG(1,("SMB2 request invalid dynamic size 0x%x\n", + dynamic_size)); + goto error; + } + } + DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", req->seqnum)); dump_data(5, req->in.body, req->in.body_size); -- cgit From fe996e8ac687dbf5b5cfdd795f14aed89663f06d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 03:32:38 +0000 Subject: r11754: make the SMB2 blob push routines take offsets, so they fit better with the rest of the packet construction code (This used to be commit 387ec2b17ff30a1c040b460b498c8fa7d8770593) --- source4/libcli/smb2/create.c | 4 +- source4/libcli/smb2/request.c | 172 ++++++++++++++++++++++-------------------- source4/libcli/smb2/session.c | 2 +- source4/libcli/smb2/tcon.c | 2 +- source4/libcli/smb2/write.c | 2 +- 5 files changed, 97 insertions(+), 85 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 79d3341bd0..47fd208643 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -48,13 +48,13 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(req->out.body, 0x24, io->in.open_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); - status = smb2_push_o16s16_string(&req->out, req->out.body+0x2C, io->in.fname); + status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } - status = smb2_push_o32s32_blob(&req->out, req->out.body+0x30, io->in.blob); + status = smb2_push_o32s32_blob(&req->out, 0x30, io->in.blob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 3e80115e47..1a98ba9987 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -50,10 +50,9 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ ZERO_STRUCT(req->in); - req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+ - body_fixed_size+body_dynamic_size; + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size; - req->out.allocated = req->out.size; + req->out.allocated = req->out.size + body_dynamic_size; req->out.buffer = talloc_size(req, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); @@ -182,26 +181,30 @@ static size_t smb2_padding_size(uint32_t offset, size_t n) return n - (offset & (n-1)); } -static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t n) +/* + grow a SMB2 buffer by the specified amount +*/ +static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t increase) { size_t dynamic_ofs; uint8_t *buffer_ptr; + uint32_t newsize = buf->size + increase; /* a packet size should be limited a bit */ - if (n >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW; + if (newsize >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW; - if (n <= buf->allocated) return NT_STATUS_OK; + if (newsize <= buf->allocated) return NT_STATUS_OK; dynamic_ofs = buf->dynamic - buf->buffer; - buffer_ptr = talloc_realloc_size(buf, buf->buffer, n); + buffer_ptr = talloc_realloc_size(buf, buf->buffer, newsize); NT_STATUS_HAVE_NO_MEMORY(buffer_ptr); buf->buffer = buffer_ptr; buf->hdr = buf->buffer + NBT_HDR_SIZE; buf->body = buf->hdr + SMB2_HDR_BODY; buf->dynamic = buf->buffer + dynamic_ofs; - buf->allocated = n; + buf->allocated = newsize; return NT_STATUS_OK; } @@ -232,15 +235,18 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ /* push a uint16_t ofs/ uint16_t length/blob triple into a data blob - the ptr points to the start of the offset/length pair + the ofs points to the start of the offset/length pair, and is relative + to the body start */ -NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, + uint16_t ofs, DATA_BLOB blob) { NTSTATUS status; size_t offset; size_t padding_length; + uint8_t *ptr = buf->body+ofs; - if (!buf->dynamic) { + if (buf->dynamic == NULL) { return NT_STATUS_INVALID_PARAMETER; } @@ -267,7 +273,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA SSVAL(ptr, 0, offset); SSVAL(ptr, 2, blob.length); - status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + status = smb2_grow_buffer(buf, padding_length + blob.length); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -276,48 +282,27 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size = buf->dynamic - buf->buffer; + buf->size += blob.length + padding_length; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } -/* - pull a uint16_t ofs/ uint32_t length/blob triple from a data blob - the ptr points to the start of the offset/length pair -*/ -NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) -{ - uint16_t ofs; - uint32_t size; - - if (smb2_oob(buf, ptr, 6)) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - ofs = SVAL(ptr, 0); - size = IVAL(ptr, 2); - if (ofs == 0 || size == 0) { - *blob = data_blob(NULL, 0); - return NT_STATUS_OK; - } - if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); - NT_STATUS_HAVE_NO_MEMORY(blob->data); - return NT_STATUS_OK; -} /* push a uint16_t ofs/ uint32_t length/blob triple into a data blob - the ptr points to the start of the offset/length pair + the ofs points to the start of the offset/length pair, and is relative + to the body start */ -NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, + uint16_t ofs, DATA_BLOB blob) { NTSTATUS status; size_t offset; size_t padding_length; + uint8_t *ptr = buf->body+ofs; - if (!buf->dynamic) { + if (buf->dynamic == NULL) { return NT_STATUS_INVALID_PARAMETER; } @@ -339,7 +324,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA SSVAL(ptr, 0, offset); SIVAL(ptr, 2, blob.length); - status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + status = smb2_grow_buffer(buf, padding_length + blob.length); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -348,46 +333,27 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size = buf->dynamic - buf->buffer; + buf->size += blob.length + padding_length; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } -/* - pull a uint32_t ofs/ uint32_t length/blob triple from a data blob - the ptr points to the start of the offset/length pair -*/ -NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) -{ - uint32_t ofs, size; - if (smb2_oob(buf, ptr, 8)) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - ofs = IVAL(ptr, 0); - size = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { - *blob = data_blob(NULL, 0); - return NT_STATUS_OK; - } - if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); - NT_STATUS_HAVE_NO_MEMORY(blob->data); - return NT_STATUS_OK; -} /* push a uint32_t ofs/ uint32_t length/blob triple into a data blob - the ptr points to the start of the offset/length pair + the ofs points to the start of the offset/length pair, and is relative + to the body start */ -NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, + uint32_t ofs, DATA_BLOB blob) { NTSTATUS status; size_t offset; size_t padding_length; + uint8_t *ptr = buf->body+ofs; - if (!buf->dynamic) { + if (buf->dynamic == NULL) { return NT_STATUS_INVALID_PARAMETER; } @@ -409,7 +375,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA SIVAL(ptr, 0, offset); SIVAL(ptr, 4, blob.length); - status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + status = smb2_grow_buffer(buf, padding_length + blob.length); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -418,8 +384,59 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size = buf->dynamic - buf->buffer; + buf->size += blob.length + padding_length; + buf->body_size += blob.length + padding_length; + + return NT_STATUS_OK; +} + +/* + pull a uint16_t ofs/ uint32_t length/blob triple from a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +{ + uint16_t ofs; + uint32_t size; + + if (smb2_oob(buf, ptr, 6)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = SVAL(ptr, 0); + size = IVAL(ptr, 2); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; +} +/* + pull a uint32_t ofs/ uint32_t length/blob triple from a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +{ + uint32_t ofs, size; + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = IVAL(ptr, 0); + size = IVAL(ptr, 4); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); return NT_STATUS_OK; } @@ -453,17 +470,14 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me UTF-16 without termination */ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, - uint8_t *ptr, const char *str) + uint16_t ofs, const char *str) { DATA_BLOB blob; NTSTATUS status; ssize_t size; if (strcmp("", str) == 0) { - blob = data_blob(NULL, 0); - status = smb2_push_o16s16_blob(buf, ptr, blob); - NT_STATUS_NOT_OK_RETURN(status); - return NT_STATUS_OK; + return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, @@ -473,11 +487,9 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, } blob.length = size; - status = smb2_push_o16s16_blob(buf, ptr, blob); + status = smb2_push_o16s16_blob(buf, ofs, blob); data_blob_free(&blob); - NT_STATUS_NOT_OK_RETURN(status); - - return NT_STATUS_OK; + return status; } /* diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index e572227a48..0a13a288fc 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -77,7 +77,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, req->session = session; - status = smb2_push_o16s16_blob(&req->out, req->out.body+0x0C, io->in.secblob); + status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 32ad05733e..886ed9828b 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -61,7 +61,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); SIVAL(req->out.body, 0x00, io->in.unknown1); - status = smb2_push_o16s16_string(&req->out, req->out.body+0x04, io->in.path); + status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index 0b28b820ec..591cf2c891 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -36,7 +36,7 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, io->in.data.length); if (req == NULL) return NULL; - status = smb2_push_o16s32_blob(&req->out, req->out.body+0x02, io->in.data); + status = smb2_push_o16s32_blob(&req->out, 0x02, io->in.data); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; -- cgit From 7a43b32c3b6aeae3572c810fef243d883fe74f28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 04:03:31 +0000 Subject: r11755: added names for all of the SMB2 qfs info levels (they all map exactly to equivalent SMB qfs levels) (This used to be commit 4ce48d02aa12d6fa699bf8b250b14851870f0096) --- source4/libcli/smb2/getinfo.c | 1 + source4/libcli/smb2/smb2_calls.h | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 1594b8c1b4..fe27cc711b 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -178,6 +178,7 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, io->all_info.write_time = smbcli_pull_nttime(blob.data, 0x10); io->all_info.change_time = smbcli_pull_nttime(blob.data, 0x18); io->all_info.file_attr = IVAL(blob.data, 0x20); + io->all_info.unknown1 = IVAL(blob.data, 0x24); io->all_info.alloc_size = BVAL(blob.data, 0x28); io->all_info.size = BVAL(blob.data, 0x30); io->all_info.nlink = IVAL(blob.data, 0x38); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index d0a1cb8905..872e20f156 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -191,13 +191,13 @@ struct smb2_close { }; /* fs information levels */ -#define SMB2_GETINFO_FS_01 0x0102 -#define SMB2_GETINFO_FS_03 0x0302 -#define SMB2_GETINFO_FS_04 0x0402 -#define SMB2_GETINFO_FS_ATTRIB_INFO 0x0502 -#define SMB2_GETINFO_FS_06 0x0602 -#define SMB2_GETINFO_FS_07 0x0702 -#define SMB2_GETINFO_FS_08 0x0802 +#define SMB2_GETINFO_FS_VOLUME_INFO 0x0102 +#define SMB2_GETINFO_FS_SIZE_INFO 0x0302 +#define SMB2_GETINFO_FS_DEVICE_INFO 0x0402 +#define SMB2_GETINFO_FS_ATTRIBUTE_INFO 0x0502 +#define SMB2_GETINFO_FS_QUOTA_INFO 0x0602 +#define SMB2_GETINFO_FS_FULL_SIZE_INFO 0x0702 +#define SMB2_GETINFO_FS_OBJECTID_INFO 0x0802 /* class 3 levels */ #define SMB2_GETINFO_SECURITY 0x0003 @@ -295,7 +295,7 @@ union smb2_fileinfo { NTTIME write_time; NTTIME change_time; uint32_t file_attr; - /* uint32_t _pad; */ + uint32_t unknown1; uint64_t alloc_size; uint64_t size; uint32_t nlink; -- cgit From c3cd4a0087d61a147f4a2f06f1668230f6704e7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 06:27:18 +0000 Subject: r11756: split out the parsers for the pass-through levels of QFSINFO and QFILEINFO levels in trans2, so they can be shared with SMB2 (This used to be commit 5ca2d609e6a3766ebd07763f850ecc62209a7db7) --- source4/libcli/raw/rawfileinfo.c | 261 ++++++++++++++++++++++++++------------- source4/libcli/raw/rawfsinfo.c | 141 ++++++++++++++------- source4/libcli/raw/rawrequest.c | 18 +-- 3 files changed, 277 insertions(+), 143 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index f631522182..2edb6d5b42 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -79,67 +79,14 @@ NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -/**************************************************************************** - Handle qfileinfo/qpathinfo trans2 backend. -****************************************************************************/ -static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, - TALLOC_CTX *mem_ctx, - union smb_fileinfo *parms, - DATA_BLOB *blob) +/* + parse the fsinfo 'passthru' level replies +*/ +NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + enum smb_fileinfo_level level, + union smb_fileinfo *parms) { - switch (parms->generic.level) { - case RAW_FILEINFO_GENERIC: - case RAW_FILEINFO_GETATTR: - case RAW_FILEINFO_GETATTRE: - case RAW_FILEINFO_SEC_DESC: - /* not handled here */ - return NT_STATUS_INVALID_LEVEL; - - case RAW_FILEINFO_STANDARD: - FINFO_CHECK_SIZE(22); - parms->standard.out.create_time = raw_pull_dos_date2(session->transport, - blob->data + 0); - parms->standard.out.access_time = raw_pull_dos_date2(session->transport, - blob->data + 4); - parms->standard.out.write_time = raw_pull_dos_date2(session->transport, - blob->data + 8); - parms->standard.out.size = IVAL(blob->data, 12); - parms->standard.out.alloc_size = IVAL(blob->data, 16); - parms->standard.out.attrib = SVAL(blob->data, 20); - return NT_STATUS_OK; - - case RAW_FILEINFO_EA_SIZE: - FINFO_CHECK_SIZE(26); - parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport, - blob->data + 0); - parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport, - blob->data + 4); - parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport, - blob->data + 8); - parms->ea_size.out.size = IVAL(blob->data, 12); - parms->ea_size.out.alloc_size = IVAL(blob->data, 16); - parms->ea_size.out.attrib = SVAL(blob->data, 20); - parms->ea_size.out.ea_size = IVAL(blob->data, 22); - return NT_STATUS_OK; - - case RAW_FILEINFO_EA_LIST: - FINFO_CHECK_MIN_SIZE(4); - return ea_pull_list(blob, mem_ctx, - &parms->ea_list.out.num_eas, - &parms->ea_list.out.eas); - - case RAW_FILEINFO_ALL_EAS: - FINFO_CHECK_MIN_SIZE(4); - return ea_pull_list(blob, mem_ctx, - &parms->all_eas.out.num_eas, - &parms->all_eas.out.eas); - - case RAW_FILEINFO_IS_NAME_VALID: - /* no data! */ - FINFO_CHECK_SIZE(0); - return NT_STATUS_OK; - - case RAW_FILEINFO_BASIC_INFO: + switch (level) { case RAW_FILEINFO_BASIC_INFORMATION: /* some servers return 40 bytes and some 36. w2k3 return 40, so thats what we should do, but we need to accept 36 */ @@ -153,7 +100,6 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->basic_info.out.attrib = IVAL(blob->data, 32); return NT_STATUS_OK; - case RAW_FILEINFO_STANDARD_INFO: case RAW_FILEINFO_STANDARD_INFORMATION: FINFO_CHECK_SIZE(24); parms->standard_info.out.alloc_size = BVAL(blob->data, 0); @@ -163,20 +109,17 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->standard_info.out.directory = CVAL(blob->data, 21); return NT_STATUS_OK; - case RAW_FILEINFO_EA_INFO: case RAW_FILEINFO_EA_INFORMATION: FINFO_CHECK_SIZE(4); parms->ea_info.out.ea_size = IVAL(blob->data, 0); return NT_STATUS_OK; - case RAW_FILEINFO_NAME_INFO: case RAW_FILEINFO_NAME_INFORMATION: FINFO_CHECK_MIN_SIZE(4); - smbcli_blob_pull_string(session, mem_ctx, blob, - &parms->name_info.out.fname, 0, 4, STR_UNICODE); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &parms->name_info.out.fname, 0, 4, STR_UNICODE); return NT_STATUS_OK; - case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: FINFO_CHECK_MIN_SIZE(72); parms->all_info.out.create_time = smbcli_pull_nttime(blob->data, 0); @@ -191,8 +134,8 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->all_info.out.directory = CVAL(blob->data, 61); #if 1 parms->all_info.out.ea_size = IVAL(blob->data, 64); - smbcli_blob_pull_string(session, mem_ctx, blob, - &parms->all_info.out.fname, 68, 72, STR_UNICODE); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &parms->all_info.out.fname, 68, 72, STR_UNICODE); #else /* this is what the CIFS spec says - and its totally wrong, but its useful having it here so we can @@ -204,19 +147,17 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, mode 4 bytes at 88 alignment 4 bytes at 92 */ - smbcli_blob_pull_string(session, mem_ctx, blob, + smbcli_blob_pull_string(NULL, mem_ctx, blob, &parms->all_info.out.fname, 96, 100, STR_UNICODE); #endif return NT_STATUS_OK; - case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: FINFO_CHECK_MIN_SIZE(4); - smbcli_blob_pull_string(session, mem_ctx, blob, - &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE); return NT_STATUS_OK; - case RAW_FILEINFO_STREAM_INFO: case RAW_FILEINFO_STREAM_INFORMATION: return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out); @@ -235,6 +176,12 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->position_information.out.position = BVAL(blob->data, 0); return NT_STATUS_OK; + case RAW_FILEINFO_FULL_EA_INFORMATION: + FINFO_CHECK_MIN_SIZE(4); + return ea_pull_list_chained(blob, mem_ctx, + &parms->all_eas.out.num_eas, + &parms->all_eas.out.eas); + case RAW_FILEINFO_MODE_INFORMATION: FINFO_CHECK_SIZE(4); parms->mode_information.out.mode = IVAL(blob->data, 0); @@ -246,7 +193,6 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, = IVAL(blob->data, 0); return NT_STATUS_OK; - case RAW_FILEINFO_COMPRESSION_INFO: case RAW_FILEINFO_COMPRESSION_INFORMATION: FINFO_CHECK_SIZE(16); parms->compression_info.out.compressed_size = BVAL(blob->data, 0); @@ -257,6 +203,155 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, /* 3 bytes of padding */ return NT_STATUS_OK; + case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: + FINFO_CHECK_SIZE(56); + parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data, 0); + parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data, 8); + parms->network_open_information.out.write_time = smbcli_pull_nttime(blob->data, 16); + parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24); + parms->network_open_information.out.alloc_size = BVAL(blob->data, 32); + parms->network_open_information.out.size = BVAL(blob->data, 40); + parms->network_open_information.out.attrib = IVAL(blob->data, 48); + return NT_STATUS_OK; + + case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: + FINFO_CHECK_SIZE(8); + parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0); + parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4); + return NT_STATUS_OK; + + default: + break; + } + + return NT_STATUS_INVALID_LEVEL; +} + + +/**************************************************************************** + Handle qfileinfo/qpathinfo trans2 backend. +****************************************************************************/ +static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms, + DATA_BLOB *blob) +{ + switch (parms->generic.level) { + case RAW_FILEINFO_GENERIC: + case RAW_FILEINFO_GETATTR: + case RAW_FILEINFO_GETATTRE: + case RAW_FILEINFO_SEC_DESC: + /* not handled here */ + return NT_STATUS_INVALID_LEVEL; + + case RAW_FILEINFO_STANDARD: + FINFO_CHECK_SIZE(22); + parms->standard.out.create_time = raw_pull_dos_date2(session->transport, + blob->data + 0); + parms->standard.out.access_time = raw_pull_dos_date2(session->transport, + blob->data + 4); + parms->standard.out.write_time = raw_pull_dos_date2(session->transport, + blob->data + 8); + parms->standard.out.size = IVAL(blob->data, 12); + parms->standard.out.alloc_size = IVAL(blob->data, 16); + parms->standard.out.attrib = SVAL(blob->data, 20); + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_SIZE: + FINFO_CHECK_SIZE(26); + parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport, + blob->data + 0); + parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport, + blob->data + 4); + parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport, + blob->data + 8); + parms->ea_size.out.size = IVAL(blob->data, 12); + parms->ea_size.out.alloc_size = IVAL(blob->data, 16); + parms->ea_size.out.attrib = SVAL(blob->data, 20); + parms->ea_size.out.ea_size = IVAL(blob->data, 22); + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_LIST: + FINFO_CHECK_MIN_SIZE(4); + return ea_pull_list(blob, mem_ctx, + &parms->ea_list.out.num_eas, + &parms->ea_list.out.eas); + + case RAW_FILEINFO_ALL_EAS: + FINFO_CHECK_MIN_SIZE(4); + return ea_pull_list(blob, mem_ctx, + &parms->all_eas.out.num_eas, + &parms->all_eas.out.eas); + + case RAW_FILEINFO_IS_NAME_VALID: + /* no data! */ + FINFO_CHECK_SIZE(0); + return NT_STATUS_OK; + + case RAW_FILEINFO_BASIC_INFO: + case RAW_FILEINFO_BASIC_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_BASIC_INFORMATION, parms); + + case RAW_FILEINFO_STANDARD_INFO: + case RAW_FILEINFO_STANDARD_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_STANDARD_INFORMATION, parms); + + case RAW_FILEINFO_EA_INFO: + case RAW_FILEINFO_EA_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_EA_INFORMATION, parms); + + case RAW_FILEINFO_NAME_INFO: + case RAW_FILEINFO_NAME_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_NAME_INFORMATION, parms); + + case RAW_FILEINFO_ALL_INFO: + case RAW_FILEINFO_ALL_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_ALL_INFORMATION, parms); + + case RAW_FILEINFO_ALT_NAME_INFO: + case RAW_FILEINFO_ALT_NAME_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_ALT_NAME_INFORMATION, parms); + + case RAW_FILEINFO_STREAM_INFO: + case RAW_FILEINFO_STREAM_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_STREAM_INFORMATION, parms); + + case RAW_FILEINFO_INTERNAL_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_INTERNAL_INFORMATION, parms); + + case RAW_FILEINFO_ACCESS_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_ACCESS_INFORMATION, parms); + + case RAW_FILEINFO_POSITION_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_POSITION_INFORMATION, parms); + + case RAW_FILEINFO_FULL_EA_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_FULL_EA_INFORMATION, parms); + + case RAW_FILEINFO_MODE_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_MODE_INFORMATION, parms); + + case RAW_FILEINFO_ALIGNMENT_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_ALIGNMENT_INFORMATION, parms); + + case RAW_FILEINFO_COMPRESSION_INFO: + case RAW_FILEINFO_COMPRESSION_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_COMPRESSION_INFORMATION, parms); + case RAW_FILEINFO_UNIX_BASIC: FINFO_CHECK_SIZE(100); parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0); @@ -280,26 +375,18 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, return NT_STATUS_OK; case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: - FINFO_CHECK_SIZE(56); - parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data, 0); - parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data, 8); - parms->network_open_information.out.write_time = smbcli_pull_nttime(blob->data, 16); - parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24); - parms->network_open_information.out.alloc_size = BVAL(blob->data, 32); - parms->network_open_information.out.size = BVAL(blob->data, 40); - parms->network_open_information.out.attrib = IVAL(blob->data, 48); - return NT_STATUS_OK; + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms); case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: - FINFO_CHECK_SIZE(8); - parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0); - parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4); - return NT_STATUS_OK; + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms); } return NT_STATUS_INVALID_LEVEL; } + /**************************************************************************** Very raw query file info - returns param/data blobs - (async send) ****************************************************************************/ diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 61f5a5027d..9b218586a2 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -151,6 +151,86 @@ struct smbcli_request *smb_raw_fsinfo_send(struct smbcli_tree *tree, return smb_raw_qfsinfo_send(tree, mem_ctx, info_level); } +/* + parse the fsinfo 'passthru' level replies +*/ +NTSTATUS smb_raw_fsinfo_passthru_parse(DATA_BLOB blob, TALLOC_CTX *mem_ctx, + enum smb_fsinfo_level level, + union smb_fsinfo *fsinfo) +{ + NTSTATUS status = NT_STATUS_OK; + int i; + + /* parse the results */ + switch (level) { + case RAW_QFS_VOLUME_INFORMATION: + QFS_CHECK_MIN_SIZE(18); + fsinfo->volume_info.out.create_time = smbcli_pull_nttime(blob.data, 0); + fsinfo->volume_info.out.serial_number = IVAL(blob.data, 8); + smbcli_blob_pull_string(NULL, mem_ctx, &blob, + &fsinfo->volume_info.out.volume_name, + 12, 18, STR_UNICODE); + break; + + case RAW_QFS_SIZE_INFORMATION: + QFS_CHECK_SIZE(24); + fsinfo->size_info.out.total_alloc_units = BVAL(blob.data, 0); + fsinfo->size_info.out.avail_alloc_units = BVAL(blob.data, 8); + fsinfo->size_info.out.sectors_per_unit = IVAL(blob.data, 16); + fsinfo->size_info.out.bytes_per_sector = IVAL(blob.data, 20); + break; + + case RAW_QFS_DEVICE_INFORMATION: + QFS_CHECK_SIZE(8); + fsinfo->device_info.out.device_type = IVAL(blob.data, 0); + fsinfo->device_info.out.characteristics = IVAL(blob.data, 4); + break; + + case RAW_QFS_ATTRIBUTE_INFORMATION: + QFS_CHECK_MIN_SIZE(12); + fsinfo->attribute_info.out.fs_attr = IVAL(blob.data, 0); + fsinfo->attribute_info.out.max_file_component_length = IVAL(blob.data, 4); + smbcli_blob_pull_string(NULL, mem_ctx, &blob, + &fsinfo->attribute_info.out.fs_type, + 8, 12, STR_UNICODE); + break; + + case RAW_QFS_QUOTA_INFORMATION: + QFS_CHECK_SIZE(48); + fsinfo->quota_information.out.unknown[0] = BVAL(blob.data, 0); + fsinfo->quota_information.out.unknown[1] = BVAL(blob.data, 8); + fsinfo->quota_information.out.unknown[2] = BVAL(blob.data, 16); + fsinfo->quota_information.out.quota_soft = BVAL(blob.data, 24); + fsinfo->quota_information.out.quota_hard = BVAL(blob.data, 32); + fsinfo->quota_information.out.quota_flags = BVAL(blob.data, 40); + break; + + case RAW_QFS_FULL_SIZE_INFORMATION: + QFS_CHECK_SIZE(32); + fsinfo->full_size_information.out.total_alloc_units = BVAL(blob.data, 0); + fsinfo->full_size_information.out.call_avail_alloc_units = BVAL(blob.data, 8); + fsinfo->full_size_information.out.actual_avail_alloc_units = BVAL(blob.data, 16); + fsinfo->full_size_information.out.sectors_per_unit = IVAL(blob.data, 24); + fsinfo->full_size_information.out.bytes_per_sector = IVAL(blob.data, 28); + break; + + case RAW_QFS_OBJECTID_INFORMATION: + QFS_CHECK_SIZE(64); + status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + for (i=0;i<6;i++) { + fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8); + } + break; + + default: + status = NT_STATUS_INVALID_INFO_CLASS; + } + +failed: + return status; +} + /**************************************************************************** Query FSInfo raw interface (async recv) @@ -161,7 +241,6 @@ NTSTATUS smb_raw_fsinfo_recv(struct smbcli_request *req, { DATA_BLOB blob; NTSTATUS status; - int i; struct smbcli_session *session = req?req->session:NULL; if (fsinfo->generic.level == RAW_QFS_DSKATTR) { @@ -199,39 +278,23 @@ NTSTATUS smb_raw_fsinfo_recv(struct smbcli_request *req, case RAW_QFS_VOLUME_INFO: case RAW_QFS_VOLUME_INFORMATION: - QFS_CHECK_MIN_SIZE(18); - fsinfo->volume_info.out.create_time = smbcli_pull_nttime(blob.data, 0); - fsinfo->volume_info.out.serial_number = IVAL(blob.data, 8); - smbcli_blob_pull_string(session, mem_ctx, &blob, - &fsinfo->volume_info.out.volume_name, - 12, 18, STR_UNICODE); - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_VOLUME_INFORMATION, fsinfo); case RAW_QFS_SIZE_INFO: case RAW_QFS_SIZE_INFORMATION: - QFS_CHECK_SIZE(24); - fsinfo->size_info.out.total_alloc_units = BVAL(blob.data, 0); - fsinfo->size_info.out.avail_alloc_units = BVAL(blob.data, 8); - fsinfo->size_info.out.sectors_per_unit = IVAL(blob.data, 16); - fsinfo->size_info.out.bytes_per_sector = IVAL(blob.data, 20); - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_SIZE_INFORMATION, fsinfo); case RAW_QFS_DEVICE_INFO: case RAW_QFS_DEVICE_INFORMATION: - QFS_CHECK_SIZE(8); - fsinfo->device_info.out.device_type = IVAL(blob.data, 0); - fsinfo->device_info.out.characteristics = IVAL(blob.data, 4); - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_DEVICE_INFORMATION, fsinfo); case RAW_QFS_ATTRIBUTE_INFO: case RAW_QFS_ATTRIBUTE_INFORMATION: - QFS_CHECK_MIN_SIZE(12); - fsinfo->attribute_info.out.fs_attr = IVAL(blob.data, 0); - fsinfo->attribute_info.out.max_file_component_length = IVAL(blob.data, 4); - smbcli_blob_pull_string(session, mem_ctx, &blob, - &fsinfo->attribute_info.out.fs_type, - 8, 12, STR_UNICODE); - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_ATTRIBUTE_INFORMATION, fsinfo); case RAW_QFS_UNIX_INFO: QFS_CHECK_SIZE(12); @@ -241,32 +304,16 @@ NTSTATUS smb_raw_fsinfo_recv(struct smbcli_request *req, break; case RAW_QFS_QUOTA_INFORMATION: - QFS_CHECK_SIZE(48); - fsinfo->quota_information.out.unknown[0] = BVAL(blob.data, 0); - fsinfo->quota_information.out.unknown[1] = BVAL(blob.data, 8); - fsinfo->quota_information.out.unknown[2] = BVAL(blob.data, 16); - fsinfo->quota_information.out.quota_soft = BVAL(blob.data, 24); - fsinfo->quota_information.out.quota_hard = BVAL(blob.data, 32); - fsinfo->quota_information.out.quota_flags = BVAL(blob.data, 40); - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_QUOTA_INFORMATION, fsinfo); case RAW_QFS_FULL_SIZE_INFORMATION: - QFS_CHECK_SIZE(32); - fsinfo->full_size_information.out.total_alloc_units = BVAL(blob.data, 0); - fsinfo->full_size_information.out.call_avail_alloc_units = BVAL(blob.data, 8); - fsinfo->full_size_information.out.actual_avail_alloc_units = BVAL(blob.data, 16); - fsinfo->full_size_information.out.sectors_per_unit = IVAL(blob.data, 24); - fsinfo->full_size_information.out.bytes_per_sector = IVAL(blob.data, 28); - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_FULL_SIZE_INFORMATION, fsinfo); case RAW_QFS_OBJECTID_INFORMATION: - QFS_CHECK_SIZE(64); - status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - for (i=0;i<6;i++) { - fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8); - } - break; + return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, + RAW_QFS_OBJECTID_INFORMATION, fsinfo); } failed: diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 33ac9c55b1..6e02ddc5c1 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -737,8 +737,8 @@ NTTIME smbcli_pull_nttime(void *base, uint16_t offset) of bytes consumed in the blob is returned */ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, - DATA_BLOB *blob, const char **dest, - const uint8_t *src, int byte_len, uint_t flags) + const DATA_BLOB *blob, const char **dest, + const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; @@ -793,8 +793,8 @@ static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, of bytes consumed in the blob is returned */ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, - DATA_BLOB *blob, const char **dest, - const uint8_t *src, int byte_len, uint_t flags) + const DATA_BLOB *blob, const char **dest, + const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; @@ -841,11 +841,11 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, of bytes consumed in the blob is returned */ size_t smbcli_blob_pull_string(struct smbcli_session *session, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob, - WIRE_STRING *dest, - uint16_t len_offset, uint16_t str_offset, - uint_t flags) + TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + WIRE_STRING *dest, + uint16_t len_offset, uint16_t str_offset, + uint_t flags) { int extra; dest->s = NULL; -- cgit From eedb92ce724e505f94ed49f9b238be617c52ccb4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 11:06:13 +0000 Subject: r11758: unified the parse code for the SMB and SMB2 qfsinfo and qfileinfo calls (This used to be commit ba897e537b9a1544dc214e9d5504c87fee6fced2) --- source4/libcli/raw/rawfileinfo.c | 64 ++++++++-- source4/libcli/smb2/getinfo.c | 257 ++++++++++----------------------------- source4/libcli/smb2/smb2_calls.h | 144 ++-------------------- 3 files changed, 126 insertions(+), 339 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 2edb6d5b42..7119eed5e7 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -176,12 +176,6 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->position_information.out.position = BVAL(blob->data, 0); return NT_STATUS_OK; - case RAW_FILEINFO_FULL_EA_INFORMATION: - FINFO_CHECK_MIN_SIZE(4); - return ea_pull_list_chained(blob, mem_ctx, - &parms->all_eas.out.num_eas, - &parms->all_eas.out.eas); - case RAW_FILEINFO_MODE_INFORMATION: FINFO_CHECK_SIZE(4); parms->mode_information.out.mode = IVAL(blob->data, 0); @@ -220,6 +214,51 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4); return NT_STATUS_OK; + case RAW_FILEINFO_SMB2_ALL_EAS: + FINFO_CHECK_MIN_SIZE(4); + return ea_pull_list_chained(blob, mem_ctx, + &parms->all_eas.out.num_eas, + &parms->all_eas.out.eas); + + case RAW_FILEINFO_SMB2_ALL_INFORMATION: + FINFO_CHECK_MIN_SIZE(0x64); + parms->all_info2.out.create_time = smbcli_pull_nttime(blob->data, 0x00); + parms->all_info2.out.access_time = smbcli_pull_nttime(blob->data, 0x08); + parms->all_info2.out.write_time = smbcli_pull_nttime(blob->data, 0x10); + parms->all_info2.out.change_time = smbcli_pull_nttime(blob->data, 0x18); + parms->all_info2.out.attrib = IVAL(blob->data, 0x20); + parms->all_info2.out.unknown1 = IVAL(blob->data, 0x24); + parms->all_info2.out.alloc_size = BVAL(blob->data, 0x28); + parms->all_info2.out.size = BVAL(blob->data, 0x30); + parms->all_info2.out.nlink = IVAL(blob->data, 0x38); + parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C); + parms->all_info2.out.directory = CVAL(blob->data, 0x3D); + parms->all_info2.out.file_id = BVAL(blob->data, 0x40); + parms->all_info2.out.ea_size = IVAL(blob->data, 0x48); + parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C); + parms->all_info2.out.unknown2 = BVAL(blob->data, 0x50); + parms->all_info2.out.unknown3 = BVAL(blob->data, 0x58); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE); + return NT_STATUS_OK; + + case RAW_FILEINFO_SEC_DESC: { + struct ndr_pull *ndr; + NTSTATUS status; + ndr = ndr_pull_init_blob(blob, mem_ctx); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor); + if (parms->query_secdesc.out.sd == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, + parms->query_secdesc.out.sd); + talloc_free(ndr); + return status; + } + default: break; } @@ -335,10 +374,6 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, RAW_FILEINFO_POSITION_INFORMATION, parms); - case RAW_FILEINFO_FULL_EA_INFORMATION: - return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, - RAW_FILEINFO_FULL_EA_INFORMATION, parms); - case RAW_FILEINFO_MODE_INFORMATION: return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, RAW_FILEINFO_MODE_INFORMATION, parms); @@ -381,6 +416,15 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms); + + case RAW_FILEINFO_SMB2_ALL_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_SMB2_ALL_INFORMATION, parms); + + case RAW_FILEINFO_SMB2_ALL_EAS: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_SMB2_ALL_EAS, parms); + } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index fe27cc711b..cb8ce76a07 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -41,8 +41,8 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin SSVAL(req->out.body, 0x02, io->in.level); SIVAL(req->out.body, 0x04, io->in.max_response_size); SIVAL(req->out.body, 0x08, io->in.unknown1); - SIVAL(req->out.body, 0x0C, io->in.flags); - SIVAL(req->out.body, 0x10, io->in.unknown3); + SIVAL(req->out.body, 0x0C, io->in.unknown2); + SIVAL(req->out.body, 0x10, io->in.flags); SIVAL(req->out.body, 0x14, io->in.unknown4); smb2_push_handle(req->out.body+0x18, &io->in.handle); @@ -87,203 +87,64 @@ NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, /* - parse a returned getinfo data blob + recv a getinfo reply and parse the level info */ -NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, - uint16_t level, - DATA_BLOB blob, - union smb2_fileinfo *io) +NTSTATUS smb2_getinfo_file_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + union smb_fileinfo *io) { - switch (level) { - case SMB2_GETINFO_FILE_BASIC_INFO: - if (blob.length != 0x28) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->basic_info.create_time = smbcli_pull_nttime(blob.data, 0x00); - io->basic_info.access_time = smbcli_pull_nttime(blob.data, 0x08); - io->basic_info.write_time = smbcli_pull_nttime(blob.data, 0x10); - io->basic_info.change_time = smbcli_pull_nttime(blob.data, 0x18); - io->basic_info.file_attr = IVAL(blob.data, 0x20); - io->basic_info.unknown = IVAL(blob.data, 0x24); - break; - - case SMB2_GETINFO_FILE_SIZE_INFO: - if (blob.length != 0x18) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->size_info.alloc_size = BVAL(blob.data, 0x00); - io->size_info.size = BVAL(blob.data, 0x08); - io->size_info.nlink = IVAL(blob.data, 0x10); - io->size_info.delete_pending = CVAL(blob.data, 0x14); - io->size_info.directory = CVAL(blob.data, 0x15); - break; - - case SMB2_GETINFO_FILE_ID: - if (blob.length != 0x8) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->file_id.file_id = BVAL(blob.data, 0x00); - break; - - case SMB2_GETINFO_FILE_EA_SIZE: - if (blob.length != 0x4) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->ea_size.ea_size = IVAL(blob.data, 0x00); - break; - - case SMB2_GETINFO_FILE_ACCESS_INFO: - if (blob.length != 0x4) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->access_info.access_mask = IVAL(blob.data, 0x00); - break; - - case SMB2_GETINFO_FILE_0E: - if (blob.length != 0x8) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->unknown0e.unknown1 = IVAL(blob.data, 0x00); - io->unknown0e.unknown2 = IVAL(blob.data, 0x04); - break; - - case SMB2_GETINFO_FILE_ALL_EAS: - return ea_pull_list_chained(&blob, mem_ctx, - &io->all_eas.num_eas, - &io->all_eas.eas); - - case SMB2_GETINFO_FILE_10: - if (blob.length != 0x4) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->unknown10.unknown = IVAL(blob.data, 0x00); - break; - - case SMB2_GETINFO_FILE_11: - if (blob.length != 0x4) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->unknown11.unknown = IVAL(blob.data, 0x00); - break; - - case SMB2_GETINFO_FILE_ALL_INFO: { - uint32_t nlen; - ssize_t size; - void *vstr; - if (blob.length < 0x64) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->all_info.create_time = smbcli_pull_nttime(blob.data, 0x00); - io->all_info.access_time = smbcli_pull_nttime(blob.data, 0x08); - io->all_info.write_time = smbcli_pull_nttime(blob.data, 0x10); - io->all_info.change_time = smbcli_pull_nttime(blob.data, 0x18); - io->all_info.file_attr = IVAL(blob.data, 0x20); - io->all_info.unknown1 = IVAL(blob.data, 0x24); - io->all_info.alloc_size = BVAL(blob.data, 0x28); - io->all_info.size = BVAL(blob.data, 0x30); - io->all_info.nlink = IVAL(blob.data, 0x38); - io->all_info.delete_pending = CVAL(blob.data, 0x3C); - io->all_info.directory = CVAL(blob.data, 0x3D); - io->all_info.file_id = BVAL(blob.data, 0x40); - io->all_info.ea_size = IVAL(blob.data, 0x48); - io->all_info.access_mask = IVAL(blob.data, 0x4C); - io->all_info.unknown5 = BVAL(blob.data, 0x50); - io->all_info.unknown6 = BVAL(blob.data, 0x58); - nlen = IVAL(blob.data, 0x60); - if (nlen > blob.length - 0x64) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, - blob.data+0x64, nlen, &vstr); - if (size == -1) { - return NT_STATUS_ILLEGAL_CHARACTER; - } - io->all_info.fname = vstr; - break; - } + struct smb2_getinfo b; + NTSTATUS status; - case SMB2_GETINFO_FILE_SHORT_INFO: { - uint32_t nlen; - ssize_t size; - void *vstr; - if (blob.length < 0x04) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - nlen = IVAL(blob.data, 0x00); - if (nlen > blob.length - 0x04) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, - blob.data+0x04, nlen, &vstr); - if (size == -1) { - return NT_STATUS_ILLEGAL_CHARACTER; - } - io->short_info.short_name = vstr; - break; - } + status = smb2_getinfo_recv(req, mem_ctx, &b); + NT_STATUS_NOT_OK_RETURN(status); - case SMB2_GETINFO_FILE_STREAM_INFO: - return smbcli_parse_stream_info(blob, mem_ctx, &io->stream_info); - - case SMB2_GETINFO_FILE_EOF_INFO: - if (blob.length != 0x10) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->eof_info.size = BVAL(blob.data, 0x00); - io->eof_info.unknown = BVAL(blob.data, 0x08); - break; - - case SMB2_GETINFO_FILE_STANDARD_INFO: - if (blob.length != 0x38) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->standard_info.create_time = smbcli_pull_nttime(blob.data, 0x00); - io->standard_info.access_time = smbcli_pull_nttime(blob.data, 0x08); - io->standard_info.write_time = smbcli_pull_nttime(blob.data, 0x10); - io->standard_info.change_time = smbcli_pull_nttime(blob.data, 0x18); - io->standard_info.alloc_size = BVAL(blob.data, 0x20); - io->standard_info.size = BVAL(blob.data, 0x28); - io->standard_info.file_attr = IVAL(blob.data, 0x30); - io->standard_info.unknown = IVAL(blob.data, 0x34); - break; - - case SMB2_GETINFO_FILE_ATTRIB_INFO: - if (blob.length != 0x08) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - io->attrib_info.file_attr = IVAL(blob.data, 0x00); - io->attrib_info.unknown = IVAL(blob.data, 0x04); - break; - - case SMB2_GETINFO_SECURITY: { - struct ndr_pull *ndr; - NTSTATUS status; - ndr = ndr_pull_init_blob(&blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - io->security.sd = talloc(mem_ctx, struct security_descriptor); - if (io->security.sd == NULL) { - return NT_STATUS_NO_MEMORY; - } - status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->security.sd); - talloc_free(ndr); - return status; + status = smb_raw_fileinfo_passthru_parse(&b.out.blob, mem_ctx, io->generic.level, io); + data_blob_free(&b.out.blob); + + return status; +} + +/* + level specific getinfo call +*/ +NTSTATUS smb2_getinfo_file(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + union smb_fileinfo *io) +{ + struct smb2_getinfo b; + struct smb2_request *req; + uint16_t smb2_level; + + if (io->generic.level == RAW_FILEINFO_SEC_DESC) { + smb2_level = SMB2_GETINFO_SECURITY; + } else if ((io->generic.level & 0xFF) == SMB2_GETINFO_FILE) { + smb2_level = io->generic.level; + } else if (io->generic.level > 1000) { + smb2_level = ((io->generic.level-1000)<<8) | SMB2_GETINFO_FILE; + } else { + /* SMB2 only does the passthru levels */ + return NT_STATUS_INVALID_LEVEL; } - - default: - return NT_STATUS_INVALID_INFO_CLASS; + + ZERO_STRUCT(b); + b.in.max_response_size = 0x10000; + b.in.handle = io->generic.in.handle; + b.in.level = smb2_level; + + if (io->generic.level == RAW_FILEINFO_SEC_DESC) { + b.in.flags = io->query_secdesc.secinfo_flags; } - return NT_STATUS_OK; + req = smb2_getinfo_send(tree, &b); + + return smb2_getinfo_file_recv(req, mem_ctx, io); } /* recv a getinfo reply and parse the level info */ -NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, - uint16_t level, union smb2_fileinfo *io) +NTSTATUS smb2_getinfo_fs_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + union smb_fsinfo *io) { struct smb2_getinfo b; NTSTATUS status; @@ -291,7 +152,7 @@ NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, status = smb2_getinfo_recv(req, mem_ctx, &b); NT_STATUS_NOT_OK_RETURN(status); - status = smb2_getinfo_parse(mem_ctx, level, b.out.blob, io); + status = smb_raw_fsinfo_passthru_parse(b.out.blob, mem_ctx, io->generic.level, io); data_blob_free(&b.out.blob); return status; @@ -300,19 +161,29 @@ NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, /* level specific getinfo call */ -NTSTATUS smb2_getinfo_level(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, - struct smb2_handle handle, - uint16_t level, union smb2_fileinfo *io) +NTSTATUS smb2_getinfo_fs(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + union smb_fsinfo *io) { struct smb2_getinfo b; struct smb2_request *req; + uint16_t smb2_level; + + if ((io->generic.level & 0xFF) == SMB2_GETINFO_FS) { + smb2_level = io->generic.level; + } else if (io->generic.level > 1000) { + smb2_level = ((io->generic.level-1000)<<8) | SMB2_GETINFO_FS; + } else { + /* SMB2 only does the passthru levels */ + return NT_STATUS_INVALID_LEVEL; + } ZERO_STRUCT(b); b.in.max_response_size = 0x10000; - b.in.handle = handle; - b.in.level = level; + b.in.handle = io->generic.handle; + b.in.level = smb2_level; req = smb2_getinfo_send(tree, &b); - return smb2_getinfo_level_recv(req, mem_ctx, level, io); + return smb2_getinfo_fs_recv(req, mem_ctx, io); } + diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 872e20f156..3ccb5309e5 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -103,14 +103,6 @@ struct smb2_tree_connect { } out; }; -/* - file handles in SMB2 are 16 bytes -*/ -struct smb2_handle { - uint64_t data[2]; -}; - - #define SMB2_CREATE_FLAG_REQUEST_OPLOCK 0x0100 #define SMB2_CREATE_FLAG_REQUEST_EXCLUSIVE_OPLOCK 0x0800 #define SMB2_CREATE_FLAG_GRANT_OPLOCK 0x0001 @@ -190,35 +182,14 @@ struct smb2_close { } out; }; -/* fs information levels */ -#define SMB2_GETINFO_FS_VOLUME_INFO 0x0102 -#define SMB2_GETINFO_FS_SIZE_INFO 0x0302 -#define SMB2_GETINFO_FS_DEVICE_INFO 0x0402 -#define SMB2_GETINFO_FS_ATTRIBUTE_INFO 0x0502 -#define SMB2_GETINFO_FS_QUOTA_INFO 0x0602 -#define SMB2_GETINFO_FS_FULL_SIZE_INFO 0x0702 -#define SMB2_GETINFO_FS_OBJECTID_INFO 0x0802 - -/* class 3 levels */ -#define SMB2_GETINFO_SECURITY 0x0003 - -/* file information levels */ -#define SMB2_GETINFO_FILE_BASIC_INFO 0x0401 -#define SMB2_GETINFO_FILE_SIZE_INFO 0x0501 -#define SMB2_GETINFO_FILE_ID 0x0601 -#define SMB2_GETINFO_FILE_EA_SIZE 0x0701 -#define SMB2_GETINFO_FILE_ACCESS_INFO 0x0801 -#define SMB2_GETINFO_FILE_0E 0x0e01 -#define SMB2_GETINFO_FILE_ALL_EAS 0x0f01 -#define SMB2_GETINFO_FILE_10 0x1001 -#define SMB2_GETINFO_FILE_11 0x1101 -#define SMB2_GETINFO_FILE_ALL_INFO 0x1201 -#define SMB2_GETINFO_FILE_SHORT_INFO 0x1501 -#define SMB2_GETINFO_FILE_STREAM_INFO 0x1601 -#define SMB2_GETINFO_FILE_EOF_INFO 0x1c01 -#define SMB2_GETINFO_FILE_STANDARD_INFO 0x2201 -#define SMB2_GETINFO_FILE_ATTRIB_INFO 0x2301 +/* getinfo classes */ +#define SMB2_GETINFO_FILE 0x01 +#define SMB2_GETINFO_FS 0x02 +#define SMB2_GETINFO_SECURITY 0x03 +/* NOTE! the getinfo fs and file levels exactly match up with the + 'passthru' SMB levels, which are levels >= 1000. The SMB2 client + lib uses the names from the libcli/raw/ library */ struct smb2_getinfo { struct { @@ -227,8 +198,8 @@ struct smb2_getinfo { uint16_t level; uint32_t max_response_size; uint32_t unknown1; + uint32_t unknown2; uint32_t flags; /* level specific */ - uint32_t unknown3; uint32_t unknown4; struct smb2_handle handle; } in; @@ -244,105 +215,6 @@ struct smb2_getinfo { } out; }; -union smb2_fileinfo { - struct { - NTTIME create_time; - NTTIME access_time; - NTTIME write_time; - NTTIME change_time; - uint32_t file_attr; - uint32_t unknown; - } basic_info; - - struct { - uint64_t alloc_size; - uint64_t size; - uint32_t nlink; - uint8_t delete_pending; - uint8_t directory; - } size_info; - - struct { - uint64_t file_id; - } file_id; - - struct { - uint32_t ea_size; - } ea_size; - - struct { - uint32_t access_mask; - } access_info; - - struct { - uint32_t unknown1; - uint32_t unknown2; - } unknown0e; - - struct smb_ea_list all_eas; - - struct { - uint32_t unknown; - } unknown10; - - struct { - uint32_t unknown; - } unknown11; - - struct { - NTTIME create_time; - NTTIME access_time; - NTTIME write_time; - NTTIME change_time; - uint32_t file_attr; - uint32_t unknown1; - uint64_t alloc_size; - uint64_t size; - uint32_t nlink; - uint8_t delete_pending; - uint8_t directory; - /* uint16_t _pad; */ - uint64_t file_id; - uint32_t ea_size; - uint32_t access_mask; - uint64_t unknown5; - uint64_t unknown6; - const char *fname; - } all_info; - - struct { - const char *short_name; - } short_info; - - struct stream_information stream_info; - - struct { - uint64_t size; - uint64_t unknown; - } eof_info; - - struct { - NTTIME create_time; - NTTIME access_time; - NTTIME write_time; - NTTIME change_time; - uint64_t alloc_size; - uint64_t size; - uint32_t file_attr; - uint32_t unknown; - } standard_info; - - struct { - uint32_t file_attr; - uint32_t unknown; - } attrib_info; - - struct { - struct security_descriptor *sd; - } security; -}; - - struct smb2_write { struct { /* static body buffer 48 (0x30) bytes */ -- cgit From 2ff21db535897eb2a4eae428b7465337bd7cfdd1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 06:28:15 +0000 Subject: r11771: - split out the setinfo blob construction in the libcli/raw code - added a smb2_setinfo call - added smb2_setinfo_file*() calls (This used to be commit da0b6fb93683331134ef2f4abd8707e0c3fc6d9d) --- source4/libcli/raw/rawsetfileinfo.c | 143 +++++++++++++++++++++++++----------- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/getinfo.c | 98 +++++++++++++----------- source4/libcli/smb2/request.c | 51 +++++++++++++ source4/libcli/smb2/setinfo.c | 109 +++++++++++++++++++++++++++ source4/libcli/smb2/smb2_calls.h | 9 +++ 6 files changed, 328 insertions(+), 85 deletions(-) create mode 100644 source4/libcli/smb2/setinfo.c (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 5e780757e8..5779cf33fb 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -22,13 +22,14 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" -/**************************************************************************** - Handle setfileinfo/setpathinfo trans2 backend. -****************************************************************************/ -static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, - TALLOC_CTX *mem_ctx, - union smb_setfileinfo *parms, - DATA_BLOB *blob) + +/* + Handle setfileinfo/setpathinfo passthu constructions +*/ +BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, + enum smb_setfileinfo_level level, + union smb_setfileinfo *parms, + DATA_BLOB *blob) { uint_t len; @@ -37,6 +38,77 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, if (blob->data == NULL) return False; \ } while (0) + switch (level) { + case RAW_SFILEINFO_BASIC_INFORMATION: + NEED_BLOB(40); + smbcli_push_nttime(blob->data, 0, parms->basic_info.in.create_time); + smbcli_push_nttime(blob->data, 8, parms->basic_info.in.access_time); + smbcli_push_nttime(blob->data, 16, parms->basic_info.in.write_time); + smbcli_push_nttime(blob->data, 24, parms->basic_info.in.change_time); + SIVAL(blob->data, 32, parms->basic_info.in.attrib); + SIVAL(blob->data, 36, 0); /* padding */ + return True; + + case RAW_SFILEINFO_DISPOSITION_INFORMATION: + NEED_BLOB(4); + SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close); + return True; + + case RAW_SFILEINFO_ALLOCATION_INFORMATION: + NEED_BLOB(8); + SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size); + return True; + + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + NEED_BLOB(8); + SBVAL(blob->data, 0, parms->end_of_file_info.in.size); + return True; + + case RAW_SFILEINFO_RENAME_INFORMATION: + NEED_BLOB(12); + SIVAL(blob->data, 0, parms->rename_information.in.overwrite); + SIVAL(blob->data, 4, parms->rename_information.in.root_fid); + len = smbcli_blob_append_string(NULL, mem_ctx, blob, + parms->rename_information.in.new_name, + STR_UNICODE|STR_TERMINATE); + SIVAL(blob->data, 8, len - 2); + return True; + + case RAW_SFILEINFO_POSITION_INFORMATION: + NEED_BLOB(8); + SBVAL(blob->data, 0, parms->position_information.in.position); + return True; + + case RAW_SFILEINFO_MODE_INFORMATION: + NEED_BLOB(4); + SIVAL(blob->data, 0, parms->mode_information.in.mode); + return True; + + /* Unhandled levels */ + case RAW_SFILEINFO_1023: + case RAW_SFILEINFO_1025: + case RAW_SFILEINFO_1029: + case RAW_SFILEINFO_1032: + case RAW_SFILEINFO_1039: + case RAW_SFILEINFO_1040: + break; + + default: + DEBUG(0,("Unhandled setfileinfo passthru level %d\n", level)); + return False; + } + + return False; +} + +/* + Handle setfileinfo/setpathinfo trans2 backend. +*/ +static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_setfileinfo *parms, + DATA_BLOB *blob) +{ switch (parms->generic.level) { case RAW_SFILEINFO_GENERIC: case RAW_SFILEINFO_SETATTR: @@ -62,14 +134,8 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: - NEED_BLOB(40); - smbcli_push_nttime(blob->data, 0, parms->basic_info.in.create_time); - smbcli_push_nttime(blob->data, 8, parms->basic_info.in.access_time); - smbcli_push_nttime(blob->data, 16, parms->basic_info.in.write_time); - smbcli_push_nttime(blob->data, 24, parms->basic_info.in.change_time); - SIVAL(blob->data, 32, parms->basic_info.in.attrib); - SIVAL(blob->data, 36, 0); /* padding */ - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_BASIC_INFORMATION, + parms, blob); case RAW_SFILEINFO_UNIX_BASIC: NEED_BLOB(92); @@ -89,52 +155,45 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - NEED_BLOB(4); - SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close); - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_DISPOSITION_INFORMATION, + parms, blob); case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: - NEED_BLOB(8); - SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size); - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_ALLOCATION_INFORMATION, + parms, blob); case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - NEED_BLOB(8); - SBVAL(blob->data, 0, parms->end_of_file_info.in.size); - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_END_OF_FILE_INFORMATION, + parms, blob); case RAW_SFILEINFO_RENAME_INFORMATION: - NEED_BLOB(12); - SIVAL(blob->data, 0, parms->rename_information.in.overwrite); - SIVAL(blob->data, 4, parms->rename_information.in.root_fid); - len = smbcli_blob_append_string(tree->session, mem_ctx, blob, - parms->rename_information.in.new_name, - STR_UNICODE|STR_TERMINATE); - SIVAL(blob->data, 8, len - 2); - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_RENAME_INFORMATION, + parms, blob); case RAW_SFILEINFO_POSITION_INFORMATION: - NEED_BLOB(8); - SBVAL(blob->data, 0, parms->position_information.in.position); - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_POSITION_INFORMATION, + parms, blob); case RAW_SFILEINFO_MODE_INFORMATION: - NEED_BLOB(4); - SIVAL(blob->data, 0, parms->mode_information.in.mode); - return True; + return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_MODE_INFORMATION, + parms, blob); - /* Unhandled levels */ - - case RAW_SFILEINFO_UNIX_LINK: - case RAW_SFILEINFO_UNIX_HLINK: + /* Unhandled passthru levels */ case RAW_SFILEINFO_1023: case RAW_SFILEINFO_1025: case RAW_SFILEINFO_1029: case RAW_SFILEINFO_1032: case RAW_SFILEINFO_1039: case RAW_SFILEINFO_1040: + return smb_raw_setfileinfo_passthru(mem_ctx, parms->generic.level, + parms, blob); + + /* Unhandled levels */ + + case RAW_SFILEINFO_UNIX_LINK: + case RAW_SFILEINFO_UNIX_HLINK: break; } diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 15f49ba88e..fcea996f01 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -10,5 +10,6 @@ OBJ_FILES = \ connect.o \ getinfo.o \ write.o \ - read.o + read.o \ + setinfo.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index cb8ce76a07..4575ae2a40 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -86,6 +86,44 @@ NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, } +/* + map a generic info level to a SMB2 info level +*/ +uint16_t smb2_getinfo_map_level(uint16_t level, uint8_t class) +{ + if ((level & 0xFF) == class) { + return level; + } else if (level > 1000) { + return ((level-1000)<<8) | class; + } + DEBUG(0,("Unable to map SMB2 info level 0x%04x of class %d\n", level, class)); + return 0; +} + +/* + level specific getinfo call - async send +*/ +struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fileinfo *io) +{ + struct smb2_getinfo b; + uint16_t smb2_level = smb2_getinfo_map_level(io->generic.level, SMB2_GETINFO_FILE); + + if (smb2_level == 0) { + return NULL; + } + + ZERO_STRUCT(b); + b.in.max_response_size = 0x10000; + b.in.handle = io->generic.in.handle; + b.in.level = smb2_level; + + if (io->generic.level == RAW_FILEINFO_SEC_DESC) { + b.in.flags = io->query_secdesc.secinfo_flags; + } + + return smb2_getinfo_send(tree, &b); +} + /* recv a getinfo reply and parse the level info */ @@ -110,36 +148,31 @@ NTSTATUS smb2_getinfo_file_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, NTSTATUS smb2_getinfo_file(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *io) { - struct smb2_getinfo b; - struct smb2_request *req; - uint16_t smb2_level; + struct smb2_request *req = smb2_getinfo_file_send(tree, io); + return smb2_getinfo_file_recv(req, mem_ctx, io); +} - if (io->generic.level == RAW_FILEINFO_SEC_DESC) { - smb2_level = SMB2_GETINFO_SECURITY; - } else if ((io->generic.level & 0xFF) == SMB2_GETINFO_FILE) { - smb2_level = io->generic.level; - } else if (io->generic.level > 1000) { - smb2_level = ((io->generic.level-1000)<<8) | SMB2_GETINFO_FILE; - } else { - /* SMB2 only does the passthru levels */ - return NT_STATUS_INVALID_LEVEL; - } +/* + level specific getinfo call - async send +*/ +struct smb2_request *smb2_getinfo_fs_send(struct smb2_tree *tree, union smb_fsinfo *io) +{ + struct smb2_getinfo b; + uint16_t smb2_level = smb2_getinfo_map_level(io->generic.level, SMB2_GETINFO_FS); + + if (smb2_level == 0) { + return NULL; + } + ZERO_STRUCT(b); b.in.max_response_size = 0x10000; - b.in.handle = io->generic.in.handle; + b.in.handle = io->generic.handle; b.in.level = smb2_level; - if (io->generic.level == RAW_FILEINFO_SEC_DESC) { - b.in.flags = io->query_secdesc.secinfo_flags; - } - - req = smb2_getinfo_send(tree, &b); - - return smb2_getinfo_file_recv(req, mem_ctx, io); + return smb2_getinfo_send(tree, &b); } - /* recv a getinfo reply and parse the level info */ @@ -164,26 +197,7 @@ NTSTATUS smb2_getinfo_fs_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, NTSTATUS smb2_getinfo_fs(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *io) { - struct smb2_getinfo b; - struct smb2_request *req; - uint16_t smb2_level; - - if ((io->generic.level & 0xFF) == SMB2_GETINFO_FS) { - smb2_level = io->generic.level; - } else if (io->generic.level > 1000) { - smb2_level = ((io->generic.level-1000)<<8) | SMB2_GETINFO_FS; - } else { - /* SMB2 only does the passthru levels */ - return NT_STATUS_INVALID_LEVEL; - } - - ZERO_STRUCT(b); - b.in.max_response_size = 0x10000; - b.in.handle = io->generic.handle; - b.in.level = smb2_level; - - req = smb2_getinfo_send(tree, &b); - + struct smb2_request *req = smb2_getinfo_fs_send(tree, io); return smb2_getinfo_fs_recv(req, mem_ctx, io); } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1a98ba9987..41e2ad74e2 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -390,6 +390,57 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, return NT_STATUS_OK; } + +/* + push a uint32_t length/ uint32_t ofs/blob triple into a data blob + the ofs points to the start of the length/offset pair, and is relative + to the body start +*/ +NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, + uint32_t ofs, DATA_BLOB blob) +{ + NTSTATUS status; + size_t offset; + size_t padding_length; + uint8_t *ptr = buf->body+ofs; + + if (buf->dynamic == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + if (blob.length == 0) { + SIVAL(ptr, 0, 0); + SIVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 8); + offset += padding_length; + + SIVAL(ptr, 0, blob.length); + SIVAL(ptr, 4, offset); + + status = smb2_grow_buffer(buf, padding_length + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size += blob.length + padding_length; + buf->body_size += blob.length + padding_length; + + return NT_STATUS_OK; +} + /* pull a uint16_t ofs/ uint32_t length/blob triple from a data blob the ptr points to the start of the offset/length pair diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c new file mode 100644 index 0000000000..d6c5555a33 --- /dev/null +++ b/source4/libcli/smb2/setinfo.c @@ -0,0 +1,109 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client setinfo calls + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a setinfo request +*/ +struct smb2_request *smb2_setinfo_send(struct smb2_tree *tree, struct smb2_setinfo *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_SETINFO, 0x20, io->in.blob.length); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, io->in.level); + smb2_push_s32o32_blob(&req->out, 0x04, io->in.blob); + SIVAL(req->out.body, 0x0C, io->in.flags); + smb2_push_handle(req->out.body+0x10, &io->in.handle); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a setinfo reply +*/ +NTSTATUS smb2_setinfo_recv(struct smb2_request *req) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x02, False); + + return smb2_request_destroy(req); +} + +/* + sync setinfo request +*/ +NTSTATUS smb2_setinfo(struct smb2_tree *tree, struct smb2_setinfo *io) +{ + struct smb2_request *req = smb2_setinfo_send(tree, io); + return smb2_setinfo_recv(req); +} + +/* + level specific file setinfo call - async send +*/ +struct smb2_request *smb2_setinfo_file_send(struct smb2_tree *tree, union smb_setfileinfo *io) +{ + struct smb2_setinfo b; + uint16_t smb2_level = smb2_getinfo_map_level(io->generic.level, SMB2_GETINFO_FILE); + struct smb2_request *req; + + if (smb2_level == 0) { + return NULL; + } + + ZERO_STRUCT(b); + b.in.level = smb2_level; + b.in.handle = io->generic.file.handle; + if (!smb_raw_setfileinfo_passthru(tree, io->generic.level, io, &b.in.blob)) { + return NULL; + } + + if (io->generic.level == RAW_SFILEINFO_SEC_DESC) { + b.in.flags = io->set_secdesc.in.secinfo_flags; + } + + req = smb2_setinfo_send(tree, &b); + data_blob_free(&b.in.blob); + return req; +} + +/* + level specific file setinfo call - sync +*/ +NTSTATUS smb2_setinfo_file(struct smb2_tree *tree, union smb_setfileinfo *io) +{ + struct smb2_request *req = smb2_setinfo_file_send(tree, io); + return smb2_setinfo_recv(req); +} diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 3ccb5309e5..1ef056da13 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -215,6 +215,15 @@ struct smb2_getinfo { } out; }; +struct smb2_setinfo { + struct { + uint16_t level; + uint32_t flags; + struct smb2_handle handle; + DATA_BLOB blob; + } in; +}; + struct smb2_write { struct { /* static body buffer 48 (0x30) bytes */ -- cgit From c8c7fb2492d3f19939df67f98e4ea6ad423274da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 09:25:25 +0000 Subject: r11775: added support for creating files on SMB2 with initial EA lists and an ACL (This used to be commit ff197092988cee64742f83df23c43ae664a196f9) --- source4/libcli/smb2/create.c | 65 ++++++++++++++++++++++++++++++++++++++-- source4/libcli/smb2/request.c | 6 ++++ source4/libcli/smb2/smb2_calls.h | 5 +++- 3 files changed, 73 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 47fd208643..647b408c68 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -25,6 +25,37 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#define CREATE_TAG_EA 0x41747845 /* "ExtA" */ +#define CREATE_TAG_SD 0x6341784D /* "MxAc" */ + +/* + add a blob to a smb2_create attribute blob +*/ +static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + uint32_t tag, + DATA_BLOB add, BOOL last) +{ + NTSTATUS status; + uint32_t ofs = blob->length; + status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length); + NT_STATUS_NOT_OK_RETURN(status); + + if (last) { + SIVAL(blob->data, ofs+0x00, 0); + } else { + SIVAL(blob->data, ofs+0x00, 0x18 + add.length); + } + SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ + SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ + SSVAL(blob->data, ofs+0x0A, 0x18); /* offset of data */ + SIVAL(blob->data, ofs+0x0C, add.length); + SIVAL(blob->data, ofs+0x10, tag); + SIVAL(blob->data, ofs+0x14, 0); /* pad? */ + memcpy(blob->data+ofs+0x18, add.data, add.length); + + return NT_STATUS_OK; +} + /* send a create request */ @@ -32,6 +63,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create { struct smb2_request *req; NTSTATUS status; + DATA_BLOB blob = data_blob(NULL, 0); req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, 1); if (req == NULL) return NULL; @@ -54,7 +86,36 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create return NULL; } - status = smb2_push_o32s32_blob(&req->out, 0x30, io->in.blob); + if (io->in.eas.num_eas != 0) { + DATA_BLOB b = data_blob_talloc(req, NULL, + ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); + ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_EA, b, False); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + data_blob_free(&b); + } + + if (io->in.sd != NULL) { + DATA_BLOB b; + status = ndr_push_struct_blob(&b, req, io->in.sd, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, b, True); + } else { + status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, data_blob(NULL, 0), True); + } + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + status = smb2_push_o32s32_blob(&req->out, 0x30, blob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -74,7 +135,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct NTSTATUS status; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 41e2ad74e2..3f09c9aeec 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -160,6 +160,12 @@ BOOL smb2_request_is_error(struct smb2_request *req) return NT_STATUS_IS_ERR(req->status); } +/* Return true if the last packet was OK */ +BOOL smb2_request_is_ok(struct smb2_request *req) +{ + return NT_STATUS_IS_OK(req->status); +} + /* check if a range in the reply body is out of bounds */ diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 1ef056da13..53f7a45d88 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -130,7 +130,10 @@ struct smb2_create { /* dynamic body */ const char *fname; - DATA_BLOB blob; + /* optional list of extended attributes and security + descriptor */ + struct smb_ea_list eas; + struct security_descriptor *sd; } in; struct { -- cgit From 3922b68d13ec79b8ebf55d0624668bf6483930a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 10:07:14 +0000 Subject: r11777: display the security_descriptor in torture_smb2_all_info() (This used to be commit d1067fc25df57b1b6ef59a69f979ed76df5c46cd) --- source4/libcli/smb2/getinfo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 4575ae2a40..85411fab92 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -91,6 +91,10 @@ NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, */ uint16_t smb2_getinfo_map_level(uint16_t level, uint8_t class) { + if (class == SMB2_GETINFO_FILE && + level == RAW_FILEINFO_SEC_DESC) { + return SMB2_GETINFO_SECURITY; + } if ((level & 0xFF) == class) { return level; } else if (level > 1000) { -- cgit From d5f37ecf94e2b63511102b3fd34c0e7bcd8d7879 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 11:45:24 +0000 Subject: r11780: it turns out that the MxAc tag isn't a security descriptor, its a request that the server return its own MxAc blob which contains the maximum allowed access_mask for the returned file handle (This used to be commit c0288aa8cd46ca384074f89430c226d725c39475) --- source4/libcli/smb2/create.c | 27 ++++++++++----------------- source4/libcli/smb2/request.c | 2 +- source4/libcli/smb2/smb2_calls.h | 4 +--- 3 files changed, 12 insertions(+), 21 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 647b408c68..564eba7f46 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -25,8 +25,8 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#define CREATE_TAG_EA 0x41747845 /* "ExtA" */ -#define CREATE_TAG_SD 0x6341784D /* "MxAc" */ +#define CREATE_TAG_EXTA 0x41747845 /* "ExtA" */ +#define CREATE_TAG_MXAC 0x6341784D /* "MxAc" */ /* add a blob to a smb2_create attribute blob @@ -37,13 +37,14 @@ static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, { NTSTATUS status; uint32_t ofs = blob->length; - status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length); + uint8_t pad = smb2_padding_size(add.length, 8); + status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad); NT_STATUS_NOT_OK_RETURN(status); if (last) { SIVAL(blob->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x18 + add.length); + SIVAL(blob->data, ofs+0x00, 0x18 + add.length + pad); } SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ @@ -52,6 +53,7 @@ static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, SIVAL(blob->data, ofs+0x10, tag); SIVAL(blob->data, ofs+0x14, 0); /* pad? */ memcpy(blob->data+ofs+0x18, add.data, add.length); + memset(blob->data+ofs+0x18+add.length, 0, pad); return NT_STATUS_OK; } @@ -90,7 +92,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EA, b, False); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, False); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -98,18 +100,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create data_blob_free(&b); } - if (io->in.sd != NULL) { - DATA_BLOB b; - status = ndr_push_struct_blob(&b, req, io->in.sd, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; - } - status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, b, True); - } else { - status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, data_blob(NULL, 0), True); - } + /* an empty MxAc tag seems to be used to ask the server to + return the maximum access mask allowed on the file */ + status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), True); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 3f09c9aeec..03c0ed4350 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -181,7 +181,7 @@ BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) return False; } -static size_t smb2_padding_size(uint32_t offset, size_t n) +size_t smb2_padding_size(uint32_t offset, size_t n) { if ((offset & (n-1)) == 0) return 0; return n - (offset & (n-1)); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 53f7a45d88..1c41d4cd66 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -130,10 +130,8 @@ struct smb2_create { /* dynamic body */ const char *fname; - /* optional list of extended attributes and security - descriptor */ + /* optional list of extended attributes */ struct smb_ea_list eas; - struct security_descriptor *sd; } in; struct { -- cgit From 552c0111a10c70d2ca24c996838d41d79494969f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 23:15:32 +0000 Subject: r11791: simplify the SMB2 connect code following some suggestions from volker (This used to be commit 71e3e61941621f72f45708340f5d03b2b79580b4) --- source4/libcli/smb2/connect.c | 46 ++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 7b538dc2e6..38b6e1924e 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -27,8 +27,6 @@ #include "libcli/composite/composite.h" struct smb2_connect_state { - struct smb2_request *req; - struct composite_context *creq; struct cli_credentials *credentials; const char *host; const char *share; @@ -68,6 +66,7 @@ static void continue_session(struct composite_context *creq) struct composite_context); struct smb2_connect_state *state = talloc_get_type(c->private_data, struct smb2_connect_state); + struct smb2_request *req; c->status = smb2_session_setup_spnego_recv(creq); if (!NT_STATUS_IS_OK(c->status)) { @@ -89,14 +88,14 @@ static void continue_session(struct composite_context *creq) return; } - state->req = smb2_tree_connect_send(state->tree, &state->tcon); - if (state->req == NULL) { + req = smb2_tree_connect_send(state->tree, &state->tcon); + if (req == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); return; } - state->req->async.fn = continue_tcon; - state->req->async.private = c; + req->async.fn = continue_tcon; + req->async.private = c; } /* @@ -109,6 +108,7 @@ static void continue_negprot(struct smb2_request *req) struct smb2_connect_state *state = talloc_get_type(c->private_data, struct smb2_connect_state); struct smb2_transport *transport = req->transport; + struct composite_context *creq; c->status = smb2_negprot_recv(req, c, &state->negprot); if (!NT_STATUS_IS_OK(c->status)) { @@ -122,14 +122,14 @@ static void continue_negprot(struct smb2_request *req) return; } - state->creq = smb2_session_setup_spnego_send(state->session, state->credentials); - if (state->creq == NULL) { + creq = smb2_session_setup_spnego_send(state->session, state->credentials); + if (creq == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); return; } - state->creq->async.fn = continue_session; - state->creq->async.private_data = c; + creq->async.fn = continue_session; + creq->async.private_data = c; } /* @@ -143,6 +143,7 @@ static void continue_socket(struct composite_context *creq) struct smb2_connect_state); struct smbcli_socket *sock; struct smb2_transport *transport; + struct smb2_request *req; c->status = smbcli_sock_connect_recv(creq, state, &sock); if (!NT_STATUS_IS_OK(c->status)) { @@ -159,14 +160,14 @@ static void continue_socket(struct composite_context *creq) ZERO_STRUCT(state->negprot); state->negprot.in.unknown1 = 0x0001; - state->req = smb2_negprot_send(transport, &state->negprot); - if (state->req == NULL) { + req = smb2_negprot_send(transport, &state->negprot); + if (req == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); return; } - state->req->async.fn = continue_negprot; - state->req->async.private = c; + req->async.fn = continue_negprot; + req->async.private = c; } @@ -187,14 +188,14 @@ static void continue_resolve(struct composite_context *creq) return; } - state->creq = smbcli_sock_connect_send(state, addr, 445, state->host, c->event_ctx); - if (state->creq == NULL) { + creq = smbcli_sock_connect_send(state, addr, 445, state->host, c->event_ctx); + if (creq == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); return; } - state->creq->async.private_data = c; - state->creq->async.fn = continue_socket; + creq->async.private_data = c; + creq->async.fn = continue_socket; } /* @@ -210,6 +211,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, struct composite_context *c; struct smb2_connect_state *state; struct nbt_name name; + struct composite_context *creq; c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) return NULL; @@ -235,11 +237,11 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, ZERO_STRUCT(name); name.name = host; - state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); - if (state->creq == NULL) goto failed; + creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); + if (creq == NULL) goto failed; - state->creq->async.private_data = c; - state->creq->async.fn = continue_resolve; + creq->async.private_data = c; + creq->async.fn = continue_resolve; return c; -- cgit From 27bab09cdb76364b0e0562304078c79c6612c6e1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 23:34:47 +0000 Subject: r11795: used a couple more of volkers composite helper functions. They certainly make the code more compact. (This used to be commit 872e2a49d8a1ad1f9a6e2f2d323b3471aeb9cba6) --- source4/libcli/smb2/connect.c | 48 ++++++++----------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 38b6e1924e..cdfc162aae 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -75,24 +75,15 @@ static void continue_session(struct composite_context *creq) } state->tree = smb2_tree_init(state->session, state, True); - if (state->tree == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } + if (composite_nomem(state->tree, c)) return; state->tcon.in.unknown1 = 0x09; state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s", state->host, state->share); - if (state->tcon.in.path == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } + if (composite_nomem(state->tcon.in.path, c)) return; req = smb2_tree_connect_send(state->tree, &state->tcon); - if (req == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } + if (composite_nomem(req, c)) return; req->async.fn = continue_tcon; req->async.private = c; @@ -117,19 +108,11 @@ static void continue_negprot(struct smb2_request *req) } state->session = smb2_session_init(transport, state, True); - if (state->session == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } + if (composite_nomem(state->session, c)) return; creq = smb2_session_setup_spnego_send(state->session, state->credentials); - if (creq == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } - creq->async.fn = continue_session; - creq->async.private_data = c; + composite_continue(c, creq, continue_session, c); } /* @@ -152,19 +135,13 @@ static void continue_socket(struct composite_context *creq) } transport = smb2_transport_init(sock, state); - if (transport == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } + if (composite_nomem(transport, c)) return; ZERO_STRUCT(state->negprot); state->negprot.in.unknown1 = 0x0001; req = smb2_negprot_send(transport, &state->negprot); - if (req == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } + if (composite_nomem(req, c)) return; req->async.fn = continue_negprot; req->async.private = c; @@ -189,13 +166,8 @@ static void continue_resolve(struct composite_context *creq) } creq = smbcli_sock_connect_send(state, addr, 445, state->host, c->event_ctx); - if (creq == NULL) { - composite_error(c, NT_STATUS_NO_MEMORY); - return; - } - creq->async.private_data = c; - creq->async.fn = continue_socket; + composite_continue(c, creq, continue_socket, c); } /* @@ -238,10 +210,8 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, name.name = host; creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); - if (creq == NULL) goto failed; - creq->async.private_data = c; - creq->async.fn = continue_resolve; + composite_continue(c, creq, continue_resolve, c); return c; -- cgit From 771d4fab26c8580cbc186caee067884a314ecbc7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 18 Nov 2005 23:48:51 +0000 Subject: r11796: Two more uses of !composite_is_ok (This used to be commit 7256157d01ff47d33706dadd45851cf2fbbce3a6) --- source4/libcli/smb2/connect.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index cdfc162aae..7ed3f97bf3 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -47,10 +47,7 @@ static void continue_tcon(struct smb2_request *req) struct smb2_connect_state); c->status = smb2_tree_connect_recv(req, &state->tcon); - if (!NT_STATUS_IS_OK(c->status)) { - composite_error(c, c->status); - return; - } + if (!composite_is_ok(c)) return; state->tree->tid = state->tcon.out.tid; @@ -69,10 +66,7 @@ static void continue_session(struct composite_context *creq) struct smb2_request *req; c->status = smb2_session_setup_spnego_recv(creq); - if (!NT_STATUS_IS_OK(c->status)) { - composite_error(c, c->status); - return; - } + if (!composite_is_ok(c)) return; state->tree = smb2_tree_init(state->session, state, True); if (composite_nomem(state->tree, c)) return; @@ -102,10 +96,7 @@ static void continue_negprot(struct smb2_request *req) struct composite_context *creq; c->status = smb2_negprot_recv(req, c, &state->negprot); - if (!NT_STATUS_IS_OK(c->status)) { - composite_error(c, c->status); - return; - } + if (!composite_is_ok(c)) return; state->session = smb2_session_init(transport, state, True); if (composite_nomem(state->session, c)) return; @@ -129,10 +120,7 @@ static void continue_socket(struct composite_context *creq) struct smb2_request *req; c->status = smbcli_sock_connect_recv(creq, state, &sock); - if (!NT_STATUS_IS_OK(c->status)) { - composite_error(c, c->status); - return; - } + if (!composite_is_ok(c)) return; transport = smb2_transport_init(sock, state); if (composite_nomem(transport, c)) return; @@ -160,10 +148,7 @@ static void continue_resolve(struct composite_context *creq) const char *addr; c->status = resolve_name_recv(creq, state, &addr); - if (!NT_STATUS_IS_OK(c->status)) { - composite_error(c, c->status); - return; - } + if (!composite_is_ok(c)) return; creq = smbcli_sock_connect_send(state, addr, 445, state->host, c->event_ctx); -- cgit From 7d6f36682eab29cb23c40dd915acad61fb5d68cb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 19 Nov 2005 05:55:08 +0000 Subject: r11800: - filled in unknown fields in SMB2 all_info level - allow setting of the ALL_EAS flags bits in SMB2 getinfo (This used to be commit 8c7c54a46dfb91c053d07a5e606892a41213c605) --- source4/libcli/raw/rawfileinfo.c | 8 ++++---- source4/libcli/smb2/getinfo.c | 5 ++++- source4/libcli/smb2/smb2_calls.h | 6 +++++- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 7119eed5e7..92d31b30ef 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -95,9 +95,9 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ } parms->basic_info.out.create_time = smbcli_pull_nttime(blob->data, 0); parms->basic_info.out.access_time = smbcli_pull_nttime(blob->data, 8); - parms->basic_info.out.write_time = smbcli_pull_nttime(blob->data, 16); + parms->basic_info.out.write_time = smbcli_pull_nttime(blob->data, 16); parms->basic_info.out.change_time = smbcli_pull_nttime(blob->data, 24); - parms->basic_info.out.attrib = IVAL(blob->data, 32); + parms->basic_info.out.attrib = IVAL(blob->data, 32); return NT_STATUS_OK; case RAW_FILEINFO_STANDARD_INFORMATION: @@ -236,8 +236,8 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->all_info2.out.file_id = BVAL(blob->data, 0x40); parms->all_info2.out.ea_size = IVAL(blob->data, 0x48); parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C); - parms->all_info2.out.unknown2 = BVAL(blob->data, 0x50); - parms->all_info2.out.unknown3 = BVAL(blob->data, 0x58); + parms->all_info2.out.position = BVAL(blob->data, 0x50); + parms->all_info2.out.mode = BVAL(blob->data, 0x58); smbcli_blob_pull_string(NULL, mem_ctx, blob, &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE); return NT_STATUS_OK; diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 85411fab92..62418a05b7 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -43,7 +43,7 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin SIVAL(req->out.body, 0x08, io->in.unknown1); SIVAL(req->out.body, 0x0C, io->in.unknown2); SIVAL(req->out.body, 0x10, io->in.flags); - SIVAL(req->out.body, 0x14, io->in.unknown4); + SIVAL(req->out.body, 0x14, io->in.flags2); smb2_push_handle(req->out.body+0x18, &io->in.handle); smb2_transport_send(req); @@ -124,6 +124,9 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi if (io->generic.level == RAW_FILEINFO_SEC_DESC) { b.in.flags = io->query_secdesc.secinfo_flags; } + if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) { + b.in.flags2 = io->all_eas.ea_flags; + } return smb2_getinfo_send(tree, &b); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 1c41d4cd66..e6e1872d5e 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -188,6 +188,10 @@ struct smb2_close { #define SMB2_GETINFO_FS 0x02 #define SMB2_GETINFO_SECURITY 0x03 +/* flags for RAW_FILEINFO_SMB2_ALL_EAS */ +#define SMB2_GETINFO_EA_FLAG_RESTART 0x01 +#define SMB2_GETINFO_EA_FLAG_SINGLE 0x02 + /* NOTE! the getinfo fs and file levels exactly match up with the 'passthru' SMB levels, which are levels >= 1000. The SMB2 client lib uses the names from the libcli/raw/ library */ @@ -201,7 +205,7 @@ struct smb2_getinfo { uint32_t unknown1; uint32_t unknown2; uint32_t flags; /* level specific */ - uint32_t unknown4; + uint32_t flags2; /* used by all_eas level */ struct smb2_handle handle; } in; -- cgit From fc04e3e795cebca5723c24e097f5374a23b2247b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 19 Nov 2005 06:39:12 +0000 Subject: r11801: - added basic SMB2 find support - added SMB2-SCANFIND test - cleaned up continue flags in EAs and find requests (This used to be commit 8792bc07d927e6470874230153177748afae3ee8) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/find.c | 90 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/getinfo.c | 2 +- source4/libcli/smb2/smb2_calls.h | 19 ++++++++- 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 source4/libcli/smb2/find.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index fcea996f01..c0974dbfa5 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -11,5 +11,6 @@ OBJ_FILES = \ getinfo.o \ write.o \ read.o \ - setinfo.o + setinfo.o \ + find.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c new file mode 100644 index 0000000000..91be5e4bb1 --- /dev/null +++ b/source4/libcli/smb2/find.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client find calls + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a find request +*/ +struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io) +{ + struct smb2_request *req; + NTSTATUS status; + + req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, 1); + if (req == NULL) return NULL; + + SCVAL(req->out.body, 0x02, io->in.level); + SCVAL(req->out.body, 0x03, io->in.continue_flags); + SIVAL(req->out.body, 0x04, io->in.unknown); + smb2_push_handle(req->out.body+0x08, &io->in.handle); + SIVAL(req->out.body, 0x1C, io->in.max_response_size); + + status = smb2_push_o16s16_string(&req->out, 0x18, io->in.pattern); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + + smb2_transport_send(req); + + return req; +} + + +/* + recv a find reply +*/ +NTSTATUS smb2_find_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + struct smb2_find *io) +{ + NTSTATUS status; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x08, True); + + status = smb2_pull_o16s32_blob(&req->in, mem_ctx, + req->in.body+0x02, &io->out.blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return smb2_request_destroy(req); +} + +/* + sync find request +*/ +NTSTATUS smb2_find(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + struct smb2_find *io) +{ + struct smb2_request *req = smb2_find_send(tree, io); + return smb2_find_recv(req, mem_ctx, io); +} + diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 62418a05b7..e406fdf45c 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -125,7 +125,7 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi b.in.flags = io->query_secdesc.secinfo_flags; } if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) { - b.in.flags2 = io->all_eas.ea_flags; + b.in.flags2 = io->all_eas.continue_flags; } return smb2_getinfo_send(tree, &b); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index e6e1872d5e..10d6cda7a3 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -189,8 +189,8 @@ struct smb2_close { #define SMB2_GETINFO_SECURITY 0x03 /* flags for RAW_FILEINFO_SMB2_ALL_EAS */ -#define SMB2_GETINFO_EA_FLAG_RESTART 0x01 -#define SMB2_GETINFO_EA_FLAG_SINGLE 0x02 +#define SMB2_CONTINUE_FLAG_RESTART 0x01 +#define SMB2_CONTINUE_FLAG_SINGLE 0x02 /* NOTE! the getinfo fs and file levels exactly match up with the 'passthru' SMB levels, which are levels >= 1000. The SMB2 client @@ -278,3 +278,18 @@ struct smb2_read { DATA_BLOB data; } out; }; + +struct smb2_find { + struct { + uint8_t level; + uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */ + uint32_t unknown; /* perhaps a continue token? */ + struct smb2_handle handle; + uint32_t max_response_size; + const char *pattern; + } in; + + struct { + DATA_BLOB blob; + } out; +}; -- cgit From a6852523d677f6c39a92e0e2b5d970211b29558b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Nov 2005 17:34:56 +0000 Subject: r11812: Convert winbind to the async bind routines. Also remove tridge's hack for the winbind "bug" :-) Volker (This used to be commit fb9a3c7ef376f289288c71bc47d67f548ddb7194) --- source4/libcli/raw/clitransport.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 83b73f2e30..1cd0a3046e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -122,11 +122,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport); packet_set_fde(transport->packet, transport->socket->event.fde); -#if 0 - /* winbind relies on non-serialised connections for dcerpc bind. Once that is - fixed we can go back to serialised connections */ packet_set_serialise(transport->packet); -#endif talloc_set_destructor(transport, transport_destructor); return transport; -- cgit From e8f17538a71b67a435882989325eb66dae8bc426 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 22 Nov 2005 13:12:22 +0000 Subject: r11848: separate out the info levels common to SMB and SMB2 for raw_search (This used to be commit ed8d3073472fbb0850209f81dd04bd94f6d1c33d) --- source4/libcli/raw/rawrequest.c | 7 + source4/libcli/raw/rawsearch.c | 288 +++++++++++++++++++++++----------------- 2 files changed, 174 insertions(+), 121 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 6e02ddc5c1..cd76e0e438 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -849,6 +849,13 @@ size_t smbcli_blob_pull_string(struct smbcli_session *session, { int extra; dest->s = NULL; + + /* this is here to cope with SMB2 calls using the SMB + parsers. SMB2 will pass smbcli_session==NULL, which forces + unicode on (as used by SMB2) */ + if (session == NULL && !(flags & STR_ASCII)) { + flags |= STR_UNICODE; + } if (flags & STR_LEN8BIT) { if (len_offset > blob->length-1) { diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 65928d1154..e844a33358 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -310,6 +310,155 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, } +/* + parse the wire search formats that are in common between SMB and + SMB2 +*/ +NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, + enum smb_search_level level, + const DATA_BLOB *blob, + union smb_search_data *data, + uint_t *next_ofs, + uint_t str_flags) +{ + uint_t len, blen; + + if (blob->length < 4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + *next_ofs = IVAL(blob->data, 0); + if (*next_ofs != 0) { + blen = *next_ofs; + } else { + blen = blob->length; + } + + switch (level) { + case RAW_SEARCH_DIRECTORY_INFO: + if (blen < 65) return NT_STATUS_INFO_LENGTH_MISMATCH; + data->directory_info.file_index = IVAL(blob->data, 4); + data->directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->directory_info.change_time = smbcli_pull_nttime(blob->data, 32); + data->directory_info.size = BVAL(blob->data, 40); + data->directory_info.alloc_size = BVAL(blob->data, 48); + data->directory_info.attrib = IVAL(blob->data, 56); + len = smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->directory_info.name, + 60, 64, str_flags); + if (*next_ofs != 0 && *next_ofs < 64+len) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + return NT_STATUS_OK; + + case RAW_SEARCH_FULL_DIRECTORY_INFO: + if (blen < 69) return NT_STATUS_INFO_LENGTH_MISMATCH; + data->full_directory_info.file_index = IVAL(blob->data, 4); + data->full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); + data->full_directory_info.size = BVAL(blob->data, 40); + data->full_directory_info.alloc_size = BVAL(blob->data, 48); + data->full_directory_info.attrib = IVAL(blob->data, 56); + data->full_directory_info.ea_size = IVAL(blob->data, 64); + len = smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->full_directory_info.name, + 60, 68, str_flags); + if (*next_ofs != 0 && *next_ofs < 68+len) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + return NT_STATUS_OK; + + case RAW_SEARCH_NAME_INFO: + if (blen < 13) return NT_STATUS_INFO_LENGTH_MISMATCH; + data->name_info.file_index = IVAL(blob->data, 4); + len = smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->name_info.name, + 8, 12, str_flags); + if (*next_ofs != 0 && *next_ofs < 12+len) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + return NT_STATUS_OK; + + + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + if (blen < 95) return NT_STATUS_INFO_LENGTH_MISMATCH; + data->both_directory_info.file_index = IVAL(blob->data, 4); + data->both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); + data->both_directory_info.size = BVAL(blob->data, 40); + data->both_directory_info.alloc_size = BVAL(blob->data, 48); + data->both_directory_info.attrib = IVAL(blob->data, 56); + data->both_directory_info.ea_size = IVAL(blob->data, 64); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->both_directory_info.short_name, + 68, 70, STR_LEN8BIT | STR_UNICODE); + len = smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->both_directory_info.name, + 60, 94, str_flags); + if (*next_ofs != 0 && *next_ofs < 94+len) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + return NT_STATUS_OK; + + + case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: + if (blen < 81) return NT_STATUS_INFO_LENGTH_MISMATCH; + data->id_full_directory_info.file_index = IVAL(blob->data, 4); + data->id_full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->id_full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->id_full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->id_full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); + data->id_full_directory_info.size = BVAL(blob->data, 40); + data->id_full_directory_info.alloc_size = BVAL(blob->data, 48); + data->id_full_directory_info.attrib = IVAL(blob->data, 56); + data->id_full_directory_info.ea_size = IVAL(blob->data, 64); + data->id_full_directory_info.file_id = BVAL(blob->data, 72); + len = smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->id_full_directory_info.name, + 60, 80, str_flags); + if (*next_ofs != 0 && *next_ofs < 80+len) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + return NT_STATUS_OK; + + case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: + if (blen < 105) return NT_STATUS_INFO_LENGTH_MISMATCH; + data->id_both_directory_info.file_index = IVAL(blob->data, 4); + data->id_both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); + data->id_both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); + data->id_both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); + data->id_both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); + data->id_both_directory_info.size = BVAL(blob->data, 40); + data->id_both_directory_info.alloc_size = BVAL(blob->data, 48); + data->id_both_directory_info.attrib = SVAL(blob->data, 56); + data->id_both_directory_info.ea_size = IVAL(blob->data, 64); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->id_both_directory_info.short_name, + 68, 70, STR_LEN8BIT | STR_UNICODE); + data->id_both_directory_info.file_id = BVAL(blob->data, 96); + len = smbcli_blob_pull_string(NULL, mem_ctx, blob, + &data->id_both_directory_info.name, + 60, 104, str_flags); + if (*next_ofs != 0 && *next_ofs < 104+len) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + return NT_STATUS_OK; + + default: + break; + } + + /* invalid level */ + return NT_STATUS_INVALID_INFO_CLASS; +} + + /* parse a trans2 search response. Return the number of bytes consumed @@ -419,127 +568,6 @@ static int parse_trans2_search(struct smbcli_tree *tree, STR_LEN8BIT | STR_NOALIGN); return len + ea_size + 23 + 1; - case RAW_SEARCH_DIRECTORY_INFO: - if (blob->length < 65) return -1; - ofs = IVAL(blob->data, 0); - data->directory_info.file_index = IVAL(blob->data, 4); - data->directory_info.create_time = smbcli_pull_nttime(blob->data, 8); - data->directory_info.access_time = smbcli_pull_nttime(blob->data, 16); - data->directory_info.write_time = smbcli_pull_nttime(blob->data, 24); - data->directory_info.change_time = smbcli_pull_nttime(blob->data, 32); - data->directory_info.size = BVAL(blob->data, 40); - data->directory_info.alloc_size = BVAL(blob->data, 48); - data->directory_info.attrib = IVAL(blob->data, 56); - len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->directory_info.name, - 60, 64, 0); - if (ofs != 0 && ofs < 64+len) { - return -1; - } - return ofs; - - case RAW_SEARCH_FULL_DIRECTORY_INFO: - if (blob->length < 69) return -1; - ofs = IVAL(blob->data, 0); - data->full_directory_info.file_index = IVAL(blob->data, 4); - data->full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); - data->full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); - data->full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); - data->full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); - data->full_directory_info.size = BVAL(blob->data, 40); - data->full_directory_info.alloc_size = BVAL(blob->data, 48); - data->full_directory_info.attrib = IVAL(blob->data, 56); - data->full_directory_info.ea_size = IVAL(blob->data, 64); - len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->full_directory_info.name, - 60, 68, 0); - if (ofs != 0 && ofs < 68+len) { - return -1; - } - return ofs; - - case RAW_SEARCH_NAME_INFO: - if (blob->length < 13) return -1; - ofs = IVAL(blob->data, 0); - data->name_info.file_index = IVAL(blob->data, 4); - len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->name_info.name, - 8, 12, 0); - if (ofs != 0 && ofs < 12+len) { - return -1; - } - return ofs; - - - case RAW_SEARCH_BOTH_DIRECTORY_INFO: - if (blob->length < 95) return -1; - ofs = IVAL(blob->data, 0); - data->both_directory_info.file_index = IVAL(blob->data, 4); - data->both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); - data->both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); - data->both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); - data->both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); - data->both_directory_info.size = BVAL(blob->data, 40); - data->both_directory_info.alloc_size = BVAL(blob->data, 48); - data->both_directory_info.attrib = IVAL(blob->data, 56); - data->both_directory_info.ea_size = IVAL(blob->data, 64); - smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->both_directory_info.short_name, - 68, 70, STR_LEN8BIT | STR_UNICODE); - len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->both_directory_info.name, - 60, 94, 0); - if (ofs != 0 && ofs < 94+len) { - return -1; - } - return ofs; - - - case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: - if (blob->length < 81) return -1; - ofs = IVAL(blob->data, 0); - data->id_full_directory_info.file_index = IVAL(blob->data, 4); - data->id_full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); - data->id_full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); - data->id_full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); - data->id_full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); - data->id_full_directory_info.size = BVAL(blob->data, 40); - data->id_full_directory_info.alloc_size = BVAL(blob->data, 48); - data->id_full_directory_info.attrib = IVAL(blob->data, 56); - data->id_full_directory_info.ea_size = IVAL(blob->data, 64); - data->id_full_directory_info.file_id = BVAL(blob->data, 72); - len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->id_full_directory_info.name, - 60, 80, 0); - if (ofs != 0 && ofs < 80+len) { - return -1; - } - return ofs; - - case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: - if (blob->length < 105) return -1; - ofs = IVAL(blob->data, 0); - data->id_both_directory_info.file_index = IVAL(blob->data, 4); - data->id_both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); - data->id_both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); - data->id_both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); - data->id_both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); - data->id_both_directory_info.size = BVAL(blob->data, 40); - data->id_both_directory_info.alloc_size = BVAL(blob->data, 48); - data->id_both_directory_info.attrib = SVAL(blob->data, 56); - data->id_both_directory_info.ea_size = IVAL(blob->data, 64); - smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->id_both_directory_info.short_name, - 68, 70, STR_LEN8BIT | STR_UNICODE); - data->id_both_directory_info.file_id = BVAL(blob->data, 96); - len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, - &data->id_both_directory_info.name, - 60, 104, 0); - if (ofs != 0 && ofs < 104+len) { - return -1; - } - return ofs; - case RAW_SEARCH_UNIX_INFO: if (blob->length < 109) return -1; ofs = IVAL(blob->data, 0); @@ -565,7 +593,25 @@ static int parse_trans2_search(struct smbcli_tree *tree, } return ofs; + case RAW_SEARCH_DIRECTORY_INFO: + case RAW_SEARCH_FULL_DIRECTORY_INFO: + case RAW_SEARCH_NAME_INFO: + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: { + uint_t str_flags = STR_UNICODE; + if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) { + str_flags = STR_ASCII; + } + + status = smb_raw_search_common(mem_ctx, level, blob, data, &ofs, str_flags); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + return ofs; } + } + /* invalid level */ return -1; } -- cgit From f7c03b2abe387ada2d05ddf4f9cd0c35c2c47de0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 22 Nov 2005 13:13:17 +0000 Subject: r11849: added mapping between SMB2 and SMB find/search levels (This used to be commit 77e0cb999c776d2cfc806445d36135e5ba3a5f3d) --- source4/libcli/smb2/find.c | 91 +++++++++++++++++++++++++++++++++++++++- source4/libcli/smb2/smb2_calls.h | 10 +++++ 2 files changed, 100 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 91be5e4bb1..273c3cad6a 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -82,9 +82,98 @@ NTSTATUS smb2_find_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, sync find request */ NTSTATUS smb2_find(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, - struct smb2_find *io) + struct smb2_find *io) { struct smb2_request *req = smb2_find_send(tree, io); return smb2_find_recv(req, mem_ctx, io); } + +/* + a varient of smb2_find_recv that parses the resulting blob into + smb_search_data structures +*/ +NTSTATUS smb2_find_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + uint8_t level, uint_t *count, + union smb_search_data **io) +{ + struct smb2_find f; + NTSTATUS status; + DATA_BLOB b; + enum smb_search_level smb_level; + uint_t next_ofs=0; + + switch (level) { + case SMB2_FIND_DIRECTORY_INFO: + smb_level = RAW_SEARCH_DIRECTORY_INFO; + break; + case SMB2_FIND_FULL_DIRECTORY_INFO: + smb_level = RAW_SEARCH_FULL_DIRECTORY_INFO; + break; + case SMB2_FIND_BOTH_DIRECTORY_INFO: + smb_level = RAW_SEARCH_BOTH_DIRECTORY_INFO; + break; + case SMB2_FIND_NAME_INFO: + smb_level = RAW_SEARCH_NAME_INFO; + break; + case SMB2_FIND_ID_FULL_DIRECTORY_INFO: + smb_level = RAW_SEARCH_ID_FULL_DIRECTORY_INFO; + break; + case SMB2_FIND_ID_BOTH_DIRECTORY_INFO: + smb_level = RAW_SEARCH_ID_BOTH_DIRECTORY_INFO; + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + status = smb2_find_recv(req, mem_ctx, &f); + NT_STATUS_NOT_OK_RETURN(status); + + b = f.out.blob; + *io = NULL; + *count = 0; + + do { + union smb_search_data *io2; + + io2 = talloc_realloc(mem_ctx, *io, union smb_search_data, (*count)+1); + if (io2 == NULL) { + data_blob_free(&f.out.blob); + talloc_free(*io); + return NT_STATUS_NO_MEMORY; + } + *io = io2; + + status = smb_raw_search_common(*io, smb_level, &b, (*io) + (*count), + &next_ofs, STR_UNICODE); + + if (NT_STATUS_IS_OK(status) && + next_ofs >= b.length) { + data_blob_free(&f.out.blob); + talloc_free(*io); + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + (*count)++; + + b = data_blob_const(b.data+next_ofs, b.length - next_ofs); + } while (NT_STATUS_IS_OK(status) && next_ofs != 0); + + data_blob_free(&f.out.blob); + + return NT_STATUS_OK; +} + +/* + a varient of smb2_find that parses the resulting blob into + smb_search_data structures +*/ +NTSTATUS smb2_find_level(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + struct smb2_find *f, + uint_t *count, union smb_search_data **io) +{ + struct smb2_request *req; + + req = smb2_find_send(tree, f); + return smb2_find_level_recv(req, mem_ctx, f->in.level, count, io); +} diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 10d6cda7a3..6d99000a42 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -279,6 +279,16 @@ struct smb2_read { } out; }; +/* + SMB2 uses different level numbers for the same old SMB search levels +*/ +#define SMB2_FIND_DIRECTORY_INFO 0x01 +#define SMB2_FIND_FULL_DIRECTORY_INFO 0x02 +#define SMB2_FIND_BOTH_DIRECTORY_INFO 0x03 +#define SMB2_FIND_NAME_INFO 0x0C +#define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25 +#define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26 + struct smb2_find { struct { uint8_t level; -- cgit From 8383a3459aa91a6edbdd996b19a685bf0cbd6627 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Nov 2005 18:49:30 +0000 Subject: r11885: Add forgotten files (This used to be commit 470cc5952981c3625c7e35f44c9fd41d19593396) --- source4/libcli/composite/composite.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index c78d039905..ba9b0673da 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -147,3 +147,12 @@ void composite_continue_irpc(struct composite_context *ctx, new_req->async.private = private_data; } +void composite_continue_smb(struct composite_context *ctx, + struct smbcli_request *new_req, + void (*continuation)(struct smbcli_request *), + void *private_data) +{ + if (composite_nomem(new_req, ctx)) return; + new_req->async.fn = continuation; + new_req->async.private = private_data; +} -- cgit From 310fa875091a85bb5d7be196906723f14305d406 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 05:23:55 +0000 Subject: r11888: - added SMB2 trans support - added session key to SMB2 - renamed 'unknown2' in create to 'impersonation' (This used to be commit aef915f312a78bf8a4123f7c40fcd14ff293d934) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/create.c | 2 +- source4/libcli/smb2/session.c | 7 +++ source4/libcli/smb2/smb2.h | 2 + source4/libcli/smb2/smb2_calls.h | 23 ++++++++- source4/libcli/smb2/trans.c | 108 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 source4/libcli/smb2/trans.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index c0974dbfa5..1a41c5c8ed 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -12,5 +12,6 @@ OBJ_FILES = \ write.o \ read.o \ setinfo.o \ - find.o + find.o \ + trans.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 564eba7f46..c7bb190559 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -71,7 +71,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.oplock_flags); - SIVAL(req->out.body, 0x04, io->in.unknown2); + SIVAL(req->out.body, 0x04, io->in.impersonation); SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); SIVAL(req->out.body, 0x10, io->in.unknown3[2]); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 0a13a288fc..c62b24797d 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -149,10 +149,17 @@ static void session_request_handler(struct smb2_request *req) if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) || (NT_STATUS_IS_OK(c->status) && NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { + NTSTATUS session_key_err; + DATA_BLOB session_key; c->status = gensec_update(session->gensec, c, state->io.out.secblob, &state->io.in.secblob); state->gensec_status = c->status; + + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { + session->session_key = session_key; + } } session->uid = state->io.out.uid; diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 0ff8b87143..7b6824f4d9 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -66,6 +66,7 @@ struct smb2_session { struct smb2_transport *transport; struct gensec_security *gensec; uint64_t uid; + DATA_BLOB session_key; }; @@ -164,6 +165,7 @@ struct smb2_request { #define SMB2_OP_CLOSE 0x06 #define SMB2_OP_READ 0x08 #define SMB2_OP_WRITE 0x09 +#define SMB2_OP_TRANS 0x0b #define SMB2_OP_CANCEL 0x0c #define SMB2_OP_FIND 0x0e #define SMB2_OP_NOTIFY 0x0f diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 6d99000a42..07f74ca229 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -113,7 +113,7 @@ struct smb2_create { /* static body buffer 56 (0x38) bytes */ /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ - uint32_t unknown2; + uint32_t impersonation; uint32_t unknown3[4]; uint32_t access_mask; @@ -303,3 +303,24 @@ struct smb2_find { DATA_BLOB blob; } out; }; + +struct smb2_trans { + struct { + uint32_t unknown1; + struct smb2_handle handle; + uint32_t unknown2; + uint32_t max_response_size; + uint64_t flags; + DATA_BLOB in; + DATA_BLOB out; + } in; + + struct { + uint32_t unknown1; + struct smb2_handle handle; + uint32_t unknown2; + uint32_t unknown3; + DATA_BLOB in; + DATA_BLOB out; + } out; +}; diff --git a/source4/libcli/smb2/trans.c b/source4/libcli/smb2/trans.c new file mode 100644 index 0000000000..fd80315e3f --- /dev/null +++ b/source4/libcli/smb2/trans.c @@ -0,0 +1,108 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client trans call + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a trans request +*/ +struct smb2_request *smb2_trans_send(struct smb2_tree *tree, struct smb2_trans *io) +{ + NTSTATUS status; + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_TRANS, 0x38, + io->in.in.length+io->in.out.length); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, 0); /* pad */ + SIVAL(req->out.body, 0x04, io->in.unknown1); + smb2_push_handle(req->out.body+0x08, &io->in.handle); + SIVAL(req->out.body, 0x20, io->in.unknown2); + SIVAL(req->out.body, 0x2C, io->in.max_response_size); + SBVAL(req->out.body, 0x30, io->in.flags); + + status = smb2_push_o32s32_blob(&req->out, 0x18, io->in.out); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + + status = smb2_push_o32s32_blob(&req->out, 0x24, io->in.in); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + + smb2_transport_send(req); + + return req; +} + + +/* + recv a trans reply +*/ +NTSTATUS smb2_trans_recv(struct smb2_request *req, + TALLOC_CTX *mem_ctx, struct smb2_trans *io) +{ + NTSTATUS status; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x30, True); + + io->out.unknown1 = IVAL(req->in.body, 0x04); + smb2_pull_handle(req->in.body+0x08, &io->out.handle); + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x18, &io->out.in); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x20, &io->out.out); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + + + io->out.unknown2 = IVAL(req->in.body, 0x28); + io->out.unknown3 = IVAL(req->in.body, 0x2C); + + return smb2_request_destroy(req); +} + +/* + sync trans request +*/ +NTSTATUS smb2_trans(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_trans *io) +{ + struct smb2_request *req = smb2_trans_send(tree, io); + return smb2_trans_recv(req, mem_ctx, io); +} -- cgit From 2f74901802dc1ef40467e62f1880d958e6c69eef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 05:46:46 +0000 Subject: r11891: - added pipe_flags field in smb2_trans - while running dcerpc over SMB2, the server will occasionally send us a oh-so-useful STATUS_PENDING result meaning "I don't have a result for you yet, but I'm working on it". These can be discarded :-) (This used to be commit 24588a9c499536299d7aaf5b56ff73fb255290ca) --- source4/libcli/smb2/smb2_calls.h | 4 +++- source4/libcli/smb2/transport.c | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 07f74ca229..e0a78937d5 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -304,9 +304,11 @@ struct smb2_find { } out; }; +#define SMB2_TRANS_PIPE_FLAGS 0x0011c017 /* what are these? */ + struct smb2_trans { struct { - uint32_t unknown1; + uint32_t pipe_flags; struct smb2_handle handle; uint32_t unknown2; uint32_t max_response_size; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 04767fa634..02ac587636 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -185,6 +185,13 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); + if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { + /* the server has helpfully told us that this request is still being + processed. how useful :) */ + talloc_free(buffer); + return NT_STATUS_OK; + } + buffer_code = SVAL(req->in.body, 0); req->in.dynamic = NULL; dynamic_size = req->in.body_size - (buffer_code & ~1); -- cgit From cc6891f88393c225b08767c693b722a8a403d3c4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 06:48:12 +0000 Subject: r11893: fixed a dependency problem (This used to be commit 085bf952dc1b8861ac6fecf25c508594f9ddf454) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 8417d770b6..47b07a353b 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -86,7 +86,7 @@ MINOR_VERSION = 0 RELEASE_VERSION = 1 REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM + LIBCLI_DGRAM LIBCLI_SMB2 [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI SOCKET -- cgit From b227b98a6c87b18db2bc949241ead6bbc46baff4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 06:50:29 +0000 Subject: r11894: fixed SMB2 trans code for pipe_flags (This used to be commit 02e3cb87c7673788e3861f33356a18b8d38d2d66) --- source4/libcli/smb2/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/trans.c b/source4/libcli/smb2/trans.c index fd80315e3f..cc03209c76 100644 --- a/source4/libcli/smb2/trans.c +++ b/source4/libcli/smb2/trans.c @@ -38,7 +38,7 @@ struct smb2_request *smb2_trans_send(struct smb2_tree *tree, struct smb2_trans * if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); /* pad */ - SIVAL(req->out.body, 0x04, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.pipe_flags); smb2_push_handle(req->out.body+0x08, &io->in.handle); SIVAL(req->out.body, 0x20, io->in.unknown2); SIVAL(req->out.body, 0x2C, io->in.max_response_size); -- cgit From d90914dda878a21372a9e6c4025a61f903c12313 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Nov 2005 08:24:36 +0000 Subject: r11895: - reorder some code to make it easier to follow, how the fields appear on the wire - add some comments to the header file, to represent the wire format metze (This used to be commit fa98f09f8b8829e66aa37cd947ab4f0cbb7b5476) --- source4/libcli/smb2/find.c | 3 ++- source4/libcli/smb2/setinfo.c | 9 ++++++++- source4/libcli/smb2/smb2_calls.h | 34 ++++++++++++++++++++++++++++++++-- source4/libcli/smb2/trans.c | 15 +++++++++------ 4 files changed, 51 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 273c3cad6a..aa14347022 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -40,7 +40,6 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io SCVAL(req->out.body, 0x03, io->in.continue_flags); SIVAL(req->out.body, 0x04, io->in.unknown); smb2_push_handle(req->out.body+0x08, &io->in.handle); - SIVAL(req->out.body, 0x1C, io->in.max_response_size); status = smb2_push_o16s16_string(&req->out, 0x18, io->in.pattern); if (!NT_STATUS_IS_OK(status)) { @@ -48,6 +47,8 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io return NULL; } + SIVAL(req->out.body, 0x1C, io->in.max_response_size); + smb2_transport_send(req); return req; diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index d6c5555a33..ce03a69482 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -30,13 +30,20 @@ */ struct smb2_request *smb2_setinfo_send(struct smb2_tree *tree, struct smb2_setinfo *io) { + NTSTATUS status; struct smb2_request *req; req = smb2_request_init_tree(tree, SMB2_OP_SETINFO, 0x20, io->in.blob.length); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.level); - smb2_push_s32o32_blob(&req->out, 0x04, io->in.blob); + + status = smb2_push_s32o32_blob(&req->out, 0x04, io->in.blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + SIVAL(req->out.body, 0x0C, io->in.flags); smb2_push_handle(req->out.body+0x10, &io->in.handle); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index e0a78937d5..cd0e80f5ae 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -291,15 +291,27 @@ struct smb2_read { struct smb2_find { struct { + /* static body buffer 32 (0x20) bytes */ + /* uint16_t buffer_code; 0x21 = 0x20 + 1 */ uint8_t level; uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */ uint32_t unknown; /* perhaps a continue token? */ struct smb2_handle handle; + /* uint16_t pattern_ofs; */ + /* uint32_t pattern_size; */ uint32_t max_response_size; + + /* dynamic body */ const char *pattern; } in; struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x08 */ + /* uint16_t blob_ofs; */ + /* uint32_t blob_size; */ + + /* dynamic body */ DATA_BLOB blob; } out; }; @@ -308,20 +320,38 @@ struct smb2_find { struct smb2_trans { struct { + /* static body buffer 56 (0x38) bytes */ + /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ + uint16_t _pad; uint32_t pipe_flags; struct smb2_handle handle; + /* uint32_t out_ofs; */ + /* uint32_t out_size; */ uint32_t unknown2; + /* uint32_t in_ofs; */ + /* uint32_t in_size; */ uint32_t max_response_size; uint64_t flags; - DATA_BLOB in; + + /* dynamic body */ DATA_BLOB out; + DATA_BLOB in; } in; struct { - uint32_t unknown1; + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ + uint16_t _pad; + uint32_t pipe_flags; struct smb2_handle handle; + /* uint32_t in_ofs; */ + /* uint32_t in_size; */ + /* uint32_t out_ofs; */ + /* uint32_t out_size; */ uint32_t unknown2; uint32_t unknown3; + + /* dynamic body */ DATA_BLOB in; DATA_BLOB out; } out; diff --git a/source4/libcli/smb2/trans.c b/source4/libcli/smb2/trans.c index cc03209c76..de4ff1d827 100644 --- a/source4/libcli/smb2/trans.c +++ b/source4/libcli/smb2/trans.c @@ -37,12 +37,9 @@ struct smb2_request *smb2_trans_send(struct smb2_tree *tree, struct smb2_trans * io->in.in.length+io->in.out.length); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, 0); /* pad */ + SSVAL(req->out.body, 0x02, io->in._pad); SIVAL(req->out.body, 0x04, io->in.pipe_flags); smb2_push_handle(req->out.body+0x08, &io->in.handle); - SIVAL(req->out.body, 0x20, io->in.unknown2); - SIVAL(req->out.body, 0x2C, io->in.max_response_size); - SBVAL(req->out.body, 0x30, io->in.flags); status = smb2_push_o32s32_blob(&req->out, 0x18, io->in.out); if (!NT_STATUS_IS_OK(status)) { @@ -50,12 +47,17 @@ struct smb2_request *smb2_trans_send(struct smb2_tree *tree, struct smb2_trans * return NULL; } + SIVAL(req->out.body, 0x20, io->in.unknown2); + status = smb2_push_o32s32_blob(&req->out, 0x24, io->in.in); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } + SIVAL(req->out.body, 0x2C, io->in.max_response_size); + SBVAL(req->out.body, 0x30, io->in.flags); + smb2_transport_send(req); return req; @@ -77,8 +79,10 @@ NTSTATUS smb2_trans_recv(struct smb2_request *req, SMB2_CHECK_PACKET_RECV(req, 0x30, True); - io->out.unknown1 = IVAL(req->in.body, 0x04); + io->out._pad = SVAL(req->in.body, 0x02); + io->out.pipe_flags = IVAL(req->in.body, 0x04); smb2_pull_handle(req->in.body+0x08, &io->out.handle); + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x18, &io->out.in); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); @@ -91,7 +95,6 @@ NTSTATUS smb2_trans_recv(struct smb2_request *req, return status; } - io->out.unknown2 = IVAL(req->in.body, 0x28); io->out.unknown3 = IVAL(req->in.body, 0x2C); -- cgit From a399cd3cea5efb644785ca63052ff18b765d5888 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 11:04:42 +0000 Subject: r11901: added smb2_logoff() support (metze correctly guessed opcode 2 was logoff) (This used to be commit 6884ce66f2881eba834b419370f74111852fe022) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/logoff.c | 67 +++++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/logoff.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 1a41c5c8ed..8380026204 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -13,5 +13,6 @@ OBJ_FILES = \ read.o \ setinfo.o \ find.o \ - trans.o + trans.o \ + logoff.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c new file mode 100644 index 0000000000..a73c7ee92e --- /dev/null +++ b/source4/libcli/smb2/logoff.c @@ -0,0 +1,67 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client logoff handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a logoff request +*/ +struct smb2_request *smb2_logoff_send(struct smb2_tree *tree) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_LOGOFF, 0x04, 0); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, 0); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a logoff reply +*/ +NTSTATUS smb2_logoff_recv(struct smb2_request *req) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x04, False); + return smb2_request_destroy(req); +} + +/* + sync logoff request +*/ +NTSTATUS smb2_logoff(struct smb2_tree *tree) +{ + struct smb2_request *req = smb2_logoff_send(tree); + return smb2_logoff_recv(req); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 7b6824f4d9..3f17f994df 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -159,6 +159,7 @@ struct smb2_request { /* SMB2 opcodes */ #define SMB2_OP_NEGPROT 0x00 #define SMB2_OP_SESSSETUP 0x01 +#define SMB2_OP_LOGOFF 0x02 #define SMB2_OP_TCON 0x03 #define SMB2_OP_TDIS 0x04 #define SMB2_OP_CREATE 0x05 -- cgit From 6724c0185cb81b16fc081691711aafdf06a8253d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 11:11:47 +0000 Subject: r11903: added smb2_tdis() (opcode 4) (This used to be commit d606b45b5b6065b5d06024bcce00a23084a20eac) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/tdis.c | 67 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/tdis.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 8380026204..ae203b952d 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -14,5 +14,6 @@ OBJ_FILES = \ setinfo.o \ find.o \ trans.o \ - logoff.o + logoff.o \ + tdis.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c new file mode 100644 index 0000000000..c08370d9e0 --- /dev/null +++ b/source4/libcli/smb2/tdis.c @@ -0,0 +1,67 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client tdis handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a tdis request +*/ +struct smb2_request *smb2_tdis_send(struct smb2_tree *tree) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_TDIS, 0x04, 0); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, 0); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a tdis reply +*/ +NTSTATUS smb2_tdis_recv(struct smb2_request *req) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x04, False); + return smb2_request_destroy(req); +} + +/* + sync tdis request +*/ +NTSTATUS smb2_tdis(struct smb2_tree *tree) +{ + struct smb2_request *req = smb2_tdis_send(tree); + return smb2_tdis_recv(req); +} -- cgit From 1e3583475fbe6be46383866f3e061637f2f20c2a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 11:33:57 +0000 Subject: r11905: added SMB2_FLUSH as opcode 7. Thanks to metze and volker for help brainstorming this one. (This used to be commit a969ad592ae4cd8f7c66b1df4763fdc70328c967) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/flush.c | 70 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 1 + source4/libcli/smb2/smb2_calls.h | 7 ++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/flush.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index ae203b952d..2af75cdcd9 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -15,5 +15,6 @@ OBJ_FILES = \ find.o \ trans.o \ logoff.o \ - tdis.o + tdis.o \ + flush.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c new file mode 100644 index 0000000000..f5d623c69c --- /dev/null +++ b/source4/libcli/smb2/flush.c @@ -0,0 +1,70 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client flush handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a flush request +*/ +struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, 0); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, 0); /* pad? */ + SIVAL(req->out.body, 0x04, io->in.unknown); + smb2_push_handle(req->out.body+0x08, &io->in.handle); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a flush reply +*/ +NTSTATUS smb2_flush_recv(struct smb2_request *req, struct smb2_flush *io) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x04, False); + + return smb2_request_destroy(req); +} + +/* + sync flush request +*/ +NTSTATUS smb2_flush(struct smb2_tree *tree, struct smb2_flush *io) +{ + struct smb2_request *req = smb2_flush_send(tree, io); + return smb2_flush_recv(req, io); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 3f17f994df..6083fcb26e 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -164,6 +164,7 @@ struct smb2_request { #define SMB2_OP_TDIS 0x04 #define SMB2_OP_CREATE 0x05 #define SMB2_OP_CLOSE 0x06 +#define SMB2_OP_FLUSH 0x07 #define SMB2_OP_READ 0x08 #define SMB2_OP_WRITE 0x09 #define SMB2_OP_TRANS 0x0b diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index cd0e80f5ae..03f65d947e 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -356,3 +356,10 @@ struct smb2_trans { DATA_BLOB out; } out; }; + +struct smb2_flush { + struct { + uint32_t unknown; + struct smb2_handle handle; + } in; +}; -- cgit From 1e935fcbde889a0f3735d4698e61bde6b93eaa39 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 11:51:15 +0000 Subject: r11906: opcode 13 appears to be keepalive. Metze guessed this one :-) (This used to be commit afe2323dc10748b97e6b30dc0c783dbe04446d8c) --- source4/libcli/smb2/config.mk | 3 +- source4/libcli/smb2/keepalive.c | 67 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/keepalive.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 2af75cdcd9..fdb28cfa78 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -16,5 +16,6 @@ OBJ_FILES = \ trans.o \ logoff.o \ tdis.o \ - flush.o + flush.o \ + keepalive.o REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c new file mode 100644 index 0000000000..64ed847757 --- /dev/null +++ b/source4/libcli/smb2/keepalive.c @@ -0,0 +1,67 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client keepalive handling + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a keepalive request +*/ +struct smb2_request *smb2_keepalive_send(struct smb2_tree *tree) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_KEEPALIVE, 0x04, 0); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, 0); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a keepalive reply +*/ +NTSTATUS smb2_keepalive_recv(struct smb2_request *req) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x04, False); + return smb2_request_destroy(req); +} + +/* + sync keepalive request +*/ +NTSTATUS smb2_keepalive(struct smb2_tree *tree) +{ + struct smb2_request *req = smb2_keepalive_send(tree); + return smb2_keepalive_recv(req); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 6083fcb26e..d12725f70f 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -169,6 +169,7 @@ struct smb2_request { #define SMB2_OP_WRITE 0x09 #define SMB2_OP_TRANS 0x0b #define SMB2_OP_CANCEL 0x0c +#define SMB2_OP_KEEPALIVE 0x0d #define SMB2_OP_FIND 0x0e #define SMB2_OP_NOTIFY 0x0f #define SMB2_OP_GETINFO 0x10 -- cgit From e052c3d66b3bce9c1315ae1f54e84a404a79bf66 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Nov 2005 13:15:57 +0000 Subject: r11941: fix cut'n'paste bug metze (This used to be commit fd77cfa49016d403c3f4c60c2422d41498438c17) --- source4/libcli/nbt/nbtsocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 905541e74a..1c41b80fdb 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -506,7 +506,7 @@ NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode) { NBT_RCODE_IMP, NT_STATUS_NOT_SUPPORTED }, { NBT_RCODE_RFS, NT_STATUS_ACCESS_DENIED }, { NBT_RCODE_ACT, NT_STATUS_ADDRESS_ALREADY_EXISTS }, - { NBT_RCODE_ACT, NT_STATUS_CONFLICTING_ADDRESSES } + { NBT_RCODE_CFT, NT_STATUS_CONFLICTING_ADDRESSES } }; for (i=0;i Date: Mon, 28 Nov 2005 22:53:42 +0000 Subject: r11949: make sure we ask gensec to give us a session key andrew, this answers your question on irc about whether the same session key mechanisms are used in smb2. They are - the RPC-LSA secret tests pass fine over ncacn_np on SMB2, which means the session key must be working (This used to be commit 91327885a2b6432ba20a8dd1370b632240d3263d) --- source4/libcli/smb2/session.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index c62b24797d..12285d5536 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -54,6 +54,8 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, return NULL; } + gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); + return session; } -- cgit From 03d301ead5f702872b8cb948b8cd01b0fa0db5f7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Nov 2005 02:08:15 +0000 Subject: r11967: Fix more 64-bit warnings. (This used to be commit 9c4436a124f874ae240feaf590141d48c33a635f) --- source4/libcli/smb2/transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 02ac587636..60dd5d2ba6 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -170,7 +170,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) if (!req) { DEBUG(1,("Discarding unmatched reply with seqnum 0x%llx op %d\n", - seqnum, SVAL(hdr, SMB2_HDR_OPCODE))); + (long long)seqnum, SVAL(hdr, SMB2_HDR_OPCODE))); goto error; } @@ -204,7 +204,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) } } - DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", req->seqnum)); + DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum)); dump_data(5, req->in.body, req->in.body_size); /* if this request has an async handler then call that to @@ -273,7 +273,7 @@ void smb2_transport_send(struct smb2_request *req) _smb_setlen2(req->out.buffer, req->out.size - NBT_HDR_SIZE); - DEBUG(2, ("SMB2 send seqnum=0x%llx\n", req->seqnum)); + DEBUG(2, ("SMB2 send seqnum=0x%llx\n", (long long)req->seqnum)); dump_data(5, req->out.body, req->out.body_size); /* check if the transport is dead */ -- cgit From 9d3b3e83953a8a97cf830581bd7933a576312cad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Nov 2005 12:39:32 +0000 Subject: r11971: add nbt specific continue wrapper metze (This used to be commit b8c5978df18b98db89069e02597d483f893e39ae) --- source4/libcli/composite/composite.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index ba9b0673da..c4b771509f 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -26,6 +26,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "lib/messaging/irpc.h" +#include "libcli/nbt/libnbt.h" /* block until a composite function has completed, then return the status @@ -156,3 +157,13 @@ void composite_continue_smb(struct composite_context *ctx, new_req->async.fn = continuation; new_req->async.private = private_data; } + +void composite_continue_nbt(struct composite_context *ctx, + struct nbt_name_request *new_req, + void (*continuation)(struct nbt_name_request *), + void *private_data) +{ + if (composite_nomem(new_req, ctx)) return; + new_req->async.fn = continuation; + new_req->async.private = private_data; +} -- cgit From 6615907b94eb2395ddf907e92a543ff0525b9d02 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 1 Dec 2005 00:18:29 +0000 Subject: r11980: ronnie worked out that opcode 0xb in SMB2 is in fact ioctl, and that it only appeared to be like a SMBtrans request as it was being called with function 0x11c017 which is "named pipe read write" I wonder if this means we could do DCE/RPC over SMB using ntioctl calls as well? (This used to be commit f2b8857797328be64b0b85e875ae6d108e2aeaaa) --- source4/libcli/smb2/config.mk | 2 +- source4/libcli/smb2/ioctl.c | 111 +++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 3 +- source4/libcli/smb2/smb2_calls.h | 8 ++- source4/libcli/smb2/trans.c | 111 --------------------------------------- 5 files changed, 117 insertions(+), 118 deletions(-) create mode 100644 source4/libcli/smb2/ioctl.c delete mode 100644 source4/libcli/smb2/trans.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index fdb28cfa78..a5b7ce2f38 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -13,7 +13,7 @@ OBJ_FILES = \ read.o \ setinfo.o \ find.o \ - trans.o \ + ioctl.o \ logoff.o \ tdis.o \ flush.o \ diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c new file mode 100644 index 0000000000..26f2bffbc1 --- /dev/null +++ b/source4/libcli/smb2/ioctl.c @@ -0,0 +1,111 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client ioctl call + + Copyright (C) Andrew Tridgell 2005 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a ioctl request +*/ +struct smb2_request *smb2_ioctl_send(struct smb2_tree *tree, struct smb2_ioctl *io) +{ + NTSTATUS status; + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_IOCTL, 0x38, + io->in.in.length+io->in.out.length); + if (req == NULL) return NULL; + + SSVAL(req->out.body, 0x02, io->in._pad); + SIVAL(req->out.body, 0x04, io->in.function); + smb2_push_handle(req->out.body+0x08, &io->in.handle); + + status = smb2_push_o32s32_blob(&req->out, 0x18, io->in.out); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + + SIVAL(req->out.body, 0x20, io->in.unknown2); + + status = smb2_push_o32s32_blob(&req->out, 0x24, io->in.in); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + + SIVAL(req->out.body, 0x2C, io->in.max_response_size); + SBVAL(req->out.body, 0x30, io->in.flags); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a ioctl reply +*/ +NTSTATUS smb2_ioctl_recv(struct smb2_request *req, + TALLOC_CTX *mem_ctx, struct smb2_ioctl *io) +{ + NTSTATUS status; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x30, True); + + io->out._pad = SVAL(req->in.body, 0x02); + io->out.function = IVAL(req->in.body, 0x04); + smb2_pull_handle(req->in.body+0x08, &io->out.handle); + + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x18, &io->out.in); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x20, &io->out.out); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + + io->out.unknown2 = IVAL(req->in.body, 0x28); + io->out.unknown3 = IVAL(req->in.body, 0x2C); + + return smb2_request_destroy(req); +} + +/* + sync ioctl request +*/ +NTSTATUS smb2_ioctl(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_ioctl *io) +{ + struct smb2_request *req = smb2_ioctl_send(tree, io); + return smb2_ioctl_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index d12725f70f..ceafacf9d4 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -167,7 +167,8 @@ struct smb2_request { #define SMB2_OP_FLUSH 0x07 #define SMB2_OP_READ 0x08 #define SMB2_OP_WRITE 0x09 -#define SMB2_OP_TRANS 0x0b +#define SMB2_OP_LOCK 0x0a +#define SMB2_OP_IOCTL 0x0b #define SMB2_OP_CANCEL 0x0c #define SMB2_OP_KEEPALIVE 0x0d #define SMB2_OP_FIND 0x0e diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 03f65d947e..08e765ad60 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -316,14 +316,12 @@ struct smb2_find { } out; }; -#define SMB2_TRANS_PIPE_FLAGS 0x0011c017 /* what are these? */ - -struct smb2_trans { +struct smb2_ioctl { struct { /* static body buffer 56 (0x38) bytes */ /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ uint16_t _pad; - uint32_t pipe_flags; + uint32_t function; struct smb2_handle handle; /* uint32_t out_ofs; */ /* uint32_t out_size; */ @@ -342,7 +340,7 @@ struct smb2_trans { /* static body buffer 48 (0x30) bytes */ /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ uint16_t _pad; - uint32_t pipe_flags; + uint32_t function; struct smb2_handle handle; /* uint32_t in_ofs; */ /* uint32_t in_size; */ diff --git a/source4/libcli/smb2/trans.c b/source4/libcli/smb2/trans.c deleted file mode 100644 index de4ff1d827..0000000000 --- a/source4/libcli/smb2/trans.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - SMB2 client trans call - - Copyright (C) Andrew Tridgell 2005 - - 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 "libcli/raw/libcliraw.h" -#include "libcli/smb2/smb2.h" -#include "libcli/smb2/smb2_calls.h" - -/* - send a trans request -*/ -struct smb2_request *smb2_trans_send(struct smb2_tree *tree, struct smb2_trans *io) -{ - NTSTATUS status; - struct smb2_request *req; - - req = smb2_request_init_tree(tree, SMB2_OP_TRANS, 0x38, - io->in.in.length+io->in.out.length); - if (req == NULL) return NULL; - - SSVAL(req->out.body, 0x02, io->in._pad); - SIVAL(req->out.body, 0x04, io->in.pipe_flags); - smb2_push_handle(req->out.body+0x08, &io->in.handle); - - status = smb2_push_o32s32_blob(&req->out, 0x18, io->in.out); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; - } - - SIVAL(req->out.body, 0x20, io->in.unknown2); - - status = smb2_push_o32s32_blob(&req->out, 0x24, io->in.in); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; - } - - SIVAL(req->out.body, 0x2C, io->in.max_response_size); - SBVAL(req->out.body, 0x30, io->in.flags); - - smb2_transport_send(req); - - return req; -} - - -/* - recv a trans reply -*/ -NTSTATUS smb2_trans_recv(struct smb2_request *req, - TALLOC_CTX *mem_ctx, struct smb2_trans *io) -{ - NTSTATUS status; - - if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { - return smb2_request_destroy(req); - } - - SMB2_CHECK_PACKET_RECV(req, 0x30, True); - - io->out._pad = SVAL(req->in.body, 0x02); - io->out.pipe_flags = IVAL(req->in.body, 0x04); - smb2_pull_handle(req->in.body+0x08, &io->out.handle); - - status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x18, &io->out.in); - if (!NT_STATUS_IS_OK(status)) { - smb2_request_destroy(req); - return status; - } - - status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x20, &io->out.out); - if (!NT_STATUS_IS_OK(status)) { - smb2_request_destroy(req); - return status; - } - - io->out.unknown2 = IVAL(req->in.body, 0x28); - io->out.unknown3 = IVAL(req->in.body, 0x2C); - - return smb2_request_destroy(req); -} - -/* - sync trans request -*/ -NTSTATUS smb2_trans(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_trans *io) -{ - struct smb2_request *req = smb2_trans_send(tree, io); - return smb2_trans_recv(req, mem_ctx, io); -} -- cgit From f5d4623ea5a755a9525b9ef4532420ee53729a3d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 1 Dec 2005 00:22:08 +0000 Subject: r11982: ensure the fde event gets freed before the socket itself, as otherwise we get a error from epoll about disabling events for a file descriptor that is closed (This used to be commit f32739307464a1f0c835cff886b8c4b960778900) --- source4/libcli/raw/clisocket.c | 8 ++++---- source4/libcli/raw/clitransport.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index be25b36007..40d9d2784a 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -179,10 +179,10 @@ NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx, ****************************************************************************/ void smbcli_sock_dead(struct smbcli_socket *sock) { - if (sock->sock != NULL) { - talloc_free(sock->sock); - sock->sock = NULL; - } + talloc_free(sock->event.fde); + sock->event.fde = NULL; + talloc_free(sock->sock); + sock->sock = NULL; } /**************************************************************************** diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 1cd0a3046e..a0efe7042c 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -115,7 +115,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, handles events up until we are connected */ talloc_free(transport->socket->event.fde); transport->socket->event.fde = event_add_fd(transport->socket->event.ctx, - transport->socket, + transport->socket->sock, socket_get_fd(transport->socket->sock), EVENT_FD_READ, smbcli_transport_event_handler, -- cgit From 28918cd0b0a091407f6e5be8396b363ffab87966 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 1 Dec 2005 07:09:24 +0000 Subject: r11996: don't overwrite the buffercode metze (This used to be commit fee5b6f40784e75a469320a584423c5030b69400) --- source4/libcli/smb2/tcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 886ed9828b..ddc4babeea 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -60,7 +60,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); - SIVAL(req->out.body, 0x00, io->in.unknown1); + SSVAL(req->out.body, 0x02, io->in.unknown1); status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); -- cgit From 8dfec3305cc1babeb5d822dc806c0f5dede7da46 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Dec 2005 03:16:42 +0000 Subject: r12005: added a SDDL (Security Descriptor Description Language) parser. Not all flags are covered yet, and object aces aren't done yet. This is needed for ACL support in ldb, as the default security descriptor for each object class is given by the defaultSecurityDescriptor attribute in the schema, which is stored in SDDL format (This used to be commit dbdeecea01a8b362a9a525a3689cb03662a86776) --- source4/libcli/security/config.mk | 1 + source4/libcli/security/sddl.c | 315 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 316 insertions(+) create mode 100644 source4/libcli/security/sddl.c (limited to 'source4/libcli') diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index d7492038d3..7faecaf5f2 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -22,6 +22,7 @@ ADD_OBJ_FILES = security_token.o \ dom_sid.o \ access_check.o \ privilege.o \ + sddl.o \ ../../librpc/ndr/ndr_sec.o REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR # End SUBSYSTEM LIB_SECURITY diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c new file mode 100644 index 0000000000..17df393de4 --- /dev/null +++ b/source4/libcli/security/sddl.c @@ -0,0 +1,315 @@ +/* + Unix SMB/CIFS implementation. + + security descriptor description language functions + + Copyright (C) Andrew Tridgell 2005 + + 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 "system/iconv.h" +#include "librpc/gen_ndr/ndr_security.h" + +struct flag_map { + const char *name; + uint32_t flag; +}; + +/* + map a series of letter codes into a uint32_t +*/ +static BOOL sddl_map_flags(const struct flag_map *map, const char *str, + uint32_t *flags, size_t *len) +{ + if (len) *len = 0; + *flags = 0; + while (str[0] && isupper(str[0])) { + int i; + for (i=0;map[i].name;i++) { + size_t l = strlen(map[i].name); + if (strncmp(map[i].name, str, l) == 0) { + *flags |= map[i].flag; + str += l; + if (len) *len += l; + break; + } + } + if (map[i].name == NULL) { + DEBUG(2, ("Unknown flag - %s\n", str)); + return False; + } + } + return True; +} + +/* + a mapping between the 2 letter SID codes and sid strings +*/ +static const struct { + const char *code; + const char *sid; +} sid_codes[] = { + { "AO", SID_BUILTIN_ACCOUNT_OPERATORS }, +}; + +/* + decode a SID + It can either be a special 2 letter code, or in S-* format +*/ +static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp) +{ + const char *sddl = (*sddlp); + int i; + + /* see if its in the numeric format */ + if (strncmp(sddl, "S-", 2) == 0) { + size_t len = strspn(sddl+2, "-0123456789"); + (*sddlp) += len+2; + return dom_sid_parse_talloc(mem_ctx, sddl); + } + + /* now check for one of the special codes */ + for (i=0;itype = v; + + /* ace flags */ + if (!sddl_map_flags(ace_flags, tok[1], &v, NULL)) { + return False; + } + ace->flags = v; + + /* access mask */ + if (strncmp(tok[2], "0x", 2) == 0) { + ace->access_mask = strtol(tok[2], NULL, 16); + } else { + if (!sddl_map_flags(ace_access_mask, tok[2], &v, NULL)) { + return False; + } + ace->access_mask = v; + } + + /* object */ + if (tok[3][0] != 0) { + /* TODO: add object parsing ... */ + return False; + } + + /* inherit object */ + if (tok[4][0] != 0) { + /* TODO: add object parsing ... */ + return False; + } + + /* trustee */ + s = tok[5]; + sid = sddl_decode_sid(mem_ctx, &s); + if (sid == NULL) { + return False; + } + ace->trustee = *sid; + talloc_steal(mem_ctx, sid->sub_auths); + talloc_free(sid); + + return True; +} + +static const struct flag_map acl_flags[] = { + { "P", SEC_DESC_DACL_PROTECTED }, + { "AR", SEC_DESC_DACL_AUTO_INHERIT_REQ }, + { "AI", SEC_DESC_DACL_AUTO_INHERITED }, + { NULL, 0 } +}; + +/* + decode an ACL +*/ +static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, + const char **sddlp, uint32_t *flags) +{ + const char *sddl = *sddlp; + struct security_acl *acl; + size_t len; + + acl = talloc_zero(sd, struct security_acl); + if (acl == NULL) return NULL; + acl->revision = SECURITY_ACL_REVISION_NT4; + + /* work out the ACL flags */ + if (!sddl_map_flags(acl_flags, sddl, flags, &len)) { + talloc_free(acl); + return NULL; + } + sddl += len; + + /* now the ACEs */ + while (*sddl == '(') { + len = strcspn(sddl+1, ")"); + char *astr = talloc_strndup(acl, sddl+1, len); + if (astr == NULL || sddl[len+1] != ')') { + talloc_free(acl); + return NULL; + } + acl->aces = talloc_realloc(acl, acl->aces, struct security_ace, + acl->num_aces+1); + if (acl->aces == NULL) { + talloc_free(acl); + return NULL; + } + if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces], astr)) { + talloc_free(acl); + return NULL; + } + talloc_free(astr); + sddl += len+2; + acl->num_aces++; + } + + (*sddlp) = sddl; + return acl; +} + +/* + decode a security descriptor in SDDL format +*/ +struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl) +{ + struct security_descriptor *sd; + sd = talloc_zero(mem_ctx, struct security_descriptor); + + sd->revision = SECURITY_DESCRIPTOR_REVISION_1; + sd->type = SEC_DESC_SELF_RELATIVE; + + while (*sddl) { + uint32_t flags; + char c = sddl[0]; + if (sddl[1] != ':') goto failed; + + sddl += 2; + switch (c) { + case 'D': + if (sd->dacl != NULL) goto failed; + sd->dacl = sddl_decode_acl(sd, &sddl, &flags); + if (sd->dacl == NULL) goto failed; + sd->type |= flags | SEC_DESC_DACL_PRESENT; + break; + case 'S': + if (sd->sacl != NULL) goto failed; + sd->sacl = sddl_decode_acl(sd, &sddl, &flags); + if (sd->sacl == NULL) goto failed; + /* this relies on the SEC_DESC_SACL_* flags being + 1 bit shifted from the SEC_DESC_DACL_* flags */ + sd->type |= (flags<<1) | SEC_DESC_SACL_PRESENT; + break; + case 'O': + if (sd->owner_sid != NULL) goto failed; + sd->owner_sid = sddl_decode_sid(sd, &sddl); + if (sd->owner_sid == NULL) goto failed; + break; + case 'G': + if (sd->group_sid != NULL) goto failed; + sd->group_sid = sddl_decode_sid(sd, &sddl); + if (sd->group_sid == NULL) goto failed; + break; + } + } + + return sd; + +failed: + DEBUG(2,("Badly formatted SDDL '%s'\n", sddl)); + talloc_free(sd); + return NULL; +} -- cgit From fd7fd22e462ef6cf46e3f63e12ffcd684ea20244 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Dec 2005 03:17:40 +0000 Subject: r12006: don't require callers to fill in pad bytes in SMB2 calls (This used to be commit 6935765fda99a6efb19f6f72358d4d48fc35ad5e) --- source4/libcli/smb2/close.c | 2 +- source4/libcli/smb2/ioctl.c | 2 +- source4/libcli/smb2/read.c | 2 +- source4/libcli/smb2/session.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index c851d60be4..3e559fe893 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -36,7 +36,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.flags); - SIVAL(req->out.body, 0x04, io->in._pad); + SIVAL(req->out.body, 0x04, 0); /* pad */ smb2_push_handle(req->out.body+0x08, &io->in.handle); smb2_transport_send(req); diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index 26f2bffbc1..37e07dbae1 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -37,7 +37,7 @@ struct smb2_request *smb2_ioctl_send(struct smb2_tree *tree, struct smb2_ioctl * io->in.in.length+io->in.out.length); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, io->in._pad); + SSVAL(req->out.body, 0x02, 0); /* pad */ SIVAL(req->out.body, 0x04, io->in.function); smb2_push_handle(req->out.body+0x08, &io->in.handle); diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index f598a78cba..8709aa6ce2 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -35,7 +35,7 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, io->in._pad); + SSVAL(req->out.body, 0x02, 0); /* pad */ SIVAL(req->out.body, 0x04, io->in.length); SBVAL(req->out.body, 0x08, io->in.offset); smb2_push_handle(req->out.body+0x10, &io->in.handle); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 12285d5536..07970747c4 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -73,7 +73,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); - SSVAL(req->out.body, 0x02, io->in._pad); + SSVAL(req->out.body, 0x02, 0); /* pad */ SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3); -- cgit From f5ed8cc829b0522ea4bd8142abc80f5133136834 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Dec 2005 04:26:51 +0000 Subject: r12010: - added support for domain specific SID codes in SDDL strings - added a bunch more tests to LOCAL-SDDL (all the ones from our schema) - fixed 'mixed coded declarations' bug (This used to be commit c30e7698e8e1d9991d35bf86c0d4041a1814ad92) --- source4/libcli/security/sddl.c | 87 ++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 17df393de4..1a15d8853a 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -35,6 +35,7 @@ struct flag_map { static BOOL sddl_map_flags(const struct flag_map *map, const char *str, uint32_t *flags, size_t *len) { + const char *str0 = str; if (len) *len = 0; *flags = 0; while (str[0] && isupper(str[0])) { @@ -49,7 +50,7 @@ static BOOL sddl_map_flags(const struct flag_map *map, const char *str, } } if (map[i].name == NULL) { - DEBUG(2, ("Unknown flag - %s\n", str)); + DEBUG(1, ("Unknown flag - %s in %s\n", str, str0)); return False; } } @@ -62,15 +63,36 @@ static BOOL sddl_map_flags(const struct flag_map *map, const char *str, static const struct { const char *code; const char *sid; + uint32_t rid; } sid_codes[] = { { "AO", SID_BUILTIN_ACCOUNT_OPERATORS }, + { "BA", SID_BUILTIN_ADMINISTRATORS }, + { "RU", SID_BUILTIN_PREW2K }, + { "PO", SID_BUILTIN_PRINT_OPERATORS }, + { "RS", SID_BUILTIN_RAS_SERVERS }, + + { "AU", SID_NT_AUTHENTICATED_USERS }, + { "SY", SID_NT_SYSTEM }, + { "PS", SID_NT_SELF }, + { "WD", SID_WORLD }, + { "ED", SID_NT_ENTERPRISE_DCS }, + + { "CO", SID_CREATOR_OWNER }, + { "CG", SID_CREATOR_GROUP }, + + { "DA", NULL, DOMAIN_RID_ADMINS }, + { "EA", NULL, DOMAIN_RID_ENTERPRISE_ADMINS }, + { "DD", NULL, DOMAIN_RID_DCS }, + { "DU", NULL, DOMAIN_RID_USERS }, + { "CA", NULL, DOMAIN_RID_CERT_ADMINS }, }; /* decode a SID It can either be a special 2 letter code, or in S-* format */ -static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp) +static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp, + struct dom_sid *domain_sid) { const char *sddl = (*sddlp); int i; @@ -84,26 +106,31 @@ static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp) /* now check for one of the special codes */ for (i=0;iobject.object.type.type); + if (!NT_STATUS_IS_OK(status)) { + return False; + } } /* inherit object */ if (tok[4][0] != 0) { - /* TODO: add object parsing ... */ - return False; + NTSTATUS status = GUID_from_string(tok[4], + &ace->object.object.inherited_type.inherited_type); + if (!NT_STATUS_IS_OK(status)) { + return False; + } } /* trustee */ s = tok[5]; - sid = sddl_decode_sid(mem_ctx, &s); + sid = sddl_decode_sid(mem_ctx, &s, domain_sid); if (sid == NULL) { return False; } @@ -217,7 +256,8 @@ static const struct flag_map acl_flags[] = { decode an ACL */ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, - const char **sddlp, uint32_t *flags) + const char **sddlp, uint32_t *flags, + struct dom_sid *domain_sid) { const char *sddl = *sddlp; struct security_acl *acl; @@ -227,6 +267,11 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, if (acl == NULL) return NULL; acl->revision = SECURITY_ACL_REVISION_NT4; + if (isupper(sddl[0]) && sddl[1] == ':') { + /* its an empty ACL */ + return acl; + } + /* work out the ACL flags */ if (!sddl_map_flags(acl_flags, sddl, flags, &len)) { talloc_free(acl); @@ -248,7 +293,8 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, talloc_free(acl); return NULL; } - if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces], astr)) { + if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces], + astr, domain_sid)) { talloc_free(acl); return NULL; } @@ -264,7 +310,8 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, /* decode a security descriptor in SDDL format */ -struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl) +struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl, + struct dom_sid *domain_sid) { struct security_descriptor *sd; sd = talloc_zero(mem_ctx, struct security_descriptor); @@ -281,13 +328,13 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl) switch (c) { case 'D': if (sd->dacl != NULL) goto failed; - sd->dacl = sddl_decode_acl(sd, &sddl, &flags); + sd->dacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid); if (sd->dacl == NULL) goto failed; sd->type |= flags | SEC_DESC_DACL_PRESENT; break; case 'S': if (sd->sacl != NULL) goto failed; - sd->sacl = sddl_decode_acl(sd, &sddl, &flags); + sd->sacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid); if (sd->sacl == NULL) goto failed; /* this relies on the SEC_DESC_SACL_* flags being 1 bit shifted from the SEC_DESC_DACL_* flags */ @@ -295,12 +342,12 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl) break; case 'O': if (sd->owner_sid != NULL) goto failed; - sd->owner_sid = sddl_decode_sid(sd, &sddl); + sd->owner_sid = sddl_decode_sid(sd, &sddl, domain_sid); if (sd->owner_sid == NULL) goto failed; break; case 'G': if (sd->group_sid != NULL) goto failed; - sd->group_sid = sddl_decode_sid(sd, &sddl); + sd->group_sid = sddl_decode_sid(sd, &sddl, domain_sid); if (sd->group_sid == NULL) goto failed; break; } -- cgit From 540483c01b0b03ecd0c9b8824b124542a12fce24 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Dec 2005 05:29:13 +0000 Subject: r12011: fixed another 'mixed code and declarations' bug (This used to be commit 1eca19d597ea21a073361fc6fc550919abf97574) --- source4/libcli/security/sddl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 1a15d8853a..fa0e15a7b6 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -281,8 +281,9 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, /* now the ACEs */ while (*sddl == '(') { + char *astr; len = strcspn(sddl+1, ")"); - char *astr = talloc_strndup(acl, sddl+1, len); + astr = talloc_strndup(acl, sddl+1, len); if (astr == NULL || sddl[len+1] != ')') { talloc_free(acl); return NULL; -- cgit From 99b344eb14f528201381b20e127a131d2c2dff24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Dec 2005 15:02:21 +0000 Subject: r12020: fix memory hierachie metze (This used to be commit 2433800834293a95669c3c48eb2462b76d1b3029) --- source4/libcli/nbt/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index c0a1e274e2..38fb2f966d 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -108,7 +108,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } for (i=0;iout.num_addrs;i++) { - io->out.reply_addrs[i] = talloc_steal(mem_ctx, + io->out.reply_addrs[i] = talloc_steal(io->out.reply_addrs, packet->answers[0].rdata.netbios.addresses[i].ipaddr); } io->out.reply_addrs[i] = NULL; -- cgit From 687545e94e0cb4f2bac0596f7f78797cca312e73 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Dec 2005 04:10:13 +0000 Subject: r12062: SASL negotiation now requires a gensec_security context, so that we only try permitted mechanims. Andrew Bartlett (This used to be commit 0f50239dc40ee128e4985f8aec5bb5f440a4f3f0) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 81e0c8b4e6..766416f575 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -223,7 +223,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } sasl_names[i] = NULL; - mechs = gensec_security_by_sasl(tmp_ctx, sasl_names); + mechs = gensec_security_by_sasl(conn->gensec, tmp_ctx, sasl_names); if (!mechs || !mechs[0]) { DEBUG(1, ("None of the %d proposed SASL mechs were acceptable\n", count)); -- cgit From 4a397070b6259cc97ccf7ce18f5a22dfff8e7d41 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Mon, 5 Dec 2005 22:34:45 +0000 Subject: r12079: Fix to the comment for sake of completness... rafal (This used to be commit 7aa40e3a3ff7a655c5ed8ee67c55af92193815f1) --- source4/libcli/composite/composite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index c4b771509f..3842ddfe9f 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -46,7 +46,7 @@ NTSTATUS composite_wait(struct composite_context *c) /* - callback from composite_trigger_done() + callback from composite_trigger_done() and composite_trigger_error() */ static void composite_trigger(struct event_context *ev, struct timed_event *te, struct timeval t, void *ptr) -- cgit From 89f5d66dfeb02ad626ad21c4c4c7800560f83676 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 7 Dec 2005 07:28:43 +0000 Subject: r12114: - smb2_keepalive() acts on the smb2_transport - smb2_logoff() acts on the smb2_session metze (This used to be commit ae1ca2bb4affefff1026c03f0765faf28c2b316b) --- source4/libcli/smb2/keepalive.c | 8 ++++---- source4/libcli/smb2/logoff.c | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index 64ed847757..4017623a61 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -28,11 +28,11 @@ /* send a keepalive request */ -struct smb2_request *smb2_keepalive_send(struct smb2_tree *tree) +struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport) { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_KEEPALIVE, 0x04, 0); + req = smb2_request_init(transport, SMB2_OP_KEEPALIVE, 0x04, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); @@ -60,8 +60,8 @@ NTSTATUS smb2_keepalive_recv(struct smb2_request *req) /* sync keepalive request */ -NTSTATUS smb2_keepalive(struct smb2_tree *tree) +NTSTATUS smb2_keepalive(struct smb2_transport *transport) { - struct smb2_request *req = smb2_keepalive_send(tree); + struct smb2_request *req = smb2_keepalive_send(transport); return smb2_keepalive_recv(req); } diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index a73c7ee92e..febe0d6b45 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -28,13 +28,15 @@ /* send a logoff request */ -struct smb2_request *smb2_logoff_send(struct smb2_tree *tree) +struct smb2_request *smb2_logoff_send(struct smb2_session *session) { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_LOGOFF, 0x04, 0); + req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, 0); if (req == NULL) return NULL; + SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); + SSVAL(req->out.body, 0x02, 0); smb2_transport_send(req); @@ -60,8 +62,8 @@ NTSTATUS smb2_logoff_recv(struct smb2_request *req) /* sync logoff request */ -NTSTATUS smb2_logoff(struct smb2_tree *tree) +NTSTATUS smb2_logoff(struct smb2_session *session) { - struct smb2_request *req = smb2_logoff_send(tree); + struct smb2_request *req = smb2_logoff_send(session); return smb2_logoff_recv(req); } -- cgit From 111a920fdb92ccef32f89b2f992bdd3051e5ac54 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Dec 2005 01:13:45 +0000 Subject: r12116: got rid of composite_trigger_done() and composite_trigger_error(), and instead make the normal composite_done() and composite_error() functions automatically trigger a delayed callback if the caller has had no opportunity to setup a async callback this removes one of the common mistakes in writing a composite function (This used to be commit f9413ce792ded682e05134b66d433eeec293e6f1) --- source4/libcli/composite/composite.c | 65 +++++++++++++++++------------------- source4/libcli/composite/composite.h | 2 ++ source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/resolve/resolve.c | 2 +- source4/libcli/smb2/connect.c | 2 +- source4/libcli/smb2/session.c | 2 +- 6 files changed, 37 insertions(+), 38 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 3842ddfe9f..c9cc20e923 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -35,6 +35,8 @@ NTSTATUS composite_wait(struct composite_context *c) { if (c == NULL) return NT_STATUS_NO_MEMORY; + c->used_wait = True; + while (c->state < COMPOSITE_STATE_DONE) { if (event_loop_once(c->event_ctx) != 0) { return NT_STATUS_UNSUCCESSFUL; @@ -45,44 +47,10 @@ NTSTATUS composite_wait(struct composite_context *c) } -/* - callback from composite_trigger_done() and composite_trigger_error() -*/ -static void composite_trigger(struct event_context *ev, struct timed_event *te, - struct timeval t, void *ptr) -{ - struct composite_context *c = talloc_get_type(ptr, struct composite_context); - if (c->async.fn) { - c->async.fn(c); - } -} - - -/* - trigger an immediate 'done' event on a composite context - this is used when the composite code works out that the call - can be completed without waiting for any external event -*/ -void composite_trigger_done(struct composite_context *c) -{ - c->state = COMPOSITE_STATE_DONE; - /* a zero timeout means immediate */ - event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); -} - -void composite_trigger_error(struct composite_context *c) -{ - c->state = COMPOSITE_STATE_ERROR; - /* a zero timeout means immediate */ - event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c); -} - - /* * Some composite helpers that are handy if you write larger composite * functions. */ - BOOL composite_is_ok(struct composite_context *ctx) { if (NT_STATUS_IS_OK(ctx->status)) { @@ -95,8 +63,34 @@ BOOL composite_is_ok(struct composite_context *ctx) return False; } +/* + callback from composite_done() and composite_error() + + this is used to allow for a composite function to complete without + going through any state transitions. When that happens the caller + has had no opportunity to fill in the async callback fields + (ctx->async.fn and ctx->async.private) which means the usual way of + dealing with composite functions doesn't work. To cope with this, + we trigger a timer event that will happen then the event loop is + re-entered. This gives the caller a chance to setup the callback, + and allows the caller to ignore the fact that the composite + function completed early +*/ +static void composite_trigger(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct composite_context *c = talloc_get_type(ptr, struct composite_context); + if (c->async.fn) { + c->async.fn(c); + } +} + + void composite_error(struct composite_context *ctx, NTSTATUS status) { + if (!ctx->used_wait && !ctx->async.fn) { + event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); + } ctx->status = status; SMB_ASSERT(!composite_is_ok(ctx)); } @@ -112,6 +106,9 @@ BOOL composite_nomem(const void *p, struct composite_context *ctx) void composite_done(struct composite_context *ctx) { + if (!ctx->used_wait && !ctx->async.fn) { + event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); + } ctx->state = COMPOSITE_STATE_DONE; if (ctx->async.fn != NULL) { ctx->async.fn(ctx); diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 1e6e9f5dc8..26490f1c4a 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -57,4 +57,6 @@ struct composite_context { void (*fn)(struct composite_context *); void *private_data; } async; + + BOOL used_wait; }; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index a5f647939f..0a787bbf57 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -341,7 +341,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, &conn->port, &conn->ldaps); if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_trigger_error(state->ctx); + composite_error(state->ctx, state->ctx->status); return result; } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index db5aefeaeb..bbed931eed 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -153,7 +153,7 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ struct ipv4_addr ip = interpret_addr2(state->name.name); state->reply_addr = talloc_strdup(state, sys_inet_ntoa(ip)); if (!state->reply_addr) goto failed; - composite_trigger_done(c); + composite_done(c); return c; } diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 7ed3f97bf3..d15f370feb 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -201,7 +201,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, return c; failed: - composite_trigger_error(c); + composite_error(c, c->status); return c; } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 07970747c4..208e2a94de 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -253,7 +253,7 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se return c; failed: - composite_trigger_error(c); + composite_error(c, c->status); return c; } -- cgit From 79eae8ffff0105cd9d16195cfd3c2c025d2c663f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Dec 2005 04:54:30 +0000 Subject: r12137: added sddl_encode(), the reverse of the sddl_decode() function added a couple of days ago. Doesn't yet encode using the shorthand for well known SIDs. (This used to be commit 655a4ebe8e0ee18133103bfba0ca6d14cbf81d56) --- source4/libcli/security/sddl.c | 170 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index fa0e15a7b6..7ae7d83839 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -263,6 +263,8 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, struct security_acl *acl; size_t len; + *flags = 0; + acl = talloc_zero(sd, struct security_acl); if (acl == NULL) return NULL; acl->revision = SECURITY_ACL_REVISION_NT4; @@ -361,3 +363,171 @@ failed: talloc_free(sd); return NULL; } + +/* + turn a set of flags into a string +*/ +static char *sddl_flags_to_string(TALLOC_CTX *mem_ctx, const struct flag_map *map, + uint32_t flags, BOOL check_all) +{ + int i; + char *s; + + /* try to find an exact match */ + for (i=0;map[i].name;i++) { + if (map[i].flag == flags) { + return talloc_strdup(mem_ctx, map[i].name); + } + } + + s = talloc_strdup(mem_ctx, ""); + + /* now by bits */ + for (i=0;map[i].name;i++) { + if ((flags & map[i].flag) != 0) { + s = talloc_asprintf_append(s, "%s", map[i].name); + if (s == NULL) goto failed; + flags &= ~map[i].flag; + } + } + + if (check_all && flags != 0) { + goto failed; + } + + return s; + +failed: + talloc_free(s); + return NULL; +} + +/* + encode a sid in SDDL format +*/ +static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, + struct dom_sid *domain_sid) +{ + /* TODO: encode well known sids as two letter codes */ + return dom_sid_string(mem_ctx, sid); +} + + +/* + encode an ACE in SDDL format +*/ +static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace, + struct dom_sid *domain_sid) +{ + char *sddl; + TALLOC_CTX *tmp_ctx; + const char *s_type="", *s_flags="", *s_mask="", + *s_object="", *s_iobject="", *s_trustee=""; + + tmp_ctx = talloc_new(mem_ctx); + + s_type = sddl_flags_to_string(tmp_ctx, ace_types, ace->type, True); + if (s_type == NULL) goto failed; + + s_flags = sddl_flags_to_string(tmp_ctx, ace_flags, ace->flags, True); + if (s_flags == NULL) goto failed; + + s_mask = sddl_flags_to_string(tmp_ctx, ace_access_mask, ace->access_mask, True); + if (s_mask == NULL) goto failed; + + s_object = GUID_string(tmp_ctx, &ace->object.object.type.type); + + s_iobject = GUID_string(tmp_ctx, &ace->object.object.inherited_type.inherited_type); + + s_trustee = sddl_encode_sid(tmp_ctx, &ace->trustee, domain_sid); + + sddl = talloc_asprintf(mem_ctx, "%s;%s;%s;%s;%s;%s", + s_type, s_flags, s_mask, s_object, s_iobject, s_trustee); + +failed: + talloc_free(tmp_ctx); + return sddl; +} + +/* + encode an ACL in SDDL format +*/ +static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl, + uint32_t flags, struct dom_sid *domain_sid) +{ + char *sddl; + int i; + + /* add any ACL flags */ + sddl = sddl_flags_to_string(mem_ctx, acl_flags, flags, False); + if (sddl == NULL) goto failed; + + /* now the ACEs, encoded in braces */ + for (i=0;inum_aces;i++) { + char *ace = sddl_encode_ace(sddl, &acl->aces[i], domain_sid); + if (ace == NULL) goto failed; + sddl = talloc_asprintf_append(sddl, "(%s)", ace); + if (sddl == NULL) goto failed; + talloc_free(ace); + } + + return sddl; + +failed: + talloc_free(sddl); + return NULL; +} + + +/* + encode a security descriptor to SDDL format +*/ +char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd, + struct dom_sid *domain_sid) +{ + char *sddl; + TALLOC_CTX *tmp_ctx; + + /* start with a blank string */ + sddl = talloc_strdup(mem_ctx, ""); + if (sddl == NULL) goto failed; + + tmp_ctx = talloc_new(mem_ctx); + + if (sd->owner_sid != NULL) { + char *sid = sddl_encode_sid(tmp_ctx, sd->owner_sid, domain_sid); + if (sid == NULL) goto failed; + sddl = talloc_asprintf_append(sddl, "O:%s", sid); + if (sddl == NULL) goto failed; + } + + if (sd->group_sid != NULL) { + char *sid = sddl_encode_sid(tmp_ctx, sd->group_sid, domain_sid); + if (sid == NULL) goto failed; + sddl = talloc_asprintf_append(sddl, "G:%s", sid); + if (sddl == NULL) goto failed; + } + + if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl != NULL) { + char *acl = sddl_encode_acl(tmp_ctx, sd->dacl, sd->type, domain_sid); + if (acl == NULL) goto failed; + sddl = talloc_asprintf_append(sddl, "D:%s", acl); + if (sddl == NULL) goto failed; + } + + if ((sd->type & SEC_DESC_SACL_PRESENT) && sd->sacl != NULL) { + char *acl = sddl_encode_acl(tmp_ctx, sd->sacl, sd->type>>1, domain_sid); + if (acl == NULL) goto failed; + sddl = talloc_asprintf_append(sddl, "S:%s", acl); + if (sddl == NULL) goto failed; + } + + talloc_free(tmp_ctx); + return sddl; + +failed: + talloc_free(sddl); + return NULL; +} + + -- cgit From 781ed1f5ef38cc057c5efa3d09f6a388791b37f3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Dec 2005 05:21:47 +0000 Subject: r12138: added use of 2 letter SID codes in sddl_encode_sid() (This used to be commit a0662ae9d3f719d2db193490361923095bd4d419) --- source4/libcli/security/sddl.c | 45 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 7ae7d83839..a1b8346969 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -146,7 +146,6 @@ static const struct flag_map ace_flags[] = { }; static const struct flag_map ace_access_mask[] = { - { "RC", SEC_STD_READ_CONTROL }, { "RP", SEC_ADS_READ_PROP }, { "WP", SEC_ADS_WRITE_PROP }, { "CR", SEC_ADS_CONTROL_ACCESS }, @@ -154,6 +153,7 @@ static const struct flag_map ace_access_mask[] = { { "DC", SEC_ADS_DELETE_CHILD }, { "LC", SEC_ADS_LIST }, { "LO", SEC_ADS_LIST_OBJECT }, + { "RC", SEC_STD_READ_CONTROL }, { "WO", SEC_STD_WRITE_OWNER }, { "WD", SEC_STD_WRITE_DAC }, { "SD", SEC_STD_DELETE }, @@ -408,6 +408,33 @@ failed: static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, struct dom_sid *domain_sid) { + int i; + char *sidstr; + + sidstr = dom_sid_string(mem_ctx, sid); + if (sidstr == NULL) return NULL; + + /* seen if its a well known sid */ + for (i=0;sid_codes[i].sid;i++) { + if (strcmp(sidstr, sid_codes[i].sid) == 0) { + talloc_free(sidstr); + return talloc_strdup(mem_ctx, sid_codes[i].code); + } + } + + /* or a well known rid in our domain */ + if (dom_sid_in_domain(domain_sid, sid)) { + uint32_t rid = sid->sub_auths[sid->num_auths-1]; + for (;iaccess_mask, True); if (s_mask == NULL) goto failed; - s_object = GUID_string(tmp_ctx, &ace->object.object.type.type); + if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || + ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || + ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) { + if (!GUID_all_zero(&ace->object.object.type.type)) { + s_object = GUID_string(tmp_ctx, &ace->object.object.type.type); + if (s_object == NULL) goto failed; + } - s_iobject = GUID_string(tmp_ctx, &ace->object.object.inherited_type.inherited_type); + if (!GUID_all_zero(&ace->object.object.inherited_type.inherited_type)) { + s_iobject = GUID_string(tmp_ctx, &ace->object.object.inherited_type.inherited_type); + if (s_iobject == NULL) goto failed; + } + } s_trustee = sddl_encode_sid(tmp_ctx, &ace->trustee, domain_sid); + if (s_trustee == NULL) goto failed; sddl = talloc_asprintf(mem_ctx, "%s;%s;%s;%s;%s;%s", s_type, s_flags, s_mask, s_object, s_iobject, s_trustee); -- cgit From 2e4d4a9e28ddd84e245e45c2c58f9cc6e8e2967f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Dec 2005 06:22:09 +0000 Subject: r12139: - fixed up the ace object flags checking - allow for arbitrary access masks in sddl_encode_ace() (This used to be commit 5e2b1bd6afafe2eb96e98c4636e0a62235693183) --- source4/libcli/security/sddl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index a1b8346969..643cb7a82c 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -221,6 +221,7 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char if (!NT_STATUS_IS_OK(status)) { return False; } + ace->object.object.flags |= SEC_ACE_OBJECT_TYPE_PRESENT; } /* inherit object */ @@ -230,6 +231,7 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char if (!NT_STATUS_IS_OK(status)) { return False; } + ace->object.object.flags |= SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT; } /* trustee */ @@ -460,18 +462,21 @@ static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace if (s_flags == NULL) goto failed; s_mask = sddl_flags_to_string(tmp_ctx, ace_access_mask, ace->access_mask, True); - if (s_mask == NULL) goto failed; + if (s_mask == NULL) { + s_mask = talloc_asprintf(tmp_ctx, "0x%08x", ace->access_mask); + if (s_mask == NULL) goto failed; + } if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) { - if (!GUID_all_zero(&ace->object.object.type.type)) { + if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) { s_object = GUID_string(tmp_ctx, &ace->object.object.type.type); if (s_object == NULL) goto failed; } - if (!GUID_all_zero(&ace->object.object.inherited_type.inherited_type)) { + if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { s_iobject = GUID_string(tmp_ctx, &ace->object.object.inherited_type.inherited_type); if (s_iobject == NULL) goto failed; } -- cgit From d811ea17bb3a487b8bdcd2f9aa8dc4ba5cb2ab01 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Dec 2005 23:43:02 +0000 Subject: r12158: added ldif handlers for the ntSecurityDescriptor attribute, so when displaying security descriptors in ldbsearch or ldbedit you can see the SDDL version. This also allows us to specify security descriptors in our setup/*.ldif files in SDDL format, which is much more convenient than the NDR binary format! (This used to be commit 8185731c1846412c1b3366824cdb3d05b2d50b73) --- source4/libcli/security/sddl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 643cb7a82c..7d7fe856cd 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -92,7 +92,7 @@ static const struct { It can either be a special 2 letter code, or in S-* format */ static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { const char *sddl = (*sddlp); int i; @@ -172,7 +172,7 @@ static const struct flag_map ace_access_mask[] = { note that this routine modifies the string */ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { const char *tok[6]; const char *s; @@ -259,7 +259,7 @@ static const struct flag_map acl_flags[] = { */ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, const char **sddlp, uint32_t *flags, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { const char *sddl = *sddlp; struct security_acl *acl; @@ -316,7 +316,7 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, decode a security descriptor in SDDL format */ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { struct security_descriptor *sd; sd = talloc_zero(mem_ctx, struct security_descriptor); @@ -408,7 +408,7 @@ failed: encode a sid in SDDL format */ static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { int i; char *sidstr; @@ -446,7 +446,7 @@ static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, encode an ACE in SDDL format */ static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { char *sddl; TALLOC_CTX *tmp_ctx; @@ -497,7 +497,7 @@ failed: encode an ACL in SDDL format */ static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl, - uint32_t flags, struct dom_sid *domain_sid) + uint32_t flags, const struct dom_sid *domain_sid) { char *sddl; int i; @@ -527,7 +527,7 @@ failed: encode a security descriptor to SDDL format */ char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd, - struct dom_sid *domain_sid) + const struct dom_sid *domain_sid) { char *sddl; TALLOC_CTX *tmp_ctx; -- cgit From 078ae0f8970a1b24a4f15f4dcffbc91d6f64143f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 10 Dec 2005 09:18:03 +0000 Subject: r12161: Fix a memleak and do the -O1 janitor :-) (This used to be commit 82d87d62614a33ec9d2ed20e63d80a7af64e8678) --- source4/libcli/security/sddl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 7d7fe856cd..83dfeed5ac 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -448,12 +448,16 @@ static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace, const struct dom_sid *domain_sid) { - char *sddl; + char *sddl = NULL; TALLOC_CTX *tmp_ctx; const char *s_type="", *s_flags="", *s_mask="", *s_object="", *s_iobject="", *s_trustee=""; tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + DEBUG(0, ("talloc_new failed\n")); + return NULL; + } s_type = sddl_flags_to_string(tmp_ctx, ace_types, ace->type, True); if (s_type == NULL) goto failed; -- cgit From 36acd6e79c8cb881b9c333313402d993a6d0f511 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Dec 2005 21:31:42 +0000 Subject: r12200: - move the the winsreplication client and server code to the packet_context system - this needs to be in one big patch, because of the merging code, that changes client in server connections and the other way around - use socket_connect_send/_recv() in the client code metze (This used to be commit f0105b7fcdc3032d22444a1973927fff2dd9a06f) --- source4/libcli/wrepl/winsrepl.c | 546 +++++++++++++++++----------------------- source4/libcli/wrepl/winsrepl.h | 27 +- 2 files changed, 237 insertions(+), 336 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 5658a2cc03..109910be1f 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -25,6 +25,10 @@ #include "dlinklist.h" #include "lib/socket/socket.h" #include "libcli/wrepl/winsrepl.h" +#include "lib/stream/packet.h" +#include "libcli/composite/composite.h" + +static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status); /* mark all pending requests as dead - called when a socket error happens @@ -34,12 +38,15 @@ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status talloc_set_destructor(wrepl_socket, NULL); wrepl_socket->dead = True; - if (wrepl_socket->fde) { - talloc_free(wrepl_socket->fde); - wrepl_socket->fde = NULL; + if (wrepl_socket->event.fde) { + packet_recv_disable(wrepl_socket->packet); + packet_set_fde(wrepl_socket->packet, NULL); + talloc_free(wrepl_socket->event.fde); + wrepl_socket->event.fde = NULL; } if (wrepl_socket->sock) { + packet_set_socket(wrepl_socket->packet, NULL); talloc_free(wrepl_socket->sock); wrepl_socket->sock = NULL; } @@ -47,23 +54,10 @@ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) { status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; } - while (wrepl_socket->send_queue) { - struct wrepl_request *req = wrepl_socket->send_queue; - DLIST_REMOVE(wrepl_socket->send_queue, req); - req->state = WREPL_REQUEST_ERROR; - req->status = status; - if (req->async.fn) { - req->async.fn(req); - } - } while (wrepl_socket->recv_queue) { struct wrepl_request *req = wrepl_socket->recv_queue; DLIST_REMOVE(wrepl_socket->recv_queue, req); - req->state = WREPL_REQUEST_ERROR; - req->status = status; - if (req->async.fn) { - req->async.fn(req); - } + wrepl_request_finished(req, status); } } @@ -74,180 +68,39 @@ static void wrepl_request_timeout_handler(struct event_context *ev, struct timed wrepl_socket_dead(req->wrepl_socket, NT_STATUS_IO_TIMEOUT); } -/* - handle send events -*/ -static void wrepl_handler_send(struct wrepl_socket *wrepl_socket) -{ - while (wrepl_socket->send_queue) { - struct wrepl_request *req = wrepl_socket->send_queue; - size_t nsent; - NTSTATUS status; - - status = socket_send(wrepl_socket->sock, &req->buffer, &nsent, 0); - if (NT_STATUS_IS_ERR(status)) { - wrepl_socket_dead(wrepl_socket, status); - return; - } - if (!NT_STATUS_IS_OK(status) || nsent == 0) return; - - req->buffer.data += nsent; - req->buffer.length -= nsent; - if (req->buffer.length != 0) { - return; - } - - if (req->disconnect_after_send) { - DLIST_REMOVE(wrepl_socket->send_queue, req); - req->status = NT_STATUS_OK; - req->state = WREPL_REQUEST_DONE; - wrepl_socket_dead(wrepl_socket, NT_STATUS_LOCAL_DISCONNECT); - if (req->async.fn) { - req->async.fn(req); - } - return; - } - - if (req->send_only) { - DLIST_REMOVE(wrepl_socket->send_queue, req); - req->status = NT_STATUS_OK; - req->state = WREPL_REQUEST_DONE; - if (req->async.fn) { - EVENT_FD_READABLE(wrepl_socket->fde); - req->async.fn(req); - return; - } - } else { - DLIST_REMOVE(wrepl_socket->send_queue, req); - DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); - req->state = WREPL_REQUEST_RECV; - } - - EVENT_FD_READABLE(wrepl_socket->fde); - } - - EVENT_FD_NOT_WRITEABLE(wrepl_socket->fde); -} - - /* handle recv events */ -static void wrepl_handler_recv(struct wrepl_socket *wrepl_socket) +static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) { - size_t nread; + struct wrepl_socket *wrepl_socket = talloc_get_type(private, struct wrepl_socket); struct wrepl_request *req = wrepl_socket->recv_queue; DATA_BLOB blob; - if (req == NULL) { - NTSTATUS status; - - EVENT_FD_NOT_READABLE(wrepl_socket->fde); - - status = socket_recv(wrepl_socket->sock, NULL, 0, &nread, 0); - if (NT_STATUS_EQUAL(NT_STATUS_END_OF_FILE,status)) return; - if (NT_STATUS_IS_ERR(status)) { - wrepl_socket_dead(wrepl_socket, status); - return; - } - return; - } - - if (req->buffer.length == 0) { - req->buffer = data_blob_talloc(req, NULL, 4); - if (req->buffer.data == NULL) { - req->status = NT_STATUS_NO_MEMORY; - goto failed; - } - req->num_read = 0; - } - - /* read in the packet length */ - if (req->num_read < 4) { - uint32_t req_length; - - req->status = socket_recv(wrepl_socket->sock, - req->buffer.data + req->num_read, - 4 - req->num_read, - &nread, 0); - if (NT_STATUS_IS_ERR(req->status)) { - wrepl_socket_dead(wrepl_socket, req->status); - return; - } - if (!NT_STATUS_IS_OK(req->status)) return; - - req->num_read += nread; - if (req->num_read != 4) return; - - req_length = RIVAL(req->buffer.data, 0) + 4; - - req->buffer.data = talloc_realloc(req, req->buffer.data, - uint8_t, req_length); - if (req->buffer.data == NULL) { - req->status = NT_STATUS_NO_MEMORY; - goto failed; - } - req->buffer.length = req_length; - } - - /* read in the body */ - req->status = socket_recv(wrepl_socket->sock, - req->buffer.data + req->num_read, - req->buffer.length - req->num_read, - &nread, 0); - if (NT_STATUS_IS_ERR(req->status)) { - wrepl_socket_dead(wrepl_socket, req->status); - return; - } - if (!NT_STATUS_IS_OK(req->status)) return; - - req->num_read += nread; - if (req->num_read != req->buffer.length) return; - req->packet = talloc(req, struct wrepl_packet); - if (req->packet == NULL) { - req->status = NT_STATUS_NO_MEMORY; - goto failed; - } + NT_STATUS_HAVE_NO_MEMORY(req->packet); - blob.data = req->buffer.data + 4; - blob.length = req->buffer.length - 4; + blob.data = packet_blob_in.data + 4; + blob.length = packet_blob_in.length - 4; /* we have a full request - parse it */ req->status = ndr_pull_struct_blob(&blob, req->packet, req->packet, (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); if (!NT_STATUS_IS_OK(req->status)) { - DEBUG(2,("Failed to parse incoming WINS packet - %s\n", - nt_errstr(req->status))); - DEBUG(10,("packet length %d\n", (int)req->buffer.length)); - NDR_PRINT_DEBUG(wrepl_packet, req->packet); - goto failed; + wrepl_request_finished(req, req->status); + return NT_STATUS_OK; } if (DEBUGLVL(10)) { - DEBUG(10,("Received WINS packet of length %d\n", (int)req->buffer.length)); + DEBUG(10,("Received WINS packet of length %u\n", packet_blob_in.length)); NDR_PRINT_DEBUG(wrepl_packet, req->packet); } - DLIST_REMOVE(wrepl_socket->recv_queue, req); - req->state = WREPL_REQUEST_DONE; - if (req->async.fn) { - req->async.fn(req); - } - return; - -failed: - if (req->state == WREPL_REQUEST_RECV) { - DLIST_REMOVE(wrepl_socket->recv_queue, req); - } - req->state = WREPL_REQUEST_ERROR; - if (req->async.fn) { - req->async.fn(req); - } + wrepl_request_finished(req, req->status); + return NT_STATUS_OK; } - /* handler for winrepl events */ @@ -256,56 +109,23 @@ static void wrepl_handler(struct event_context *ev, struct fd_event *fde, { struct wrepl_socket *wrepl_socket = talloc_get_type(private, struct wrepl_socket); - if (flags & EVENT_FD_WRITE) { - wrepl_handler_send(wrepl_socket); - } if (flags & EVENT_FD_READ) { - wrepl_handler_recv(wrepl_socket); + packet_recv(wrepl_socket->packet); + return; + } + if (flags & EVENT_FD_WRITE) { + packet_queue_run(wrepl_socket->packet); } } - -/* - handler for winrepl connection completion -*/ -static void wrepl_connect_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) +static void wrepl_error(void *private, NTSTATUS status) { struct wrepl_socket *wrepl_socket = talloc_get_type(private, struct wrepl_socket); - struct wrepl_request *req = wrepl_socket->recv_queue; - - talloc_free(wrepl_socket->fde); - wrepl_socket->fde = NULL; - - if (req == NULL) return; - - req->status = socket_connect_complete(wrepl_socket->sock, 0); - if (NT_STATUS_IS_ERR(req->status)) goto failed; - - if (!NT_STATUS_IS_OK(req->status)) return; - - wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, - socket_get_fd(wrepl_socket->sock), - EVENT_FD_WRITE, - wrepl_handler, wrepl_socket); - if (wrepl_socket->fde == NULL) { - req->status = NT_STATUS_NO_MEMORY; - } - - -failed: - DLIST_REMOVE(wrepl_socket->recv_queue, req); - if (!NT_STATUS_IS_OK(req->status)) { - req->state = WREPL_REQUEST_ERROR; - } else { - req->state = WREPL_REQUEST_DONE; - } - if (req->async.fn) { - req->async.fn(req); - } + wrepl_socket_dead(wrepl_socket, status); } + /* destroy a wrepl_socket destructor */ @@ -326,35 +146,22 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, struct wrepl_socket *wrepl_socket; NTSTATUS status; - wrepl_socket = talloc(mem_ctx, struct wrepl_socket); - if (wrepl_socket == NULL) goto failed; + wrepl_socket = talloc_zero(mem_ctx, struct wrepl_socket); + if (!wrepl_socket) return NULL; if (event_ctx == NULL) { - wrepl_socket->event_ctx = event_context_init(wrepl_socket); + wrepl_socket->event.ctx = event_context_init(wrepl_socket); } else { - wrepl_socket->event_ctx = talloc_reference(wrepl_socket, event_ctx); + wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx); } - if (wrepl_socket->event_ctx == NULL) goto failed; + if (!wrepl_socket->event.ctx) goto failed; status = socket_create("ip", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0); if (!NT_STATUS_IS_OK(status)) goto failed; talloc_steal(wrepl_socket, wrepl_socket->sock); - wrepl_socket->send_queue = NULL; - wrepl_socket->recv_queue = NULL; wrepl_socket->request_timeout = WREPL_SOCKET_REQUEST_TIMEOUT; - wrepl_socket->dead = False; - - wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, - socket_get_fd(wrepl_socket->sock), - EVENT_FD_WRITE, - wrepl_connect_handler, wrepl_socket); - if (wrepl_socket->fde == NULL) { - goto failed; - } - - set_blocking(socket_get_fd(wrepl_socket->sock), False); talloc_set_destructor(wrepl_socket, wrepl_socket_destructor); @@ -370,32 +177,42 @@ failed: */ struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, - struct socket_context *socket) + struct socket_context *socket, + struct packet_context *packet) { struct wrepl_socket *wrepl_socket; - wrepl_socket = talloc(mem_ctx, struct wrepl_socket); + wrepl_socket = talloc_zero(mem_ctx, struct wrepl_socket); if (wrepl_socket == NULL) goto failed; - wrepl_socket->event_ctx = talloc_reference(wrepl_socket, event_ctx); - if (wrepl_socket->event_ctx == NULL) goto failed; + wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx); + if (wrepl_socket->event.ctx == NULL) goto failed; wrepl_socket->sock = socket; talloc_steal(wrepl_socket, wrepl_socket->sock); - wrepl_socket->send_queue = NULL; - wrepl_socket->recv_queue = NULL; + wrepl_socket->request_timeout = WREPL_SOCKET_REQUEST_TIMEOUT; - wrepl_socket->dead = False; - wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, - socket_get_fd(wrepl_socket->sock), - 0, - wrepl_handler, wrepl_socket); - if (wrepl_socket->fde == NULL) { + wrepl_socket->event.fde = event_add_fd(wrepl_socket->event.ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + EVENT_FD_READ, + wrepl_handler, wrepl_socket); + if (wrepl_socket->event.fde == NULL) { goto failed; } + wrepl_socket->packet = packet; + talloc_steal(wrepl_socket, wrepl_socket->packet); + packet_set_private(wrepl_socket->packet, wrepl_socket); + packet_set_socket(wrepl_socket->packet, wrepl_socket->sock); + packet_set_callback(wrepl_socket->packet, wrepl_finish_recv); + packet_set_full_request(wrepl_socket->packet, packet_full_request_u32); + packet_set_error_handler(wrepl_socket->packet, wrepl_error); + packet_set_event_context(wrepl_socket->packet, wrepl_socket->event.ctx); + packet_set_fde(wrepl_socket->packet, wrepl_socket->event.fde); + packet_set_serialise(wrepl_socket->packet); + talloc_set_destructor(wrepl_socket, wrepl_socket_destructor); return wrepl_socket; @@ -411,9 +228,6 @@ failed: static int wrepl_request_destructor(void *ptr) { struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); - if (req->state == WREPL_REQUEST_SEND) { - DLIST_REMOVE(req->wrepl_socket->send_queue, req); - } if (req->state == WREPL_REQUEST_RECV) { DLIST_REMOVE(req->wrepl_socket->recv_queue, req); } @@ -428,79 +242,108 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req) { NT_STATUS_HAVE_NO_MEMORY(req); while (req->state < WREPL_REQUEST_DONE) { - event_loop_once(req->wrepl_socket->event_ctx); + event_loop_once(req->wrepl_socket->event.ctx); } return req->status; } -static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status); +struct wrepl_connect_state { + struct composite_context *result; + struct wrepl_socket *wrepl_socket; + struct composite_context *creq; +}; + +/* + handler for winrepl connection completion +*/ +static void wrepl_connect_handler(struct composite_context *creq) +{ + struct wrepl_connect_state *state = talloc_get_type(creq->async.private_data, + struct wrepl_connect_state); + struct wrepl_socket *wrepl_socket = state->wrepl_socket; + struct composite_context *result = state->result; + + result->status = socket_connect_recv(state->creq); + if (!composite_is_ok(result)) return; + + wrepl_socket->event.fde = event_add_fd(wrepl_socket->event.ctx, wrepl_socket, + socket_get_fd(wrepl_socket->sock), + EVENT_FD_READ, + wrepl_handler, wrepl_socket); + if (composite_nomem(wrepl_socket->event.fde, result)) return; + + /* setup the stream -> packet parser */ + wrepl_socket->packet = packet_init(wrepl_socket); + if (composite_nomem(wrepl_socket->packet, result)) return; + packet_set_private(wrepl_socket->packet, wrepl_socket); + packet_set_socket(wrepl_socket->packet, wrepl_socket->sock); + packet_set_callback(wrepl_socket->packet, wrepl_finish_recv); + packet_set_full_request(wrepl_socket->packet, packet_full_request_u32); + packet_set_error_handler(wrepl_socket->packet, wrepl_error); + packet_set_event_context(wrepl_socket->packet, wrepl_socket->event.ctx); + packet_set_fde(wrepl_socket->packet, wrepl_socket->event.fde); + packet_set_serialise(wrepl_socket->packet); + + composite_done(result); +} /* connect a wrepl_socket to a WINS server */ -struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket, - const char *our_ip, const char *peer_ip) +struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, + const char *our_ip, const char *peer_ip) { - struct wrepl_request *req; - NTSTATUS status; + struct composite_context *result; + struct wrepl_connect_state *state; - req = talloc_zero(wrepl_socket, struct wrepl_request); - if (req == NULL) goto failed; + result = talloc_zero(wrepl_socket, struct composite_context); + if (!result) return NULL; - req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_RECV; - - DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->event_ctx = wrepl_socket->event.ctx; - talloc_set_destructor(req, wrepl_request_destructor); + state = talloc_zero(result, struct wrepl_connect_state); + if (composite_nomem(state, result)) return result; + result->private_data = state; + state->result = result; + state->wrepl_socket = wrepl_socket; if (!our_ip) { our_ip = iface_best_ip(peer_ip); } - status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip, - WINS_REPLICATION_PORT, 0); - if (NT_STATUS_IS_OK(status)) { - talloc_free(wrepl_socket->fde); - - wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, - socket_get_fd(wrepl_socket->sock), - EVENT_FD_WRITE, - wrepl_handler, wrepl_socket); - if (wrepl_socket->fde == NULL) { - status = NT_STATUS_NO_MEMORY; - } - } - - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - req->wrepl_socket = wrepl_socket; - wrepl_request_trigger(req, status); - return req; - } - - return req; - -failed: - talloc_free(req); - return NULL; + state->creq = socket_connect_send(wrepl_socket->sock, our_ip, 0, + peer_ip, WINS_REPLICATION_PORT, + 0, wrepl_socket->event.ctx); + composite_continue(result, state->creq, wrepl_connect_handler, state); + return result; } /* connect a wrepl_socket to a WINS server - recv side */ -NTSTATUS wrepl_connect_recv(struct wrepl_request *req) +NTSTATUS wrepl_connect_recv(struct composite_context *result) { - return wrepl_request_wait(req); -} + struct wrepl_connect_state *state = talloc_get_type(result->private_data, + struct wrepl_connect_state); + struct wrepl_socket *wrepl_socket = state->wrepl_socket; + NTSTATUS status = composite_wait(result); + if (!NT_STATUS_IS_OK(status)) { + wrepl_socket_dead(wrepl_socket, status); + } + + talloc_free(result); + return status; +} /* connect a wrepl_socket to a WINS server - sync API */ NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *our_ip, const char *peer_ip) { - struct wrepl_request *req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip); - return wrepl_connect_recv(req); + struct composite_context *c_req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip); + return wrepl_connect_recv(c_req); } /* @@ -517,12 +360,13 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed /* trigger an immediate event on a wrepl_request + the return value should only be used in wrepl_request_send() + this is the only place where req->trigger is True */ -static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status) +static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status) { - if (req->state == WREPL_REQUEST_SEND) { - DLIST_REMOVE(req->wrepl_socket->send_queue, req); - } + struct timed_event *te; + if (req->state == WREPL_REQUEST_RECV) { DLIST_REMOVE(req->wrepl_socket->recv_queue, req); } @@ -535,61 +379,119 @@ static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status) req->status = status; - /* a zero timeout means immediate */ - event_add_timed(req->wrepl_socket->event_ctx, - req, timeval_zero(), - wrepl_request_trigger_handler, req); + if (req->trigger) { + req->trigger = False; + /* a zero timeout means immediate */ + te = event_add_timed(req->wrepl_socket->event.ctx, + req, timeval_zero(), + wrepl_request_trigger_handler, req); + if (!te) { + talloc_free(req); + return NULL; + } + return req; + } + + if (req->async.fn) { + req->async.fn(req); + } + return NULL; } +struct wrepl_send_ctrl_state { + struct wrepl_send_ctrl ctrl; + struct wrepl_request *req; + struct wrepl_socket *wrepl_sock; +}; + +static int wrepl_send_ctrl_destructor(void *ptr) +{ + struct wrepl_send_ctrl_state *s = talloc_get_type(ptr, struct wrepl_send_ctrl_state); + struct wrepl_request *req = s->wrepl_sock->recv_queue; + + /* check if the request is still in WREPL_STATE_RECV, + * we need this here because the caller has may called + * talloc_free(req) and wrepl_send_ctrl_state isn't + * a talloc child of the request, so our s->req pointer + * is maybe invalid! + */ + for (; req; req = req->next) { + if (req == s->req) break; + } + if (!req) return 0; + + /* here, we need to make sure the async request handler is called + * later in the next event_loop and now now + */ + req->trigger = True; + wrepl_request_finished(req, NT_STATUS_OK); + + if (s->ctrl.disconnect_after_send) { + wrepl_socket_dead(s->wrepl_sock, NT_STATUS_LOCAL_DISCONNECT); + } + + return 0; +} /* send a generic wins replication request */ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, - struct wrepl_packet *packet) + struct wrepl_packet *packet, + struct wrepl_send_ctrl *ctrl) { struct wrepl_request *req; struct wrepl_wrap wrap; + DATA_BLOB blob; req = talloc_zero(wrepl_socket, struct wrepl_request); - if (req == NULL) goto failed; - + if (!req) return NULL; req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_SEND; - - DLIST_ADD_END(wrepl_socket->send_queue, req, struct wrepl_request *); + req->state = WREPL_REQUEST_RECV; + req->trigger = True; + DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); talloc_set_destructor(req, wrepl_request_destructor); if (wrepl_socket->dead) { - req->wrepl_socket = wrepl_socket; - wrepl_request_trigger(req, NT_STATUS_INVALID_CONNECTION); - return req; + return wrepl_request_finished(req, NT_STATUS_INVALID_CONNECTION); } wrap.packet = *packet; - req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, + req->status = ndr_push_struct_blob(&blob, req, &wrap, (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); - if (!NT_STATUS_IS_OK(req->status)) goto failed; + if (!NT_STATUS_IS_OK(req->status)) { + return wrepl_request_finished(req, req->status); + } if (DEBUGLVL(10)) { - DEBUG(10,("Sending WINS packet of length %d\n", (int)req->buffer.length)); + DEBUG(10,("Sending WINS packet of length %u\n", blob.length)); NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); } if (wrepl_socket->request_timeout > 0) { - req->te = event_add_timed(wrepl_socket->event_ctx, req, + req->te = event_add_timed(wrepl_socket->event.ctx, req, timeval_current_ofs(wrepl_socket->request_timeout, 0), wrepl_request_timeout_handler, req); + if (!req->te) return wrepl_request_finished(req, NT_STATUS_NO_MEMORY); } - EVENT_FD_WRITEABLE(wrepl_socket->fde); - - return req; + if (ctrl && (ctrl->send_only || ctrl->disconnect_after_send)) { + struct wrepl_send_ctrl_state *s = talloc(blob.data, struct wrepl_send_ctrl_state); + if (!s) return wrepl_request_finished(req, NT_STATUS_NO_MEMORY); + s->ctrl = *ctrl; + s->req = req; + s->wrepl_sock = wrepl_socket; + talloc_set_destructor(s, wrepl_send_ctrl_destructor); + } -failed: - talloc_free(req); - return NULL; + req->status = packet_send(wrepl_socket->packet, blob); + if (!NT_STATUS_IS_OK(req->status)) { + return wrepl_request_finished(req, req->status); + } + + req->trigger = False; + return req; } /* @@ -615,7 +517,7 @@ NTSTATUS wrepl_request(struct wrepl_socket *wrepl_socket, struct wrepl_packet *req_packet, struct wrepl_packet **reply_packet) { - struct wrepl_request *req = wrepl_request_send(wrepl_socket, req_packet); + struct wrepl_request *req = wrepl_request_send(wrepl_socket, req_packet, NULL); return wrepl_request_recv(req, mem_ctx, reply_packet); } @@ -637,7 +539,7 @@ struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket, packet->message.start.minor_version = 2; packet->message.start.major_version = 5; - req = wrepl_request_send(wrepl_socket, packet); + req = wrepl_request_send(wrepl_socket, packet, NULL); talloc_free(packet); @@ -683,6 +585,7 @@ struct wrepl_request *wrepl_associate_stop_send(struct wrepl_socket *wrepl_socke { struct wrepl_packet *packet; struct wrepl_request *req; + struct wrepl_send_ctrl ctrl; packet = talloc_zero(wrepl_socket, struct wrepl_packet); if (packet == NULL) return NULL; @@ -692,13 +595,14 @@ struct wrepl_request *wrepl_associate_stop_send(struct wrepl_socket *wrepl_socke packet->mess_type = WREPL_STOP_ASSOCIATION; packet->message.stop.reason = io->in.reason; - req = wrepl_request_send(wrepl_socket, packet); - - if (req && io->in.reason == 0) { - req->send_only = True; - req->disconnect_after_send = True; + ZERO_STRUCT(ctrl); + if (io->in.reason == 0) { + ctrl.send_only = True; + ctrl.disconnect_after_send = True; } + req = wrepl_request_send(wrepl_socket, packet, &ctrl); + talloc_free(packet); return req; @@ -745,7 +649,7 @@ struct wrepl_request *wrepl_pull_table_send(struct wrepl_socket *wrepl_socket, packet->mess_type = WREPL_REPLICATION; packet->message.replication.command = WREPL_REPL_TABLE_QUERY; - req = wrepl_request_send(wrepl_socket, packet); + req = wrepl_request_send(wrepl_socket, packet, NULL); talloc_free(packet); @@ -817,7 +721,7 @@ struct wrepl_request *wrepl_pull_names_send(struct wrepl_socket *wrepl_socket, packet->message.replication.command = WREPL_REPL_SEND_REQUEST; packet->message.replication.info.owner = io->in.partner; - req = wrepl_request_send(wrepl_socket, packet); + req = wrepl_request_send(wrepl_socket, packet, NULL); talloc_free(packet); diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 89a4c642b2..9bedfe7548 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -28,17 +28,16 @@ */ struct wrepl_socket { struct socket_context *sock; - struct event_context *event_ctx; + struct packet_context *packet; - /* a queue of requests pending to be sent */ - struct wrepl_request *send_queue; + struct { + struct event_context *ctx; + struct fd_event *fde; + } event; /* a queue of replies waiting to be received */ struct wrepl_request *recv_queue; - /* the fd event */ - struct fd_event *fde; - /* the default timeout for requests, 0 means no timeout */ #define WREPL_SOCKET_REQUEST_TIMEOUT (60) uint32_t request_timeout; @@ -50,8 +49,13 @@ struct wrepl_socket { BOOL dead; }; +struct wrepl_send_ctrl { + BOOL send_only; + BOOL disconnect_after_send; +}; + enum wrepl_request_state { - WREPL_REQUEST_SEND = 0, + WREPL_REQUEST_INIT = 0, WREPL_REQUEST_RECV = 1, WREPL_REQUEST_DONE = 2, WREPL_REQUEST_ERROR = 3 @@ -65,16 +69,9 @@ struct wrepl_request { struct wrepl_socket *wrepl_socket; enum wrepl_request_state state; + BOOL trigger; NTSTATUS status; - DATA_BLOB buffer; - - BOOL disconnect_after_send; - - BOOL send_only; - - size_t num_read; - struct timed_event *te; struct wrepl_packet *packet; -- cgit From efe67458c17ffa52b48f979505caf11c2ac52c4e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Dec 2005 19:38:12 +0000 Subject: r12216: Couple of small fixes: reduce include/includes.h a bit, simplify headers in build/smb_build/, remove unused pstring macros (This used to be commit 432296207400636dd81d0929ec7b1b4cebbcaa62) --- source4/libcli/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 47b07a353b..cbbc2f4235 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -58,8 +58,8 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 -ADD_OBJ_FILES = \ - cldap/cldap.o +ADD_OBJ_FILES = cldap/cldap.o +PUBLIC_HEADERS = cldap/cldap.h NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP -- cgit From d09a32f5d795ad9ddf6ed5d67f2b1f2b4480dcf0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Dec 2005 18:22:38 +0000 Subject: r12238: don't crash when an error happens while connecting and the packet_context isn't inplace yet metze (This used to be commit 064d9409c3dda25a803fd5ca9ad15c48271e8905) --- source4/libcli/wrepl/winsrepl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 109910be1f..f8e51d925f 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -38,15 +38,18 @@ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status talloc_set_destructor(wrepl_socket, NULL); wrepl_socket->dead = True; - if (wrepl_socket->event.fde) { + if (wrepl_socket->packet) { packet_recv_disable(wrepl_socket->packet); packet_set_fde(wrepl_socket->packet, NULL); + packet_set_socket(wrepl_socket->packet, NULL); + } + + if (wrepl_socket->event.fde) { talloc_free(wrepl_socket->event.fde); wrepl_socket->event.fde = NULL; } if (wrepl_socket->sock) { - packet_set_socket(wrepl_socket->packet, NULL); talloc_free(wrepl_socket->sock); wrepl_socket->sock = NULL; } -- cgit From e55a7077e6526b53b23e2343165006652026de50 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Dec 2005 19:04:45 +0000 Subject: r12240: if the caller isn't interessted in the reply packet, just free it (mostly use for send_only requests, where we don't have a reply at all) metze (This used to be commit a01d5a769c63777232aad89f8c4b5460824ca2b1) --- source4/libcli/wrepl/winsrepl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index f8e51d925f..adb2f09469 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -505,7 +505,7 @@ NTSTATUS wrepl_request_recv(struct wrepl_request *req, struct wrepl_packet **packet) { NTSTATUS status = wrepl_request_wait(req); - if (NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_OK(status) && packet) { *packet = talloc_steal(mem_ctx, req->packet); } talloc_free(req); -- cgit From c0c55a8168b5231c3b7667a82c41709949375402 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Dec 2005 21:27:29 +0000 Subject: r12247: - reject freeing the wrepl_socket inside of wrepl_socket_dead() - free it at the end of wrepl_socket_dead() if needed metze (This used to be commit 58285115c83a3b7bbc9bf52a105cebd11831e9d8) --- source4/libcli/wrepl/winsrepl.c | 10 +++++++++- source4/libcli/wrepl/winsrepl.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index adb2f09469..ead8376834 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -35,7 +35,6 @@ static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, N */ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status) { - talloc_set_destructor(wrepl_socket, NULL); wrepl_socket->dead = True; if (wrepl_socket->packet) { @@ -62,6 +61,11 @@ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status DLIST_REMOVE(wrepl_socket->recv_queue, req); wrepl_request_finished(req, status); } + + talloc_set_destructor(wrepl_socket, NULL); + if (wrepl_socket->free_skipped) { + talloc_free(wrepl_socket); + } } static void wrepl_request_timeout_handler(struct event_context *ev, struct timed_event *te, @@ -135,6 +139,10 @@ static void wrepl_error(void *private, NTSTATUS status) static int wrepl_socket_destructor(void *ptr) { struct wrepl_socket *sock = talloc_get_type(ptr, struct wrepl_socket); + if (sock->dead) { + sock->free_skipped = True; + return -1; + } wrepl_socket_dead(sock, NT_STATUS_LOCAL_DISCONNECT); return 0; } diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 9bedfe7548..e679bef6e6 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -47,6 +47,9 @@ struct wrepl_socket { /* remember is the socket is dead */ BOOL dead; + + /* remember if we need to free the wrepl_socket at the end of wrepl_socket_dead() */ + BOOL free_skipped; }; struct wrepl_send_ctrl { -- cgit From ab31a4421688142690a7903388abeb0786e7f4f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 15 Dec 2005 16:32:08 +0000 Subject: r12254: Add some (hopefully correct) descriptions for libraries that are installed. Install pkg-config files. (This used to be commit a86abe84e2cae7c6188c094a92c6b62aace02fdf) --- source4/libcli/config.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index cbbc2f4235..782dac2dd7 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -34,6 +34,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 +DESCRIPTION = NetBios over TCP/IP client library ADD_OBJ_FILES = \ nbt/nbtname.o \ nbt/nbtsocket.o \ @@ -58,6 +59,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 +DESCRIPTION = CLDAP client library ADD_OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h NOPROTO=YES @@ -67,6 +69,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_LDAP MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 +DESCRIPTION = WINS Replication client library ADD_OBJ_FILES = \ wrepl/winsrepl.o REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS @@ -84,6 +87,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 +DESCRIPTION = SMB/CIFS client library REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 -- cgit From 8cf545b0ae171da891266baba93a7d016890ea93 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 19 Dec 2005 21:19:14 +0000 Subject: r12370: - if we got a reply without a pending request, mark the socket as dead instead of segfaulting metze (This used to be commit 043f5c1054cd2dc95571d601b0872c4cb0d99588) --- source4/libcli/wrepl/winsrepl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index ead8376834..b67138f1dd 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -84,6 +84,11 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) struct wrepl_request *req = wrepl_socket->recv_queue; DATA_BLOB blob; + if (!req) { + DEBUG(1,("Received unexpected WINS packet of length %u!\n", packet_blob_in.length)); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + req->packet = talloc(req, struct wrepl_packet); NT_STATUS_HAVE_NO_MEMORY(req->packet); -- cgit From d8e35f882879e189f55b3bca818dd44cc5f0c6fa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:03:50 +0000 Subject: r12498: Eliminate INIT_OBJ_FILES and ADD_OBJ_FILES. We were not using the difference between these at all, and in the future the fact that INIT_OBJ_FILES include smb_build.h will be sufficient to have recompiles at the right time. (This used to be commit b24f2583edee38abafa58578d8b5c4b43e517def) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.m4 | 2 +- source4/libcli/config.mk | 20 ++++++++++---------- source4/libcli/ldap/config.mk | 2 +- source4/libcli/security/config.mk | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index c97bcd1e73..51d16d8231 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,7 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] -ADD_OBJ_FILES = credentials.o \ +OBJ_FILES = credentials.o \ session.o \ smbencrypt.o REQUIRED_SUBSYSTEMS = \ diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 6e0a88ec35..feb9e79d38 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -5,4 +5,4 @@ if test x"$with_ads_support" = x"yes"; then LIBCLI_RAW_LIBS="KRB5" fi -SMB_SUBSYSTEM(LIBCLI_RAW_KRB5,[], [], [${LIBCLI_RAW_LIBS}]) +SMB_SUBSYSTEM(LIBCLI_RAW_KRB5, [], [${LIBCLI_RAW_LIBS}]) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 782dac2dd7..f76a396852 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,7 +3,7 @@ include ldap/config.mk include security/config.mk [SUBSYSTEM::LIBCLI_UTILS] -ADD_OBJ_FILES = util/asn1.o \ +OBJ_FILES = util/asn1.o \ util/doserr.o \ util/errormap.o \ util/clierror.o \ @@ -11,16 +11,16 @@ ADD_OBJ_FILES = util/asn1.o \ util/smbdes.o [SUBSYSTEM::LIBCLI_LSA] -ADD_OBJ_FILES = util/clilsa.o +OBJ_FILES = util/clilsa.o REQUIRED_SUBSYSTEMS = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_COMPOSITE] -ADD_OBJ_FILES = \ +OBJ_FILES = \ composite/composite.o REQUIRED_SUBSYSTEMS = LIBEVENTS [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] -ADD_OBJ_FILES = \ +OBJ_FILES = \ smb_composite/loadfile.o \ smb_composite/savefile.o \ smb_composite/connect.o \ @@ -35,7 +35,7 @@ MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 DESCRIPTION = NetBios over TCP/IP client library -ADD_OBJ_FILES = \ +OBJ_FILES = \ nbt/nbtname.o \ nbt/nbtsocket.o \ nbt/namequery.o \ @@ -46,7 +46,7 @@ REQUIRED_SUBSYSTEMS = LIBNDR NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ LIB_SECURITY_NDR [SUBSYSTEM::LIBCLI_DGRAM] -ADD_OBJ_FILES = \ +OBJ_FILES = \ dgram/dgramsocket.o \ dgram/mailslot.o \ dgram/netlogon.o \ @@ -60,7 +60,7 @@ MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 DESCRIPTION = CLDAP client library -ADD_OBJ_FILES = cldap/cldap.o +OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP @@ -70,12 +70,12 @@ MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 DESCRIPTION = WINS Replication client library -ADD_OBJ_FILES = \ +OBJ_FILES = \ wrepl/winsrepl.o REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] -ADD_OBJ_FILES = \ +OBJ_FILES = \ resolve/resolve.o \ resolve/nbtlist.o \ resolve/bcast.o \ @@ -94,7 +94,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI SOCKET -ADD_OBJ_FILES = clireadwrite.o \ +OBJ_FILES = clireadwrite.o \ cliconnect.o \ clifile.o \ clilist.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index face7caa66..243de79fce 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -ADD_OBJ_FILES = ldap.o \ +OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ ldap_msg.o \ diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 7faecaf5f2..368a56d2b4 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,14 +1,14 @@ ################################# # Start SUBSYSTEM LIB_SECURITY_NDR_HELPER [SUBSYSTEM::LIB_SECURITY_NDR_HELPER] -ADD_OBJ_FILES = ../../librpc/ndr/ndr_sec_helper.o +OBJ_FILES = ../../librpc/ndr/ndr_sec_helper.o # End SUBSYSTEM LIB_SECURITY_NDR_HELPER ################################# ################################# # Start SUBSYSTEM LIB_SECURITY_NDR [SUBSYSTEM::LIB_SECURITY_NDR] -ADD_OBJ_FILES = ../../librpc/gen_ndr/ndr_security.o +OBJ_FILES = ../../librpc/gen_ndr/ndr_security.o NOPROTO = YES REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR_HELPER # End SUBSYSTEM LIB_SECURITY_NDR @@ -17,7 +17,7 @@ REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR_HELPER ################################# # Start SUBSYSTEM LIB_SECURITY [SUBSYSTEM::LIB_SECURITY] -ADD_OBJ_FILES = security_token.o \ +OBJ_FILES = security_token.o \ security_descriptor.o \ dom_sid.o \ access_check.o \ -- cgit From 09c44f6cae89621871d2e5475b0c0f99c25804b4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 21:58:31 +0000 Subject: r12500: Use init functions explicitly in a few more places. 'gensec' and 'librpc' are the only two subsystems left to convert. (This used to be commit f6bbc72996aeee8607fc583140fd60be0e06e969) --- source4/libcli/auth/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 51d16d8231..75b4180976 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -5,6 +5,6 @@ OBJ_FILES = credentials.o \ session.o \ smbencrypt.o REQUIRED_SUBSYSTEMS = \ - AUTH SCHANNELDB GENSEC + AUTH SCHANNELDB # End SUBSYSTEM LIBCLI_AUTH ################################# -- cgit From acd6a086b341096fcbea1775ce748587fcc8020a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 14:28:01 +0000 Subject: r12510: Change the DCE/RPC interfaces to take a pointer to a dcerpc_interface_table struct rather then a tuple of interface name, UUID and version. This removes the requirement for having a global list of DCE/RPC interfaces, except for these parts of the code that use that list explicitly (ndrdump and the scanner torture test). This should also allow us to remove the hack that put the authservice parameter in the dcerpc_binding struct as it can now be read directly from dcerpc_interface_table. I will now modify some of these functions to take a dcerpc_syntax_id structure rather then a full dcerpc_interface_table. (This used to be commit 8aae0f168e54c01d0866ad6e0da141dbd828574f) --- source4/libcli/util/clilsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index f5de5014e3..3c7850b7fd 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -90,7 +90,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } /* bind to the LSA pipe */ - status = dcerpc_bind_auth_none(lsa->pipe, DCERPC_LSARPC_UUID, DCERPC_LSARPC_VERSION); + status = dcerpc_bind_auth_none(lsa->pipe, &dcerpc_table_lsarpc); if (!NT_STATUS_IS_OK(status)) { talloc_free(lsa); return status; -- cgit From 2cd5ca7d25f12aa9198bf8c2deb6aea282f573ee Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Dec 2005 15:38:36 +0000 Subject: r12542: Move some more prototypes out to seperate headers (This used to be commit 0aca5fd5130d980d07398f3291d294202aefe3c2) --- source4/libcli/clitrans2.c | 1 + source4/libcli/config.mk | 3 +++ source4/libcli/ldap/config.mk | 1 + source4/libcli/ldap/ldap.h | 2 ++ source4/libcli/ldap/ldap_client.c | 1 + source4/libcli/nbt/libnbt.h | 7 +++++++ source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/libcliraw.h | 2 ++ source4/libcli/raw/rawacl.c | 1 + source4/libcli/resolve/host.c | 1 + source4/libcli/resolve/resolve.c | 1 + source4/libcli/security/security_token.c | 1 + source4/libcli/smb2/config.mk | 1 + source4/libcli/smb2/smb2.h | 2 ++ source4/libcli/smb_composite/connect.c | 1 + source4/libcli/wrepl/winsrepl.h | 2 ++ 16 files changed, 28 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 6be92fa17d..c440b25e36 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** send a qpathinfo call diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index f76a396852..c3ebebed41 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -35,6 +35,7 @@ MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 DESCRIPTION = NetBios over TCP/IP client library +PRIVATE_PROTO_HEADER = nbt/nbt_proto.h OBJ_FILES = \ nbt/nbtname.o \ nbt/nbtsocket.o \ @@ -66,6 +67,7 @@ NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP [LIBRARY::LIBCLI_WREPL] +PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h MAJOR_VERSION = 0 MINOR_VERSION = 0 RELEASE_VERSION = 1 @@ -103,6 +105,7 @@ OBJ_FILES = clireadwrite.o \ clideltree.o [SUBSYSTEM::LIBCLI_RAW] +PRIVATE_PROTO_HEADER = raw/raw_proto.h REQUIRED_SUBSYSTEMS = LIBCLI_RAW_KRB5 OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 243de79fce..b9fcb20038 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] +PRIVATE_PROTO_HEADER = ldap_proto.h OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 4f2dbc0787..b6e69ff8e6 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -254,4 +254,6 @@ struct ldap_message { struct ldap_Control *controls; }; +#include "libcli/ldap/ldap_proto.h" + #endif diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 0a787bbf57..1ce86f7f85 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -33,6 +33,7 @@ #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" +#include "auth/gensec/gensec.h" /* diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 218b5e5921..7c9e3e9651 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -20,6 +20,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef __LIBNBT_H__ +#define __LIBNBT_H__ + #include "librpc/gen_ndr/ndr_nbt.h" /* @@ -267,3 +270,7 @@ struct nbt_name_release { uint8_t rcode; } out; }; + +#include "libcli/nbt/nbt_proto.h" + +#endif /* __LIBNBT_H__ */ diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index a0efe7042c..2972da07a0 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -26,6 +26,7 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/stream/packet.h" +#include "libcli/nbt/libnbt.h" /* diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index decee83eb7..b09361b5ff 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -269,3 +269,5 @@ struct smbcli_request { req->status = NT_STATUS_INVALID_PARAMETER; \ goto failed; \ } + +#include "libcli/raw/raw_proto.h" diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index e168da9d1d..ae17447784 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -21,6 +21,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_security.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** fetch file ACL (async send) diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 13503b66b3..f1925ca0d8 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -35,6 +35,7 @@ #include "system/filesys.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "libcli/nbt/libnbt.h" struct host_state { struct nbt_name name; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index bbed931eed..dcbccc0c70 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -24,6 +24,7 @@ #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "libcli/nbt/libnbt.h" struct resolve_state { struct nbt_name name; diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 8e52759e70..e61e2edcf5 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -23,6 +23,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_security.h" +#include "dsdb/samdb/samdb.h" /* return a blank security token diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index a5b7ce2f38..dc4715ffe4 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -1,4 +1,5 @@ [SUBSYSTEM::LIBCLI_SMB2] +PRIVATE_PROTO_HEADER = smb2_proto.h OBJ_FILES = \ transport.o \ request.o \ diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index ceafacf9d4..eb7c10ed9d 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -197,3 +197,5 @@ struct smb2_request { return NT_STATUS_INVALID_PARAMETER; \ } \ } while (0) + +#include "libcli/smb2/smb2_proto.h" diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 785b0d076b..4191c43ca6 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -26,6 +26,7 @@ #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "lib/events/events.h" +#include "libcli/nbt/libnbt.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index e679bef6e6..2fea11bd63 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -154,3 +154,5 @@ struct wrepl_pull_names { } *names; } out; }; + +#include "libcli/wrepl/winsrepl_proto.h" -- cgit From 46aa296cc94933082dbb4b9b2b1ed210a600ad2d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Dec 2005 23:14:33 +0000 Subject: r12592: Remove some useless dependencies (This used to be commit ca8db1a0cd77682ac2c6dc4718f5d753a4fcc4db) --- source4/libcli/config.mk | 6 ++++-- source4/libcli/ldap/config.mk | 3 ++- source4/libcli/security/config.mk | 21 ++------------------- 3 files changed, 8 insertions(+), 22 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c3ebebed41..fb04c32d85 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -30,6 +30,9 @@ OBJ_FILES = \ smb_composite/fsinfo.o REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE +[SUBSYSTEM::NDR_NBT_BUF] +OBJ_FILES = nbt/nbtname.o\ + [LIBRARY::LIBCLI_NBT] MAJOR_VERSION = 0 MINOR_VERSION = 0 @@ -37,14 +40,13 @@ RELEASE_VERSION = 1 DESCRIPTION = NetBios over TCP/IP client library PRIVATE_PROTO_HEADER = nbt/nbt_proto.h OBJ_FILES = \ - nbt/nbtname.o \ nbt/nbtsocket.o \ nbt/namequery.o \ nbt/nameregister.o \ nbt/namerefresh.o \ nbt/namerelease.o REQUIRED_SUBSYSTEMS = LIBNDR NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ - LIB_SECURITY_NDR + NDR_SECURITY [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index b9fcb20038..912cb133bf 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -8,6 +8,7 @@ OBJ_FILES = ldap.o \ ldap_msg.o \ ldap_ndr.o \ ldap_ildap.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR LIBTLS +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET NDR_SAMR LIBTLS \ + LIBPACKET # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 368a56d2b4..a8de499531 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,19 +1,3 @@ -################################# -# Start SUBSYSTEM LIB_SECURITY_NDR_HELPER -[SUBSYSTEM::LIB_SECURITY_NDR_HELPER] -OBJ_FILES = ../../librpc/ndr/ndr_sec_helper.o -# End SUBSYSTEM LIB_SECURITY_NDR_HELPER -################################# - -################################# -# Start SUBSYSTEM LIB_SECURITY_NDR -[SUBSYSTEM::LIB_SECURITY_NDR] -OBJ_FILES = ../../librpc/gen_ndr/ndr_security.o -NOPROTO = YES -REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR_HELPER -# End SUBSYSTEM LIB_SECURITY_NDR -################################# - ################################# # Start SUBSYSTEM LIB_SECURITY [SUBSYSTEM::LIB_SECURITY] @@ -22,8 +6,7 @@ OBJ_FILES = security_token.o \ dom_sid.o \ access_check.o \ privilege.o \ - sddl.o \ - ../../librpc/ndr/ndr_sec.o -REQUIRED_SUBSYSTEMS = LIB_SECURITY_NDR + sddl.o +REQUIRED_SUBSYSTEMS = NDR_SECURITY # End SUBSYSTEM LIB_SECURITY ################################# -- cgit From 964487e4b9925a85b707eafcaff6aca8bd54a846 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Dec 2005 10:45:43 +0000 Subject: r12602: fix compiler warning metze (This used to be commit 82d5bdb1e73dd203cfaf83fdb46c485d212d5c65) --- source4/libcli/wrepl/winsrepl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index b67138f1dd..0409607aa9 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -193,8 +193,8 @@ failed: */ struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, - struct socket_context *socket, - struct packet_context *packet) + struct socket_context *sock, + struct packet_context *pack) { struct wrepl_socket *wrepl_socket; @@ -204,7 +204,7 @@ struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx, wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx); if (wrepl_socket->event.ctx == NULL) goto failed; - wrepl_socket->sock = socket; + wrepl_socket->sock = sock; talloc_steal(wrepl_socket, wrepl_socket->sock); @@ -218,7 +218,7 @@ struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx, goto failed; } - wrepl_socket->packet = packet; + wrepl_socket->packet = pack; talloc_steal(wrepl_socket, wrepl_socket->packet); packet_set_private(wrepl_socket->packet, wrepl_socket); packet_set_socket(wrepl_socket->packet, wrepl_socket->sock); -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/libcli/cldap/cldap.c | 1 - source4/libcli/cliconnect.c | 1 - source4/libcli/composite/composite.c | 1 - source4/libcli/dgram/browse.c | 4 ---- source4/libcli/dgram/dgramsocket.c | 1 - source4/libcli/dgram/mailslot.c | 1 - source4/libcli/dgram/netlogon.c | 5 ----- source4/libcli/dgram/ntlogon.c | 5 ----- source4/libcli/ldap/ldap_bind.c | 1 - source4/libcli/ldap/ldap_client.c | 2 -- source4/libcli/ldap/ldap_ildap.c | 1 - source4/libcli/ldap/ldap_msg.c | 1 - source4/libcli/ldap/ldap_ndr.c | 1 - source4/libcli/raw/clitransport.c | 1 - source4/libcli/raw/clitree.c | 1 - source4/libcli/raw/rawacl.c | 1 - source4/libcli/raw/rawfile.c | 1 - source4/libcli/raw/rawlpq.c | 1 - source4/libcli/resolve/bcast.c | 3 --- source4/libcli/resolve/host.c | 2 -- source4/libcli/resolve/nbtlist.c | 2 -- source4/libcli/resolve/resolve.c | 2 -- source4/libcli/resolve/wins.c | 3 --- source4/libcli/security/access_check.c | 1 - source4/libcli/security/dom_sid.c | 1 - source4/libcli/security/privilege.c | 1 - source4/libcli/security/sddl.c | 1 - source4/libcli/security/security_descriptor.c | 1 - source4/libcli/security/security_token.c | 1 - source4/libcli/smb2/flush.c | 1 - source4/libcli/smb2/ioctl.c | 1 - source4/libcli/smb2/keepalive.c | 2 -- source4/libcli/smb2/logoff.c | 2 -- source4/libcli/smb2/read.c | 1 - source4/libcli/smb2/request.c | 1 - source4/libcli/smb2/tcon.c | 1 - source4/libcli/smb2/tdis.c | 2 -- source4/libcli/smb2/write.c | 1 - source4/libcli/smb_composite/appendacl.c | 1 - source4/libcli/smb_composite/connect.c | 1 - source4/libcli/smb_composite/fetchfile.c | 1 - source4/libcli/smb_composite/fsinfo.c | 1 - source4/libcli/smb_composite/loadfile.c | 1 - source4/libcli/smb_composite/savefile.c | 1 - source4/libcli/util/smbdes.c | 1 - 45 files changed, 67 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 07744553c8..d406b50baf 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -38,7 +38,6 @@ #include "libcli/ldap/ldap.h" #include "libcli/cldap/cldap.h" #include "lib/socket/socket.h" -#include "include/asn_1.h" /* destroy a pending request diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index c344ece385..220b5a3898 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -22,7 +22,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" /* diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index c9cc20e923..33b5b77c06 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -26,7 +26,6 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "lib/messaging/irpc.h" -#include "libcli/nbt/libnbt.h" /* block until a composite function has completed, then return the status diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index d6813b36b9..821bf9d815 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -22,11 +22,7 @@ */ #include "includes.h" -#include "lib/events/events.h" -#include "libcli/nbt/libnbt.h" #include "libcli/dgram/libdgram.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, const struct nbt_peer_socket *dest, diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 6c6a45f48e..143b9c309b 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -23,7 +23,6 @@ #include "includes.h" #include "lib/events/events.h" #include "dlinklist.h" -#include "libcli/nbt/libnbt.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index d521484422..0e6b99c3e3 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -35,7 +35,6 @@ #include "includes.h" #include "lib/events/events.h" #include "dlinklist.h" -#include "libcli/nbt/libnbt.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 0627fe900c..dffeae2007 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -21,12 +21,7 @@ */ #include "includes.h" -#include "lib/events/events.h" -#include "dlinklist.h" -#include "libcli/nbt/libnbt.h" #include "libcli/dgram/libdgram.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" /* send a netlogon mailslot request diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 2bdce6f853..3205416cea 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -21,12 +21,7 @@ */ #include "includes.h" -#include "lib/events/events.h" -#include "dlinklist.h" -#include "libcli/nbt/libnbt.h" #include "libcli/dgram/libdgram.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" /* send a ntlogon mailslot request diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 766416f575..6b1c321d49 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -23,7 +23,6 @@ */ #include "includes.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "auth/auth.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 1ce86f7f85..77fc7db049 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -28,8 +28,6 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" -#include "lib/tls/tls.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 666cc02536..f29685a67c 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" /* diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 9b531f3138..c77d9eb356 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -23,7 +23,6 @@ */ #include "includes.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 0cccdbe971..1d5e4ccf20 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -23,7 +23,6 @@ #include "includes.h" #include "libcli/ldap/ldap.h" -#include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" /* diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 2972da07a0..a0efe7042c 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -26,7 +26,6 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/stream/packet.h" -#include "libcli/nbt/libnbt.h" /* diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 96d36c569c..6e120ed615 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -23,7 +23,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index ae17447784..08515eadde 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" #include "libcli/raw/libcliraw.h" /**************************************************************************** diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index c6652125c2..6981a76800 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -22,7 +22,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" -#include "librpc/gen_ndr/ndr_security.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/rawlpq.c b/source4/libcli/raw/rawlpq.c index e83ee48707..40669e51de 100644 --- a/source4/libcli/raw/rawlpq.c +++ b/source4/libcli/raw/rawlpq.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" /**************************************************************************** lpq - async send diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index c47bba38c5..c95fe945b1 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -21,9 +21,6 @@ */ #include "includes.h" -#include "system/network.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" /* broadcast name resolution method - async send diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index f1925ca0d8..c283f0fda1 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -33,9 +33,7 @@ #include "lib/events/events.h" #include "system/network.h" #include "system/filesys.h" -#include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -#include "libcli/nbt/libnbt.h" struct host_state { struct nbt_name name; diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index f8fe5df9a1..3af40c1b24 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -25,8 +25,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" struct nbtlist_state { diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index dcbccc0c70..d3d197e567 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -22,9 +22,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -#include "libcli/nbt/libnbt.h" struct resolve_state { struct nbt_name name; diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index aa4ec0cea4..b2e0ddae6f 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -21,9 +21,6 @@ */ #include "includes.h" -#include "system/network.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" /* wins name resolution method - async send diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 0ffca1ade8..00275d8824 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" /* diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index c19959f8ae..646a513df5 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" /***************************************************************** Compare the auth portion of two sids. diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index aa01dc2c65..fec8c1278c 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" static const struct { diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 83dfeed5ac..c434072529 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -22,7 +22,6 @@ #include "includes.h" #include "system/iconv.h" -#include "librpc/gen_ndr/ndr_security.h" struct flag_map { const char *name; diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 91448e7c35..64983e20d0 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" /* return a blank security descriptor (no owners, dacl or sacl) diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index e61e2edcf5..04d10bf83b 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" #include "dsdb/samdb/samdb.h" /* diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index f5d623c69c..d9178aeb9f 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index 37e07dbae1..533f12c9d3 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index 4017623a61..99d9dd3ae9 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -21,9 +21,7 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "libcli/smb2/smb2_calls.h" /* send a keepalive request diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index febe0d6b45..ba0e691e8b 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -21,9 +21,7 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "libcli/smb2/smb2_calls.h" /* send a logoff request diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index 8709aa6ce2..da2d3bb7c9 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 03c0ed4350..9fe9ad12fa 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -24,7 +24,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "libcli/smb2/smb2_calls.h" #include "include/dlinklist.h" #include "lib/events/events.h" diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index ddc4babeea..3fc14075a5 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c index c08370d9e0..7d1f7aee4e 100644 --- a/source4/libcli/smb2/tdis.c +++ b/source4/libcli/smb2/tdis.c @@ -21,9 +21,7 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "libcli/smb2/smb2_calls.h" /* send a tdis request diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index 591cf2c891..adf690c1b3 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index b47a41a43b..c68c0a185d 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -2,7 +2,6 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" -#include "librpc/gen_ndr/ndr_security.h" /* the stages of this call */ enum appendacl_stage {APPENDACL_OPENPATH, APPENDACL_GET, diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 4191c43ca6..785b0d076b 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -26,7 +26,6 @@ #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "lib/events/events.h" -#include "libcli/nbt/libnbt.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index a885aaa911..5783a3258f 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index 1d3860e5c6..e81e3a2085 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -6,7 +6,6 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" -#include "librpc/gen_ndr/ndr_security.h" /* the stages of this call */ enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY}; diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index 93122e287f..2551b6da9e 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -25,7 +25,6 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" -#include "librpc/gen_ndr/ndr_security.h" /* the stages of this call */ enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE}; diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c index 0e11031dab..9600af97d2 100644 --- a/source4/libcli/smb_composite/savefile.c +++ b/source4/libcli/smb_composite/savefile.c @@ -25,7 +25,6 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" -#include "librpc/gen_ndr/ndr_security.h" /* the stages of this call */ enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE}; diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c index d02cae602f..d392109b1e 100644 --- a/source4/libcli/util/smbdes.c +++ b/source4/libcli/util/smbdes.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "lib/crypto/crypto.h" /* NOTES: -- cgit From bc4aebfaecf52678eb40aee2fd4bd81a315c554d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 2 Jan 2006 00:16:08 +0000 Subject: r12670: Make a couple of dependencies stricter Re-introduce and use the OUTPUT_TYPE property for MODULEs to force specific modules to always be included (This used to be commit f9eede3d40098eddc3618ee48f9253cdddb94a6f) --- source4/libcli/auth/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 75b4180976..0d8c21d527 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -5,6 +5,6 @@ OBJ_FILES = credentials.o \ session.o \ smbencrypt.o REQUIRED_SUBSYSTEMS = \ - AUTH SCHANNELDB + AUTH SCHANNELDB gensec_ntlmssp # End SUBSYSTEM LIBCLI_AUTH ################################# -- cgit From 78c50015bb8bd5a1d831a6e7ec796b3367c73145 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 15:40:05 +0000 Subject: r12694: Move some headers to the directory of the subsystem they belong to. (This used to be commit c722f665c90103f3ed57621c460e32ad33e7a8a3) --- source4/libcli/auth/smbencrypt.c | 1 + source4/libcli/cldap/cldap.h | 2 +- source4/libcli/cliconnect.c | 1 + source4/libcli/clideltree.c | 3 ++- source4/libcli/clilist.c | 2 +- source4/libcli/config.mk | 1 + source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/libcli.h | 45 +++++++++++++++++++++++++++++++++ source4/libcli/raw/libcliraw.h | 1 + source4/libcli/raw/rawfile.c | 1 + source4/libcli/raw/smb_signing.c | 1 + source4/libcli/smb2/smb2.h | 2 ++ source4/libcli/util/asn1.c | 2 +- source4/libcli/util/asn_1.h | 53 +++++++++++++++++++++++++++++++++++++++ source4/libcli/util/clilsa.c | 1 + 16 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 source4/libcli/libcli.h create mode 100644 source4/libcli/util/asn_1.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index b031bf4886..6bc9de2f2b 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -24,6 +24,7 @@ #include "includes.h" #include "system/time.h" +#include "smb.h" #include "auth/ntlmssp/ntlmssp.h" #include "lib/crypto/crypto.h" #include "pstring.h" diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 632dbd1f65..e1f59464e5 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "asn_1.h" +#include "libcli/util/asn_1.h" #include "librpc/gen_ndr/ndr_nbt.h" enum cldap_request_state {CLDAP_REQUEST_SEND, diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 220b5a3898..fe0ad9c9f5 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb_composite/smb_composite.h" diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 30369b977f..0c65d993c8 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -19,7 +19,8 @@ */ #include "includes.h" -#include "clilist.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" struct delete_state { struct smbcli_tree *tree; diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 0d69a386eb..f18ec84db9 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "clilist.h" +#include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" struct search_private { diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index fb04c32d85..20219be0f4 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -98,6 +98,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI SOCKET +PRIVATE_PROTO_HEADER = libcli_proto.h OBJ_FILES = clireadwrite.o \ cliconnect.o \ clifile.o \ diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 3cfbe3a1e1..c699820cea 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,7 +25,7 @@ #include "includes.h" #include "system/iconv.h" -#include "asn_1.h" +#include "libcli/util/asn_1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 77fc7db049..9b1a4ef9d5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -24,7 +24,7 @@ */ #include "includes.h" -#include "asn_1.h" +#include "libcli/util/asn_1.h" #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h new file mode 100644 index 0000000000..917ab27519 --- /dev/null +++ b/source4/libcli/libcli.h @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup + Copyright (C) Andrew Tridgell 2004 + Copyright (C) James Myers 2003 + + 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 "smb.h" + +/* + smbcli_state: internal state used in libcli library for single-threaded callers, + i.e. a single session on a single socket. + */ +struct smbcli_state { + struct smbcli_transport *transport; + struct smbcli_session *session; + struct smbcli_tree *tree; + struct substitute_context *substitute; + struct smblsa_state *lsa; +}; + +struct clilist_file_info { + uint64_t size; + uint16_t attrib; + time_t mtime; + const char *name; + const char *short_name; +}; + + +#include "libcli/libcli_proto.h" diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index b09361b5ff..7eb0694bd2 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -21,6 +21,7 @@ */ #include "request.h" +#include "smb.h" #include "librpc/gen_ndr/ndr_nbt.h" struct smbcli_tree; /* forward declare */ diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 6981a76800..0cc7385cee 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "smb.h" #include "libcli/raw/libcliraw.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index df63c33cb9..a73db78f7b 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "smb.h" #include "libcli/raw/libcliraw.h" #include "lib/crypto/crypto.h" diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index eb7c10ed9d..cf84f34442 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "smb.h" + struct smb2_options { uint32_t timeout; }; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 0dceb1bba6..db3f7823fa 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -19,7 +19,7 @@ */ #include "includes.h" -#include "asn_1.h" +#include "libcli/util/asn_1.h" /* free an asn1 structure */ void asn1_free(struct asn1_data *data) diff --git a/source4/libcli/util/asn_1.h b/source4/libcli/util/asn_1.h new file mode 100644 index 0000000000..2dc9bef06d --- /dev/null +++ b/source4/libcli/util/asn_1.h @@ -0,0 +1,53 @@ +/* + Unix SMB/CIFS implementation. + simple ASN1 code + Copyright (C) Andrew Tridgell 2001 + + 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. +*/ + +#ifndef _ASN_1_H +#define _ASN_1_H + +struct nesting { + off_t start; + size_t taglen; /* for parsing */ + struct nesting *next; +}; + +struct asn1_data { + uint8_t *data; + size_t length; + off_t ofs; + struct nesting *nesting; + BOOL has_error; +}; + +#define ASN1_APPLICATION(x) ((x)+0x60) +#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40) +#define ASN1_SEQUENCE(x) ((x)+0x30) +#define ASN1_CONTEXT(x) ((x)+0xa0) +#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80) +#define ASN1_GENERAL_STRING 0x1b +#define ASN1_OCTET_STRING 0x4 +#define ASN1_OID 0x6 +#define ASN1_BOOLEAN 0x1 +#define ASN1_INTEGER 0x2 +#define ASN1_ENUMERATED 0xa +#define ASN1_SET 0x31 + +#define ASN1_MAX_OIDS 20 + +#endif /* _ASN_1_H */ diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 3c7850b7fd..bf5048b02a 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -28,6 +28,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" #include "librpc/gen_ndr/ndr_lsa.h" struct smblsa_state { -- cgit From 63d718e243fd03e6ea24c47e7442975ec088a5b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 17:27:33 +0000 Subject: r12696: Reduce the size of include/structs.h (This used to be commit 63917616016133c623fc6ff59454bc313ee7dd8f) --- source4/libcli/cldap/cldap.h | 2 ++ source4/libcli/smb2/keepalive.c | 1 + source4/libcli/smb2/logoff.c | 1 + source4/libcli/smb2/smb2.h | 2 -- source4/libcli/smb2/smb2_calls.h | 2 ++ source4/libcli/smb2/tdis.c | 1 + source4/libcli/smb2/transport.c | 1 + 7 files changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index e1f59464e5..0baaec02df 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -23,6 +23,8 @@ #include "libcli/util/asn_1.h" #include "librpc/gen_ndr/ndr_nbt.h" +struct ldap_message; + enum cldap_request_state {CLDAP_REQUEST_SEND, CLDAP_REQUEST_WAIT, CLDAP_REQUEST_DONE, diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index 99d9dd3ae9..b800bdb3b1 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* send a keepalive request diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index ba0e691e8b..977c1e57af 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* send a logoff request diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index cf84f34442..913d58409b 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -199,5 +199,3 @@ struct smb2_request { return NT_STATUS_INVALID_PARAMETER; \ } \ } while (0) - -#include "libcli/smb2/smb2_proto.h" diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 08e765ad60..7349b609cb 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -361,3 +361,5 @@ struct smb2_flush { struct smb2_handle handle; } in; }; + +#include "libcli/smb2/smb2_proto.h" diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c index 7d1f7aee4e..9ea58113b3 100644 --- a/source4/libcli/smb2/tdis.c +++ b/source4/libcli/smb2/tdis.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* send a tdis request diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 60dd5d2ba6..d5591fa11c 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" #include "lib/socket/socket.h" #include "lib/events/events.h" #include "lib/stream/packet.h" -- cgit From db04cffbbfe15a52b954960ff0eb40d2a5e4f00d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Jan 2006 16:43:56 +0000 Subject: r12725: some minor updates metze (This used to be commit f2e97983f278211c6d70400ce1f43d6a69df0d8a) --- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/smb2/transport.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index a0efe7042c..df5c608d08 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -184,7 +184,7 @@ struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *tr memcpy(p, calling_blob.data, calling_blob.length); p += calling_blob.length; - _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer)-4); + _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer) - NBT_HDR_SIZE); SCVAL(req->out.buffer,0,0x81); if (!smbcli_request_send(req)) { diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index d5591fa11c..6567ad4de7 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -272,7 +272,7 @@ void smb2_transport_send(struct smb2_request *req) DATA_BLOB blob; NTSTATUS status; - _smb_setlen2(req->out.buffer, req->out.size - NBT_HDR_SIZE); + _smb2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); DEBUG(2, ("SMB2 send seqnum=0x%llx\n", (long long)req->seqnum)); dump_data(5, req->out.body, req->out.body_size); -- cgit From c908d0b2aa111659e57a73efb8c33c413965c846 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 6 Jan 2006 04:01:23 +0000 Subject: r12733: Merge ldap/ldb controls into main tree There's still lot of work to do but the patch is stable enough to be pushed into the main samba4 tree. Simo. (This used to be commit 77125feaff252cab44d26593093a9c211c846ce8) --- source4/libcli/cldap/cldap.c | 2 - source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 39 +-- source4/libcli/ldap/ldap.h | 7 +- source4/libcli/ldap/ldap_bind.c | 5 +- source4/libcli/ldap/ldap_client.c | 1 + source4/libcli/ldap/ldap_controls.c | 470 ++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_ildap.c | 14 +- source4/libcli/ldap/ldap_msg.c | 3 +- source4/libcli/ldap/ldap_ndr.c | 1 + 10 files changed, 518 insertions(+), 27 deletions(-) create mode 100644 source4/libcli/ldap/ldap_controls.c (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index d406b50baf..a6710cf32c 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -319,7 +319,6 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, if (msg == NULL) goto failed; msg->messageid = req->message_id; msg->type = LDAP_TAG_SearchRequest; - msg->num_controls = 0; msg->controls = NULL; search = &msg->r.SearchRequest; @@ -380,7 +379,6 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg = talloc(req, struct ldap_message); if (msg == NULL) goto failed; msg->messageid = io->messageid; - msg->num_controls = 0; msg->controls = NULL; if (io->response) { diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 912cb133bf..59d2d1ea30 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -7,7 +7,8 @@ OBJ_FILES = ldap.o \ ldap_bind.o \ ldap_msg.o \ ldap_ndr.o \ - ldap_ildap.o + ldap_ildap.o \ + ldap_controls.o REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET NDR_SAMR LIBTLS \ LIBPACKET # End SUBSYSTEM LIBCLI_LDAP diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c699820cea..d021fc3bd6 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -455,6 +455,18 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct return False; } + if (msg->controls != NULL) { + asn1_push_tag(&data, ASN1_CONTEXT(0)); + + for (i = 0; msg->controls[i] != NULL; i++) { + if (!ldap_encode_control(mem_ctx, &data, msg->controls[i])) { + return False; + } + } + + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); if (data.has_error) { @@ -1243,42 +1255,35 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) return False; } - msg->num_controls = 0; msg->controls = NULL; if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { int i; - struct ldap_Control *ctrl = NULL; + struct ldap_Control **ctrl = NULL; asn1_start_tag(data, ASN1_CONTEXT(0)); for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { asn1_start_tag(data, ASN1_SEQUENCE(0)); - ctrl = talloc_realloc(msg, ctrl, struct ldap_Control, i+1); + ctrl = talloc_realloc(msg, ctrl, struct ldap_Control *, i+2); if (!ctrl) { return False; } - ctrl[i].oid = NULL; - ctrl[i].critical = False; - ctrl[i].value = data_blob(NULL, 0); - asn1_read_OctetString_talloc(ctrl, data, &ctrl[i].oid); - - if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - asn1_read_BOOLEAN(data, &ctrl[i].critical); + ctrl[i] = talloc(ctrl, struct ldap_Control); + if (!ctrl[i]) { + return False; } - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - asn1_read_OctetString(data, &ctrl[i].value); - if (ctrl[i].value.data) { - talloc_steal(msg, ctrl[i].value.data); - } + if (!ldap_decode_control(ctrl, data, ctrl[i])) { + return False; } - asn1_end_tag(data); } - msg->num_controls = i; + + ctrl[i] = NULL; + msg->controls = ctrl; asn1_end_tag(data); diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index b6e69ff8e6..5283553f13 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -243,15 +243,14 @@ union ldap_Request { struct ldap_Control { const char *oid; BOOL critical; - DATA_BLOB value; + void *value; }; struct ldap_message { - uint32_t messageid; + int messageid; enum ldap_request_tag type; union ldap_Request r; - int num_controls; - struct ldap_Control *controls; + struct ldap_Control **controls; }; #include "libcli/ldap/ldap_proto.h" diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 6b1c321d49..1f6ef77631 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "auth/auth.h" @@ -41,6 +42,7 @@ static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *con res->r.BindRequest.dn = talloc_strdup(res, dn); res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; res->r.BindRequest.creds.password = talloc_strdup(res, pw); + res->controls = NULL; return res; } @@ -128,6 +130,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism); res->r.BindRequest.creds.SASL.secblob = *secblob; + res->controls = NULL; return res; } @@ -186,7 +189,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, - False, &sasl_mechs_msgs); + False, NULL, NULL, &sasl_mechs_msgs); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", nt_errstr(status))); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 9b1a4ef9d5..9103e939e7 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -28,6 +28,7 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" +#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c new file mode 100644 index 0000000000..55e7a94aa7 --- /dev/null +++ b/source4/libcli/ldap/ldap_controls.c @@ -0,0 +1,470 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Simo Sorce 2005 + + 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 "system/iconv.h" +#include "libcli/util/asn_1.h" +#include "libcli/ldap/ldap.h" +#include "lib/ldb/include/ldb.h" + +struct control_handler { + const char *oid; + BOOL (*decode)(void *mem_ctx, DATA_BLOB in, void **out); + BOOL (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); +}; + +static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB attr; + struct asn1_data data; + struct ldb_sort_resp_control *lsrc; + + if (!asn1_load(&data, in)) { + return False; + } + + lsrc = talloc(mem_ctx, struct ldb_sort_resp_control); + if (!lsrc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_enumerated(&data, &(lsrc->result))) { + return False; + } + + lsrc->attr_desc = NULL; + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(&data, &attr)) { + return False; + } + lsrc->attr_desc = talloc_strndup(lsrc, attr.data, attr.length); + if (!lsrc->attr_desc) { + return False; + } + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lsrc; + + return True; +} + +static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB attr; + DATA_BLOB rule; + struct asn1_data data; + struct ldb_server_sort_control **lssc; + int num; + + if (!asn1_load(&data, in)) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + lssc = NULL; + + for (num = 0; asn1_peek_tag(&data, ASN1_SEQUENCE(0)); num++) { + lssc = talloc_realloc(mem_ctx, lssc, struct ldb_server_sort_control *, num + 2); + if (!lssc) { + return False; + } + lssc[num] = talloc(lssc, struct ldb_server_sort_control); + if (!lssc[num]) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_OctetString(&data, &attr)) { + return False; + } + + lssc[num]->attributeName = talloc_strndup(lssc[num], attr.data, attr.length); + if (!lssc [num]->attributeName) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(&data, &rule)) { + return False; + } + lssc[num]->orderingRule = talloc_strndup(lssc[num], rule.data, rule.length); + if (!lssc[num]->orderingRule) { + return False; + } + } + + if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { + if (!asn1_read_BOOLEAN(&data, &(lssc[num]->reverse))) { + return False; + } + } + + if (!asn1_end_tag(&data)) { + return False; + } + } + + lssc[num] = NULL; + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lssc; + + return True; +} + +static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + struct asn1_data data; + struct ldb_extended_dn_control *ledc; + + if (!asn1_load(&data, in)) { + return False; + } + + ledc = talloc(mem_ctx, struct ldb_extended_dn_control); + if (!ledc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(ledc->type))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = ledc; + + return True; +} + +static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB cookie; + struct asn1_data data; + struct ldb_paged_control *lprc; + + if (!asn1_load(&data, in)) { + return False; + } + + lprc = talloc(mem_ctx, struct ldb_paged_control); + if (!lprc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lprc->size))) { + return False; + } + + if (!asn1_read_OctetString(&data, &cookie)) { + return False; + } + lprc->cookie_len = cookie.length; + if (lprc->cookie_len) { + lprc->cookie = talloc_memdup(lprc, cookie.data, cookie.length); + + if (!(lprc->cookie)) { + return False; + } + } else { + lprc->cookie = NULL; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lprc; + + return True; +} + +static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_enumerated(&data, lsrc->result)) { + return False; + } + + if (lsrc->attr_desc) { + if (!asn1_write_OctetString(&data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { + return False; + } + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + +static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *); + struct asn1_data data; + int num; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + for (num = 0; lssc[num]; num++) { + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_OctetString(&data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { + return False; + } + + if (lssc[num]->orderingRule) { + if (!asn1_write_OctetString(&data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) { + return False; + } + } + + if (lssc[num]->reverse) { + if (!asn1_write_BOOLEAN(&data, lssc[num]->reverse)) { + return False; + } + } + + if (!asn1_pop_tag(&data)) { + return False; + } + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + +static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, ledc->type)) { + return False; + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + +static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lprc->size)) { + return False; + } + + if (!asn1_write_OctetString(&data, lprc->cookie, lprc->cookie_len)) { + return False; + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + +struct control_handler ldap_known_controls[] = { + { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, + { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, + { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, + { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response }, + { NULL, NULL, NULL } +}; + +BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl) +{ + int i; + DATA_BLOB oid; + DATA_BLOB value; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_OctetString(data, &oid)) { + return False; + } + ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); + if (!(ctrl->oid)) { + return False; + } + + if (asn1_peek_tag(data, ASN1_BOOLEAN)) { + if (!asn1_read_BOOLEAN(data, &(ctrl->critical))) { + return False; + } + } else { + ctrl->critical = False; + } + + ctrl->value = NULL; + + for (i = 0; ldap_known_controls[i].oid != NULL; i++) { + if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { + + if (!asn1_read_OctetString(data, &value)) { + return False; + } + if (!ldap_known_controls[i].decode(mem_ctx, value, &(ctrl->value))) { + return False; + } + break; + } + } + if (ldap_known_controls[i].oid == NULL) { + return False; + } + + if (!asn1_end_tag(data)) { + return False; + } + + return True; +} + +BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl) +{ + DATA_BLOB value; + int i; + + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { + return False; + } + + if (ctrl->critical) { + if (!asn1_write_BOOLEAN(data, ctrl->critical)) { + return False; + } + } + + for (i = 0; ldap_known_controls[i].oid != NULL; i++) { + if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { + if (!ldap_known_controls[i].encode(mem_ctx, ctrl->value, &value)) { + return False; + } + break; + } + } + if (ldap_known_controls[i].oid == NULL) { + return False; + } + + if (value.length != 0) { + if (!asn1_write_OctetString(data, value.data, value.length)) { + return False; + } + } + + if (!asn1_pop_tag(data)) { + return False; + } + + return True; +} diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index f29685a67c..a5227ec37f 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" /* @@ -156,6 +157,8 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, int scope, struct ldb_parse_tree *tree, const char * const *attrs, BOOL attributesonly, + struct ldap_Control **control_req, + struct ldap_Control ***control_res, struct ldap_message ***results) { struct ldap_message *msg; @@ -163,6 +166,8 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, NTSTATUS status; struct ldap_request *req; + if (control_res) + *control_res = NULL; *results = NULL; msg = new_ldap_message(conn); @@ -180,6 +185,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, msg->r.SearchRequest.tree = tree; msg->r.SearchRequest.num_attributes = n; msg->r.SearchRequest.attributes = discard_const(attrs); + msg->controls = control_req; req = ldap_request_send(conn, msg); talloc_steal(msg, req); @@ -191,6 +197,9 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, if (res->type == LDAP_TAG_SearchResultDone) { status = ldap_check_response(conn, &res->r.GeneralResult); + if (control_res) { + *control_res = talloc_steal(conn, res->controls); + } break; } @@ -219,12 +228,15 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, int scope, const char *expression, const char * const *attrs, BOOL attributesonly, + struct ldap_Control **control_req, + struct ldap_Control ***control_res, struct ldap_message ***results) { struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); NTSTATUS status; status = ildap_search_bytree(conn, basedn, scope, tree, attrs, - attributesonly, results); + attributesonly, control_req, + control_res, results); talloc_free(tree); return status; } diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index c77d9eb356..d74aa500ca 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -23,12 +23,13 @@ */ #include "includes.h" +#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { - return talloc(mem_ctx, struct ldap_message); + return talloc_zero(mem_ctx, struct ldap_message); } diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 1d5e4ccf20..0cccdbe971 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/ldap/ldap.h" +#include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" /* -- cgit From 66700b484f674d66692f4a5a498f511f69db7faa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Jan 2006 21:20:09 +0000 Subject: r12747: Add a couple more token tests, used by the kludge ACL module. Andrew Bartlett (This used to be commit 10eadf48124d61f2eb586fb277a66aa4b9e6cad3) --- source4/libcli/security/security_token.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 04d10bf83b..6774894a86 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -190,3 +190,33 @@ BOOL is_anonymous_token(struct security_token *token) return False; } +BOOL is_authenticated_token(struct security_token *token) +{ + TALLOC_CTX *mem_ctx = talloc_new(token); + int i; + struct dom_sid *authenticated = dom_sid_parse_talloc(mem_ctx, SID_NT_ANONYMOUS); + for (i = 0; i < token->num_sids; i++) { + if (dom_sid_equal(token->sids[i], authenticated)) { + talloc_free(mem_ctx); + return True; + } + } + talloc_free(mem_ctx); + return False; +} + +BOOL is_administrator_token(struct security_token *token) +{ + TALLOC_CTX *mem_ctx = talloc_new(token); + int i; + struct dom_sid *administrators = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN_ADMINISTRATORS); + for (i = 0; i < token->num_sids; i++) { + if (dom_sid_equal(token->sids[i], administrators)) { + talloc_free(mem_ctx); + return True; + } + } + talloc_free(mem_ctx); + return False; +} + -- cgit From 5c8447773f306e302c7182611e4fc03978c340b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 9 Jan 2006 21:44:30 +0000 Subject: r12801: Some more include/ cleanups (remove unused macros + move files to specific dirs) (This used to be commit 243cf760b077e155f5ac508aeebf819f7708a84e) --- source4/libcli/raw/libcliraw.h | 2 +- source4/libcli/raw/request.h | 62 ++++++++++++++++++++++++++++++++++++++++++ source4/libcli/raw/signing.h | 40 +++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/raw/request.h create mode 100644 source4/libcli/raw/signing.h (limited to 'source4/libcli') diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 7eb0694bd2..96a06b9bec 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "request.h" +#include "libcli/raw/request.h" #include "smb.h" #include "librpc/gen_ndr/ndr_nbt.h" diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h new file mode 100644 index 0000000000..4a569cfe66 --- /dev/null +++ b/source4/libcli/raw/request.h @@ -0,0 +1,62 @@ +#ifndef _REQUEST_H +#define _REQUEST_H +/* + Unix SMB/CIFS implementation. + SMB parameters and setup + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James Myers 2003 + + 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 "libcli/raw/signing.h" + +/* + Shared state structure between client and server, representing the basic packet. +*/ + +struct request_buffer { + /* the raw SMB buffer, including the 4 byte length header */ + uint8_t *buffer; + + /* the size of the raw buffer, including 4 byte header */ + uint_t size; + + /* how much has been allocated - on reply the buffer is over-allocated to + prevent too many realloc() calls + */ + uint_t allocated; + + /* the start of the SMB header - this is always buffer+4 */ + uint8_t *hdr; + + /* the command words and command word count. vwv points + into the raw buffer */ + uint8_t *vwv; + uint_t wct; + + /* the data buffer and size. data points into the raw buffer */ + uint8_t *data; + uint_t data_size; + + /* ptr is used as a moving pointer into the data area + * of the packet. The reason its here and not a local + * variable in each function is that when a realloc of + * a send packet is done we need to move this + * pointer */ + uint8_t *ptr; +}; + +#endif diff --git a/source4/libcli/raw/signing.h b/source4/libcli/raw/signing.h new file mode 100644 index 0000000000..dfc5a4bd7e --- /dev/null +++ b/source4/libcli/raw/signing.h @@ -0,0 +1,40 @@ +#ifndef _SIGNING_H +#define _SIGNING_H +/* + Unix SMB/CIFS implementation. + SMB Signing + + Andrew Bartlett 2003-2004 + + 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. +*/ + +enum smb_signing_engine_state { + SMB_SIGNING_ENGINE_OFF, + SMB_SIGNING_ENGINE_BSRSPYL, + SMB_SIGNING_ENGINE_ON +}; + +struct smb_signing_context { + enum smb_signing_engine_state signing_state; + DATA_BLOB mac_key; + uint32_t next_seq_num; + BOOL allow_smb_signing; + BOOL doing_signing; + BOOL mandatory_signing; + BOOL seen_valid; /* Have I ever seen a validly signed packet? */ +}; + +#endif -- cgit From f55ea8bb3dca868e21663cd90eaea7a35cd7886c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 9 Jan 2006 22:12:53 +0000 Subject: r12804: This patch reworks the Samba4 sockets layer to use a socket_address structure that is more generic than just 'IP/port'. It now passes make test, and has been reviewed and updated by metze. (Thankyou *very* much). This passes 'make test' as well as kerberos use (not currently in the testsuite). The original purpose of this patch was to have Samba able to pass a socket address stucture from the BSD layer into the kerberos routines and back again. It also removes nbt_peer_addr, which was being used for a similar purpose. It is a large change, but worthwhile I feel. Andrew Bartlett (This used to be commit 88198c4881d8620a37086f80e4da5a5b71c5bbb2) --- source4/libcli/cldap/cldap.c | 47 +++++++++++++++++--------------------- source4/libcli/cldap/cldap.h | 14 +++++------- source4/libcli/dgram/browse.c | 16 +++++++++---- source4/libcli/dgram/dgramsocket.c | 24 +++++++++---------- source4/libcli/dgram/libdgram.h | 24 +++++++++---------- source4/libcli/dgram/mailslot.c | 25 ++++++++++++++------ source4/libcli/dgram/netlogon.c | 16 +++++++++---- source4/libcli/dgram/ntlogon.c | 17 ++++++++++---- source4/libcli/nbt/libnbt.h | 14 ++++-------- source4/libcli/nbt/namequery.c | 24 ++++++++++--------- source4/libcli/nbt/namerefresh.c | 12 ++++++---- source4/libcli/nbt/nameregister.c | 12 ++++++---- source4/libcli/nbt/namerelease.c | 12 ++++++---- source4/libcli/nbt/nbtsocket.c | 39 +++++++++++++++---------------- source4/libcli/wrepl/winsrepl.c | 12 ++++++++-- 15 files changed, 168 insertions(+), 140 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index a6710cf32c..490a03d50e 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -62,8 +62,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) { TALLOC_CTX *tmp_ctx = talloc_new(cldap); NTSTATUS status; - const char *src_addr; - int src_port; + struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct asn1_data asn1; @@ -83,16 +82,15 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } status = socket_recvfrom(cldap->sock, blob.data, blob.length, &nread, 0, - &src_addr, &src_port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src_addr); blob.length = nread; DEBUG(2,("Received cldap packet of length %d from %s:%d\n", - (int)blob.length, src_addr, src_port)); + (int)blob.length, src->addr, src->port)); if (!asn1_load(&asn1, blob)) { DEBUG(2,("Failed to setup for asn.1 decode\n")); @@ -118,10 +116,10 @@ static void cldap_socket_recv(struct cldap_socket *cldap) req = idr_find(cldap->idr, ldap_msg->messageid); if (req == NULL) { if (cldap->incoming.handler) { - cldap->incoming.handler(cldap, ldap_msg, src_addr, src_port); + cldap->incoming.handler(cldap, ldap_msg, src); } else { DEBUG(2,("Mismatched cldap reply %u from %s:%d\n", - ldap_msg->messageid, src_addr, src_port)); + ldap_msg->messageid, src->addr, src->port)); } talloc_free(tmp_ctx); return; @@ -157,7 +155,7 @@ static void cldap_request_timeout(struct event_context *event_ctx, req->num_retries--; socket_sendto(req->cldap->sock, &req->encoded, &len, 0, - req->dest_addr, req->dest_port); + req->dest); req->te = event_add_timed(req->cldap->event_ctx, req, timeval_current_ofs(req->timeout, 0), @@ -184,10 +182,10 @@ static void cldap_socket_send(struct cldap_socket *cldap) len = req->encoded.length; status = socket_sendto(cldap->sock, &req->encoded, &len, 0, - req->dest_addr, req->dest_port); + req->dest); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send cldap request of length %u to %s:%d\n", - (unsigned)req->encoded.length, req->dest_addr, req->dest_port)); + (unsigned)req->encoded.length, req->dest->addr, req->dest->port)); DLIST_REMOVE(cldap->send_queue, req); talloc_free(req); continue; @@ -278,7 +276,7 @@ failed: */ NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, void (*handler)(struct cldap_socket *, struct ldap_message *, - const char *, int ), + struct socket_address *), void *private) { cldap->incoming.handler = handler; @@ -306,9 +304,9 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->num_retries = io->in.retries; req->is_reply = False; - req->dest_addr = talloc_strdup(req, io->in.dest_address); - if (req->dest_addr == NULL) goto failed; - req->dest_port = lp_cldap_port(); + req->dest = socket_address_from_strings(req, cldap->sock->backend_name, + io->in.dest_address, lp_cldap_port()); + if (!req->dest) goto failed; req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); if (req->message_id == -1) goto failed; @@ -337,7 +335,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, if (!ldap_encode(msg, &req->encoded, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest->addr, req->dest->port)); goto failed; } @@ -370,9 +368,8 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) req->state = CLDAP_REQUEST_SEND; req->is_reply = True; - req->dest_addr = talloc_strdup(req, io->dest_address); - if (req->dest_addr == NULL) goto failed; - req->dest_port = io->dest_port; + req->dest = io->dest; + if (talloc_reference(req, io->dest) == NULL) goto failed; talloc_set_destructor(req, cldap_request_destructor); @@ -387,7 +384,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) if (!ldap_encode(msg, &blob1, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; goto failed; } @@ -400,7 +397,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) if (!ldap_encode(msg, &blob2, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; goto failed; } @@ -620,15 +617,14 @@ NTSTATUS cldap_netlogon(struct cldap_socket *cldap, */ NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port) + struct socket_address *src) { NTSTATUS status; struct cldap_reply reply; struct ldap_Result result; reply.messageid = message_id; - reply.dest_address = src_address; - reply.dest_port = src_port; + reply.dest = src; reply.response = NULL; reply.result = &result; @@ -645,7 +641,7 @@ NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, */ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port, + struct socket_address *src, uint32_t version, union nbt_cldap_netlogon *netlogon) { @@ -664,8 +660,7 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, } reply.messageid = message_id; - reply.dest_address = src_address; - reply.dest_port = src_port; + reply.dest = src; reply.response = &response; reply.result = &result; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 0baaec02df..944510077b 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -41,8 +41,7 @@ struct cldap_request { enum cldap_request_state state; /* where to send the request */ - const char *dest_addr; - int dest_port; + struct socket_address *dest; /* timeout between retries (seconds) */ int timeout; @@ -87,7 +86,7 @@ struct cldap_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct cldap_socket *, struct ldap_message *, - const char *, int ); + struct socket_address *); void *private; } incoming; }; @@ -114,7 +113,7 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, void (*handler)(struct cldap_socket *, struct ldap_message *, - const char *, int ), + struct socket_address *), void *private); struct cldap_request *cldap_search_send(struct cldap_socket *cldap, struct cldap_search *io); @@ -129,8 +128,7 @@ NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, */ struct cldap_reply { uint32_t messageid; - const char *dest_address; - int dest_port; + struct socket_address *dest; struct ldap_SearchResEntry *response; struct ldap_Result *result; }; @@ -167,9 +165,9 @@ NTSTATUS cldap_netlogon(struct cldap_socket *cldap, NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port); + struct socket_address *src); NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port, + struct socket_address *src, uint32_t version, union nbt_cldap_netlogon *netlogon); diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 821bf9d815..433d1c1971 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -23,9 +23,10 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, - struct nbt_name *dest_name, const struct nbt_peer_socket *dest, + struct nbt_name *dest_name, struct socket_address *dest, struct nbt_name *src_name, struct nbt_browse_packet *request) { NTSTATUS status; @@ -55,7 +56,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; - struct nbt_peer_socket dest; + struct socket_address *dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); @@ -66,12 +67,17 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); - dest.port = request->src_port; - dest.addr = request->src_addr; + dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, + request->src_addr, request->src_port); + if (!dest) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - &dest, + dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 143b9c309b..326ec7e908 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -34,7 +34,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); NTSTATUS status; - struct nbt_peer_socket src; + struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct nbt_dgram_packet *packet; @@ -53,16 +53,15 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) } status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, 0, - &src.addr, &src.port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src.addr); blob.length = nread; DEBUG(2,("Received dgram packet of length %d from %s:%d\n", - (int)blob.length, src.addr, src.port)); + (int)blob.length, src->addr, src->port)); packet = talloc(tmp_ctx, struct nbt_dgram_packet); if (packet == NULL) { @@ -86,14 +85,14 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, &src); + dgmslot->handler(dgmslot, packet, src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } } else { /* dispatch if there is a general handler */ if (dgmsock->incoming.handler) { - dgmsock->incoming.handler(dgmsock, packet, &src); + dgmsock->incoming.handler(dgmsock, packet, src); } } @@ -114,10 +113,10 @@ static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) len = req->encoded.length; status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0, - req->dest.addr, req->dest.port); + req->dest); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send datagram of length %u to %s:%d: %s\n", - (unsigned)req->encoded.length, req->dest.addr, req->dest.port, + (unsigned)req->encoded.length, req->dest->addr, req->dest->port, nt_errstr(status))); DLIST_REMOVE(dgmsock->send_queue, req); talloc_free(req); @@ -200,7 +199,7 @@ failed: NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *), + struct socket_address *), void *private) { dgmsock->incoming.handler = handler; @@ -215,7 +214,7 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, */ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *dest) + struct socket_address *dest) { struct nbt_dgram_request *req; NTSTATUS status = NT_STATUS_NO_MEMORY; @@ -223,9 +222,8 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, req = talloc(dgmsock, struct nbt_dgram_request); if (req == NULL) goto failed; - req->dest.port = dest->port; - req->dest.addr = talloc_strdup(req, dest->addr); - if (req->dest.addr == NULL) goto failed; + req->dest = dest; + if (talloc_reference(req, dest) == NULL) goto failed; status = ndr_push_struct_blob(&req->encoded, req, packet, (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index f913e90d88..d5e28ed03d 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -29,7 +29,7 @@ struct nbt_dgram_request { struct nbt_dgram_request *next, *prev; /* where to send the request */ - struct nbt_peer_socket dest; + struct socket_address *dest; /* the encoded request */ DATA_BLOB encoded; @@ -54,7 +54,7 @@ struct nbt_dgram_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *src); + struct socket_address *src); void *private; } incoming; }; @@ -70,7 +70,7 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *src); + struct socket_address *src); struct dgram_mailslot_handler { struct dgram_mailslot_handler *next, *prev; @@ -86,11 +86,11 @@ struct dgram_mailslot_handler { /* prototypes */ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *dest); + struct socket_address *dest); NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *), + struct socket_address *), void *private); struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); @@ -113,13 +113,13 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, DATA_BLOB *request); NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, @@ -132,11 +132,11 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_packet *netlogon); NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request); + enum dgram_msg_type msg_type, + struct nbt_name *dest_name, + struct socket_address *dest, + struct nbt_name *src_name, + struct nbt_ntlogon_packet *request); NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *mailslot_name, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 0e6b99c3e3..33bca166ce 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -151,28 +151,39 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - const struct nbt_peer_socket *_dest, + struct socket_address *_dest, struct nbt_name *src_name, DATA_BLOB *request) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_dgram_packet packet; - struct nbt_peer_socket dest = *_dest; + struct socket_address *dest; struct dgram_message *msg; struct dgram_smb_packet *smb; struct smb_trans_body *trans; + struct socket_address *src; NTSTATUS status; - if (dest.port == 0) { - dest.port = lp_dgram_port(); + if (_dest->port == 0) { + dest = socket_address_from_strings(tmp_ctx, _dest->family, + _dest->addr, lp_dgram_port()); + } else { + dest = _dest; + } + if (!dest) { + return NT_STATUS_NO_MEMORY; } ZERO_STRUCT(packet); packet.msg_type = msg_type; packet.flags = DGRAM_FLAG_FIRST | DGRAM_NODE_NBDD; packet.dgram_id = generate_random() % UINT16_MAX; - packet.src_addr = socket_get_my_addr(dgmsock->sock, tmp_ctx); - packet.src_port = socket_get_my_port(dgmsock->sock); + src = socket_get_my_addr(dgmsock->sock, tmp_ctx); + if (!src) { + return NT_STATUS_NO_MEMORY; + } + packet.src_addr = src->addr; + packet.src_port = src->port; msg = &packet.data.msg; /* this length calculation is very crude - it should be based on gensize @@ -198,7 +209,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, trans->mailslot_name = mailslot_name; trans->data = *request; - status = nbt_dgram_send(dgmsock, &packet, &dest); + status = nbt_dgram_send(dgmsock, &packet, dest); talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index dffeae2007..6ad4c28811 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -22,13 +22,14 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" /* send a netlogon mailslot request */ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -65,7 +66,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; - struct nbt_peer_socket dest; + struct socket_address *dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); @@ -76,12 +77,17 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); - dest.port = request->src_port; - dest.addr = request->src_addr; + dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, + request->src_addr, request->src_port); + if (!dest) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - &dest, + dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 3205416cea..ecd6bd4587 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" /* send a ntlogon mailslot request @@ -29,7 +30,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, struct nbt_ntlogon_packet *request) { @@ -66,7 +67,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; - struct nbt_peer_socket dest; + struct socket_address *dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); @@ -77,12 +78,18 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); - dest.port = request->src_port; - dest.addr = request->src_addr; + dest = socket_address_from_strings(tmp_ctx, + dgmsock->sock->backend_name, + request->src_addr, request->src_port); + if (!dest) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - &dest, + dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 7c9e3e9651..b4411d6fe6 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -34,12 +34,6 @@ enum nbt_request_state {NBT_REQUEST_SEND, NBT_REQUEST_TIMEOUT, NBT_REQUEST_ERROR}; -/* where to send the request/replies */ -struct nbt_peer_socket { - const char *addr; - int port; -}; - /* a nbt name request */ @@ -54,7 +48,7 @@ struct nbt_name_request { struct nbt_name_socket *nbtsock; /* where to send the request */ - struct nbt_peer_socket dest; + struct socket_address *dest; /* timeout between retries */ int timeout; @@ -83,7 +77,7 @@ struct nbt_name_request { uint_t num_replies; struct nbt_name_reply { struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; } *replies; /* information on what to do on completion */ @@ -117,14 +111,14 @@ struct nbt_name_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const struct nbt_peer_socket *); + struct socket_address *); void *private; } incoming; /* what to do with unexpected replies */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const struct nbt_peer_socket *); + struct socket_address *); void *private; } unexpected; }; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 38fb2f966d..6566e48a5a 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -22,7 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" - +#include "lib/socket/socket.h" /* send a nbt name query */ @@ -31,7 +31,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -52,9 +52,10 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_NETBIOS; packet->questions[0].question_class = NBT_QCLASS_IP; - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -84,7 +85,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if ((packet->operation & NBT_RCODE) != 0) { status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); @@ -140,7 +141,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -155,9 +156,10 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_STATUS; packet->questions[0].question_class = NBT_QCLASS_IP; - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -187,7 +189,7 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if ((packet->operation & NBT_RCODE) != 0) { status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index e6464885f7..8940fbb95e 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" +#include "lib/socket/socket.h" /* send a nbt name refresh request @@ -32,7 +33,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -66,9 +67,10 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -97,7 +99,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 4f3e046274..5c7e86367f 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" +#include "lib/socket/socket.h" /* send a nbt name registration request @@ -32,7 +33,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -74,9 +75,10 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, talloc_strdup(packet->additional, io->in.address); if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -105,7 +107,7 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index 0a0cd45276..e8dc175b36 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "lib/socket/socket.h" /* send a nbt name release request @@ -31,7 +32,7 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -65,9 +66,10 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -96,7 +98,7 @@ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1c41b80fdb..42b92b14cc 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -73,7 +73,7 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) len = req->encoded.length; status = socket_sendto(nbtsock->sock, &req->encoded, &len, 0, - req->dest.addr, req->dest.port); + req->dest); if (NT_STATUS_IS_ERR(status)) goto failed; if (!NT_STATUS_IS_OK(status)) { @@ -153,7 +153,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) { TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); NTSTATUS status; - struct nbt_peer_socket src; + struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct nbt_name_packet *packet; @@ -172,13 +172,11 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, - &src.addr, &src.port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src.addr); - blob.length = nread; packet = talloc(tmp_ctx, struct nbt_name_packet); if (packet == NULL) { @@ -198,7 +196,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) if (DEBUGLVL(10)) { DEBUG(10,("Received nbt packet of length %d from %s:%d\n", - (int)blob.length, src.addr, src.port)); + (int)blob.length, src->addr, src->port)); NDR_PRINT_DEBUG(nbt_name_packet, packet); } @@ -206,7 +204,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) handler, if any */ if (!(packet->operation & NBT_FLAG_REPLY)) { if (nbtsock->incoming.handler) { - nbtsock->incoming.handler(nbtsock, packet, &src); + nbtsock->incoming.handler(nbtsock, packet, src); } talloc_free(tmp_ctx); return; @@ -216,7 +214,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req = idr_find(nbtsock->idr, packet->name_trn_id); if (req == NULL) { if (nbtsock->unexpected.handler) { - nbtsock->unexpected.handler(nbtsock, packet, &src); + nbtsock->unexpected.handler(nbtsock, packet, src); } else { DEBUG(2,("Failed to match request for incoming name packet id 0x%04x on %p\n", packet->name_trn_id, nbtsock)); @@ -258,9 +256,10 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) goto done; } - req->replies[req->num_replies].dest.addr = talloc_steal(req, src.addr); - req->replies[req->num_replies].dest.port = src.port; - req->replies[req->num_replies].packet = talloc_steal(req, packet); + talloc_steal(req, src); + req->replies[req->num_replies].dest = src; + talloc_steal(req, packet); + req->replies[req->num_replies].packet = packet; req->num_replies++; /* if we don't want multiple replies then we are done */ @@ -348,7 +347,7 @@ failed: send off a nbt name request */ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name_packet *request, int timeout, int retries, BOOL allow_multiple_replies) @@ -366,9 +365,8 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, req->is_reply = False; req->timeout = timeout; req->num_retries = retries; - req->dest.port = dest->port; - req->dest.addr = talloc_strdup(req, dest->addr); - if (req->dest.addr == NULL) goto failed; + req->dest = dest; + if (talloc_reference(req, dest) == NULL) goto failed; /* we select a random transaction id unless the user supplied one */ if (request->name_trn_id == 0) { @@ -397,7 +395,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, if (DEBUGLVL(10)) { DEBUG(10,("Queueing nbt packet to %s:%d\n", - req->dest.addr, req->dest.port)); + req->dest->addr, req->dest->port)); NDR_PRINT_DEBUG(nbt_name_packet, request); } @@ -415,7 +413,7 @@ failed: send off a nbt name reply */ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name_packet *request) { struct nbt_name_request *req; @@ -425,9 +423,8 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, NT_STATUS_HAVE_NO_MEMORY(req); req->nbtsock = nbtsock; - req->dest.port = dest->port; - req->dest.addr = talloc_strdup(req, dest->addr); - if (req->dest.addr == NULL) goto failed; + req->dest = dest; + if (talloc_reference(req, dest) == NULL) goto failed; req->state = NBT_REQUEST_SEND; req->is_reply = True; @@ -480,7 +477,7 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) */ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const struct nbt_peer_socket *), + struct socket_address *), void *private) { nbtsock->incoming.handler = handler; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 0409607aa9..909bedf530 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -311,6 +311,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, { struct composite_context *result; struct wrepl_connect_state *state; + struct socket_address *peer, *us; result = talloc_zero(wrepl_socket, struct composite_context); if (!result) return NULL; @@ -328,8 +329,15 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, our_ip = iface_best_ip(peer_ip); } - state->creq = socket_connect_send(wrepl_socket->sock, our_ip, 0, - peer_ip, WINS_REPLICATION_PORT, + us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, + our_ip, 0); + if (composite_nomem(us, result)) return result; + + peer = socket_address_from_strings(state, wrepl_socket->sock->backend_name, + peer_ip, WINS_REPLICATION_PORT); + if (composite_nomem(peer, result)) return result; + + state->creq = socket_connect_send(wrepl_socket->sock, us, peer, 0, wrepl_socket->event.ctx); composite_continue(result, state->creq, wrepl_connect_handler, state); return result; -- cgit From b135f4467f8413f6ac44df54b8430305f6c26c0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 03:02:00 +0000 Subject: r12858: This moves the libnet_LookupPdc code to use a GetDC request to find the remote server's name, or in the absence of a local nbt_server to communicate with (or without root access), a node status request. The result is that we are in a better position to use kerberos, as well as to remove the 'password server' mandatory parameter for the samsync and samdump commands. (I need this to put these into SWAT). The only problem I have is that I must create a messaging context, which requires a server ID. As a client process, I don't expect to get messages, but it is currently required for replies, so I generate a random() number. We probably need the servers to accept connections on streamed sockets too, for client-only tasks that want IRPC. Because I wanted to test this code, I have put the NET-API-* tests into our test scripts, to ensure they pass and keep passing. They are good frontends onto the libnet system, and I see no reason not to test them. In doing so the NET-API-RPCCONNECT test was simplified to take a binding string on the command line, removing duplicate code, and testing the combinations in the scripts instead. (I have done a bit of work on the list shares code in libnet_share.c to make it pass 'make test') In the future, I would like to extend the libcli/findds.c code (based off volker's winbind/wb_async_helpers.c, which is why it shows up a bit odd in the patch) to handle getting multiple name replies, sending a getdc request to each in turn. (posted to samba-technical for review, and I'll happily update with any comments) Andrew Bartlett (This used to be commit 7ccddfd3515fc2c0d6f447c768ccbf7a220c3380) --- source4/libcli/config.mk | 7 +- source4/libcli/finddcs.c | 245 ++++++++++++++++++++++++++++++++++++++ source4/libcli/libcli.h | 4 + source4/libcli/security/dom_sid.c | 5 + 4 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/finddcs.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 20219be0f4..0040339fd2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -87,6 +87,11 @@ OBJ_FILES = \ resolve/host.o REQUIRED_SUBSYSTEMS = LIBCLI_NBT +[SUBSYSTEM::LIBCLI_FINDDCS] +OBJ_FILES = \ + finddcs.o +REQUIRED_SUBSYSTEMS = LIBCLI_NBT MESSAGING + [LIBRARY::LIBCLI] MAJOR_VERSION = 0 MINOR_VERSION = 0 @@ -94,7 +99,7 @@ RELEASE_VERSION = 1 DESCRIPTION = SMB/CIFS client library REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM LIBCLI_SMB2 + LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI SOCKET diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c new file mode 100644 index 0000000000..ff4b255a13 --- /dev/null +++ b/source4/libcli/finddcs.c @@ -0,0 +1,245 @@ +/* + Unix SMB/CIFS implementation. + + a composite API for finding a DC and its name + + Copyright (C) Volker Lendecke 2005 + Copyright (C) Andrew Bartlett 2006 + + 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 "include/includes.h" +#include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_irpc.h" +#include "librpc/gen_ndr/ndr_samr.h" +#include "libcli/composite/composite.h" +#include "libcli/libcli.h" + +struct finddcs_state { + struct composite_context *ctx; + struct messaging_context *msg_ctx; + + const char *domain_name; + struct dom_sid *domain_sid; + + struct nbtd_getdcname r; + struct nbt_name_status node_status; + + int num_dcs; + struct nbt_dc_name *dcs; +}; + +static void finddcs_name_resolved(struct composite_context *ctx); +static void finddcs_getdc_replied(struct irpc_request *ireq); +static void fallback_node_status(struct finddcs_state *state); +static void fallback_node_status_replied(struct nbt_name_request *name_req); + +/* + * Setup and send off the a normal name resolution for the target name. + * + * The domain_sid parameter is optional, and is used in the subsequent getdc request. + * + * This will try a GetDC request, but this may not work. It will try + * a node status as a fallback, then return no name (but still include + * the IP) + */ + +struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, + const char *domain_name, + int name_type, + struct dom_sid *domain_sid, + const char **methods, + struct event_context *event_ctx, + struct messaging_context *msg_ctx) +{ + struct composite_context *result, *ctx; + struct finddcs_state *state; + struct nbt_name name; + + result = talloc(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = event_ctx; + + state = talloc(result, struct finddcs_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; + + state->domain_name = talloc_strdup(state, domain_name); + if (state->domain_name == NULL) goto failed; + state->domain_sid = domain_sid; + if (domain_sid != NULL) { + if (talloc_reference(state, domain_sid) == NULL) { + goto failed; + } + } + state->msg_ctx = msg_ctx; + + make_nbt_name(&name, state->domain_name, name_type); + ctx = resolve_name_send(&name, result->event_ctx, + methods); + + if (ctx == NULL) goto failed; + ctx->async.fn = finddcs_name_resolved; + ctx->async.private_data = state; + + return result; + +failed: + talloc_free(result); + return NULL; +} + +/* Having got an name query answer, fire off a GetDC request, so we + * can find the target's all-important name. (Kerberos and some + * netlogon operations are quite picky about names) + * + * The name is a courtasy, if we don't find it, don't compleatly fail. + * + * However, if the nbt server is down, fall back to a node status + * request + */ +static void finddcs_name_resolved(struct composite_context *ctx) +{ + struct finddcs_state *state = + talloc_get_type(ctx->async.private_data, struct finddcs_state); + struct irpc_request *ireq; + uint32_t *nbt_servers; + const char *address; + + state->ctx->status = resolve_name_recv(ctx, state, &address); + if (!composite_is_ok(state->ctx)) return; + + state->num_dcs = 1; + state->dcs = talloc_array(state, struct nbt_dc_name, state->num_dcs); + if (composite_nomem(state->dcs, state->ctx)) return; + + state->dcs[0].address = talloc_steal(state->dcs, address); + + /* Try and find the nbt server. We are not going to fail if + * we can't get the name, it will just be a disapointment. + * The nbt server just might not be running */ + nbt_servers = irpc_servers_byname(state->msg_ctx, "nbt_server"); + if ((nbt_servers == NULL) || (nbt_servers[0] == 0)) { + fallback_node_status(state); + return; + } + + state->r.in.domainname = state->domain_name; + state->r.in.ip_address = state->dcs[0].address; + state->r.in.my_computername = lp_netbios_name(); + state->r.in.my_accountname = talloc_asprintf(state, "%s$", + lp_netbios_name()); + if (composite_nomem(state->r.in.my_accountname, state->ctx)) return; + state->r.in.account_control = ACB_WSTRUST; + state->r.in.domain_sid = state->domain_sid; + + ireq = irpc_call_send(state->msg_ctx, nbt_servers[0], + &dcerpc_table_irpc, DCERPC_NBTD_GETDCNAME, + &state->r, state); + if (!ireq) { + fallback_node_status(state); + return; + } + + composite_continue_irpc(state->ctx, ireq, finddcs_getdc_replied, state); +} + +/* Called when the GetDC request returns */ +static void finddcs_getdc_replied(struct irpc_request *ireq) +{ + struct finddcs_state *state = + talloc_get_type(ireq->async.private, struct finddcs_state); + + state->ctx->status = irpc_call_recv(ireq); + if (!composite_is_ok(state->ctx)) return; + + state->dcs[0].name = talloc_steal(state->dcs, state->r.out.dcname); + composite_done(state->ctx); +} + +/* The GetDC request might not be availible (such as occours when the + * NBT server is down). Fallback to a node status. It is the best + * hope we have... */ +static void fallback_node_status(struct finddcs_state *state) +{ + struct nbt_name_socket *nbtsock; + struct nbt_name_request *name_req; + + state->node_status.in.name.name = "*"; + state->node_status.in.name.type = NBT_NAME_CLIENT; + state->node_status.in.name.scope = NULL; + state->node_status.in.dest_addr = state->dcs[0].address; + state->node_status.in.timeout = 1; + state->node_status.in.retries = 2; + + nbtsock = nbt_name_socket_init(state, state->ctx->event_ctx); + if (composite_nomem(nbtsock, state->ctx)) return; + + name_req = nbt_name_status_send(nbtsock, &state->node_status); + if (composite_nomem(name_req, state->ctx)) return; + + composite_continue_nbt(state->ctx, + name_req, + fallback_node_status_replied, + state); +} + +/* We have a node status reply (or perhaps a timeout) */ +static void fallback_node_status_replied(struct nbt_name_request *name_req) +{ + struct finddcs_state *state = talloc_get_type(name_req->async.private, struct finddcs_state); + state->ctx->status = nbt_name_status_recv(name_req, state, &state->node_status); + if (!composite_is_ok(state->ctx)) return; + + if (state->node_status.out.status.num_names > 0) { + state->dcs[0].name = talloc_steal(state->dcs, state->node_status.out.status.names[0].name); + composite_done(state->ctx); + return; + } + composite_error(state->ctx, NT_STATUS_NO_LOGON_SERVERS); +} + +NTSTATUS finddcs_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + int *num_dcs, struct nbt_dc_name **dcs) +{ + NTSTATUS status = composite_wait(c); + if (NT_STATUS_IS_OK(status)) { + struct finddcs_state *state = + talloc_get_type(c->private_data, struct finddcs_state); + *num_dcs = state->num_dcs; + *dcs = talloc_steal(mem_ctx, state->dcs); + } + talloc_free(c); + return status; +} + +NTSTATUS finddcs(TALLOC_CTX *mem_ctx, + const char *domain_name, int name_type, + struct dom_sid *domain_sid, + const char **methods, + struct event_context *event_ctx, + struct messaging_context *msg_ctx, + int *num_dcs, struct nbt_dc_name **dcs) +{ + struct composite_context *c = finddcs_send(mem_ctx, + domain_name, name_type, + domain_sid, methods, + event_ctx, msg_ctx); + return finddcs_recv(c, mem_ctx, num_dcs, dcs); +} diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index 917ab27519..76fa13525e 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -41,5 +41,9 @@ struct clilist_file_info { const char *short_name; }; +struct nbt_dc_name { + const char *address; + const char *name; +}; #include "libcli/libcli_proto.h" diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 646a513df5..b5ced9fcc2 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -157,6 +157,11 @@ struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid) { struct dom_sid *ret; int i; + + if (!dom_sid) { + return NULL; + } + ret = talloc(mem_ctx, struct dom_sid); if (!ret) { return NULL; -- cgit From 4b2ed199ca12cedab42683e628eb7e8da6eb0fb4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 03:30:20 +0000 Subject: r12861: Cope when we are not supplied the messaging context. This is just another case where we have to fallback to the node status request. Andrew Bartlett (This used to be commit 181064dbcf102de80937fc30b3d3ba5114194a72) --- source4/libcli/finddcs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index ff4b255a13..036b937f69 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -131,9 +131,15 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->dcs[0].address = talloc_steal(state->dcs, address); - /* Try and find the nbt server. We are not going to fail if - * we can't get the name, it will just be a disapointment. - * The nbt server just might not be running */ + /* Try and find the nbt server. Fallback to a node status + * request if we can't make this happen The nbt server just + * might not be running, or we may not have a messaging + * context (not root etc) */ + if (!state->msg_ctx) { + fallback_node_status(state); + return; + } + nbt_servers = irpc_servers_byname(state->msg_ctx, "nbt_server"); if ((nbt_servers == NULL) || (nbt_servers[0] == 0)) { fallback_node_status(state); -- cgit From 3f8ee534bafa149c00f050abea8ae111fea61287 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 06:44:28 +0000 Subject: r12862: Need to trim spaces off the end of the node status reply. Andrew Bartlett (This used to be commit 3e90e7edfa7d343a6b6bf073b8f4d018e3b463d0) --- source4/libcli/finddcs.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 036b937f69..3b72cceba0 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -214,7 +214,16 @@ static void fallback_node_status_replied(struct nbt_name_request *name_req) if (!composite_is_ok(state->ctx)) return; if (state->node_status.out.status.num_names > 0) { - state->dcs[0].name = talloc_steal(state->dcs, state->node_status.out.status.names[0].name); + int i; + char *name = talloc_strndup(state->dcs, state->node_status.out.status.names[0].name, 15); + /* Strip space padding */ + if (name) { + i = MIN(strlen(name), 15); + for (; i > 0 && name[i - 1] == ' '; i--) { + name[i - 1] = '\0'; + } + } + state->dcs[0].name = name; composite_done(state->ctx); return; } -- cgit From 23aa4becf20ae8a1384bad7d819745d7c38b211b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Jan 2006 17:07:28 +0000 Subject: r12910: fix bug #3069 metze (This used to be commit 1768a698a461bfb8aeaa8f28efaab4ad300823a2) --- source4/libcli/util/errormap.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 526e9085c9..bbaac629e4 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1284,14 +1284,17 @@ const struct unix_error_map unix_nt_errmap[] = { #ifdef ENOTSUP { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, #endif +#ifdef EOPNOTSUPP + { EOPNOTSUPP, NT_STATUS_NOT_SUPPORTED}, +#endif #ifdef EHOSTUNREACH { EHOSTUNREACH, NT_STATUS_HOST_UNREACHABLE }, #endif #ifdef ENETUNREACH - { ENETUNREACH, NT_STATUS_NETWORK_UNREACHABLE }, + { ENETUNREACH, NT_STATUS_NETWORK_UNREACHABLE }, #endif #ifdef ETIMEDOUT - { ETIMEDOUT, NT_STATUS_IO_TIMEOUT }, + { ETIMEDOUT, NT_STATUS_IO_TIMEOUT }, #endif #ifdef EADDRINUSE { EADDRINUSE, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, -- cgit From eed0a95128714b93b9ff484780e5d74fc301be6d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 13 Jan 2006 22:48:08 +0000 Subject: r12917: fix decoding of ldap controls some more work on timeouts (This used to be commit a7e2fe3cb33be2effff7eb764047567f2da3cd55) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index d021fc3bd6..b281f62ed0 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1264,7 +1264,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT(0)); for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { - asn1_start_tag(data, ASN1_SEQUENCE(0)); + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ ctrl = talloc_realloc(msg, ctrl, struct ldap_Control *, i+2); if (!ctrl) { -- cgit From 5db0c6b3042292e0f343ced3d45f2f7a8f97de12 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jan 2006 01:06:16 +0000 Subject: r12925: implement client side of ASQ control (This used to be commit dd386bdc6ca6fe0b25705d5a375d29e6940b437f) --- source4/libcli/ldap/ldap_controls.c | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 55e7a94aa7..2a48d401c9 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -225,6 +225,67 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return True; } +/* seem that this controls has 2 forms one in case it is used with + * a Search Request and another when used ina Search Response + */ +static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB source_attribute; + struct asn1_data data; + struct ldb_asq_control *lac; + + if (!asn1_load(&data, in)) { + return False; + } + + lac = talloc(mem_ctx, struct ldb_asq_control); + if (!lac) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + + if (!asn1_read_OctetString(&data, &source_attribute)) { + return False; + } + lac->src_attr_len = source_attribute.length; + if (lac->src_attr_len) { + lac->source_attribute = talloc_memdup(lac, source_attribute.data, source_attribute.length); + + if (!(lac->source_attribute)) { + return False; + } + } else { + lac->source_attribute = NULL; + } + + lac->request = 1; + + } else if (asn1_peek_tag(&data, ASN1_ENUMERATED)) { + + if (!asn1_read_enumerated(&data, &(lac->result))) { + return False; + } + + lac->request = 0; + + } else { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lac; + + return True; +} + static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); @@ -366,11 +427,49 @@ static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out return True; } +/* seem that this controls has 2 forms one in case it is used with + * a Search Request and another when used ina Search Response + */ +static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (lac->request) { + + if (!asn1_write_OctetString(&data, lac->source_attribute, lac->src_attr_len)) { + return False; + } + } else { + if (!asn1_write_enumerated(&data, lac->result)) { + return False; + } + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response }, + { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { NULL, NULL, NULL } }; -- cgit From df62387c642d8ef28a3d1549c306803fa03b7eae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Jan 2006 10:03:18 +0000 Subject: r12932: export function prototypes metze (This used to be commit 8208a4abf0cacb9ee3496611f121c095b5d1bcca) --- source4/libcli/dgram/browse.c | 16 ++++++++++------ source4/libcli/dgram/libdgram.h | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 433d1c1971..25cee387c4 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -26,8 +26,10 @@ #include "lib/socket/socket.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, - struct nbt_name *dest_name, struct socket_address *dest, - struct nbt_name *src_name, struct nbt_browse_packet *request) + struct nbt_name *dest_name, + struct socket_address *dest, + struct nbt_name *src_name, + struct nbt_browse_packet *request) { NTSTATUS status; DATA_BLOB blob; @@ -49,8 +51,9 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, } NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, const char *mailslot_name, - struct nbt_browse_packet *reply) + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_browse_packet *reply) { NTSTATUS status; DATA_BLOB blob; @@ -84,8 +87,9 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, } NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, - struct nbt_browse_packet *pkt) + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_browse_packet *pkt) { DATA_BLOB data = dgram_mailslot_data(dgram); NTSTATUS status; diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index d5e28ed03d..830d81257d 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -145,3 +145,19 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, struct nbt_ntlogon_packet *ntlogon); + +NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + struct socket_address *dest, + struct nbt_name *src_name, + struct nbt_browse_packet *request); + +NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_browse_packet *reply); + +NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_browse_packet *pkt); -- cgit From 3b447ab4a131509491b42a1843c52ba69bab5e11 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 17 Jan 2006 04:04:57 +0000 Subject: r12977: Some code to implement the client side of the Dirsync control Still investigating how it works. Simo. (This used to be commit bebd403523e581606505e05e7cb621efbc22fa36) --- source4/libcli/ldap/ldap_controls.c | 86 +++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 2a48d401c9..744f21fed1 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -225,6 +225,56 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return True; } +static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB cookie; + struct asn1_data data; + struct ldb_dirsync_control *ldc; + + if (!asn1_load(&data, in)) { + return False; + } + + ldc = talloc(mem_ctx, struct ldb_dirsync_control); + if (!ldc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(ldc->flags))) { + return False; + } + + if (!asn1_read_Integer(&data, &(ldc->max_attributes))) { + return False; + } + + if (!asn1_read_OctetString(&data, &cookie)) { + return False; + } + ldc->cookie_len = cookie.length; + if (ldc->cookie_len) { + ldc->cookie = talloc_memdup(ldc, cookie.data, cookie.length); + + if (!(ldc->cookie)) { + return False; + } + } else { + ldc->cookie = NULL; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = ldc; + + return True; +} + /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ @@ -464,12 +514,48 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, ldc->flags)) { + return False; + } + + if (!asn1_write_Integer(&data, ldc->max_attributes)) { + return False; + } + + if (!asn1_write_OctetString(&data, ldc->cookie, ldc->cookie_len)) { + return False; + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response }, { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, + { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { NULL, NULL, NULL } }; -- cgit From 828ee2bc6fa4f757c63a31054a0046fe09f8c26e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jan 2006 18:56:04 +0000 Subject: r12984: add parse code and ldbsearch cmdline code for NOTIFICATION LDAP Controls http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_notification_oid.asp this doesn't work yet, but it shows that we need to extend ldb to correctly handle async requests... metze (This used to be commit 1fe67189490c9faf499b68a28071a6294a53db0e) --- source4/libcli/ldap/ldap_controls.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 744f21fed1..1f7a415e8e 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -60,7 +60,7 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) if (!asn1_read_OctetString(&data, &attr)) { return False; } - lsrc->attr_desc = talloc_strndup(lsrc, attr.data, attr.length); + lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); if (!lsrc->attr_desc) { return False; } @@ -111,7 +111,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - lssc[num]->attributeName = talloc_strndup(lssc[num], attr.data, attr.length); + lssc[num]->attributeName = talloc_strndup(lssc[num], (const char *)attr.data, attr.length); if (!lssc [num]->attributeName) { return False; } @@ -120,7 +120,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) if (!asn1_read_OctetString(&data, &rule)) { return False; } - lssc[num]->orderingRule = talloc_strndup(lssc[num], rule.data, rule.length); + lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); if (!lssc[num]->orderingRule) { return False; } @@ -336,6 +336,15 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); @@ -549,6 +558,16 @@ static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, @@ -556,6 +575,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response }, { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, + { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { NULL, NULL, NULL } }; -- cgit From 4326572af29bcf2a98aab7db6ca2b1489d3f6874 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jan 2006 15:46:00 +0000 Subject: r12999: fix compiler warnings metze (This used to be commit ec30a40f042016bc167382b63bd284f656ed7cb1) --- source4/libcli/nbt/nbtname.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index b0424b430f..c6fc18f55a 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -77,7 +77,7 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, if (*offset + len + 2 > ndr->data_size) { return NT_STATUS_BAD_NETWORK_NAME; } - *component = (uint8_t*)talloc_strndup(ndr, &ndr->data[1 + *offset], len); + *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len); NT_STATUS_HAVE_NO_MEMORY(*component); *offset += len + 1; *max_offset = MAX(*max_offset, *offset); @@ -115,7 +115,7 @@ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s name = talloc_asprintf_append(name, ".%s", component); NT_STATUS_HAVE_NO_MEMORY(name); } else { - name = component; + name = (char *)component; } } if (num_components == MAX_COMPONENTS) { @@ -244,7 +244,7 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, int i; uint8_t pad_char; - if (strlen(name) > 15) { + if (strlen((const char *)name) > 15) { return NULL; } @@ -255,7 +255,7 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, cname[2*i] = 'A' + (name[i]>>4); cname[1+2*i] = 'A' + (name[i]&0xF); } - if (strcmp(name, "*") == 0) { + if (strcmp((const char *)name, "*") == 0) { pad_char = 0; } else { pad_char = ' '; @@ -291,10 +291,10 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name status = ndr_pull_nbt_string(ndr, ndr_flags, &s); NT_STATUS_NOT_OK_RETURN(status); - scope = strchr(s, '.'); + scope = (uint8_t *)strchr(s, '.'); if (scope) { *scope = 0; - r->scope = talloc_strdup(ndr->current_mem_ctx, scope+1); + r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]); NT_STATUS_HAVE_NO_MEMORY(r->scope); } else { r->scope = NULL; @@ -332,18 +332,18 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt return NT_STATUS_OK; } - cname = compress_name(ndr, r->name, r->type); + cname = compress_name(ndr, (const uint8_t *)r->name, r->type); NT_STATUS_HAVE_NO_MEMORY(cname); if (r->scope) { - fullname = talloc_asprintf(ndr, "%s.%s", cname, r->scope); + fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope); NT_STATUS_HAVE_NO_MEMORY(fullname); talloc_free(cname); } else { fullname = cname; } - status = ndr_push_nbt_string(ndr, ndr_flags, fullname); + status = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); return status; } -- cgit From e2ce6fec9cfb9d3efbe0e97a8faf7f60a8ea3a1d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 24 Jan 2006 01:57:31 +0000 Subject: r13103: Walk the names in the node status request, so I can find a server name, and use that. (I was trying to find a machine by the name of __SAMBA__) Andrew Bartlett (This used to be commit cde044d023c7580442bceb60ac62dc4cfc1b85fe) --- source4/libcli/finddcs.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 3b72cceba0..9caf9b5578 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -209,23 +209,26 @@ static void fallback_node_status(struct finddcs_state *state) /* We have a node status reply (or perhaps a timeout) */ static void fallback_node_status_replied(struct nbt_name_request *name_req) { + int i; struct finddcs_state *state = talloc_get_type(name_req->async.private, struct finddcs_state); state->ctx->status = nbt_name_status_recv(name_req, state, &state->node_status); if (!composite_is_ok(state->ctx)) return; - if (state->node_status.out.status.num_names > 0) { - int i; - char *name = talloc_strndup(state->dcs, state->node_status.out.status.names[0].name, 15); - /* Strip space padding */ - if (name) { - i = MIN(strlen(name), 15); - for (; i > 0 && name[i - 1] == ' '; i--) { - name[i - 1] = '\0'; + for (i=0; i < state->node_status.out.status.num_names; i++) { + int j; + if (state->node_status.out.status.names[i].type == NBT_NAME_SERVER) { + char *name = talloc_strndup(state->dcs, state->node_status.out.status.names[0].name, 15); + /* Strip space padding */ + if (name) { + j = MIN(strlen(name), 15); + for (; j > 0 && name[j - 1] == ' '; j--) { + name[j - 1] = '\0'; + } } + state->dcs[0].name = name; + composite_done(state->ctx); + return; } - state->dcs[0].name = name; - composite_done(state->ctx); - return; } composite_error(state->ctx, NT_STATUS_NO_LOGON_SERVERS); } -- cgit From 106da006c48f83e2484bfc9cf436523d267eeb57 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 26 Jan 2006 06:29:59 +0000 Subject: r13154: Add some const (This used to be commit 62822a26550842dbb763b27994cb38474fe8eea3) --- source4/libcli/climessage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index febd7db65c..010d48c9bb 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -26,7 +26,7 @@ /**************************************************************************** start a message sequence ****************************************************************************/ -BOOL smbcli_message_start(struct smbcli_tree *tree, char *host, const char *username, +BOOL smbcli_message_start(struct smbcli_tree *tree, const char *host, const char *username, int *grp) { struct smbcli_request *req; -- cgit From fd007e5512d7818d3a8ed8ff504e175dbe24642c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Jan 2006 11:57:33 +0000 Subject: r13203: Make this comment clearer. Andrew Bartlett (This used to be commit 8e2b461669d2d4d5a789da66b5049ecbddd8fd15) --- source4/libcli/smb_composite/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 4cdc4c5e6b..bf027a0425 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -324,7 +324,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, status = gensec_start_mech_by_oid(session->gensec, chosen_oid); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n", + DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); return status; } -- cgit From 60f8666ae88c5a03b0da58acb94015337442e18b Mon Sep 17 00:00:00 2001 From: James Peach Date: Tue, 31 Jan 2006 06:09:18 +0000 Subject: r13255: New CIFS dd client for use in performance testing. The guts of this is in client/cifsdd*, which implements a minimal implementation of dd. The IO path is careful to always perform IO at the requested block size. There is a very basic test suite in script/tests/test_cifsdd.sh which covers local and remote IO at a variety of block sizes. Added to lib/util_str.c is a small set of conv_str_*() functions to convert strings to the corresponding type. smbcli_parse_unc is modified to insert NULL terminators after its hostname and sharename parameters. This allows it to correctly parse a path of the form //foo/share/path/file. (This used to be commit cd2f94a65817bfae20ac21b730a2c42d8e581ab3) --- source4/libcli/cliconnect.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index fe0ad9c9f5..9a5236a661 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -4,6 +4,7 @@ client connect/disconnect routines Copyright (C) Andrew Tridgell 2003-2005 + Copyright (C) James Peach 2005 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 @@ -175,11 +176,33 @@ struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) return talloc_zero(mem_ctx, struct smbcli_state); } +/* Insert a NULL at the first separator of the given path and return a pointer + * to the location it was inserted at. + */ +static char * +terminate_path_at_separator(char * path) +{ + char * p; + + if ((p = strchr_m(path, '/'))) { + *p = '\0'; + return(p); + } + + if ((p = strchr_m(path, '\\'))) { + *p = '\0'; + return(p); + } + + /* No terminator. Return pointer to the last byte. */ + return(p + strlen(path)); +} + /* parse a //server/share type UNC name */ BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, - const char **hostname, const char **sharename) + char **hostname, char **sharename) { char *p; @@ -189,13 +212,10 @@ BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, } *hostname = talloc_strdup(mem_ctx, &unc_name[2]); - p = strchr_m(&(*hostname)[2],'/'); - if (!p) { - p = strchr_m(&(*hostname)[2],'\\'); - if (!p) return False; - } - *p = 0; + p = terminate_path_at_separator(*hostname); + *sharename = talloc_strdup(mem_ctx, p+1); + p = terminate_path_at_separator(*sharename); return True; } -- cgit From f256a9c55e4785e4383a0546e75bba355a51fa04 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Feb 2006 09:53:50 +0000 Subject: r13342: Make the GSSAPI SASL mech actually work, by (shock horror) reading the spec. GSSAPI differs from GSS-SPNEGO in an additional 3 packets, negotiating a buffer size and what integrity protection/privacy should be used. I worked off draft-ietf-sasl-gssapi-03, and this works against Win2k3. I'm doing this in the hope that Apple clients as well as SASL-based LDAP tools may get a bit further. I still can't get ldapsearch to work, it fails with the ever-helpful 'Local error'. Andrew Bartlett (This used to be commit 3e462897754b30306c1983af2d137329dd937ad6) --- source4/libcli/ldap/ldap_bind.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 1f6ef77631..2880298dd5 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -152,7 +152,6 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr int count, i; const char **sasl_names; - const struct gensec_security_ops **mechs; static const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", @@ -225,17 +224,10 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } sasl_names[i] = NULL; - mechs = gensec_security_by_sasl(conn->gensec, tmp_ctx, sasl_names); - if (!mechs || !mechs[0]) { - DEBUG(1, ("None of the %d proposed SASL mechs were acceptable\n", - count)); - goto failed; - } - - status = gensec_start_mech_by_ops(conn->gensec, mechs[0]); + status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set GENSEC client mechanism: %s/%s %s\n", - mechs[0]->name, mechs[0]->sasl_name, nt_errstr(status))); + DEBUG(1, ("None of the %d proposed SASL mechs were acceptable: %s\n", + count, nt_errstr(status))); goto failed; } @@ -265,11 +257,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr !NT_STATUS_IS_OK(status)) { break; } - if (output.length == 0) { + if (NT_STATUS_IS_OK(status) && output.length == 0) { break; } - msg = new_ldap_sasl_bind_msg(tmp_ctx, "GSS-SPNEGO", &output); + /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */ + msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, &output); if (msg == NULL) { status = NT_STATUS_NO_MEMORY; goto failed; -- cgit From 2e7f35f88faedb5b6e2302c5dacf62709dee12a9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Feb 2006 11:19:09 +0000 Subject: r13344: Trust SASL to have subtle distinctions between NULL and zero-length responses... Also trust OpenLDAP to be pedantic about it, breaking connections to AD. In any case, we now get this 'right' (by nasty overloading hacks, but hey), and we can now use system-supplied OpenLDAP libs and SASL/GSSAPI to talk to Samba4. Andrew Bartlett (This used to be commit 0cbe18211a95f811b51865bc0e8729e9a302ad25) --- source4/libcli/ldap/ldap.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b281f62ed0..496fec527f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -219,8 +219,15 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); - asn1_write_OctetString(&data, r->creds.SASL.secblob.data, - r->creds.SASL.secblob.length); + /* The value of data indicates if this + * optional element exists at all. In SASL + * there is a difference between NULL and + * zero-legnth, but our APIs don't express it + * well */ + if (r->creds.SASL.secblob.data) { + asn1_write_OctetString(&data, r->creds.SASL.secblob.data, + r->creds.SASL.secblob.length); + } asn1_pop_tag(&data); break; default: @@ -234,7 +241,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + /* The value of data indicates if this + * optional element exists at all. In SASL + * there is a difference between NULL and + * zero-legnth, but our APIs don't express it + * well */ + if (r->SASL.secblob.data) { + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + } asn1_pop_tag(&data); break; } -- cgit From 289e9baa1d9ab7fa36d88a5cd50c0a0f706c07bb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 4 Feb 2006 13:54:30 +0000 Subject: r13345: let us replicate with NT4sp6a I don't yet know what the extra data in the start_association call mean... This also let w2k use WREPL_REPL_INFORM messages to us, but w2k3 doesn't it do it yet... metze (This used to be commit 02d6dfa1da754857c28125392a561cfde0087c48) --- source4/libcli/wrepl/winsrepl.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 909bedf530..ba7203c33a 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -563,6 +563,21 @@ struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket, packet->message.start.minor_version = 2; packet->message.start.major_version = 5; + /* + * nt4 uses 41 bytes for the start_association call + * so do it the same and as we don't know th emeanings of this bytes + * we just send zeros and nt4, w2k and w2k3 seems to be happy with this + * + * if we don't do this nt4 uses an old version of the wins replication protocol + * and that would break nt4 <-> samba replication + */ + packet->padding = data_blob_talloc(packet, NULL, 21); + if (packet->padding.data == NULL) { + talloc_free(packet); + return NULL; + } + memset(packet->padding.data, 0, packet->padding.length); + req = wrepl_request_send(wrepl_socket, packet, NULL); talloc_free(packet); -- cgit From ad5e8bbe9d5c2250092bb3a83098c3af46304a82 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 5 Feb 2006 17:28:27 +0000 Subject: r13352: Integrate Patch to support the ManageDSAIT control from Pete Rowley (This used to be commit bf20a848fda1607ca1b0d84791c299c0035793a1) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 1f7a415e8e..cb7b52d423 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -345,6 +345,15 @@ static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); @@ -568,6 +577,16 @@ static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, @@ -576,6 +595,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, + { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { NULL, NULL, NULL } }; -- cgit From 3721bca79dc6ff409085a2fc40cbd060d25191d4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 5 Feb 2006 20:48:27 +0000 Subject: r13354: Add tests to check that controls work properly Fix asq module, add a second_stage_init to register with rootdse Fix asq control ldap parsing routines (this was nasty to find out) (This used to be commit 933a80397d137f7d5b79c82a068d62bb6928ef47) --- source4/libcli/ldap/ldap_controls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index cb7b52d423..e02efdee2c 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -304,7 +304,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { - lac->source_attribute = talloc_memdup(lac, source_attribute.data, source_attribute.length); + lac->source_attribute = talloc_strndup(lac, source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { return False; -- cgit From 338c410fec8dbd902485e56567f6aecf256cdba2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 6 Feb 2006 01:21:17 +0000 Subject: r13361: initial implementation of the vlv control seem still buggy, can't make w2k3 to like it yet (This used to be commit e1318383e91f6f6db39e3e3c9946fbb089753947) --- source4/libcli/ldap/ldap_controls.c | 245 +++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index e02efdee2c..222b4a3358 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -304,7 +304,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { - lac->source_attribute = talloc_strndup(lac, source_attribute.data, source_attribute.length); + lac->source_attribute = talloc_strndup(lac, (char *)source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { return False; @@ -354,6 +354,154 @@ static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB assertion_value, context_id; + struct asn1_data data; + struct ldb_vlv_req_control *lvrc; + + if (!asn1_load(&data, in)) { + return False; + } + + lvrc = talloc(mem_ctx, struct ldb_vlv_req_control); + if (!lvrc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->beforeCount))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->afterCount))) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_SEQUENCE(0))) { + + lvrc->type = 0; + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.offset))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.contentCount))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + } else { + + lvrc->type = 1; + + if (!asn1_read_OctetString(&data, &assertion_value)) { + return False; + } + lvrc->match.gtOrEq.value_len = assertion_value.length; + if (lvrc->match.gtOrEq.value_len) { + lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length); + + if (!(lvrc->match.gtOrEq.value)) { + return False; + } + } else { + lvrc->match.gtOrEq.value = NULL; + } + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(&data, &context_id)) { + return False; + } + lvrc->ctxid_len = context_id.length; + if (lvrc->ctxid_len) { + lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length); + + if (!(lvrc->contextId)) { + return False; + } + } else { + lvrc->contextId = NULL; + } + } else { + lvrc->contextId = NULL; + lvrc->ctxid_len = 0; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lvrc; + + return True; +} + +static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB context_id; + struct asn1_data data; + struct ldb_vlv_resp_control *lvrc; + + if (!asn1_load(&data, in)) { + return False; + } + + lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control); + if (!lvrc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->targetPosition))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->contentCount))) { + return False; + } + + if (!asn1_read_enumerated(&data, &(lvrc->vlv_result))) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(&data, &context_id)) { + return False; + } + lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); + if (!lvrc->contextId) { + return False; + } + lvrc->ctxid_len = context_id.length; + } else { + lvrc->contextId = NULL; + lvrc->ctxid_len = 0; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lvrc; + + return True; +} + static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); @@ -587,6 +735,99 @@ static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->beforeCount)) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->afterCount)) { + return False; + } + + if (lvrc->type == 0) { + if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) { + return False; + } + } else { + + if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { + return False; + } + } + + if (lvrc->ctxid_len) { + if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) { + return False; + } + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + +static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->targetPosition)) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->contentCount)) { + return False; + } + + if (!asn1_write_enumerated(&data, lvrc->vlv_result)) { + return False; + } + + if (lvrc->ctxid_len) { + if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) { + return False; + } + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, @@ -596,6 +837,8 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, + { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, + { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, { NULL, NULL, NULL } }; -- cgit From f7def09a1ec105294b189c0d933f59977a252057 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 6 Feb 2006 22:55:34 +0000 Subject: r13372: fixes ... still no joy (This used to be commit 0e2cca9153619d646b90f32620905ab66b017c6a) --- source4/libcli/ldap/ldap_controls.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 222b4a3358..f85e4843c1 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -755,6 +755,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) } if (lvrc->type == 0) { + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) { return False; } @@ -762,6 +766,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) { return False; } + + if (!asn1_pop_tag(&data)) { + return False; + } } else { if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { -- cgit From b7f7adb2e1068d1c382f774e54d1b495e6345938 Mon Sep 17 00:00:00 2001 From: James Peach Date: Wed, 8 Feb 2006 05:13:11 +0000 Subject: r13387: Make sure smbcli_parse_unc reports a failure for strings of the form //server. Make sure failure cases are well-defined. (This used to be commit e0020df66bf38873eaaacb95cadac55e17f432be) --- source4/libcli/cliconnect.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 9a5236a661..8103208a26 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -177,25 +177,29 @@ struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx) } /* Insert a NULL at the first separator of the given path and return a pointer - * to the location it was inserted at. + * to the remainder of the string. */ static char * terminate_path_at_separator(char * path) { char * p; + if (!path) { + return NULL; + } + if ((p = strchr_m(path, '/'))) { - *p = '\0'; - return(p); + *p = '\0'; + return p + 1; } if ((p = strchr_m(path, '\\'))) { - *p = '\0'; - return(p); + *p = '\0'; + return p + 1; } - /* No terminator. Return pointer to the last byte. */ - return(p + strlen(path)); + /* No separator. */ + return NULL; } /* @@ -206,6 +210,8 @@ BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, { char *p; + *hostname = *sharename = NULL; + if (strncmp(unc_name, "\\\\", 2) && strncmp(unc_name, "//", 2)) { return False; @@ -214,10 +220,19 @@ BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, *hostname = talloc_strdup(mem_ctx, &unc_name[2]); p = terminate_path_at_separator(*hostname); - *sharename = talloc_strdup(mem_ctx, p+1); - p = terminate_path_at_separator(*sharename); + if (p && *p) { + *sharename = talloc_strdup(mem_ctx, p); + terminate_path_at_separator(*sharename); + } - return True; + if (*hostname && *sharename) { + return True; + } + + talloc_free(*hostname); + talloc_free(*sharename); + *hostname = *sharename = NULL; + return False; } -- cgit From debf1c9a926cf91cde577b9f4f31109899757a8e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 9 Feb 2006 03:06:02 +0000 Subject: r13405: Allow a fallback if SPNEGO is somehow disabled in the client, to just NTLMSSP. Andrew Bartlett (This used to be commit 3e96975d910496db87e8e34e310f0f6d283210bf) --- source4/libcli/smb_composite/sesssetup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index bf027a0425..2edeb76503 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -326,7 +326,13 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return status; + chosen_oid = GENSEC_OID_NTLMSSP; + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set (fallback) GENSEC client mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + return status; + } } status = gensec_update(session->gensec, state, -- cgit From 93d6990dd41e1509fb55a7077e3a10834117f244 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 12 Feb 2006 12:04:41 +0000 Subject: r13466: Make it easier to understand what this function actually does. Andrew Bartlett (This used to be commit f075497926f3b8131bf8427ee3a3d5c9e5ee77d7) --- source4/libcli/auth/smbencrypt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 6bc9de2f2b..12c5d2dfb6 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -270,13 +270,13 @@ void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], /* Calculate the LM session key (effective length 40 bits, but changes with each session) */ uint8_t p24[24]; - uint8_t p21[21]; + uint8_t partial_lm_hash[14]; - memset(p21,'\0',21); - memcpy(p21, lm_hash, 8); - memset(p21 + 8, 0xbd, 8); + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 6); - E_P24(p21, lm_resp, p24); + des_crypt56(p24, lm_resp, partial_lm_hash, 1); + des_crypt56(p24+8, lm_resp, partial_lm_hash + 7, 1); memcpy(sess_key, p24, 16); -- cgit From 048704a7e54573086e7913519d2b72577a34b135 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Feb 2006 04:18:11 +0000 Subject: r13505: allow servers to bind to non-broadcast interfaces. Servers now specifically ask for iface_n_bcast() and have to check if it returns NULL, in which case it is a non-broadcast interface (This used to be commit d004e250b6710251ea089ac242775481f13b5c2b) --- source4/libcli/resolve/bcast.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index c95fe945b1..f8ea6b2b3b 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -31,19 +31,22 @@ struct composite_context *resolve_name_bcast_send(struct nbt_name *name, int num_interfaces = iface_count(); const char **address_list; struct composite_context *c; - int i; + int i, count=0; address_list = talloc_array(NULL, const char *, num_interfaces+1); if (address_list == NULL) return NULL; for (i=0;i Date: Wed, 15 Feb 2006 13:33:33 +0000 Subject: r13506: zero memory as some ASN.1 elements are optional, and we should initialize them for the internal use... found by 'make valgrindtest' metze (This used to be commit 1db9501c5261a974c6da1938537c7991ff6cfefd) --- source4/libcli/ldap/ldap_controls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index f85e4843c1..4a28fa510b 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -98,7 +98,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) if (!lssc) { return False; } - lssc[num] = talloc(lssc, struct ldb_server_sort_control); + lssc[num] = talloc_zero(lssc, struct ldb_server_sort_control); if (!lssc[num]) { return False; } -- cgit From 7449f4d8030e7d4a14c75d35af5ea68cf682d24f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Feb 2006 15:19:10 +0000 Subject: r13508: some ASN.1 element in LDAP are optional, make it possible to code the difference between a zero length and a NULL DATA_BLOB... metze (This used to be commit 54f0b19c55df8ad3882f31a114e2ea0e4cf940ae) --- source4/libcli/ldap/ldap.c | 102 ++++++++++++++++++++++++------------ source4/libcli/ldap/ldap.h | 12 ++--- source4/libcli/ldap/ldap_bind.c | 19 +++++-- source4/libcli/ldap/ldap_controls.c | 34 +++++++----- 4 files changed, 112 insertions(+), 55 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 496fec527f..55f1361e16 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -219,14 +219,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); - /* The value of data indicates if this - * optional element exists at all. In SASL - * there is a difference between NULL and - * zero-legnth, but our APIs don't express it - * well */ - if (r->creds.SASL.secblob.data) { - asn1_write_OctetString(&data, r->creds.SASL.secblob.data, - r->creds.SASL.secblob.length); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(&data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); } asn1_pop_tag(&data); break; @@ -241,13 +236,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - /* The value of data indicates if this - * optional element exists at all. In SASL - * there is a difference between NULL and - * zero-legnth, but our APIs don't express it - * well */ - if (r->SASL.secblob.data) { - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + if (r->SASL.secblob) { + asn1_write_ContextSimple(&data, 7, r->SASL.secblob); } asn1_pop_tag(&data); break; @@ -396,7 +386,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); asn1_write_BOOLEAN(&data, r->deleteolddn); - if (r->newsuperior != NULL) { + if (r->newsuperior) { asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->newsuperior, strlen(r->newsuperior)); @@ -452,9 +442,11 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->oid, strlen(r->oid)); asn1_pop_tag(&data); - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(&data, r->value.data, r->value.length); - asn1_pop_tag(&data); + if (r->value) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(&data, r->value->data, r->value->length); + asn1_pop_tag(&data); + } asn1_pop_tag(&data); break; } @@ -462,6 +454,16 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); + if (r->oid) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(&data, r->oid, strlen(r->oid)); + asn1_pop_tag(&data); + } + if (r->value) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(&data, r->value->data, r->value->length); + asn1_pop_tag(&data); + } asn1_pop_tag(&data); break; } @@ -960,12 +962,17 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->mechanism = LDAP_AUTH_MECH_SASL; asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - asn1_read_OctetString(data, &r->creds.SASL.secblob); - if (r->creds.SASL.secblob.data) { - talloc_steal(msg, r->creds.SASL.secblob.data); + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return False; } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); } else { - r->creds.SASL.secblob = data_blob(NULL, 0); + r->creds.SASL.secblob = NULL; } asn1_end_tag(data); } @@ -981,10 +988,15 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return False; + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { - r->SASL.secblob = data_blob(NULL, 0); + r->SASL.secblob = NULL; } asn1_end_tag(data); break; @@ -1241,10 +1253,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return False; + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { - r->value = data_blob(NULL, 0); + r->value = NULL; } asn1_end_tag(data); @@ -1253,15 +1269,35 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + msg->type = LDAP_TAG_ExtendedResponse; asn1_start_tag(data, tag); ldap_decode_response(msg, data, &r->response); - /* I have to come across an operation that actually sends - * something back to really see what's going on. The currently - * needed pwdchange does not send anything back. */ - r->name = NULL; - r->value.data = NULL; - r->value.length = 0; + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return False; + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return False; + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + asn1_end_tag(data); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 5283553f13..de284d23d1 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -109,7 +109,7 @@ struct ldap_BindRequest { const char *password; struct { const char *mechanism; - DATA_BLOB secblob; + DATA_BLOB *secblob;/* optional */ } SASL; } creds; }; @@ -117,7 +117,7 @@ struct ldap_BindRequest { struct ldap_BindResponse { struct ldap_Result response; union { - DATA_BLOB secblob; + DATA_BLOB *secblob;/* optional */ } SASL; }; @@ -192,7 +192,7 @@ struct ldap_ModifyDNRequest { const char *dn; const char *newrdn; BOOL deleteolddn; - const char *newsuperior; + const char *newsuperior;/* optional */ }; struct ldap_CompareRequest { @@ -207,13 +207,13 @@ struct ldap_AbandonRequest { struct ldap_ExtendedRequest { const char *oid; - DATA_BLOB value; + DATA_BLOB *value;/* optional */ }; struct ldap_ExtendedResponse { struct ldap_Result response; - const char *name; - DATA_BLOB value; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ }; union ldap_Request { diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2880298dd5..cacb0d150e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -129,7 +129,16 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, res->r.BindRequest.dn = ""; res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism); - res->r.BindRequest.creds.SASL.secblob = *secblob; + if (secblob) { + res->r.BindRequest.creds.SASL.secblob = talloc(res, DATA_BLOB); + if (!res->r.BindRequest.creds.SASL.secblob) { + talloc_free(res); + return NULL; + } + *res->r.BindRequest.creds.SASL.secblob = *secblob; + } else { + res->r.BindRequest.creds.SASL.secblob = NULL; + } res->controls = NULL; return res; @@ -262,7 +271,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */ - msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, &output); + msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, (output.data?&output:NULL)); if (msg == NULL) { status = NT_STATUS_NO_MEMORY; goto failed; @@ -297,7 +306,11 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr if (!NT_STATUS_EQUAL(gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { break; } - input = response->r.BindResponse.SASL.secblob; + if (response->r.BindResponse.SASL.secblob) { + input = *response->r.BindResponse.SASL.secblob; + } else { + input = data_blob(NULL, 0); + } } if (NT_STATUS_IS_OK(status) && diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 4a28fa510b..5bd46cf7a9 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -304,7 +304,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { - lac->source_attribute = talloc_strndup(lac, (char *)source_attribute.data, source_attribute.length); + lac->source_attribute = talloc_strndup(lac, (const char *)source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { return False; @@ -864,7 +864,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont return False; } ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); - if (!(ctrl->oid)) { + if (!ctrl->oid) { return False; } @@ -878,13 +878,17 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont ctrl->value = NULL; + if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { + goto end_tag; + } + + if (!asn1_read_OctetString(data, &value)) { + return False; + } + for (i = 0; ldap_known_controls[i].oid != NULL; i++) { if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - - if (!asn1_read_OctetString(data, &value)) { - return False; - } - if (!ldap_known_controls[i].decode(mem_ctx, value, &(ctrl->value))) { + if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->value)) { return False; } break; @@ -894,6 +898,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont return False; } +end_tag: if (!asn1_end_tag(data)) { return False; } @@ -909,17 +914,21 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - + if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { return False; } - + if (ctrl->critical) { if (!asn1_write_BOOLEAN(data, ctrl->critical)) { return False; } } + if (!ctrl->value) { + goto pop_tag; + } + for (i = 0; ldap_known_controls[i].oid != NULL; i++) { if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { if (!ldap_known_controls[i].encode(mem_ctx, ctrl->value, &value)) { @@ -932,12 +941,11 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont return False; } - if (value.length != 0) { - if (!asn1_write_OctetString(data, value.data, value.length)) { - return False; - } + if (!asn1_write_OctetString(data, value.data, value.length)) { + return False; } +pop_tag: if (!asn1_pop_tag(data)) { return False; } -- cgit From 00fe70e5b917769418f68eaa255d3a06a9a08ce7 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Feb 2006 01:31:35 +0000 Subject: r13609: Get in the initial work on making ldb async Currently only ldb_ildap is async, the plan is to first make all backend support the async calls, and then remove the sync functions from backends and keep the only in the API. Modules will need to be transformed along the way. Simo (This used to be commit 1e2c13b2d52de7c534493dd79a2c0596a3e8c1f5) --- source4/libcli/ldap/ldap.c | 8 +++--- source4/libcli/ldap/ldap.h | 8 +----- source4/libcli/ldap/ldap_client.c | 34 ++++++++++++------------- source4/libcli/ldap/ldap_client.h | 4 ++- source4/libcli/ldap/ldap_controls.c | 49 ++++++++++++++++++++++++++++++------- source4/libcli/ldap/ldap_ildap.c | 14 ++++++----- 6 files changed, 73 insertions(+), 44 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 55f1361e16..42cad3a63e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1309,19 +1309,19 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { int i; - struct ldap_Control **ctrl = NULL; + struct ldb_control **ctrl = NULL; asn1_start_tag(data, ASN1_CONTEXT(0)); for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - ctrl = talloc_realloc(msg, ctrl, struct ldap_Control *, i+2); + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); if (!ctrl) { return False; } - ctrl[i] = talloc(ctrl, struct ldap_Control); + ctrl[i] = talloc(ctrl, struct ldb_control); if (!ctrl[i]) { return False; } @@ -1348,7 +1348,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_OK if a blob has enough bytes in it to be a full ldap packet. Set packet_size if true. */ -NTSTATUS ldap_full_packet(void *private, DATA_BLOB blob, size_t *packet_size) +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) { return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index de284d23d1..1deabf0b10 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -240,17 +240,11 @@ union ldap_Request { struct ldap_ExtendedResponse ExtendedResponse; }; -struct ldap_Control { - const char *oid; - BOOL critical; - void *value; -}; - struct ldap_message { int messageid; enum ldap_request_tag type; union ldap_Request r; - struct ldap_Control **controls; + struct ldb_control **controls; }; #include "libcli/ldap/ldap_proto.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 9103e939e7..364961cf47 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -90,9 +90,9 @@ static void ldap_connection_dead(struct ldap_connection *conn) /* handle packet errors */ -static void ldap_error_handler(void *private, NTSTATUS status) +static void ldap_error_handler(void *private_data, NTSTATUS status) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); ldap_connection_dead(conn); } @@ -155,14 +155,14 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message check if a blob is a complete ldap packet handle wrapper or unwrapped connections */ -NTSTATUS ldap_complete_packet(void *private, DATA_BLOB blob, size_t *size) +NTSTATUS ldap_complete_packet(void *private_data, DATA_BLOB blob, size_t *size) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); if (conn->enable_wrap) { - return packet_full_request_u32(private, blob, size); + return packet_full_request_u32(private_data, blob, size); } - return ldap_full_packet(private, blob, size); + return ldap_full_packet(private_data, blob, size); } /* @@ -234,9 +234,9 @@ static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob /* handle ldap recv events */ -static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob) +static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); if (conn->enable_wrap) { return ldap_decode_wrapped(conn, blob); @@ -250,9 +250,9 @@ static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob) handle ldap socket events */ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) + uint16_t flags, void *private_data) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); if (flags & EVENT_FD_WRITE) { packet_queue_run(conn->packet); @@ -433,9 +433,9 @@ static int ldap_request_destructor(void *ptr) called on timeout of a ldap request */ static void ldap_request_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) + struct timeval t, void *private_data) { - struct ldap_request *req = talloc_get_type(private, struct ldap_request); + struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); req->status = NT_STATUS_IO_TIMEOUT; if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); @@ -451,9 +451,9 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t called on completion of a one-way ldap request */ static void ldap_request_complete(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) + struct timeval t, void *private_data) { - struct ldap_request *req = talloc_get_type(private, struct ldap_request); + struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); if (req->async.fn) { req->async.fn(req); } @@ -534,9 +534,9 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, DLIST_ADD(conn->pending, req); /* put a timeout on the request */ - event_add_timed(conn->event.event_ctx, req, - timeval_current_ofs(conn->timeout, 0), - ldap_request_timeout, req); + req->time_event = event_add_timed(conn->event.event_ctx, req, + timeval_current_ofs(conn->timeout, 0), + ldap_request_timeout, req); return req; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index ee458dc5b0..3f71c42f22 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -42,8 +42,10 @@ struct ldap_request { DATA_BLOB data; struct { void (*fn)(struct ldap_request *); - void *private; + void *private_data; } async; + + struct timed_event *time_event; }; diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 5bd46cf7a9..373b71d370 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -381,10 +381,14 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (asn1_peek_tag(&data, ASN1_SEQUENCE(0))) { + if (asn1_peek_tag(&data, ASN1_CONTEXT(0))) { lvrc->type = 0; + if (!asn1_start_tag(&data, ASN1_CONTEXT(0))) { + return False; + } + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { return False; } @@ -397,7 +401,11 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(&data)) { /*SEQUENCE*/ + return False; + } + + if (!asn1_end_tag(&data)) { /*CONTEXT*/ return False; } @@ -405,6 +413,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 1; + if (!asn1_start_tag(&data, ASN1_CONTEXT(1))) { + return False; + } + if (!asn1_read_OctetString(&data, &assertion_value)) { return False; } @@ -418,6 +430,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) } else { lvrc->match.gtOrEq.value = NULL; } + + if (!asn1_end_tag(&data)) { /*CONTEXT*/ + return False; + } } if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { @@ -755,6 +771,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) } if (lvrc->type == 0) { + if (!asn1_push_tag(&data, ASN1_CONTEXT(0))) { + return False; + } + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { return False; } @@ -767,14 +787,25 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(&data)) { /*SEQUENCE*/ + return False; + } + + if (!asn1_pop_tag(&data)) { /*CONTEXT*/ return False; } } else { + if (!asn1_push_tag(&data, ASN1_CONTEXT(1))) { + return False; + } if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { return False; } + + if (!asn1_pop_tag(&data)) { /*CONTEXT*/ + return False; + } } if (lvrc->ctxid_len) { @@ -850,7 +881,7 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl) +BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) { int i; DATA_BLOB oid; @@ -876,7 +907,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont ctrl->critical = False; } - ctrl->value = NULL; + ctrl->data = NULL; if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { goto end_tag; @@ -888,7 +919,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont for (i = 0; ldap_known_controls[i].oid != NULL; i++) { if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->value)) { + if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { return False; } break; @@ -906,7 +937,7 @@ end_tag: return True; } -BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl) +BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) { DATA_BLOB value; int i; @@ -925,13 +956,13 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont } } - if (!ctrl->value) { + if (!ctrl->data) { goto pop_tag; } for (i = 0; ldap_known_controls[i].oid != NULL; i++) { if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].encode(mem_ctx, ctrl->value, &value)) { + if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { return False; } break; diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index a5227ec37f..f26fb7db78 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -152,13 +152,13 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) /* - perform a ldap search + perform a synchronous ldap search */ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, int scope, struct ldb_parse_tree *tree, const char * const *attrs, BOOL attributesonly, - struct ldap_Control **control_req, - struct ldap_Control ***control_res, + struct ldb_control **control_req, + struct ldb_control ***control_res, struct ldap_message ***results) { struct ldap_message *msg; @@ -203,7 +203,9 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, break; } - if (res->type != LDAP_TAG_SearchResultEntry) continue; + if (res->type != LDAP_TAG_SearchResultEntry && + res->type != LDAP_TAG_SearchResultReference) + continue; (*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2); if (*results == NULL) { @@ -228,8 +230,8 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, int scope, const char *expression, const char * const *attrs, BOOL attributesonly, - struct ldap_Control **control_req, - struct ldap_Control ***control_res, + struct ldb_control **control_req, + struct ldb_control ***control_res, struct ldap_message ***results) { struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); -- cgit From 10d88a02d727ae16336eec8f696a94b76c1132cd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 11:29:01 +0000 Subject: r13652: Move some more stuff out off include/ (This used to be commit 26bf2a393b90acc098be0b30886dbba34d348a01) --- source4/libcli/rap/rap.h | 345 +++++++++++++++++++++++++ source4/libcli/util/doserr.h | 266 ++++++++++++++++++++ source4/libcli/util/nterr.h | 587 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1198 insertions(+) create mode 100644 source4/libcli/rap/rap.h create mode 100644 source4/libcli/util/doserr.h create mode 100644 source4/libcli/util/nterr.h (limited to 'source4/libcli') diff --git a/source4/libcli/rap/rap.h b/source4/libcli/rap/rap.h new file mode 100644 index 0000000000..c831f6f007 --- /dev/null +++ b/source4/libcli/rap/rap.h @@ -0,0 +1,345 @@ +/* + Unix SMB/CIFS implementation. + RAP operations + Copyright (C) Volker Lendecke 2004 + + 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 RAP_WshareEnum 0 +#define RAP_WshareGetInfo 1 +#define RAP_WshareSetInfo 2 +#define RAP_WshareAdd 3 +#define RAP_WshareDel 4 +#define RAP_NetShareCheck 5 +#define RAP_WsessionEnum 6 +#define RAP_WsessionGetInfo 7 +#define RAP_WsessionDel 8 +#define RAP_WconnectionEnum 9 +#define RAP_WfileEnum 10 +#define RAP_WfileGetInfo 11 +#define RAP_WfileClose 12 +#define RAP_WserverGetInfo 13 +#define RAP_WserverSetInfo 14 +#define RAP_WserverDiskEnum 15 +#define RAP_WserverAdminCommand 16 +#define RAP_NetAuditOpen 17 +#define RAP_WauditClear 18 +#define RAP_NetErrorLogOpen 19 +#define RAP_WerrorLogClear 20 +#define RAP_NetCharDevEnum 21 +#define RAP_NetCharDevGetInfo 22 +#define RAP_WCharDevControl 23 +#define RAP_NetCharDevQEnum 24 +#define RAP_NetCharDevQGetInfo 25 +#define RAP_WCharDevQSetInfo 26 +#define RAP_WCharDevQPurge 27 +#define RAP_WCharDevQPurgeSelf 28 +#define RAP_WMessageNameEnum 29 +#define RAP_WMessageNameGetInfo 30 +#define RAP_WMessageNameAdd 31 +#define RAP_WMessageNameDel 32 +#define RAP_WMessageNameFwd 33 +#define RAP_WMessageNameUnFwd 34 +#define RAP_WMessageBufferSend 35 +#define RAP_WMessageFileSend 36 +#define RAP_WMessageLogFileSet 37 +#define RAP_WMessageLogFileGet 38 +#define RAP_WServiceEnum 39 +#define RAP_WServiceInstall 40 +#define RAP_WServiceControl 41 +#define RAP_WAccessEnum 42 +#define RAP_WAccessGetInfo 43 +#define RAP_WAccessSetInfo 44 +#define RAP_WAccessAdd 45 +#define RAP_WAccessDel 46 +#define RAP_WGroupEnum 47 +#define RAP_WGroupAdd 48 +#define RAP_WGroupDel 49 +#define RAP_WGroupAddUser 50 +#define RAP_WGroupDelUser 51 +#define RAP_WGroupGetUsers 52 +#define RAP_WUserEnum 53 +#define RAP_WUserAdd 54 +#define RAP_WUserDel 55 +#define RAP_WUserGetInfo 56 +#define RAP_WUserSetInfo 57 +#define RAP_WUserPasswordSet 58 +#define RAP_WUserGetGroups 59 +#define RAP_WWkstaSetUID 62 +#define RAP_WWkstaGetInfo 63 +#define RAP_WWkstaSetInfo 64 +#define RAP_WUseEnum 65 +#define RAP_WUseAdd 66 +#define RAP_WUseDel 67 +#define RAP_WUseGetInfo 68 +#define RAP_WPrintQEnum 69 +#define RAP_WPrintQGetInfo 70 +#define RAP_WPrintQSetInfo 71 +#define RAP_WPrintQAdd 72 +#define RAP_WPrintQDel 73 +#define RAP_WPrintQPause 74 +#define RAP_WPrintQContinue 75 +#define RAP_WPrintJobEnum 76 +#define RAP_WPrintJobGetInfo 77 +#define RAP_WPrintJobSetInfo_OLD 78 +#define RAP_WPrintJobDel 81 +#define RAP_WPrintJobPause 82 +#define RAP_WPrintJobContinue 83 +#define RAP_WPrintDestEnum 84 +#define RAP_WPrintDestGetInfo 85 +#define RAP_WPrintDestControl 86 +#define RAP_WProfileSave 87 +#define RAP_WProfileLoad 88 +#define RAP_WStatisticsGet 89 +#define RAP_WStatisticsClear 90 +#define RAP_NetRemoteTOD 91 +#define RAP_WNetBiosEnum 92 +#define RAP_WNetBiosGetInfo 93 +#define RAP_NetServerEnum 94 +#define RAP_I_NetServerEnum 95 +#define RAP_WServiceGetInfo 96 +#define RAP_WPrintQPurge 103 +#define RAP_NetServerEnum2 104 +#define RAP_WAccessGetUserPerms 105 +#define RAP_WGroupGetInfo 106 +#define RAP_WGroupSetInfo 107 +#define RAP_WGroupSetUsers 108 +#define RAP_WUserSetGroups 109 +#define RAP_WUserModalsGet 110 +#define RAP_WUserModalsSet 111 +#define RAP_WFileEnum2 112 +#define RAP_WUserAdd2 113 +#define RAP_WUserSetInfo2 114 +#define RAP_WUserPasswordSet2 115 +#define RAP_I_NetServerEnum2 116 +#define RAP_WConfigGet2 117 +#define RAP_WConfigGetAll2 118 +#define RAP_WGetDCName 119 +#define RAP_NetHandleGetInfo 120 +#define RAP_NetHandleSetInfo 121 +#define RAP_WStatisticsGet2 122 +#define RAP_WBuildGetInfo 123 +#define RAP_WFileGetInfo2 124 +#define RAP_WFileClose2 125 +#define RAP_WNetServerReqChallenge 126 +#define RAP_WNetServerAuthenticate 127 +#define RAP_WNetServerPasswordSet 128 +#define RAP_WNetAccountDeltas 129 +#define RAP_WNetAccountSync 130 +#define RAP_WUserEnum2 131 +#define RAP_WWkstaUserLogon 132 +#define RAP_WWkstaUserLogoff 133 +#define RAP_WLogonEnum 134 +#define RAP_WErrorLogRead 135 +#define RAP_NetPathType 136 +#define RAP_NetPathCanonicalize 137 +#define RAP_NetPathCompare 138 +#define RAP_NetNameValidate 139 +#define RAP_NetNameCanonicalize 140 +#define RAP_NetNameCompare 141 +#define RAP_WAuditRead 142 +#define RAP_WPrintDestAdd 143 +#define RAP_WPrintDestSetInfo 144 +#define RAP_WPrintDestDel 145 +#define RAP_WUserValidate2 146 +#define RAP_WPrintJobSetInfo 147 +#define RAP_TI_NetServerDiskEnum 148 +#define RAP_TI_NetServerDiskGetInfo 149 +#define RAP_TI_FTVerifyMirror 150 +#define RAP_TI_FTAbortVerify 151 +#define RAP_TI_FTGetInfo 152 +#define RAP_TI_FTSetInfo 153 +#define RAP_TI_FTLockDisk 154 +#define RAP_TI_FTFixError 155 +#define RAP_TI_FTAbortFix 156 +#define RAP_TI_FTDiagnoseError 157 +#define RAP_TI_FTGetDriveStats 158 +#define RAP_TI_FTErrorGetInfo 160 +#define RAP_NetAccessCheck 163 +#define RAP_NetAlertRaise 164 +#define RAP_NetAlertStart 165 +#define RAP_NetAlertStop 166 +#define RAP_NetAuditWrite 167 +#define RAP_NetIRemoteAPI 168 +#define RAP_NetServiceStatus 169 +#define RAP_NetServerRegister 170 +#define RAP_NetServerDeregister 171 +#define RAP_NetSessionEntryMake 172 +#define RAP_NetSessionEntryClear 173 +#define RAP_NetSessionEntryGetInfo 174 +#define RAP_NetSessionEntrySetInfo 175 +#define RAP_NetConnectionEntryMake 176 +#define RAP_NetConnectionEntryClear 177 +#define RAP_NetConnectionEntrySetInfo 178 +#define RAP_NetConnectionEntryGetInfo 179 +#define RAP_NetFileEntryMake 180 +#define RAP_NetFileEntryClear 181 +#define RAP_NetFileEntrySetInfo 182 +#define RAP_NetFileEntryGetInfo 183 +#define RAP_AltSrvMessageBufferSend 184 +#define RAP_AltSrvMessageFileSend 185 +#define RAP_wI_NetRplWkstaEnum 186 +#define RAP_wI_NetRplWkstaGetInfo 187 +#define RAP_wI_NetRplWkstaSetInfo 188 +#define RAP_wI_NetRplWkstaAdd 189 +#define RAP_wI_NetRplWkstaDel 190 +#define RAP_wI_NetRplProfileEnum 191 +#define RAP_wI_NetRplProfileGetInfo 192 +#define RAP_wI_NetRplProfileSetInfo 193 +#define RAP_wI_NetRplProfileAdd 194 +#define RAP_wI_NetRplProfileDel 195 +#define RAP_wI_NetRplProfileClone 196 +#define RAP_wI_NetRplBaseProfileEnum 197 +#define RAP_WIServerSetInfo 201 +#define RAP_WPrintDriverEnum 205 +#define RAP_WPrintQProcessorEnum 206 +#define RAP_WPrintPortEnum 207 +#define RAP_WNetWriteUpdateLog 208 +#define RAP_WNetAccountUpdate 209 +#define RAP_WNetAccountConfirmUpdate 210 +#define RAP_WConfigSet 211 +#define RAP_WAccountsReplicate 212 +#define RAP_SamOEMChgPasswordUser2_P 214 +#define RAP_NetServerEnum3 215 +#define RAP_WprintDriverGetInfo 250 +#define RAP_WprintDriverSetInfo 251 +#define RAP_WaliasAdd 252 +#define RAP_WaliasDel 253 +#define RAP_WaliasGetInfo 254 +#define RAP_WaliasSetInfo 255 +#define RAP_WaliasEnum 256 +#define RAP_WuserGetLogonAsn 257 +#define RAP_WuserSetLogonAsn 258 +#define RAP_WuserGetAppSel 259 +#define RAP_WuserSetAppSel 260 +#define RAP_WappAdd 261 +#define RAP_WappDel 262 +#define RAP_WappGetInfo 263 +#define RAP_WappSetInfo 264 +#define RAP_WappEnum 265 +#define RAP_WUserDCDBInit 266 +#define RAP_WDASDAdd 267 +#define RAP_WDASDDel 268 +#define RAP_WDASDGetInfo 269 +#define RAP_WDASDSetInfo 270 +#define RAP_WDASDEnum 271 +#define RAP_WDASDCheck 272 +#define RAP_WDASDCtl 273 +#define RAP_WuserRemoteLogonCheck 274 +#define RAP_WUserPasswordSet3 275 +#define RAP_WCreateRIPLMachine 276 +#define RAP_WDeleteRIPLMachine 277 +#define RAP_WGetRIPLMachineInfo 278 +#define RAP_WSetRIPLMachineInfo 279 +#define RAP_WEnumRIPLMachine 280 +#define RAP_I_ShareAdd 281 +#define RAP_AliasEnum 282 +#define RAP_WaccessApply 283 +#define RAP_WPrt16Query 284 +#define RAP_WPrt16Set 285 +#define RAP_WUserDel100 286 +#define RAP_WUserRemoteLogonCheck2 287 +#define RAP_WRemoteTODSet 294 +#define RAP_WprintJobMoveAll 295 +#define RAP_W16AppParmAdd 296 +#define RAP_W16AppParmDel 297 +#define RAP_W16AppParmGet 298 +#define RAP_W16AppParmSet 299 +#define RAP_W16RIPLMachineCreate 300 +#define RAP_W16RIPLMachineGetInfo 301 +#define RAP_W16RIPLMachineSetInfo 302 +#define RAP_W16RIPLMachineEnum 303 +#define RAP_W16RIPLMachineListParmEnum 304 +#define RAP_W16RIPLMachClassGetInfo 305 +#define RAP_W16RIPLMachClassEnum 306 +#define RAP_W16RIPLMachClassCreate 307 +#define RAP_W16RIPLMachClassSetInfo 308 +#define RAP_W16RIPLMachClassDelete 309 +#define RAP_W16RIPLMachClassLPEnum 310 +#define RAP_W16RIPLMachineDelete 311 +#define RAP_W16WSLevelGetInfo 312 +#define RAP_WserverNameAdd 313 +#define RAP_WserverNameDel 314 +#define RAP_WserverNameEnum 315 +#define RAP_I_WDASDEnum 316 +#define RAP_WDASDEnumTerminate 317 +#define RAP_WDASDSetInfo2 318 +#define MAX_API 318 + +struct rap_shareenum_info_0 { + char name[13]; +}; + +struct rap_shareenum_info_1 { + char name[13]; + char pad; + uint16_t type; + char *comment; +}; + +union rap_shareenum_info { + struct rap_shareenum_info_0 info0; + struct rap_shareenum_info_1 info1; +}; + +struct rap_NetShareEnum { + struct { + uint16_t level; + uint16_t bufsize; + } in; + + struct { + uint16_t status; + uint16_t convert; + uint16_t count; + uint16_t available; + union rap_shareenum_info *info; + } out; +}; + +struct rap_server_info_0 { + char name[16]; +}; + +struct rap_server_info_1 { + char name[16]; + uint8_t version_major; + uint8_t version_minor; + uint32_t servertype; + char *comment; +}; + +union rap_server_info { + struct rap_server_info_0 info0; + struct rap_server_info_1 info1; +}; + +struct rap_NetServerEnum2 { + struct { + uint16_t level; + uint16_t bufsize; + uint32_t servertype; + const char *domain; + } in; + + struct { + uint16_t status; + uint16_t convert; + uint16_t count; + uint16_t available; + union rap_server_info *info; + } out; +}; diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h new file mode 100644 index 0000000000..5b8ff1dd3d --- /dev/null +++ b/source4/libcli/util/doserr.h @@ -0,0 +1,266 @@ +/* + Unix SMB/CIFS implementation. + DOS error code constants + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) John H Terpstra 1996-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Paul Ashton 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. +*/ + +#ifndef _DOSERR_H +#define _DOSERR_H + +/* Error classes */ + +#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */ +#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/ +#define ERRHRD 0x03 /* Error is an hardware error. */ +#define ERRCMD 0xFF /* Command was not in the "SMB" format. */ + +/* SMB X/Open error codes for the ERRDOS error class */ +#define ERRsuccess 0 /* No error */ +#define ERRbadfunc 1 /* Invalid function (or system call) */ +#define ERRbadfile 2 /* File not found (pathname error) */ +#define ERRbadpath 3 /* Directory not found */ +#define ERRnofids 4 /* Too many open files */ +#define ERRnoaccess 5 /* Access denied */ +#define ERRbadfid 6 /* Invalid fid */ +#define ERRbadmcb 7 /* Memory control blocks destroyed. */ +#define ERRnomem 8 /* Out of memory */ +#define ERRbadmem 9 /* Invalid memory block address */ +#define ERRbadenv 10 /* Invalid environment */ +#define ERRbadaccess 12 /* Invalid open mode */ +#define ERRbaddata 13 /* Invalid data (only from ioctl call) */ +#define ERRres 14 /* reserved */ +#define ERRbaddrive 15 /* Invalid drive */ +#define ERRremcd 16 /* Attempt to delete current directory */ +#define ERRdiffdevice 17 /* rename/move across different filesystems */ +#define ERRnofiles 18 /* no more files found in file search */ +#define ERRgeneral 31 /* General failure */ +#define ERRbadshare 32 /* Share mode on file conflict with open mode */ +#define ERRlock 33 /* Lock request conflicts with existing lock */ +#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */ +#define ERRnetnamedel 64 /* Network name deleted or not available */ +#define ERRnosuchshare 67 /* You specified an invalid share name */ +#define ERRfilexists 80 /* File in operation already exists */ +#define ERRinvalidparam 87 +#define ERRcannotopen 110 /* Cannot open the file specified */ +#define ERRinsufficientbuffer 122 +#define ERRinvalidname 123 /* Invalid name */ +#define ERRunknownlevel 124 +#define ERRnotlocked 158 /* This region is not locked by this locking context. */ +#define ERRinvalidpath 161 +#define ERRcancelviolation 173 +#define ERRnoatomiclocks 174 +#define ERRrename 183 +#define ERRbadpipe 230 /* Named pipe invalid */ +#define ERRpipebusy 231 /* All instances of pipe are busy */ +#define ERRpipeclosing 232 /* named pipe close in progress */ +#define ERRnotconnected 233 /* No process on other end of named pipe */ +#define ERRmoredata 234 /* More data to be returned */ +#define ERReainconsistent 255 /* from EMC */ +#define ERRnomoreitems 259 +#define ERRbaddirectory 267 /* Invalid directory name in a path. */ +#define ERReasnotsupported 282 /* Extended attributes */ +#define ERRlogonfailure 1326 /* Unknown username or bad password */ +#define ERRbuftoosmall 2123 +#define ERRunknownipc 2142 +#define ERRnosuchprintjob 2151 +#define ERRinvgroup 2455 + +/* here's a special one from observing NT */ +#define ERRnoipc 66 /* don't support ipc */ + +/* These errors seem to be only returned by the NT printer driver system */ +#define ERRdriveralreadyinstalled 1795 /* ERROR_PRINTER_DRIVER_ALREADY_INSTALLED */ +#define ERRunknownprinterport 1796 /* ERROR_UNKNOWN_PORT */ +#define ERRunknownprinterdriver 1797 /* ERROR_UNKNOWN_PRINTER_DRIVER */ +#define ERRunknownprintprocessor 1798 /* ERROR_UNKNOWN_PRINTPROCESSOR */ +#define ERRinvalidseparatorfile 1799 /* ERROR_INVALID_SEPARATOR_FILE */ +#define ERRinvalidjobpriority 1800 /* ERROR_INVALID_PRIORITY */ +#define ERRinvalidprintername 1801 /* ERROR_INVALID_PRINTER_NAME */ +#define ERRprinteralreadyexists 1802 /* ERROR_PRINTER_ALREADY_EXISTS */ +#define ERRinvalidprintercommand 1803 /* ERROR_INVALID_PRINTER_COMMAND */ +#define ERRinvaliddatatype 1804 /* ERROR_INVALID_DATATYPE */ +#define ERRinvalidenvironment 1805 /* ERROR_INVALID_ENVIRONMENT */ + +#define ERRunknownprintmonitor 3000 /* ERROR_UNKNOWN_PRINT_MONITOR */ +#define ERRprinterdriverinuse 3001 /* ERROR_PRINTER_DRIVER_IN_USE */ +#define ERRspoolfilenotfound 3002 /* ERROR_SPOOL_FILE_NOT_FOUND */ +#define ERRnostartdoc 3003 /* ERROR_SPL_NO_STARTDOC */ +#define ERRnoaddjob 3004 /* ERROR_SPL_NO_ADDJOB */ +#define ERRprintprocessoralreadyinstalled 3005 /* ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED */ +#define ERRprintmonitoralreadyinstalled 3006 /* ERROR_PRINT_MONITOR_ALREADY_INSTALLED */ +#define ERRinvalidprintmonitor 3007 /* ERROR_INVALID_PRINT_MONITOR */ +#define ERRprintmonitorinuse 3008 /* ERROR_PRINT_MONITOR_IN_USE */ +#define ERRprinterhasjobsqueued 3009 /* ERROR_PRINTER_HAS_JOBS_QUEUED */ + +/* Error codes for the ERRSRV class */ + +#define ERRerror 1 /* Non specific error code */ +#define ERRbadpw 2 /* Bad password */ +#define ERRbadtype 3 /* reserved */ +#define ERRaccess 4 /* No permissions to do the requested operation */ +#define ERRinvnid 5 /* tid invalid */ +#define ERRinvnetname 6 /* Invalid servername */ +#define ERRinvdevice 7 /* Invalid device */ +#define ERRqfull 49 /* Print queue full */ +#define ERRqtoobig 50 /* Queued item too big */ +#define ERRinvpfid 52 /* Invalid print file in smb_fid */ +#define ERRsmbcmd 64 /* Unrecognised command */ +#define ERRsrverror 65 /* smb server internal error */ +#define ERRfilespecs 67 /* fid and pathname invalid combination */ +#define ERRbadlink 68 /* reserved */ +#define ERRbadpermits 69 /* Access specified for a file is not valid */ +#define ERRbadpid 70 /* reserved */ +#define ERRsetattrmode 71 /* attribute mode invalid */ +#define ERRpaused 81 /* Message server paused */ +#define ERRmsgoff 82 /* Not receiving messages */ +#define ERRnoroom 83 /* No room for message */ +#define ERRrmuns 87 /* too many remote usernames */ +#define ERRtimeout 88 /* operation timed out */ +#define ERRnoresource 89 /* No resources currently available for request. */ +#define ERRtoomanyuids 90 /* too many userids */ +#define ERRbaduid 91 /* bad userid */ +#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */ +#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */ +#define ERRcontMPX 252 /* resume MPX mode */ +#define ERRnosupport 0xFFFF +#define ERRunknownsmb 22 /* from NT 3.5 response */ + +/* Error codes for the ERRHRD class */ + +#define ERRnowrite 19 /* read only media */ +#define ERRbadunit 20 /* Unknown device */ +#define ERRnotready 21 /* Drive not ready */ +#define ERRbadcmd 22 /* Unknown command */ +#define ERRdata 23 /* Data (CRC) error */ +#define ERRbadreq 24 /* Bad request structure length */ +#define ERRseek 25 +#define ERRbadmedia 26 +#define ERRbadsector 27 +#define ERRnopaper 28 +#define ERRwrite 29 /* write fault */ +#define ERRread 30 /* read fault */ +#define ERRgeneral 31 /* General hardware failure */ +#define ERRwrongdisk 34 +#define ERRFCBunavail 35 +#define ERRsharebufexc 36 /* share buffer exceeded */ +#define ERRdiskfull 39 + + +/* these are win32 error codes. There are only a few places where + these matter for Samba, primarily in the NT printing code */ +#define WERR_OK W_ERROR(0) +#define WERR_BADFUNC W_ERROR(1) +#define WERR_BADFILE W_ERROR(2) +#define WERR_ACCESS_DENIED W_ERROR(5) +#define WERR_BADFID W_ERROR(6) +#define WERR_NOMEM W_ERROR(8) +#define WERR_GENERAL_FAILURE W_ERROR(31) +#define WERR_NOT_SUPPORTED W_ERROR(50) +#define WERR_BAD_NETPATH W_ERROR(53) +#define WERR_PRINTQ_FULL W_ERROR(61) +#define WERR_NO_SPOOL_SPACE W_ERROR(62) +#define WERR_NO_SUCH_SHARE W_ERROR(67) +#define WERR_ALREADY_EXISTS W_ERROR(80) +#define WERR_BAD_PASSWORD W_ERROR(86) +#define WERR_INVALID_PARAM W_ERROR(87) +#define WERR_INSUFFICIENT_BUFFER W_ERROR(122) +#define WERR_INVALID_NAME W_ERROR(123) +#define WERR_UNKNOWN_LEVEL W_ERROR(124) +#define WERR_OBJECT_PATH_INVALID W_ERROR(161) +#define WERR_NO_MORE_ITEMS W_ERROR(259) +#define WERR_MORE_DATA W_ERROR(234) +#define WERR_CAN_NOT_COMPLETE W_ERROR(1003) +#define WERR_INVALID_COMPUTERNAME W_ERROR(1210) +#define WERR_INVALID_DOMAINNAME W_ERROR(1212) +#define WERR_UNKNOWN_REVISION W_ERROR(1305) +#define WERR_REVISION_MISMATCH W_ERROR(1306) +#define WERR_INVALID_OWNER W_ERROR(1307) +#define WERR_NO_SUCH_USER W_ERROR(1317) +#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) +#define WERR_NO_SUCH_DOMAIN W_ERROR(1355) +#define WERR_SERVER_UNAVAILABLE W_ERROR(1722) +#define WERR_INVALID_FORM_NAME W_ERROR(1902) +#define WERR_INVALID_FORM_SIZE W_ERROR(1903) +#define WERR_BUF_TOO_SMALL W_ERROR(2123) +#define WERR_JOB_NOT_FOUND W_ERROR(2151) +#define WERR_DEST_NOT_FOUND W_ERROR(2152) +#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) +#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) + +#define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled) +#define WERR_UNKNOWN_PORT W_ERROR(ERRunknownprinterport) +#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(ERRunknownprinterdriver) +#define WERR_UNKNOWN_PRINTPROCESSOR W_ERROR(ERRunknownprintprocessor) +#define WERR_INVALID_SEPARATOR_FILE W_ERROR(ERRinvalidseparatorfile) +#define WERR_INVALID_PRIORITY W_ERROR(ERRinvalidjobpriority) +#define WERR_INVALID_PRINTER_NAME W_ERROR(ERRinvalidprintername) +#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(ERRprinteralreadyexists) +#define WERR_INVALID_PRINTER_COMMAND W_ERROR(ERRinvalidprintercommand) +#define WERR_INVALID_DATATYPE W_ERROR(ERRinvaliddatatype) +#define WERR_INVALID_ENVIRONMENT W_ERROR(ERRinvalidenvironment) + +#define WERR_UNKNOWN_PRINT_MONITOR W_ERROR(ERRunknownprintmonitor) +#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(ERRprinterdriverinuse) +#define WERR_SPOOL_FILE_NOT_FOUND W_ERROR(ERRspoolfilenotfound) +#define WERR_SPL_NO_STARTDOC W_ERROR(ERRnostartdoc) +#define WERR_SPL_NO_ADDJOB W_ERROR(ERRnoaddjob) +#define WERR_PRINT_PROCESSOR_ALREADY_INSTALLED W_ERROR(ERRprintprocessoralreadyinstalled) +#define WERR_PRINT_MONITOR_ALREADY_INSTALLED W_ERROR(ERRprintmonitoralreadyinstalled) +#define WERR_INVALID_PRINT_MONITOR W_ERROR(ERRinvalidprintmonitor) +#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse) +#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued) + +#define WERR_CLASS_NOT_REGISTERED W_ERROR(0x40154) +#define WERR_NO_SHUTDOWN_IN_PROGRESS W_ERROR(0x45c) +#define WERR_SHUTDOWN_ALREADY_IN_PROGRESS W_ERROR(0x45b) + + +#ifndef NERR_BASE +#define NERR_BASE (2100) +#endif + +#define WERR_NET_NAME_NOT_FOUND W_ERROR(NERR_BASE+210) +#define WERR_DEVICE_NOT_SHARED W_ERROR(NERR_BASE+211) + +/* DFS errors */ +#define WERR_DFS_NO_SUCH_VOL W_ERROR(NERR_BASE+562) +#define WERR_DFS_NO_SUCH_SHARE W_ERROR(NERR_BASE+565) +#define WERR_DFS_NO_SUCH_SERVER W_ERROR(NERR_BASE+573) +#define WERR_DFS_INTERNAL_ERROR W_ERROR(NERR_BASE+590) +#define WERR_DFS_CANT_CREATE_JUNCT W_ERROR(NERR_BASE+569) + +/* DS errors */ +#define WERR_DS_SERVICE_BUSY W_ERROR(0x0000200e) +#define WERR_DS_SERVICE_UNAVAILABLE W_ERROR(0x0000200f) +#define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030) +#define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208d) +#define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020f5) +#define WERR_DS_DRA_BAD_DN W_ERROR(0x000020f7) +#define WERR_DS_DRA_BAD_NC W_ERROR(0x000020f8) +#define WERR_DS_DRA_INTERNAL_ERROR W_ERROR(0x000020fa) +#define WERR_DS_SINGLE_VALUE_CONSTRAINT W_ERROR(0x00002081) +#define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) +#define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) +#define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) +#define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) + +#define WERR_FOOBAR WERR_GENERAL_FAILURE + +#endif /* _DOSERR_H */ diff --git a/source4/libcli/util/nterr.h b/source4/libcli/util/nterr.h new file mode 100644 index 0000000000..08e3fa2db0 --- /dev/null +++ b/source4/libcli/util/nterr.h @@ -0,0 +1,587 @@ +/* + Unix SMB/CIFS implementation. + NT error code constants + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) John H Terpstra 1996-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Paul Ashton 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. +*/ + +#ifndef _NTERR_H +#define _NTERR_H + +/* Win32 Status codes. */ + +#define STATUS_BUFFER_OVERFLOW NT_STATUS(0x80000005) +#define STATUS_NO_MORE_FILES NT_STATUS(0x80000006) +#define STATUS_NO_MORE_EAS NT_STATUS(0x80000012) +#define STATUS_INVALID_EA_NAME NT_STATUS(0x80000013) +#define STATUS_EA_LIST_INCONSISTENT NT_STATUS(0x80000014) +#define STATUS_INVALID_EA_FLAG NT_STATUS(0x80000015) +#define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a) + +#define STATUS_PENDING NT_STATUS(0x0103) +#define STATUS_MORE_ENTRIES NT_STATUS(0x0105) +#define STATUS_SOME_UNMAPPED NT_STATUS(0x0107) +#define ERROR_INVALID_PARAMETER NT_STATUS(0x0057) +#define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a) +#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) +#define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) + +/* Win32 Error codes extracted using a loop in smbclient then printing a + netmon sniff to a file. */ + +/* + -------------- + / \ + / REST \ + / IN \ + / PEACE \ + / \ + | NT_STATUS_NOPROBLEMO | + | | + | | + | 4 September | + | | + | 2001 | + *| * * * | * + _________)/\\_//(\/(/\)/\//\/\///|_)_______ +*/ + +#define NT_STATUS_OK NT_STATUS(0x0000) +#define NT_STATUS_UNSUCCESSFUL NT_STATUS(0xC0000000 | 0x0001) +#define NT_STATUS_NOT_IMPLEMENTED NT_STATUS(0xC0000000 | 0x0002) +#define NT_STATUS_INVALID_INFO_CLASS NT_STATUS(0xC0000000 | 0x0003) +#define NT_STATUS_INFO_LENGTH_MISMATCH NT_STATUS(0xC0000000 | 0x0004) +#define NT_STATUS_ACCESS_VIOLATION NT_STATUS(0xC0000000 | 0x0005) +#define NT_STATUS_IN_PAGE_ERROR NT_STATUS(0xC0000000 | 0x0006) +#define NT_STATUS_PAGEFILE_QUOTA NT_STATUS(0xC0000000 | 0x0007) +#define NT_STATUS_INVALID_HANDLE NT_STATUS(0xC0000000 | 0x0008) +#define NT_STATUS_BAD_INITIAL_STACK NT_STATUS(0xC0000000 | 0x0009) +#define NT_STATUS_BAD_INITIAL_PC NT_STATUS(0xC0000000 | 0x000a) +#define NT_STATUS_INVALID_CID NT_STATUS(0xC0000000 | 0x000b) +#define NT_STATUS_TIMER_NOT_CANCELED NT_STATUS(0xC0000000 | 0x000c) +#define NT_STATUS_INVALID_PARAMETER NT_STATUS(0xC0000000 | 0x000d) +#define NT_STATUS_NO_SUCH_DEVICE NT_STATUS(0xC0000000 | 0x000e) +#define NT_STATUS_NO_SUCH_FILE NT_STATUS(0xC0000000 | 0x000f) +#define NT_STATUS_INVALID_DEVICE_REQUEST NT_STATUS(0xC0000000 | 0x0010) +#define NT_STATUS_END_OF_FILE NT_STATUS(0xC0000000 | 0x0011) +#define NT_STATUS_WRONG_VOLUME NT_STATUS(0xC0000000 | 0x0012) +#define NT_STATUS_NO_MEDIA_IN_DEVICE NT_STATUS(0xC0000000 | 0x0013) +#define NT_STATUS_UNRECOGNIZED_MEDIA NT_STATUS(0xC0000000 | 0x0014) +#define NT_STATUS_NONEXISTENT_SECTOR NT_STATUS(0xC0000000 | 0x0015) +#define NT_STATUS_MORE_PROCESSING_REQUIRED NT_STATUS(0xC0000000 | 0x0016) +#if 0 +/* this demonstrates a little trick when tracking down error codes */ +#define NT_STATUS_NO_MEMORY (printf("no memory at %s\n", __location__), NT_STATUS(0xC0000000 | 0x0017)) +#else +#define NT_STATUS_NO_MEMORY NT_STATUS(0xC0000000 | 0x0017) +#endif +#define NT_STATUS_CONFLICTING_ADDRESSES NT_STATUS(0xC0000000 | 0x0018) +#define NT_STATUS_NOT_MAPPED_VIEW NT_STATUS(0xC0000000 | 0x0019) +#define NT_STATUS_UNABLE_TO_FREE_VM NT_STATUS(0xC0000000 | 0x001a) +#define NT_STATUS_UNABLE_TO_DELETE_SECTION NT_STATUS(0xC0000000 | 0x001b) +#define NT_STATUS_INVALID_SYSTEM_SERVICE NT_STATUS(0xC0000000 | 0x001c) +#define NT_STATUS_ILLEGAL_INSTRUCTION NT_STATUS(0xC0000000 | 0x001d) +#define NT_STATUS_INVALID_LOCK_SEQUENCE NT_STATUS(0xC0000000 | 0x001e) +#define NT_STATUS_INVALID_VIEW_SIZE NT_STATUS(0xC0000000 | 0x001f) +#define NT_STATUS_INVALID_FILE_FOR_SECTION NT_STATUS(0xC0000000 | 0x0020) +#define NT_STATUS_ALREADY_COMMITTED NT_STATUS(0xC0000000 | 0x0021) +#if 0 +/* this demonstrates a little trick when tracking down error codes */ +#define NT_STATUS_ACCESS_DENIED (printf("access denied at %s\n", __location__), NT_STATUS(0xC0000000 | 0x0022)) +#else +#define NT_STATUS_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x0022) +#endif +#define NT_STATUS_BUFFER_TOO_SMALL NT_STATUS(0xC0000000 | 0x0023) +#define NT_STATUS_OBJECT_TYPE_MISMATCH NT_STATUS(0xC0000000 | 0x0024) +#define NT_STATUS_NONCONTINUABLE_EXCEPTION NT_STATUS(0xC0000000 | 0x0025) +#define NT_STATUS_INVALID_DISPOSITION NT_STATUS(0xC0000000 | 0x0026) +#define NT_STATUS_UNWIND NT_STATUS(0xC0000000 | 0x0027) +#define NT_STATUS_BAD_STACK NT_STATUS(0xC0000000 | 0x0028) +#define NT_STATUS_INVALID_UNWIND_TARGET NT_STATUS(0xC0000000 | 0x0029) +#define NT_STATUS_NOT_LOCKED NT_STATUS(0xC0000000 | 0x002a) +#define NT_STATUS_PARITY_ERROR NT_STATUS(0xC0000000 | 0x002b) +#define NT_STATUS_UNABLE_TO_DECOMMIT_VM NT_STATUS(0xC0000000 | 0x002c) +#define NT_STATUS_NOT_COMMITTED NT_STATUS(0xC0000000 | 0x002d) +#define NT_STATUS_INVALID_PORT_ATTRIBUTES NT_STATUS(0xC0000000 | 0x002e) +#define NT_STATUS_PORT_MESSAGE_TOO_LONG NT_STATUS(0xC0000000 | 0x002f) +#define NT_STATUS_INVALID_PARAMETER_MIX NT_STATUS(0xC0000000 | 0x0030) +#define NT_STATUS_INVALID_QUOTA_LOWER NT_STATUS(0xC0000000 | 0x0031) +#define NT_STATUS_DISK_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0032) +#define NT_STATUS_OBJECT_NAME_INVALID NT_STATUS(0xC0000000 | 0x0033) +#define NT_STATUS_OBJECT_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x0034) +#define NT_STATUS_OBJECT_NAME_COLLISION NT_STATUS(0xC0000000 | 0x0035) +#define NT_STATUS_HANDLE_NOT_WAITABLE NT_STATUS(0xC0000000 | 0x0036) +#define NT_STATUS_PORT_DISCONNECTED NT_STATUS(0xC0000000 | 0x0037) +#define NT_STATUS_DEVICE_ALREADY_ATTACHED NT_STATUS(0xC0000000 | 0x0038) +#define NT_STATUS_OBJECT_PATH_INVALID NT_STATUS(0xC0000000 | 0x0039) +#define NT_STATUS_OBJECT_PATH_NOT_FOUND NT_STATUS(0xC0000000 | 0x003a) +#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD NT_STATUS(0xC0000000 | 0x003b) +#define NT_STATUS_DATA_OVERRUN NT_STATUS(0xC0000000 | 0x003c) +#define NT_STATUS_DATA_LATE_ERROR NT_STATUS(0xC0000000 | 0x003d) +#define NT_STATUS_DATA_ERROR NT_STATUS(0xC0000000 | 0x003e) +#define NT_STATUS_CRC_ERROR NT_STATUS(0xC0000000 | 0x003f) +#define NT_STATUS_SECTION_TOO_BIG NT_STATUS(0xC0000000 | 0x0040) +#define NT_STATUS_PORT_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0041) +#define NT_STATUS_INVALID_PORT_HANDLE NT_STATUS(0xC0000000 | 0x0042) +#define NT_STATUS_SHARING_VIOLATION NT_STATUS(0xC0000000 | 0x0043) +#define NT_STATUS_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0044) +#define NT_STATUS_INVALID_PAGE_PROTECTION NT_STATUS(0xC0000000 | 0x0045) +#define NT_STATUS_MUTANT_NOT_OWNED NT_STATUS(0xC0000000 | 0x0046) +#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0047) +#define NT_STATUS_PORT_ALREADY_SET NT_STATUS(0xC0000000 | 0x0048) +#define NT_STATUS_SECTION_NOT_IMAGE NT_STATUS(0xC0000000 | 0x0049) +#define NT_STATUS_SUSPEND_COUNT_EXCEEDED NT_STATUS(0xC0000000 | 0x004a) +#define NT_STATUS_THREAD_IS_TERMINATING NT_STATUS(0xC0000000 | 0x004b) +#define NT_STATUS_BAD_WORKING_SET_LIMIT NT_STATUS(0xC0000000 | 0x004c) +#define NT_STATUS_INCOMPATIBLE_FILE_MAP NT_STATUS(0xC0000000 | 0x004d) +#define NT_STATUS_SECTION_PROTECTION NT_STATUS(0xC0000000 | 0x004e) +#define NT_STATUS_EAS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x004f) +#define NT_STATUS_EA_TOO_LARGE NT_STATUS(0xC0000000 | 0x0050) +#define NT_STATUS_NONEXISTENT_EA_ENTRY NT_STATUS(0xC0000000 | 0x0051) +#define NT_STATUS_NO_EAS_ON_FILE NT_STATUS(0xC0000000 | 0x0052) +#define NT_STATUS_EA_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0053) +#define NT_STATUS_FILE_LOCK_CONFLICT NT_STATUS(0xC0000000 | 0x0054) +#define NT_STATUS_LOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0055) +#define NT_STATUS_DELETE_PENDING NT_STATUS(0xC0000000 | 0x0056) +#define NT_STATUS_CTL_FILE_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x0057) +#define NT_STATUS_UNKNOWN_REVISION NT_STATUS(0xC0000000 | 0x0058) +#define NT_STATUS_REVISION_MISMATCH NT_STATUS(0xC0000000 | 0x0059) +#define NT_STATUS_INVALID_OWNER NT_STATUS(0xC0000000 | 0x005a) +#define NT_STATUS_INVALID_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x005b) +#define NT_STATUS_NO_IMPERSONATION_TOKEN NT_STATUS(0xC0000000 | 0x005c) +#define NT_STATUS_CANT_DISABLE_MANDATORY NT_STATUS(0xC0000000 | 0x005d) +#define NT_STATUS_NO_LOGON_SERVERS NT_STATUS(0xC0000000 | 0x005e) +#define NT_STATUS_NO_SUCH_LOGON_SESSION NT_STATUS(0xC0000000 | 0x005f) +#define NT_STATUS_NO_SUCH_PRIVILEGE NT_STATUS(0xC0000000 | 0x0060) +#define NT_STATUS_PRIVILEGE_NOT_HELD NT_STATUS(0xC0000000 | 0x0061) +#define NT_STATUS_INVALID_ACCOUNT_NAME NT_STATUS(0xC0000000 | 0x0062) +#define NT_STATUS_USER_EXISTS NT_STATUS(0xC0000000 | 0x0063) +#define NT_STATUS_NO_SUCH_USER NT_STATUS(0xC0000000 | 0x0064) +#define NT_STATUS_GROUP_EXISTS NT_STATUS(0xC0000000 | 0x0065) +#define NT_STATUS_NO_SUCH_GROUP NT_STATUS(0xC0000000 | 0x0066) +#define NT_STATUS_MEMBER_IN_GROUP NT_STATUS(0xC0000000 | 0x0067) +#define NT_STATUS_MEMBER_NOT_IN_GROUP NT_STATUS(0xC0000000 | 0x0068) +#define NT_STATUS_LAST_ADMIN NT_STATUS(0xC0000000 | 0x0069) +#define NT_STATUS_WRONG_PASSWORD NT_STATUS(0xC0000000 | 0x006a) +#define NT_STATUS_ILL_FORMED_PASSWORD NT_STATUS(0xC0000000 | 0x006b) +#define NT_STATUS_PASSWORD_RESTRICTION NT_STATUS(0xC0000000 | 0x006c) +#define NT_STATUS_LOGON_FAILURE NT_STATUS(0xC0000000 | 0x006d) +#define NT_STATUS_ACCOUNT_RESTRICTION NT_STATUS(0xC0000000 | 0x006e) +#define NT_STATUS_INVALID_LOGON_HOURS NT_STATUS(0xC0000000 | 0x006f) +#define NT_STATUS_INVALID_WORKSTATION NT_STATUS(0xC0000000 | 0x0070) +#define NT_STATUS_PASSWORD_EXPIRED NT_STATUS(0xC0000000 | 0x0071) +#define NT_STATUS_ACCOUNT_DISABLED NT_STATUS(0xC0000000 | 0x0072) +#define NT_STATUS_NONE_MAPPED NT_STATUS(0xC0000000 | 0x0073) +#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0074) +#define NT_STATUS_LUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0075) +#define NT_STATUS_INVALID_SUB_AUTHORITY NT_STATUS(0xC0000000 | 0x0076) +#define NT_STATUS_INVALID_ACL NT_STATUS(0xC0000000 | 0x0077) +#define NT_STATUS_INVALID_SID NT_STATUS(0xC0000000 | 0x0078) +#define NT_STATUS_INVALID_SECURITY_DESCR NT_STATUS(0xC0000000 | 0x0079) +#define NT_STATUS_PROCEDURE_NOT_FOUND NT_STATUS(0xC0000000 | 0x007a) +#define NT_STATUS_INVALID_IMAGE_FORMAT NT_STATUS(0xC0000000 | 0x007b) +#define NT_STATUS_NO_TOKEN NT_STATUS(0xC0000000 | 0x007c) +#define NT_STATUS_BAD_INHERITANCE_ACL NT_STATUS(0xC0000000 | 0x007d) +#define NT_STATUS_RANGE_NOT_LOCKED NT_STATUS(0xC0000000 | 0x007e) +#define NT_STATUS_DISK_FULL NT_STATUS(0xC0000000 | 0x007f) +#define NT_STATUS_SERVER_DISABLED NT_STATUS(0xC0000000 | 0x0080) +#define NT_STATUS_SERVER_NOT_DISABLED NT_STATUS(0xC0000000 | 0x0081) +#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0082) +#define NT_STATUS_GUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0083) +#define NT_STATUS_INVALID_ID_AUTHORITY NT_STATUS(0xC0000000 | 0x0084) +#define NT_STATUS_AGENTS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0085) +#define NT_STATUS_INVALID_VOLUME_LABEL NT_STATUS(0xC0000000 | 0x0086) +#define NT_STATUS_SECTION_NOT_EXTENDED NT_STATUS(0xC0000000 | 0x0087) +#define NT_STATUS_NOT_MAPPED_DATA NT_STATUS(0xC0000000 | 0x0088) +#define NT_STATUS_RESOURCE_DATA_NOT_FOUND NT_STATUS(0xC0000000 | 0x0089) +#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND NT_STATUS(0xC0000000 | 0x008a) +#define NT_STATUS_RESOURCE_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x008b) +#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED NT_STATUS(0xC0000000 | 0x008c) +#define NT_STATUS_FLOAT_DENORMAL_OPERAND NT_STATUS(0xC0000000 | 0x008d) +#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x008e) +#define NT_STATUS_FLOAT_INEXACT_RESULT NT_STATUS(0xC0000000 | 0x008f) +#define NT_STATUS_FLOAT_INVALID_OPERATION NT_STATUS(0xC0000000 | 0x0090) +#define NT_STATUS_FLOAT_OVERFLOW NT_STATUS(0xC0000000 | 0x0091) +#define NT_STATUS_FLOAT_STACK_CHECK NT_STATUS(0xC0000000 | 0x0092) +#define NT_STATUS_FLOAT_UNDERFLOW NT_STATUS(0xC0000000 | 0x0093) +#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x0094) +#define NT_STATUS_INTEGER_OVERFLOW NT_STATUS(0xC0000000 | 0x0095) +#define NT_STATUS_PRIVILEGED_INSTRUCTION NT_STATUS(0xC0000000 | 0x0096) +#define NT_STATUS_TOO_MANY_PAGING_FILES NT_STATUS(0xC0000000 | 0x0097) +#define NT_STATUS_FILE_INVALID NT_STATUS(0xC0000000 | 0x0098) +#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED NT_STATUS(0xC0000000 | 0x0099) +#define NT_STATUS_INSUFFICIENT_RESOURCES NT_STATUS(0xC0000000 | 0x009a) +#define NT_STATUS_DFS_EXIT_PATH_FOUND NT_STATUS(0xC0000000 | 0x009b) +#define NT_STATUS_DEVICE_DATA_ERROR NT_STATUS(0xC0000000 | 0x009c) +#define NT_STATUS_DEVICE_NOT_CONNECTED NT_STATUS(0xC0000000 | 0x009d) +#define NT_STATUS_DEVICE_POWER_FAILURE NT_STATUS(0xC0000000 | 0x009e) +#define NT_STATUS_FREE_VM_NOT_AT_BASE NT_STATUS(0xC0000000 | 0x009f) +#define NT_STATUS_MEMORY_NOT_ALLOCATED NT_STATUS(0xC0000000 | 0x00a0) +#define NT_STATUS_WORKING_SET_QUOTA NT_STATUS(0xC0000000 | 0x00a1) +#define NT_STATUS_MEDIA_WRITE_PROTECTED NT_STATUS(0xC0000000 | 0x00a2) +#define NT_STATUS_DEVICE_NOT_READY NT_STATUS(0xC0000000 | 0x00a3) +#define NT_STATUS_INVALID_GROUP_ATTRIBUTES NT_STATUS(0xC0000000 | 0x00a4) +#define NT_STATUS_BAD_IMPERSONATION_LEVEL NT_STATUS(0xC0000000 | 0x00a5) +#define NT_STATUS_CANT_OPEN_ANONYMOUS NT_STATUS(0xC0000000 | 0x00a6) +#define NT_STATUS_BAD_VALIDATION_CLASS NT_STATUS(0xC0000000 | 0x00a7) +#define NT_STATUS_BAD_TOKEN_TYPE NT_STATUS(0xC0000000 | 0x00a8) +#define NT_STATUS_BAD_MASTER_BOOT_RECORD NT_STATUS(0xC0000000 | 0x00a9) +#define NT_STATUS_INSTRUCTION_MISALIGNMENT NT_STATUS(0xC0000000 | 0x00aa) +#define NT_STATUS_INSTANCE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ab) +#define NT_STATUS_PIPE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ac) +#define NT_STATUS_INVALID_PIPE_STATE NT_STATUS(0xC0000000 | 0x00ad) +#define NT_STATUS_PIPE_BUSY NT_STATUS(0xC0000000 | 0x00ae) +#define NT_STATUS_ILLEGAL_FUNCTION NT_STATUS(0xC0000000 | 0x00af) +#define NT_STATUS_PIPE_DISCONNECTED NT_STATUS(0xC0000000 | 0x00b0) +#define NT_STATUS_PIPE_CLOSING NT_STATUS(0xC0000000 | 0x00b1) +#define NT_STATUS_PIPE_CONNECTED NT_STATUS(0xC0000000 | 0x00b2) +#define NT_STATUS_PIPE_LISTENING NT_STATUS(0xC0000000 | 0x00b3) +#define NT_STATUS_INVALID_READ_MODE NT_STATUS(0xC0000000 | 0x00b4) +#define NT_STATUS_IO_TIMEOUT NT_STATUS(0xC0000000 | 0x00b5) +#define NT_STATUS_FILE_FORCED_CLOSED NT_STATUS(0xC0000000 | 0x00b6) +#define NT_STATUS_PROFILING_NOT_STARTED NT_STATUS(0xC0000000 | 0x00b7) +#define NT_STATUS_PROFILING_NOT_STOPPED NT_STATUS(0xC0000000 | 0x00b8) +#define NT_STATUS_COULD_NOT_INTERPRET NT_STATUS(0xC0000000 | 0x00b9) +#define NT_STATUS_FILE_IS_A_DIRECTORY NT_STATUS(0xC0000000 | 0x00ba) +#define NT_STATUS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x00bb) +#define NT_STATUS_REMOTE_NOT_LISTENING NT_STATUS(0xC0000000 | 0x00bc) +#define NT_STATUS_DUPLICATE_NAME NT_STATUS(0xC0000000 | 0x00bd) +#define NT_STATUS_BAD_NETWORK_PATH NT_STATUS(0xC0000000 | 0x00be) +#define NT_STATUS_NETWORK_BUSY NT_STATUS(0xC0000000 | 0x00bf) +#define NT_STATUS_DEVICE_DOES_NOT_EXIST NT_STATUS(0xC0000000 | 0x00c0) +#define NT_STATUS_TOO_MANY_COMMANDS NT_STATUS(0xC0000000 | 0x00c1) +#define NT_STATUS_ADAPTER_HARDWARE_ERROR NT_STATUS(0xC0000000 | 0x00c2) +#define NT_STATUS_INVALID_NETWORK_RESPONSE NT_STATUS(0xC0000000 | 0x00c3) +#define NT_STATUS_UNEXPECTED_NETWORK_ERROR NT_STATUS(0xC0000000 | 0x00c4) +#define NT_STATUS_BAD_REMOTE_ADAPTER NT_STATUS(0xC0000000 | 0x00c5) +#define NT_STATUS_PRINT_QUEUE_FULL NT_STATUS(0xC0000000 | 0x00c6) +#define NT_STATUS_NO_SPOOL_SPACE NT_STATUS(0xC0000000 | 0x00c7) +#define NT_STATUS_PRINT_CANCELLED NT_STATUS(0xC0000000 | 0x00c8) +#define NT_STATUS_NETWORK_NAME_DELETED NT_STATUS(0xC0000000 | 0x00c9) +#define NT_STATUS_NETWORK_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x00ca) +#define NT_STATUS_BAD_DEVICE_TYPE NT_STATUS(0xC0000000 | 0x00cb) +#define NT_STATUS_BAD_NETWORK_NAME NT_STATUS(0xC0000000 | 0x00cc) +#define NT_STATUS_TOO_MANY_NAMES NT_STATUS(0xC0000000 | 0x00cd) +#define NT_STATUS_TOO_MANY_SESSIONS NT_STATUS(0xC0000000 | 0x00ce) +#define NT_STATUS_SHARING_PAUSED NT_STATUS(0xC0000000 | 0x00cf) +#define NT_STATUS_REQUEST_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x00d0) +#define NT_STATUS_REDIRECTOR_PAUSED NT_STATUS(0xC0000000 | 0x00d1) +#define NT_STATUS_NET_WRITE_FAULT NT_STATUS(0xC0000000 | 0x00d2) +#define NT_STATUS_PROFILING_AT_LIMIT NT_STATUS(0xC0000000 | 0x00d3) +#define NT_STATUS_NOT_SAME_DEVICE NT_STATUS(0xC0000000 | 0x00d4) +#define NT_STATUS_FILE_RENAMED NT_STATUS(0xC0000000 | 0x00d5) +#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED NT_STATUS(0xC0000000 | 0x00d6) +#define NT_STATUS_NO_SECURITY_ON_OBJECT NT_STATUS(0xC0000000 | 0x00d7) +#define NT_STATUS_CANT_WAIT NT_STATUS(0xC0000000 | 0x00d8) +#define NT_STATUS_PIPE_EMPTY NT_STATUS(0xC0000000 | 0x00d9) +#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO NT_STATUS(0xC0000000 | 0x00da) +#define NT_STATUS_CANT_TERMINATE_SELF NT_STATUS(0xC0000000 | 0x00db) +#define NT_STATUS_INVALID_SERVER_STATE NT_STATUS(0xC0000000 | 0x00dc) +#define NT_STATUS_INVALID_DOMAIN_STATE NT_STATUS(0xC0000000 | 0x00dd) +#define NT_STATUS_INVALID_DOMAIN_ROLE NT_STATUS(0xC0000000 | 0x00de) +#define NT_STATUS_NO_SUCH_DOMAIN NT_STATUS(0xC0000000 | 0x00df) +#define NT_STATUS_DOMAIN_EXISTS NT_STATUS(0xC0000000 | 0x00e0) +#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x00e1) +#define NT_STATUS_OPLOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x00e2) +#define NT_STATUS_INVALID_OPLOCK_PROTOCOL NT_STATUS(0xC0000000 | 0x00e3) +#define NT_STATUS_INTERNAL_DB_CORRUPTION NT_STATUS(0xC0000000 | 0x00e4) +#define NT_STATUS_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x00e5) +#define NT_STATUS_GENERIC_NOT_MAPPED NT_STATUS(0xC0000000 | 0x00e6) +#define NT_STATUS_BAD_DESCRIPTOR_FORMAT NT_STATUS(0xC0000000 | 0x00e7) +#define NT_STATUS_INVALID_USER_BUFFER NT_STATUS(0xC0000000 | 0x00e8) +#define NT_STATUS_UNEXPECTED_IO_ERROR NT_STATUS(0xC0000000 | 0x00e9) +#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR NT_STATUS(0xC0000000 | 0x00ea) +#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR NT_STATUS(0xC0000000 | 0x00eb) +#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR NT_STATUS(0xC0000000 | 0x00ec) +#define NT_STATUS_NOT_LOGON_PROCESS NT_STATUS(0xC0000000 | 0x00ed) +#define NT_STATUS_LOGON_SESSION_EXISTS NT_STATUS(0xC0000000 | 0x00ee) +#define NT_STATUS_INVALID_PARAMETER_1 NT_STATUS(0xC0000000 | 0x00ef) +#define NT_STATUS_INVALID_PARAMETER_2 NT_STATUS(0xC0000000 | 0x00f0) +#define NT_STATUS_INVALID_PARAMETER_3 NT_STATUS(0xC0000000 | 0x00f1) +#define NT_STATUS_INVALID_PARAMETER_4 NT_STATUS(0xC0000000 | 0x00f2) +#define NT_STATUS_INVALID_PARAMETER_5 NT_STATUS(0xC0000000 | 0x00f3) +#define NT_STATUS_INVALID_PARAMETER_6 NT_STATUS(0xC0000000 | 0x00f4) +#define NT_STATUS_INVALID_PARAMETER_7 NT_STATUS(0xC0000000 | 0x00f5) +#define NT_STATUS_INVALID_PARAMETER_8 NT_STATUS(0xC0000000 | 0x00f6) +#define NT_STATUS_INVALID_PARAMETER_9 NT_STATUS(0xC0000000 | 0x00f7) +#define NT_STATUS_INVALID_PARAMETER_10 NT_STATUS(0xC0000000 | 0x00f8) +#define NT_STATUS_INVALID_PARAMETER_11 NT_STATUS(0xC0000000 | 0x00f9) +#define NT_STATUS_INVALID_PARAMETER_12 NT_STATUS(0xC0000000 | 0x00fa) +#define NT_STATUS_REDIRECTOR_NOT_STARTED NT_STATUS(0xC0000000 | 0x00fb) +#define NT_STATUS_REDIRECTOR_STARTED NT_STATUS(0xC0000000 | 0x00fc) +#define NT_STATUS_STACK_OVERFLOW NT_STATUS(0xC0000000 | 0x00fd) +#define NT_STATUS_NO_SUCH_PACKAGE NT_STATUS(0xC0000000 | 0x00fe) +#define NT_STATUS_BAD_FUNCTION_TABLE NT_STATUS(0xC0000000 | 0x00ff) +#define NT_STATUS_DIRECTORY_NOT_EMPTY NT_STATUS(0xC0000000 | 0x0101) +#define NT_STATUS_FILE_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0102) +#define NT_STATUS_NOT_A_DIRECTORY NT_STATUS(0xC0000000 | 0x0103) +#define NT_STATUS_BAD_LOGON_SESSION_STATE NT_STATUS(0xC0000000 | 0x0104) +#define NT_STATUS_LOGON_SESSION_COLLISION NT_STATUS(0xC0000000 | 0x0105) +#define NT_STATUS_NAME_TOO_LONG NT_STATUS(0xC0000000 | 0x0106) +#define NT_STATUS_FILES_OPEN NT_STATUS(0xC0000000 | 0x0107) +#define NT_STATUS_CONNECTION_IN_USE NT_STATUS(0xC0000000 | 0x0108) +#define NT_STATUS_MESSAGE_NOT_FOUND NT_STATUS(0xC0000000 | 0x0109) +#define NT_STATUS_PROCESS_IS_TERMINATING NT_STATUS(0xC0000000 | 0x010a) +#define NT_STATUS_INVALID_LOGON_TYPE NT_STATUS(0xC0000000 | 0x010b) +#define NT_STATUS_NO_GUID_TRANSLATION NT_STATUS(0xC0000000 | 0x010c) +#define NT_STATUS_CANNOT_IMPERSONATE NT_STATUS(0xC0000000 | 0x010d) +#define NT_STATUS_IMAGE_ALREADY_LOADED NT_STATUS(0xC0000000 | 0x010e) +#define NT_STATUS_ABIOS_NOT_PRESENT NT_STATUS(0xC0000000 | 0x010f) +#define NT_STATUS_ABIOS_LID_NOT_EXIST NT_STATUS(0xC0000000 | 0x0110) +#define NT_STATUS_ABIOS_LID_ALREADY_OWNED NT_STATUS(0xC0000000 | 0x0111) +#define NT_STATUS_ABIOS_NOT_LID_OWNER NT_STATUS(0xC0000000 | 0x0112) +#define NT_STATUS_ABIOS_INVALID_COMMAND NT_STATUS(0xC0000000 | 0x0113) +#define NT_STATUS_ABIOS_INVALID_LID NT_STATUS(0xC0000000 | 0x0114) +#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x0115) +#define NT_STATUS_ABIOS_INVALID_SELECTOR NT_STATUS(0xC0000000 | 0x0116) +#define NT_STATUS_NO_LDT NT_STATUS(0xC0000000 | 0x0117) +#define NT_STATUS_INVALID_LDT_SIZE NT_STATUS(0xC0000000 | 0x0118) +#define NT_STATUS_INVALID_LDT_OFFSET NT_STATUS(0xC0000000 | 0x0119) +#define NT_STATUS_INVALID_LDT_DESCRIPTOR NT_STATUS(0xC0000000 | 0x011a) +#define NT_STATUS_INVALID_IMAGE_NE_FORMAT NT_STATUS(0xC0000000 | 0x011b) +#define NT_STATUS_RXACT_INVALID_STATE NT_STATUS(0xC0000000 | 0x011c) +#define NT_STATUS_RXACT_COMMIT_FAILURE NT_STATUS(0xC0000000 | 0x011d) +#define NT_STATUS_MAPPED_FILE_SIZE_ZERO NT_STATUS(0xC0000000 | 0x011e) +#define NT_STATUS_TOO_MANY_OPENED_FILES NT_STATUS(0xC0000000 | 0x011f) +#define NT_STATUS_CANCELLED NT_STATUS(0xC0000000 | 0x0120) +#define NT_STATUS_CANNOT_DELETE NT_STATUS(0xC0000000 | 0x0121) +#define NT_STATUS_INVALID_COMPUTER_NAME NT_STATUS(0xC0000000 | 0x0122) +#define NT_STATUS_FILE_DELETED NT_STATUS(0xC0000000 | 0x0123) +#define NT_STATUS_SPECIAL_ACCOUNT NT_STATUS(0xC0000000 | 0x0124) +#define NT_STATUS_SPECIAL_GROUP NT_STATUS(0xC0000000 | 0x0125) +#define NT_STATUS_SPECIAL_USER NT_STATUS(0xC0000000 | 0x0126) +#define NT_STATUS_MEMBERS_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x0127) +#define NT_STATUS_FILE_CLOSED NT_STATUS(0xC0000000 | 0x0128) +#define NT_STATUS_TOO_MANY_THREADS NT_STATUS(0xC0000000 | 0x0129) +#define NT_STATUS_THREAD_NOT_IN_PROCESS NT_STATUS(0xC0000000 | 0x012a) +#define NT_STATUS_TOKEN_ALREADY_IN_USE NT_STATUS(0xC0000000 | 0x012b) +#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x012c) +#define NT_STATUS_COMMITMENT_LIMIT NT_STATUS(0xC0000000 | 0x012d) +#define NT_STATUS_INVALID_IMAGE_LE_FORMAT NT_STATUS(0xC0000000 | 0x012e) +#define NT_STATUS_INVALID_IMAGE_NOT_MZ NT_STATUS(0xC0000000 | 0x012f) +#define NT_STATUS_INVALID_IMAGE_PROTECT NT_STATUS(0xC0000000 | 0x0130) +#define NT_STATUS_INVALID_IMAGE_WIN_16 NT_STATUS(0xC0000000 | 0x0131) +#define NT_STATUS_LOGON_SERVER_CONFLICT NT_STATUS(0xC0000000 | 0x0132) +#define NT_STATUS_TIME_DIFFERENCE_AT_DC NT_STATUS(0xC0000000 | 0x0133) +#define NT_STATUS_SYNCHRONIZATION_REQUIRED NT_STATUS(0xC0000000 | 0x0134) +#define NT_STATUS_DLL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0135) +#define NT_STATUS_OPEN_FAILED NT_STATUS(0xC0000000 | 0x0136) +#define NT_STATUS_IO_PRIVILEGE_FAILED NT_STATUS(0xC0000000 | 0x0137) +#define NT_STATUS_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0138) +#define NT_STATUS_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0139) +#define NT_STATUS_CONTROL_C_EXIT NT_STATUS(0xC0000000 | 0x013a) +#define NT_STATUS_LOCAL_DISCONNECT NT_STATUS(0xC0000000 | 0x013b) +#define NT_STATUS_REMOTE_DISCONNECT NT_STATUS(0xC0000000 | 0x013c) +#define NT_STATUS_REMOTE_RESOURCES NT_STATUS(0xC0000000 | 0x013d) +#define NT_STATUS_LINK_FAILED NT_STATUS(0xC0000000 | 0x013e) +#define NT_STATUS_LINK_TIMEOUT NT_STATUS(0xC0000000 | 0x013f) +#define NT_STATUS_INVALID_CONNECTION NT_STATUS(0xC0000000 | 0x0140) +#define NT_STATUS_INVALID_ADDRESS NT_STATUS(0xC0000000 | 0x0141) +#define NT_STATUS_DLL_INIT_FAILED NT_STATUS(0xC0000000 | 0x0142) +#define NT_STATUS_MISSING_SYSTEMFILE NT_STATUS(0xC0000000 | 0x0143) +#define NT_STATUS_UNHANDLED_EXCEPTION NT_STATUS(0xC0000000 | 0x0144) +#define NT_STATUS_APP_INIT_FAILURE NT_STATUS(0xC0000000 | 0x0145) +#define NT_STATUS_PAGEFILE_CREATE_FAILED NT_STATUS(0xC0000000 | 0x0146) +#define NT_STATUS_NO_PAGEFILE NT_STATUS(0xC0000000 | 0x0147) +#define NT_STATUS_INVALID_LEVEL NT_STATUS(0xC0000000 | 0x0148) +#define NT_STATUS_WRONG_PASSWORD_CORE NT_STATUS(0xC0000000 | 0x0149) +#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT NT_STATUS(0xC0000000 | 0x014a) +#define NT_STATUS_PIPE_BROKEN NT_STATUS(0xC0000000 | 0x014b) +#define NT_STATUS_REGISTRY_CORRUPT NT_STATUS(0xC0000000 | 0x014c) +#define NT_STATUS_REGISTRY_IO_FAILED NT_STATUS(0xC0000000 | 0x014d) +#define NT_STATUS_NO_EVENT_PAIR NT_STATUS(0xC0000000 | 0x014e) +#define NT_STATUS_UNRECOGNIZED_VOLUME NT_STATUS(0xC0000000 | 0x014f) +#define NT_STATUS_SERIAL_NO_DEVICE_INITED NT_STATUS(0xC0000000 | 0x0150) +#define NT_STATUS_NO_SUCH_ALIAS NT_STATUS(0xC0000000 | 0x0151) +#define NT_STATUS_MEMBER_NOT_IN_ALIAS NT_STATUS(0xC0000000 | 0x0152) +#define NT_STATUS_MEMBER_IN_ALIAS NT_STATUS(0xC0000000 | 0x0153) +#define NT_STATUS_ALIAS_EXISTS NT_STATUS(0xC0000000 | 0x0154) +#define NT_STATUS_LOGON_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0155) +#define NT_STATUS_TOO_MANY_SECRETS NT_STATUS(0xC0000000 | 0x0156) +#define NT_STATUS_SECRET_TOO_LONG NT_STATUS(0xC0000000 | 0x0157) +#define NT_STATUS_INTERNAL_DB_ERROR NT_STATUS(0xC0000000 | 0x0158) +#define NT_STATUS_FULLSCREEN_MODE NT_STATUS(0xC0000000 | 0x0159) +#define NT_STATUS_TOO_MANY_CONTEXT_IDS NT_STATUS(0xC0000000 | 0x015a) +#define NT_STATUS_LOGON_TYPE_NOT_GRANTED NT_STATUS(0xC0000000 | 0x015b) +#define NT_STATUS_NOT_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x015c) +#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x015d) +#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR NT_STATUS(0xC0000000 | 0x015e) +#define NT_STATUS_FT_MISSING_MEMBER NT_STATUS(0xC0000000 | 0x015f) +#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY NT_STATUS(0xC0000000 | 0x0160) +#define NT_STATUS_ILLEGAL_CHARACTER NT_STATUS(0xC0000000 | 0x0161) +#define NT_STATUS_UNMAPPABLE_CHARACTER NT_STATUS(0xC0000000 | 0x0162) +#define NT_STATUS_UNDEFINED_CHARACTER NT_STATUS(0xC0000000 | 0x0163) +#define NT_STATUS_FLOPPY_VOLUME NT_STATUS(0xC0000000 | 0x0164) +#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND NT_STATUS(0xC0000000 | 0x0165) +#define NT_STATUS_FLOPPY_WRONG_CYLINDER NT_STATUS(0xC0000000 | 0x0166) +#define NT_STATUS_FLOPPY_UNKNOWN_ERROR NT_STATUS(0xC0000000 | 0x0167) +#define NT_STATUS_FLOPPY_BAD_REGISTERS NT_STATUS(0xC0000000 | 0x0168) +#define NT_STATUS_DISK_RECALIBRATE_FAILED NT_STATUS(0xC0000000 | 0x0169) +#define NT_STATUS_DISK_OPERATION_FAILED NT_STATUS(0xC0000000 | 0x016a) +#define NT_STATUS_DISK_RESET_FAILED NT_STATUS(0xC0000000 | 0x016b) +#define NT_STATUS_SHARED_IRQ_BUSY NT_STATUS(0xC0000000 | 0x016c) +#define NT_STATUS_FT_ORPHANING NT_STATUS(0xC0000000 | 0x016d) +#define NT_STATUS_PARTITION_FAILURE NT_STATUS(0xC0000000 | 0x0172) +#define NT_STATUS_INVALID_BLOCK_LENGTH NT_STATUS(0xC0000000 | 0x0173) +#define NT_STATUS_DEVICE_NOT_PARTITIONED NT_STATUS(0xC0000000 | 0x0174) +#define NT_STATUS_UNABLE_TO_LOCK_MEDIA NT_STATUS(0xC0000000 | 0x0175) +#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA NT_STATUS(0xC0000000 | 0x0176) +#define NT_STATUS_EOM_OVERFLOW NT_STATUS(0xC0000000 | 0x0177) +#define NT_STATUS_NO_MEDIA NT_STATUS(0xC0000000 | 0x0178) +#define NT_STATUS_NO_SUCH_MEMBER NT_STATUS(0xC0000000 | 0x017a) +#define NT_STATUS_INVALID_MEMBER NT_STATUS(0xC0000000 | 0x017b) +#define NT_STATUS_KEY_DELETED NT_STATUS(0xC0000000 | 0x017c) +#define NT_STATUS_NO_LOG_SPACE NT_STATUS(0xC0000000 | 0x017d) +#define NT_STATUS_TOO_MANY_SIDS NT_STATUS(0xC0000000 | 0x017e) +#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x017f) +#define NT_STATUS_KEY_HAS_CHILDREN NT_STATUS(0xC0000000 | 0x0180) +#define NT_STATUS_CHILD_MUST_BE_VOLATILE NT_STATUS(0xC0000000 | 0x0181) +#define NT_STATUS_DEVICE_CONFIGURATION_ERROR NT_STATUS(0xC0000000 | 0x0182) +#define NT_STATUS_DRIVER_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x0183) +#define NT_STATUS_INVALID_DEVICE_STATE NT_STATUS(0xC0000000 | 0x0184) +#define NT_STATUS_IO_DEVICE_ERROR NT_STATUS(0xC0000000 | 0x0185) +#define NT_STATUS_DEVICE_PROTOCOL_ERROR NT_STATUS(0xC0000000 | 0x0186) +#define NT_STATUS_BACKUP_CONTROLLER NT_STATUS(0xC0000000 | 0x0187) +#define NT_STATUS_LOG_FILE_FULL NT_STATUS(0xC0000000 | 0x0188) +#define NT_STATUS_TOO_LATE NT_STATUS(0xC0000000 | 0x0189) +#define NT_STATUS_NO_TRUST_LSA_SECRET NT_STATUS(0xC0000000 | 0x018a) +#define NT_STATUS_NO_TRUST_SAM_ACCOUNT NT_STATUS(0xC0000000 | 0x018b) +#define NT_STATUS_TRUSTED_DOMAIN_FAILURE NT_STATUS(0xC0000000 | 0x018c) +#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE NT_STATUS(0xC0000000 | 0x018d) +#define NT_STATUS_EVENTLOG_FILE_CORRUPT NT_STATUS(0xC0000000 | 0x018e) +#define NT_STATUS_EVENTLOG_CANT_START NT_STATUS(0xC0000000 | 0x018f) +#define NT_STATUS_TRUST_FAILURE NT_STATUS(0xC0000000 | 0x0190) +#define NT_STATUS_MUTANT_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0191) +#define NT_STATUS_NETLOGON_NOT_STARTED NT_STATUS(0xC0000000 | 0x0192) +#define NT_STATUS_ACCOUNT_EXPIRED NT_STATUS(0xC0000000 | 0x0193) +#define NT_STATUS_POSSIBLE_DEADLOCK NT_STATUS(0xC0000000 | 0x0194) +#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT NT_STATUS(0xC0000000 | 0x0195) +#define NT_STATUS_REMOTE_SESSION_LIMIT NT_STATUS(0xC0000000 | 0x0196) +#define NT_STATUS_EVENTLOG_FILE_CHANGED NT_STATUS(0xC0000000 | 0x0197) +#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0198) +#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0199) +#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x019a) +#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT NT_STATUS(0xC0000000 | 0x019b) +#define NT_STATUS_FS_DRIVER_REQUIRED NT_STATUS(0xC0000000 | 0x019c) +#define NT_STATUS_NO_USER_SESSION_KEY NT_STATUS(0xC0000000 | 0x0202) +#define NT_STATUS_USER_SESSION_DELETED NT_STATUS(0xC0000000 | 0x0203) +#define NT_STATUS_RESOURCE_LANG_NOT_FOUND NT_STATUS(0xC0000000 | 0x0204) +#define NT_STATUS_INSUFF_SERVER_RESOURCES NT_STATUS(0xC0000000 | 0x0205) +#define NT_STATUS_INVALID_BUFFER_SIZE NT_STATUS(0xC0000000 | 0x0206) +#define NT_STATUS_INVALID_ADDRESS_COMPONENT NT_STATUS(0xC0000000 | 0x0207) +#define NT_STATUS_INVALID_ADDRESS_WILDCARD NT_STATUS(0xC0000000 | 0x0208) +#define NT_STATUS_TOO_MANY_ADDRESSES NT_STATUS(0xC0000000 | 0x0209) +#define NT_STATUS_ADDRESS_ALREADY_EXISTS NT_STATUS(0xC0000000 | 0x020a) +#define NT_STATUS_ADDRESS_CLOSED NT_STATUS(0xC0000000 | 0x020b) +#define NT_STATUS_CONNECTION_DISCONNECTED NT_STATUS(0xC0000000 | 0x020c) +#define NT_STATUS_CONNECTION_RESET NT_STATUS(0xC0000000 | 0x020d) +#define NT_STATUS_TOO_MANY_NODES NT_STATUS(0xC0000000 | 0x020e) +#define NT_STATUS_TRANSACTION_ABORTED NT_STATUS(0xC0000000 | 0x020f) +#define NT_STATUS_TRANSACTION_TIMED_OUT NT_STATUS(0xC0000000 | 0x0210) +#define NT_STATUS_TRANSACTION_NO_RELEASE NT_STATUS(0xC0000000 | 0x0211) +#define NT_STATUS_TRANSACTION_NO_MATCH NT_STATUS(0xC0000000 | 0x0212) +#define NT_STATUS_TRANSACTION_RESPONDED NT_STATUS(0xC0000000 | 0x0213) +#define NT_STATUS_TRANSACTION_INVALID_ID NT_STATUS(0xC0000000 | 0x0214) +#define NT_STATUS_TRANSACTION_INVALID_TYPE NT_STATUS(0xC0000000 | 0x0215) +#define NT_STATUS_NOT_SERVER_SESSION NT_STATUS(0xC0000000 | 0x0216) +#define NT_STATUS_NOT_CLIENT_SESSION NT_STATUS(0xC0000000 | 0x0217) +#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x0218) +#define NT_STATUS_DEBUG_ATTACH_FAILED NT_STATUS(0xC0000000 | 0x0219) +#define NT_STATUS_SYSTEM_PROCESS_TERMINATED NT_STATUS(0xC0000000 | 0x021a) +#define NT_STATUS_DATA_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x021b) +#define NT_STATUS_NO_BROWSER_SERVERS_FOUND NT_STATUS(0xC0000000 | 0x021c) +#define NT_STATUS_VDM_HARD_ERROR NT_STATUS(0xC0000000 | 0x021d) +#define NT_STATUS_DRIVER_CANCEL_TIMEOUT NT_STATUS(0xC0000000 | 0x021e) +#define NT_STATUS_REPLY_MESSAGE_MISMATCH NT_STATUS(0xC0000000 | 0x021f) +#define NT_STATUS_MAPPED_ALIGNMENT NT_STATUS(0xC0000000 | 0x0220) +#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH NT_STATUS(0xC0000000 | 0x0221) +#define NT_STATUS_LOST_WRITEBEHIND_DATA NT_STATUS(0xC0000000 | 0x0222) +#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID NT_STATUS(0xC0000000 | 0x0223) +#define NT_STATUS_PASSWORD_MUST_CHANGE NT_STATUS(0xC0000000 | 0x0224) +#define NT_STATUS_NOT_FOUND NT_STATUS(0xC0000000 | 0x0225) +#define NT_STATUS_NOT_TINY_STREAM NT_STATUS(0xC0000000 | 0x0226) +#define NT_STATUS_RECOVERY_FAILURE NT_STATUS(0xC0000000 | 0x0227) +#define NT_STATUS_STACK_OVERFLOW_READ NT_STATUS(0xC0000000 | 0x0228) +#define NT_STATUS_FAIL_CHECK NT_STATUS(0xC0000000 | 0x0229) +#define NT_STATUS_DUPLICATE_OBJECTID NT_STATUS(0xC0000000 | 0x022a) +#define NT_STATUS_OBJECTID_EXISTS NT_STATUS(0xC0000000 | 0x022b) +#define NT_STATUS_CONVERT_TO_LARGE NT_STATUS(0xC0000000 | 0x022c) +#define NT_STATUS_RETRY NT_STATUS(0xC0000000 | 0x022d) +#define NT_STATUS_FOUND_OUT_OF_SCOPE NT_STATUS(0xC0000000 | 0x022e) +#define NT_STATUS_ALLOCATE_BUCKET NT_STATUS(0xC0000000 | 0x022f) +#define NT_STATUS_PROPSET_NOT_FOUND NT_STATUS(0xC0000000 | 0x0230) +#define NT_STATUS_MARSHALL_OVERFLOW NT_STATUS(0xC0000000 | 0x0231) +#define NT_STATUS_INVALID_VARIANT NT_STATUS(0xC0000000 | 0x0232) +#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND NT_STATUS(0xC0000000 | 0x0233) +#define NT_STATUS_ACCOUNT_LOCKED_OUT NT_STATUS(0xC0000000 | 0x0234) +#define NT_STATUS_HANDLE_NOT_CLOSABLE NT_STATUS(0xC0000000 | 0x0235) +#define NT_STATUS_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0236) +#define NT_STATUS_GRACEFUL_DISCONNECT NT_STATUS(0xC0000000 | 0x0237) +#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED NT_STATUS(0xC0000000 | 0x0238) +#define NT_STATUS_ADDRESS_NOT_ASSOCIATED NT_STATUS(0xC0000000 | 0x0239) +#define NT_STATUS_CONNECTION_INVALID NT_STATUS(0xC0000000 | 0x023a) +#define NT_STATUS_CONNECTION_ACTIVE NT_STATUS(0xC0000000 | 0x023b) +#define NT_STATUS_NETWORK_UNREACHABLE NT_STATUS(0xC0000000 | 0x023c) +#define NT_STATUS_HOST_UNREACHABLE NT_STATUS(0xC0000000 | 0x023d) +#define NT_STATUS_PROTOCOL_UNREACHABLE NT_STATUS(0xC0000000 | 0x023e) +#define NT_STATUS_PORT_UNREACHABLE NT_STATUS(0xC0000000 | 0x023f) +#define NT_STATUS_REQUEST_ABORTED NT_STATUS(0xC0000000 | 0x0240) +#define NT_STATUS_CONNECTION_ABORTED NT_STATUS(0xC0000000 | 0x0241) +#define NT_STATUS_BAD_COMPRESSION_BUFFER NT_STATUS(0xC0000000 | 0x0242) +#define NT_STATUS_USER_MAPPED_FILE NT_STATUS(0xC0000000 | 0x0243) +#define NT_STATUS_AUDIT_FAILED NT_STATUS(0xC0000000 | 0x0244) +#define NT_STATUS_TIMER_RESOLUTION_NOT_SET NT_STATUS(0xC0000000 | 0x0245) +#define NT_STATUS_CONNECTION_COUNT_LIMIT NT_STATUS(0xC0000000 | 0x0246) +#define NT_STATUS_LOGIN_TIME_RESTRICTION NT_STATUS(0xC0000000 | 0x0247) +#define NT_STATUS_LOGIN_WKSTA_RESTRICTION NT_STATUS(0xC0000000 | 0x0248) +#define NT_STATUS_IMAGE_MP_UP_MISMATCH NT_STATUS(0xC0000000 | 0x0249) +#define NT_STATUS_INSUFFICIENT_LOGON_INFO NT_STATUS(0xC0000000 | 0x0250) +#define NT_STATUS_BAD_DLL_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0251) +#define NT_STATUS_BAD_SERVICE_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0252) +#define NT_STATUS_LPC_REPLY_LOST NT_STATUS(0xC0000000 | 0x0253) +#define NT_STATUS_IP_ADDRESS_CONFLICT1 NT_STATUS(0xC0000000 | 0x0254) +#define NT_STATUS_IP_ADDRESS_CONFLICT2 NT_STATUS(0xC0000000 | 0x0255) +#define NT_STATUS_REGISTRY_QUOTA_LIMIT NT_STATUS(0xC0000000 | 0x0256) +#define NT_STATUS_PATH_NOT_COVERED NT_STATUS(0xC0000000 | 0x0257) +#define NT_STATUS_NO_CALLBACK_ACTIVE NT_STATUS(0xC0000000 | 0x0258) +#define NT_STATUS_LICENSE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0259) +#define NT_STATUS_PWD_TOO_SHORT NT_STATUS(0xC0000000 | 0x025a) +#define NT_STATUS_PWD_TOO_RECENT NT_STATUS(0xC0000000 | 0x025b) +#define NT_STATUS_PWD_HISTORY_CONFLICT NT_STATUS(0xC0000000 | 0x025c) +#define NT_STATUS_PLUGPLAY_NO_DEVICE NT_STATUS(0xC0000000 | 0x025e) +#define NT_STATUS_UNSUPPORTED_COMPRESSION NT_STATUS(0xC0000000 | 0x025f) +#define NT_STATUS_INVALID_HW_PROFILE NT_STATUS(0xC0000000 | 0x0260) +#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH NT_STATUS(0xC0000000 | 0x0261) +#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0262) +#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0263) +#define NT_STATUS_RESOURCE_NOT_OWNED NT_STATUS(0xC0000000 | 0x0264) +#define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265) +#define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266) +#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) +#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) +#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ +#define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) +#define NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX NT_STATUS(0xC0000000 | 0x20026) + + +/* I use NT_STATUS_FOOBAR when I have no idea what error code to use - + * this means we need a torture test */ +#define NT_STATUS_FOOBAR NT_STATUS_UNSUCCESSFUL + +#endif /* _NTERR_H */ -- cgit From 559ba6f12aacf3639ad6268490bc8ed33b1fb803 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 11:52:55 +0000 Subject: r13653: Copy headers from the right place (This used to be commit 5e884f156f8f824b0540351ce07cd423595d9d1f) --- source4/libcli/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0040339fd2..b431922de7 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,6 +3,7 @@ include ldap/config.mk include security/config.mk [SUBSYSTEM::LIBCLI_UTILS] +PUBLIC_HEADERS = util/nterr.h util/doserr.h OBJ_FILES = util/asn1.o \ util/doserr.o \ util/errormap.o \ -- cgit From d3bcaf66a8568fc19a3013f9dc974fb08ee3a39a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 12:44:21 +0000 Subject: r13654: Move some more stuff out of include/ (This used to be commit 2ec7bba03a2edf713004941e9ed74798f5cf8d32) --- source4/libcli/raw/interfaces.h | 2035 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 2035 insertions(+) create mode 100644 source4/libcli/raw/interfaces.h (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h new file mode 100644 index 0000000000..49fe085f2c --- /dev/null +++ b/source4/libcli/raw/interfaces.h @@ -0,0 +1,2035 @@ +/* + Unix SMB/CIFS implementation. + SMB request interface structures + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + 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. +*/ + + + +/* this structure is just a wrapper for a string, the only reason we + bother with this is that it allows us to check the length provided + on the wire in testsuite test code to ensure that we are + terminating names in the same way that win2003 is. The *ONLY* time + you should ever look at the 'private_length' field in this + structure is inside compliance test code, in all other cases just + use the null terminated char* as the definitive definition of the + string + + also note that this structure is only used in packets where there + is an explicit length provided on the wire (hence the name). That + length is placed in 'private_length'. For packets where the length + is always determined by NULL or packet termination a normal char* + is used in the structure definition. + */ +typedef struct { + uint32_t private_length; + const char *s; +} WIRE_STRING; + + +/* + use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really + just a dom sid, but with the sub_auths represented as a conformant + array. As with all in-structure conformant arrays, the array length + is placed before the start of the structure. That's what gives rise + to the extra num_auths elemenent. We don't want the Samba code to + have to bother with such esoteric NDR details, so its easier to just + define it as a dom_sid and use pidl magic to make it all work. It + just means you need to mark a sid as a "dom_sid2" in the IDL when you + know it is of the conformant array variety +*/ +#define dom_sid2 dom_sid + +/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ +#define dom_sid28 dom_sid + + +/* + this header defines the structures and unions used between the SMB + parser and the backends. +*/ + +/* struct used for SMBlseek call */ +struct smb_seek { + struct { + uint16_t fnum; + uint16_t mode; + int32_t offset; /* signed */ + } in; + struct { + int32_t offset; + } out; +}; + + +/* struct used in unlink() call */ +struct smb_unlink { + struct { + const char *pattern; + uint16_t attrib; + } in; +}; + + +/* struct used in chkpath() call */ +struct smb_chkpath { + struct { + const char *path; + } in; +}; + +enum smb_mkdir_level {RAW_MKDIR_GENERIC, RAW_MKDIR_MKDIR, RAW_MKDIR_T2MKDIR}; + +/* union used in mkdir() call */ +union smb_mkdir { + /* generic level */ + struct { + enum smb_mkdir_level level; + } generic; + + struct { + enum smb_mkdir_level level; + struct { + const char *path; + } in; + } mkdir; + + struct { + enum smb_mkdir_level level; + struct { + const char *path; + uint_t num_eas; + struct ea_struct *eas; + } in; + } t2mkdir; +}; + +/* struct used in rmdir() call */ +struct smb_rmdir { + struct { + const char *path; + } in; +}; + +/* struct used in rename() call */ +enum smb_rename_level {RAW_RENAME_RENAME, RAW_RENAME_NTRENAME}; + +union smb_rename { + struct { + enum smb_rename_level level; + } generic; + + /* SMBrename interface */ + struct { + enum smb_rename_level level; + + struct { + const char *pattern1; + const char *pattern2; + uint16_t attrib; + } in; + } rename; + + + /* SMBntrename interface */ + struct { + enum smb_rename_level level; + + struct { + uint16_t attrib; + uint16_t flags; /* see RENAME_FLAG_* */ + uint32_t cluster_size; + const char *old_name; + const char *new_name; + } in; + } ntrename; +}; + +enum smb_tcon_level {RAW_TCON_TCON, RAW_TCON_TCONX}; + +/* union used in tree connect call */ +union smb_tcon { + /* generic interface */ + struct { + enum smb_tcon_level level; + } generic; + + /* SMBtcon interface */ + struct { + enum smb_tcon_level level; + + struct { + const char *service; + const char *password; + const char *dev; + } in; + struct { + uint16_t max_xmit; + uint16_t tid; + } out; + } tcon; + + /* SMBtconX interface */ + struct { + enum smb_tcon_level level; + + struct { + uint16_t flags; + DATA_BLOB password; + const char *path; + const char *device; + } in; + struct { + uint16_t options; + char *dev_type; + char *fs_type; + uint16_t tid; + } out; + } tconx; +}; + + +enum smb_sesssetup_level {RAW_SESSSETUP_OLD, RAW_SESSSETUP_NT1, RAW_SESSSETUP_SPNEGO}; + +/* union used in session_setup call */ +union smb_sesssetup { + /* the pre-NT1 interface */ + struct { + enum smb_sesssetup_level level; + + struct { + uint16_t bufsize; + uint16_t mpx_max; + uint16_t vc_num; + uint32_t sesskey; + DATA_BLOB password; + const char *user; + const char *domain; + const char *os; + const char *lanman; + } in; + struct { + uint16_t action; + uint16_t vuid; + char *os; + char *lanman; + char *domain; + } out; + } old; + + /* the NT1 interface */ + struct { + enum smb_sesssetup_level level; + + struct { + uint16_t bufsize; + uint16_t mpx_max; + uint16_t vc_num; + uint32_t sesskey; + uint32_t capabilities; + DATA_BLOB password1; + DATA_BLOB password2; + const char *user; + const char *domain; + const char *os; + const char *lanman; + } in; + struct { + uint16_t action; + uint16_t vuid; + char *os; + char *lanman; + char *domain; + } out; + } nt1; + + + /* the SPNEGO interface */ + struct { + enum smb_sesssetup_level level; + + struct { + uint16_t bufsize; + uint16_t mpx_max; + uint16_t vc_num; + uint32_t sesskey; + uint32_t capabilities; + DATA_BLOB secblob; + const char *os; + const char *lanman; + const char *workgroup; + } in; + struct { + uint16_t action; + DATA_BLOB secblob; + char *os; + char *lanman; + char *workgroup; + uint16_t vuid; + } out; + } spnego; +}; + +/* Note that the specified enum values are identical to the actual info-levels used + * on the wire. + */ +enum smb_fileinfo_level { + RAW_FILEINFO_GENERIC = 0xF000, + RAW_FILEINFO_GETATTR, /* SMBgetatr */ + RAW_FILEINFO_GETATTRE, /* SMBgetattrE */ + RAW_FILEINFO_SEC_DESC, /* NT_TRANSACT_QUERY_SECURITY_DESC */ + RAW_FILEINFO_STANDARD = SMB_QFILEINFO_STANDARD, + RAW_FILEINFO_EA_SIZE = SMB_QFILEINFO_EA_SIZE, + RAW_FILEINFO_EA_LIST = SMB_QFILEINFO_EA_LIST, + RAW_FILEINFO_ALL_EAS = SMB_QFILEINFO_ALL_EAS, + RAW_FILEINFO_IS_NAME_VALID = SMB_QFILEINFO_IS_NAME_VALID, + RAW_FILEINFO_BASIC_INFO = SMB_QFILEINFO_BASIC_INFO, + RAW_FILEINFO_STANDARD_INFO = SMB_QFILEINFO_STANDARD_INFO, + RAW_FILEINFO_EA_INFO = SMB_QFILEINFO_EA_INFO, + RAW_FILEINFO_NAME_INFO = SMB_QFILEINFO_NAME_INFO, + RAW_FILEINFO_ALL_INFO = SMB_QFILEINFO_ALL_INFO, + RAW_FILEINFO_ALT_NAME_INFO = SMB_QFILEINFO_ALT_NAME_INFO, + RAW_FILEINFO_STREAM_INFO = SMB_QFILEINFO_STREAM_INFO, + RAW_FILEINFO_COMPRESSION_INFO = SMB_QFILEINFO_COMPRESSION_INFO, + RAW_FILEINFO_UNIX_BASIC = SMB_QFILEINFO_UNIX_BASIC, + RAW_FILEINFO_UNIX_LINK = SMB_QFILEINFO_UNIX_LINK, + RAW_FILEINFO_BASIC_INFORMATION = SMB_QFILEINFO_BASIC_INFORMATION, + RAW_FILEINFO_STANDARD_INFORMATION = SMB_QFILEINFO_STANDARD_INFORMATION, + RAW_FILEINFO_INTERNAL_INFORMATION = SMB_QFILEINFO_INTERNAL_INFORMATION, + RAW_FILEINFO_EA_INFORMATION = SMB_QFILEINFO_EA_INFORMATION, + RAW_FILEINFO_ACCESS_INFORMATION = SMB_QFILEINFO_ACCESS_INFORMATION, + RAW_FILEINFO_NAME_INFORMATION = SMB_QFILEINFO_NAME_INFORMATION, + RAW_FILEINFO_POSITION_INFORMATION = SMB_QFILEINFO_POSITION_INFORMATION, + RAW_FILEINFO_MODE_INFORMATION = SMB_QFILEINFO_MODE_INFORMATION, + RAW_FILEINFO_ALIGNMENT_INFORMATION = SMB_QFILEINFO_ALIGNMENT_INFORMATION, + RAW_FILEINFO_ALL_INFORMATION = SMB_QFILEINFO_ALL_INFORMATION, + RAW_FILEINFO_ALT_NAME_INFORMATION = SMB_QFILEINFO_ALT_NAME_INFORMATION, + RAW_FILEINFO_STREAM_INFORMATION = SMB_QFILEINFO_STREAM_INFORMATION, + RAW_FILEINFO_COMPRESSION_INFORMATION = SMB_QFILEINFO_COMPRESSION_INFORMATION, + RAW_FILEINFO_NETWORK_OPEN_INFORMATION = SMB_QFILEINFO_NETWORK_OPEN_INFORMATION, + RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION = SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION, + /* SMB2 specific levels */ + RAW_FILEINFO_SMB2_ALL_EAS = 0x0f01, + RAW_FILEINFO_SMB2_ALL_INFORMATION = 0x1201 +}; + +/* + file handles in SMB2 are 16 bytes +*/ +struct smb2_handle { + uint64_t data[2]; +}; + + +/* union used in qfileinfo() and qpathinfo() backend calls */ +union smb_fileinfo { + /* generic interface: + * matches RAW_FILEINFO_GENERIC */ + struct { + enum smb_fileinfo_level level; + + /* each level can be called on either a pathname or a + filename, in either case the return format is + identical + On SMB2 a 16 byte handle is used + */ + union smb_fileinfo_in { + const char *fname; + uint16_t fnum; + struct smb2_handle handle; + } in; + + struct { + uint32_t attrib; + uint32_t ea_size; + uint_t num_eas; + struct ea_struct { + uint8_t flags; + WIRE_STRING name; + DATA_BLOB value; + } *eas; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + WIRE_STRING fname; + WIRE_STRING alt_fname; + uint8_t delete_pending; + uint8_t directory; + uint64_t compressed_size; + uint16_t format; + uint8_t unit_shift; + uint8_t chunk_shift; + uint8_t cluster_shift; + uint64_t file_id; + uint32_t access_flags; /* seen 0x001f01ff from w2k3 */ + uint64_t position; + uint32_t mode; + uint32_t alignment_requirement; + uint32_t reparse_tag; + uint_t num_streams; + struct stream_struct { + uint64_t size; + uint64_t alloc_size; + WIRE_STRING stream_name; + } *streams; + } out; + } generic; + + + /* SMBgetatr interface: + * matches RAW_FILEINFO_GETATTR */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint16_t attrib; + uint32_t size; + time_t write_time; + } out; + } getattr; + + /* SMBgetattrE and RAW_FILEINFO_STANDARD interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + time_t create_time; + time_t access_time; + time_t write_time; + uint32_t size; + uint32_t alloc_size; + uint16_t attrib; + } out; + } getattre, standard; + + /* trans2 RAW_FILEINFO_EA_SIZE interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + time_t create_time; + time_t access_time; + time_t write_time; + uint32_t size; + uint32_t alloc_size; + uint16_t attrib; + uint32_t ea_size; + } out; + } ea_size; + + /* trans2 RAW_FILEINFO_EA_LIST interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in file; + + struct { + uint_t num_names; + struct ea_name { + WIRE_STRING name; + } *ea_names; + } in; + + struct smb_ea_list { + uint_t num_eas; + struct ea_struct *eas; + } out; + } ea_list; + + /* trans2 RAW_FILEINFO_ALL_EAS and RAW_FILEINFO_FULL_EA_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + uint8_t continue_flags; /* SMB2 only - SMB2_CONTINUE_FLAG_* */ + + struct smb_ea_list out; + } all_eas; + + /* trans2 qpathinfo RAW_FILEINFO_IS_NAME_VALID interface + only valid for a QPATHNAME call - no returned data */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + } is_name_valid; + + /* RAW_FILEINFO_BASIC_INFO and RAW_FILEINFO_BASIC_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + } out; + } basic_info; + + + /* RAW_FILEINFO_STANDARD_INFO and RAW_FILEINFO_STANDARD_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + BOOL delete_pending; + BOOL directory; + } out; + } standard_info; + + /* RAW_FILEINFO_EA_INFO and RAW_FILEINFO_EA_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint32_t ea_size; + } out; + } ea_info; + + /* RAW_FILEINFO_NAME_INFO and RAW_FILEINFO_NAME_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + WIRE_STRING fname; + } out; + } name_info; + + /* RAW_FILEINFO_ALL_INFO and RAW_FILEINFO_ALL_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + uint8_t delete_pending; + uint8_t directory; + uint32_t ea_size; + WIRE_STRING fname; + } out; + } all_info; + + /* RAW_FILEINFO_SMB2_ALL_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + uint32_t unknown1; + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + uint8_t delete_pending; + uint8_t directory; + /* uint16_t _pad; */ + uint64_t file_id; + uint32_t ea_size; + uint32_t access_mask; + uint64_t position; + uint64_t mode; + WIRE_STRING fname; + } out; + } all_info2; + + /* RAW_FILEINFO_ALT_NAME_INFO and RAW_FILEINFO_ALT_NAME_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + WIRE_STRING fname; + } out; + } alt_name_info; + + /* RAW_FILEINFO_STREAM_INFO and RAW_FILEINFO_STREAM_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct stream_information { + uint_t num_streams; + struct stream_struct *streams; + } out; + } stream_info; + + /* RAW_FILEINFO_COMPRESSION_INFO and RAW_FILEINFO_COMPRESSION_INFORMATION interfaces */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint64_t compressed_size; + uint16_t format; + uint8_t unit_shift; + uint8_t chunk_shift; + uint8_t cluster_shift; + } out; + } compression_info; + + /* RAW_FILEINFO_UNIX_BASIC interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + } out; + } unix_basic_info; + + /* RAW_FILEINFO_UNIX_LINK interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + WIRE_STRING link_dest; + } out; + } unix_link_info; + + /* RAW_FILEINFO_INTERNAL_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint64_t file_id; + } out; + } internal_information; + + /* RAW_FILEINFO_ACCESS_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint32_t access_flags; + } out; + } access_information; + + /* RAW_FILEINFO_POSITION_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint64_t position; + } out; + } position_information; + + /* RAW_FILEINFO_MODE_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint32_t mode; + } out; + } mode_information; + + /* RAW_FILEINFO_ALIGNMENT_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint32_t alignment_requirement; + } out; + } alignment_information; + + /* RAW_FILEINFO_NETWORK_OPEN_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t attrib; + } out; + } network_open_information; + + + /* RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION interface */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + + struct { + uint32_t attrib; + uint32_t reparse_tag; + } out; + } attribute_tag_information; + + /* RAW_FILEINFO_SEC_DESC */ + struct { + enum smb_fileinfo_level level; + union smb_fileinfo_in in; + uint32_t secinfo_flags; + struct { + struct security_descriptor *sd; + } out; + } query_secdesc; +}; + + +enum smb_setfileinfo_level { + RAW_SFILEINFO_GENERIC = 0xF000, + RAW_SFILEINFO_SETATTR, /* SMBsetatr */ + RAW_SFILEINFO_SETATTRE, /* SMBsetattrE */ + RAW_SFILEINFO_SEC_DESC, /* NT_TRANSACT_SET_SECURITY_DESC */ + RAW_SFILEINFO_STANDARD = SMB_SFILEINFO_STANDARD, + RAW_SFILEINFO_EA_SET = SMB_SFILEINFO_EA_SET, + RAW_SFILEINFO_BASIC_INFO = SMB_SFILEINFO_BASIC_INFO, + RAW_SFILEINFO_DISPOSITION_INFO = SMB_SFILEINFO_DISPOSITION_INFO, + RAW_SFILEINFO_ALLOCATION_INFO = SMB_SFILEINFO_ALLOCATION_INFO, + RAW_SFILEINFO_END_OF_FILE_INFO = SMB_SFILEINFO_END_OF_FILE_INFO, + RAW_SFILEINFO_UNIX_BASIC = SMB_SFILEINFO_UNIX_BASIC, + RAW_SFILEINFO_UNIX_LINK = SMB_SFILEINFO_UNIX_LINK, + RAW_SFILEINFO_UNIX_HLINK = SMB_SFILEINFO_UNIX_HLINK, + RAW_SFILEINFO_BASIC_INFORMATION = SMB_SFILEINFO_BASIC_INFORMATION, + RAW_SFILEINFO_RENAME_INFORMATION = SMB_SFILEINFO_RENAME_INFORMATION, + RAW_SFILEINFO_DISPOSITION_INFORMATION = SMB_SFILEINFO_DISPOSITION_INFORMATION, + RAW_SFILEINFO_POSITION_INFORMATION = SMB_SFILEINFO_POSITION_INFORMATION, + RAW_SFILEINFO_MODE_INFORMATION = SMB_SFILEINFO_MODE_INFORMATION, + RAW_SFILEINFO_ALLOCATION_INFORMATION = SMB_SFILEINFO_ALLOCATION_INFORMATION, + RAW_SFILEINFO_END_OF_FILE_INFORMATION = SMB_SFILEINFO_END_OF_FILE_INFORMATION, + RAW_SFILEINFO_1023 = SMB_SFILEINFO_1023, + RAW_SFILEINFO_1025 = SMB_SFILEINFO_1025, + RAW_SFILEINFO_1029 = SMB_SFILEINFO_1029, + RAW_SFILEINFO_1032 = SMB_SFILEINFO_1032, + RAW_SFILEINFO_1039 = SMB_SFILEINFO_1039, + RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040 +}; + +/* union used in setfileinfo() and setpathinfo() calls */ +union smb_setfileinfo { + /* generic interface */ + struct { + enum smb_setfileinfo_level level; + + /* we are combining setfileinfo and setpathinfo into one + interface */ + union setfileinfo_file { + const char *fname; + uint16_t fnum; + struct smb2_handle handle; /* only for SMB2 */ + } file; + } generic; + + /* RAW_SFILEINFO_SETATTR (SMBsetatr) interface - only via setpathinfo() */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + struct { + uint16_t attrib; + time_t write_time; + } in; + } setattr; + + /* RAW_SFILEINFO_SETATTRE (SMBsetattrE) interface - only via setfileinfo() + also RAW_SFILEINFO_STANDARD */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + time_t create_time; + time_t access_time; + time_t write_time; + /* notice that size, alloc_size and attrib are not settable, + unlike the corresponding qfileinfo level */ + } in; + } setattre, standard; + + /* RAW_SFILEINFO_EA_SET interface */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + struct { + uint_t num_eas; + struct ea_struct *eas; + } in; + } ea_set; + + /* RAW_SFILEINFO_BASIC_INFO and + RAW_SFILEINFO_BASIC_INFORMATION interfaces */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + } in; + } basic_info; + + /* RAW_SFILEINFO_DISPOSITION_INFO and + RAW_SFILEINFO_DISPOSITION_INFORMATION interfaces */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + BOOL delete_on_close; + } in; + } disposition_info; + + /* RAW_SFILEINFO_ALLOCATION_INFO and + RAW_SFILEINFO_ALLOCATION_INFORMATION interfaces */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + /* w2k3 rounds this up to nearest 4096 */ + uint64_t alloc_size; + } in; + } allocation_info; + + /* RAW_SFILEINFO_END_OF_FILE_INFO and + RAW_SFILEINFO_END_OF_FILE_INFORMATION interfaces */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + uint64_t size; + } in; + } end_of_file_info; + + /* RAW_SFILEINFO_RENAME_INFORMATION interface */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct smb_rename_information { + uint8_t overwrite; + uint32_t root_fid; + const char *new_name; + } in; + } rename_information; + + /* RAW_SFILEINFO_POSITION_INFORMATION interface */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + uint64_t position; + } in; + } position_information; + + /* RAW_SFILEINFO_MODE_INFORMATION interface */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + + struct { + /* valid values seem to be 0, 2, 4 and 6 */ + uint32_t mode; + } in; + } mode_information; + + + + /* RAW_SFILEINFO_UNIX_BASIC interface */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + struct { + uint32_t mode; /* yuck - this field remains to fix compile of libcli/clifile.c */ + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + } in; + } unix_basic; + + /* RAW_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK interface */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + struct { + const char *link_dest; + } in; + } unix_link, unix_hlink; + + /* RAW_FILEINFO_SET_SEC_DESC */ + struct { + enum smb_setfileinfo_level level; + union setfileinfo_file file; + struct { + uint32_t secinfo_flags; + struct security_descriptor *sd; + } in; + } set_secdesc; +}; + + +enum smb_fsinfo_level { + RAW_QFS_GENERIC = 0xF000, + RAW_QFS_DSKATTR, /* SMBdskattr */ + RAW_QFS_ALLOCATION = SMB_QFS_ALLOCATION, + RAW_QFS_VOLUME = SMB_QFS_VOLUME, + RAW_QFS_VOLUME_INFO = SMB_QFS_VOLUME_INFO, + RAW_QFS_SIZE_INFO = SMB_QFS_SIZE_INFO, + RAW_QFS_DEVICE_INFO = SMB_QFS_DEVICE_INFO, + RAW_QFS_ATTRIBUTE_INFO = SMB_QFS_ATTRIBUTE_INFO, + RAW_QFS_UNIX_INFO = SMB_QFS_UNIX_INFO, + RAW_QFS_VOLUME_INFORMATION = SMB_QFS_VOLUME_INFORMATION, + RAW_QFS_SIZE_INFORMATION = SMB_QFS_SIZE_INFORMATION, + RAW_QFS_DEVICE_INFORMATION = SMB_QFS_DEVICE_INFORMATION, + RAW_QFS_ATTRIBUTE_INFORMATION = SMB_QFS_ATTRIBUTE_INFORMATION, + RAW_QFS_QUOTA_INFORMATION = SMB_QFS_QUOTA_INFORMATION, + RAW_QFS_FULL_SIZE_INFORMATION = SMB_QFS_FULL_SIZE_INFORMATION, + RAW_QFS_OBJECTID_INFORMATION = SMB_QFS_OBJECTID_INFORMATION}; + + +/* union for fsinfo() backend call. Note that there are no in + structures, as this call only contains out parameters */ +union smb_fsinfo { + /* generic interface */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + uint32_t block_size; + uint64_t blocks_total; + uint64_t blocks_free; + uint32_t fs_id; + NTTIME create_time; + uint32_t serial_number; + uint32_t fs_attr; + uint32_t max_file_component_length; + uint32_t device_type; + uint32_t device_characteristics; + uint64_t quota_soft; + uint64_t quota_hard; + uint64_t quota_flags; + struct GUID guid; + char *volume_name; + char *fs_type; + } out; + } generic; + + /* SMBdskattr interface */ + struct { + enum smb_fsinfo_level level; + + struct { + uint16_t units_total; + uint16_t blocks_per_unit; + uint16_t block_size; + uint16_t units_free; + } out; + } dskattr; + + /* trans2 RAW_QFS_ALLOCATION interface */ + struct { + enum smb_fsinfo_level level; + + struct { + uint32_t fs_id; + uint32_t sectors_per_unit; + uint32_t total_alloc_units; + uint32_t avail_alloc_units; + uint16_t bytes_per_sector; + } out; + } allocation; + + /* TRANS2 RAW_QFS_VOLUME interface */ + struct { + enum smb_fsinfo_level level; + + struct { + uint32_t serial_number; + WIRE_STRING volume_name; + } out; + } volume; + + /* TRANS2 RAW_QFS_VOLUME_INFO and RAW_QFS_VOLUME_INFORMATION interfaces */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + NTTIME create_time; + uint32_t serial_number; + WIRE_STRING volume_name; + } out; + } volume_info; + + /* trans2 RAW_QFS_SIZE_INFO and RAW_QFS_SIZE_INFORMATION interfaces */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + uint64_t total_alloc_units; + uint64_t avail_alloc_units; /* maps to call_avail_alloc_units */ + uint32_t sectors_per_unit; + uint32_t bytes_per_sector; + } out; + } size_info; + + /* TRANS2 RAW_QFS_DEVICE_INFO and RAW_QFS_DEVICE_INFORMATION interfaces */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + uint32_t device_type; + uint32_t characteristics; + } out; + } device_info; + + + /* TRANS2 RAW_QFS_ATTRIBUTE_INFO and RAW_QFS_ATTRIBUTE_INFORMATION interfaces */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + uint32_t fs_attr; + uint32_t max_file_component_length; + WIRE_STRING fs_type; + } out; + } attribute_info; + + + /* TRANS2 RAW_QFS_UNIX_INFO interface */ + struct { + enum smb_fsinfo_level level; + + struct { + uint16_t major_version; + uint16_t minor_version; + uint64_t capability; + } out; + } unix_info; + + /* trans2 RAW_QFS_QUOTA_INFORMATION interface */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + uint64_t unknown[3]; + uint64_t quota_soft; + uint64_t quota_hard; + uint64_t quota_flags; + } out; + } quota_information; + + /* trans2 RAW_QFS_FULL_SIZE_INFORMATION interface */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + uint64_t total_alloc_units; + uint64_t call_avail_alloc_units; + uint64_t actual_avail_alloc_units; + uint32_t sectors_per_unit; + uint32_t bytes_per_sector; + } out; + } full_size_information; + + /* trans2 RAW_QFS_OBJECTID_INFORMATION interface */ + struct { + enum smb_fsinfo_level level; + struct smb2_handle handle; /* only for smb2 */ + + struct { + struct GUID guid; + uint64_t unknown[6]; + } out; + } objectid_information; +}; + + + +enum smb_open_level { + RAW_OPEN_OPEN, RAW_OPEN_OPENX, + RAW_OPEN_MKNEW, RAW_OPEN_CREATE, + RAW_OPEN_CTEMP, RAW_OPEN_SPLOPEN, + RAW_OPEN_NTCREATEX, RAW_OPEN_T2OPEN, + RAW_OPEN_NTTRANS_CREATE, + RAW_OPEN_OPENX_READX}; + +/* the generic interface is defined to be equal to the NTCREATEX interface */ +#define RAW_OPEN_GENERIC RAW_OPEN_NTCREATEX + +/* union for open() backend call */ +union smb_open { + /* SMBNTCreateX interface */ + struct { + enum smb_open_level level; + + struct { + uint32_t flags; + uint32_t root_fid; + uint32_t access_mask; + uint64_t alloc_size; + uint32_t file_attr; + uint32_t share_access; + uint32_t open_disposition; + uint32_t create_options; + uint32_t impersonation; + uint8_t security_flags; + /* NOTE: fname can also be a pointer to a + uint64_t file_id if create_options has the + NTCREATEX_OPTIONS_OPEN_BY_FILE_ID flag set */ + const char *fname; + + /* these last 2 elements are only used in the + NTTRANS varient of the call */ + struct security_descriptor *sec_desc; + struct smb_ea_list *ea_list; + } in; + + struct { + uint8_t oplock_level; + uint16_t fnum; + uint32_t create_action; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + uint64_t alloc_size; + uint64_t size; + uint16_t file_type; + uint16_t ipc_state; + uint8_t is_directory; + } out; + } ntcreatex, generic; + + /* TRANS2_OPEN interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t flags; + uint16_t open_mode; + uint16_t search_attrs; + uint16_t file_attrs; + time_t write_time; + uint16_t open_func; + uint32_t size; + uint32_t timeout; + const char *fname; + uint_t num_eas; + struct ea_struct *eas; + } in; + + struct { + uint16_t fnum; + uint16_t attrib; + time_t write_time; + uint32_t size; + uint16_t access; + uint16_t ftype; + uint16_t devstate; + uint16_t action; + uint32_t file_id; + } out; + } t2open; + + /* SMBopen interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t open_mode; + uint16_t search_attrs; + const char *fname; + } in; + struct { + uint16_t fnum; + uint16_t attrib; + time_t write_time; + uint32_t size; + uint16_t rmode; + } out; + } openold; + + /* SMBopenX interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t flags; + uint16_t open_mode; + uint16_t search_attrs; /* not honoured by win2003 */ + uint16_t file_attrs; + time_t write_time; /* not honoured by win2003 */ + uint16_t open_func; + uint32_t size; /* note that this sets the + initial file size, not + just allocation size */ + uint32_t timeout; /* not honoured by win2003 */ + const char *fname; + } in; + struct { + uint16_t fnum; + uint16_t attrib; + time_t write_time; + uint32_t size; + uint16_t access; + uint16_t ftype; + uint16_t devstate; + uint16_t action; + uint32_t unique_fid; + uint32_t access_mask; + uint32_t unknown; + } out; + } openx; + + /* SMBmknew interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t attrib; + time_t write_time; + const char *fname; + } in; + struct { + uint16_t fnum; + } out; + } mknew, create; + + /* SMBctemp interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t attrib; + time_t write_time; + const char *directory; + } in; + struct { + uint16_t fnum; + /* temp name, relative to directory */ + char *name; + } out; + } ctemp; + + /* SMBsplopen interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t setup_length; + uint16_t mode; + const char *ident; + } in; + struct { + uint16_t fnum; + } out; + } splopen; + + + /* chained OpenX/ReadX interface */ + struct { + enum smb_open_level level; + + struct { + uint16_t flags; + uint16_t open_mode; + uint16_t search_attrs; /* not honoured by win2003 */ + uint16_t file_attrs; + time_t write_time; /* not honoured by win2003 */ + uint16_t open_func; + uint32_t size; /* note that this sets the + initial file size, not + just allocation size */ + uint32_t timeout; /* not honoured by win2003 */ + const char *fname; + + /* readx part */ + uint64_t offset; + uint16_t mincnt; + uint32_t maxcnt; + uint16_t remaining; + } in; + struct { + uint16_t fnum; + uint16_t attrib; + time_t write_time; + uint32_t size; + uint16_t access; + uint16_t ftype; + uint16_t devstate; + uint16_t action; + uint32_t unique_fid; + uint32_t access_mask; + uint32_t unknown; + + /* readx part */ + uint8_t *data; + uint16_t remaining; + uint16_t compaction_mode; + uint16_t nread; + } out; + } openxreadx; +}; + + + +enum smb_read_level {RAW_READ_READBRAW, RAW_READ_LOCKREAD, RAW_READ_READ, RAW_READ_READX}; + +#define RAW_READ_GENERIC RAW_READ_READX + +/* union for read() backend call + + note that .infoX.out.data will be allocated before the backend is + called. It will be big enough to hold the maximum size asked for +*/ +union smb_read { + /* SMBreadX (and generic) interface */ + struct { + enum smb_read_level level; + + struct { + uint16_t fnum; + uint64_t offset; + uint16_t mincnt; + uint32_t maxcnt; + uint16_t remaining; + } in; + struct { + uint8_t *data; + uint16_t remaining; + uint16_t compaction_mode; + uint16_t nread; + } out; + } readx, generic; + + /* SMBreadbraw interface */ + struct { + enum smb_read_level level; + + struct { + uint16_t fnum; + uint64_t offset; + uint16_t maxcnt; + uint16_t mincnt; + uint32_t timeout; + } in; + struct { + uint8_t *data; + uint32_t nread; + } out; + } readbraw; + + + /* SMBlockandread interface */ + struct { + enum smb_read_level level; + + struct { + uint16_t fnum; + uint16_t count; + uint32_t offset; + uint16_t remaining; + } in; + struct { + uint8_t *data; + uint16_t nread; + } out; + } lockread; + + /* SMBread interface */ + struct { + enum smb_read_level level; + + struct { + uint16_t fnum; + uint16_t count; + uint32_t offset; + uint16_t remaining; + } in; + struct { + uint8_t *data; + uint16_t nread; + } out; + } read; +}; + + +enum smb_write_level {RAW_WRITE_WRITEUNLOCK, RAW_WRITE_WRITE, + RAW_WRITE_WRITEX, RAW_WRITE_WRITECLOSE, + RAW_WRITE_SPLWRITE}; + +#define RAW_WRITE_GENERIC RAW_WRITE_WRITEX + +/* union for write() backend call +*/ +union smb_write { + /* SMBwriteX interface */ + struct { + enum smb_write_level level; + + struct { + uint16_t fnum; + uint64_t offset; + uint16_t wmode; + uint16_t remaining; + uint32_t count; + const uint8_t *data; + } in; + struct { + uint32_t nwritten; + uint16_t remaining; + } out; + } writex, generic; + + /* SMBwriteunlock interface */ + struct { + enum smb_write_level level; + + struct { + uint16_t fnum; + uint16_t count; + uint32_t offset; + uint16_t remaining; + const uint8_t *data; + } in; + struct { + uint32_t nwritten; + } out; + } writeunlock; + + /* SMBwrite interface */ + struct { + enum smb_write_level level; + + struct { + uint16_t fnum; + uint16_t count; + uint32_t offset; + uint16_t remaining; + const uint8_t *data; + } in; + struct { + uint16_t nwritten; + } out; + } write; + + /* SMBwriteclose interface */ + struct { + enum smb_write_level level; + + struct { + uint16_t fnum; + uint16_t count; + uint32_t offset; + time_t mtime; + const uint8_t *data; + } in; + struct { + uint16_t nwritten; + } out; + } writeclose; + + /* SMBsplwrite interface */ + struct { + enum smb_write_level level; + + struct { + uint16_t fnum; + uint16_t count; + const uint8_t *data; + } in; + } splwrite; +}; + + +enum smb_lock_level {RAW_LOCK_LOCK, RAW_LOCK_UNLOCK, RAW_LOCK_LOCKX}; + +/* the generic interface is defined to be equal to the lockingX interface */ +#define RAW_LOCK_GENERIC RAW_LOCK_LOCKX + +/* union for lock() backend call +*/ +union smb_lock { + /* SMBlockingX (and generic) interface */ + struct { + enum smb_lock_level level; + + struct { + uint16_t fnum; + uint16_t mode; + uint32_t timeout; + uint16_t ulock_cnt; + uint16_t lock_cnt; + struct smb_lock_entry { + uint16_t pid; + uint64_t offset; + uint64_t count; + } *locks; /* unlocks are first in the arrray */ + } in; + } lockx, generic; + + /* SMBlock and SMBunlock interface */ + struct { + enum smb_lock_level level; + + struct { + uint16_t fnum; + uint32_t count; + uint32_t offset; + } in; + } lock, unlock; +}; + + +enum smb_close_level {RAW_CLOSE_CLOSE, RAW_CLOSE_SPLCLOSE}; + +#define RAW_CLOSE_GENERIC RAW_CLOSE_CLOSE + +/* + union for close() backend call +*/ +union smb_close { + /* SMBclose (and generic) interface */ + struct { + enum smb_close_level level; + + struct { + uint16_t fnum; + time_t write_time; + } in; + } close, generic; + + /* SMBsplclose interface - empty! */ + struct { + enum smb_close_level level; + + struct { + uint16_t fnum; + } in; + } splclose; +}; + + +enum smb_lpq_level {RAW_LPQ_GENERIC, RAW_LPQ_RETQ}; + +/* + union for lpq() backend +*/ +union smb_lpq { + /* generic interface */ + struct { + enum smb_lpq_level level; + + } generic; + + + /* SMBsplretq interface */ + struct { + enum smb_lpq_level level; + + struct { + uint16_t maxcount; + uint16_t startidx; + } in; + struct { + uint16_t count; + uint16_t restart_idx; + struct { + time_t time; + uint8_t status; + uint16_t job; + uint32_t size; + char *user; + } *queue; + } out; + } retq; +}; + +enum smb_ioctl_level {RAW_IOCTL_IOCTL, RAW_IOCTL_NTIOCTL}; + +/* + union for ioctl() backend +*/ +union smb_ioctl { + /* generic interface */ + struct { + enum smb_ioctl_level level; + + } generic; + + /* struct for SMBioctl */ + struct { + enum smb_ioctl_level level; + struct { + uint16_t fnum; + uint32_t request; + } in; + struct { + DATA_BLOB blob; + } out; + } ioctl; + + + /* struct for NT ioctl call */ + struct { + enum smb_ioctl_level level; + struct { + uint32_t function; + uint16_t fnum; + BOOL fsctl; + uint8_t filter; + } in; + struct { + DATA_BLOB blob; + } out; + } ntioctl; +}; + +/* struct for SMBflush */ +struct smb_flush { + struct { + uint16_t fnum; + } in; +}; + + +/* struct for SMBcopy */ +struct smb_copy { + struct { + uint16_t tid2; + uint16_t ofun; + uint16_t flags; + const char *path1; + const char *path2; + } in; + struct { + uint16_t count; + } out; +}; + + +/* struct for transact/transact2 call */ +struct smb_trans2 { + struct { + uint16_t max_param; + uint16_t max_data; + uint8_t max_setup; + uint16_t flags; + uint32_t timeout; + uint8_t setup_count; + uint16_t *setup; + const char *trans_name; /* SMBtrans only */ + DATA_BLOB params; + DATA_BLOB data; + } in; + + struct { + uint8_t setup_count; + uint16_t *setup; + DATA_BLOB params; + DATA_BLOB data; + } out; +}; + +/* struct for nttransact2 call */ +struct smb_nttrans { + struct { + uint8_t max_setup; + uint32_t max_param; + uint32_t max_data; + uint32_t setup_count; + uint16_t function; + uint16_t *setup; + DATA_BLOB params; + DATA_BLOB data; + } in; + + struct { + uint8_t setup_count; + uint16_t *setup; + DATA_BLOB params; + DATA_BLOB data; + } out; +}; + + +/* struct for nttrans change notify call */ +struct smb_notify { + struct { + uint32_t buffer_size; + uint32_t completion_filter; + uint16_t fnum; + BOOL recursive; + } in; + + struct { + uint32_t num_changes; + struct notify_changes { + uint32_t action; + WIRE_STRING name; + } *changes; + } out; +}; + + +enum smb_search_level {RAW_SEARCH_GENERIC = 0xF000, + RAW_SEARCH_SEARCH, /* SMBsearch */ + RAW_SEARCH_FFIRST, /* SMBffirst */ + RAW_SEARCH_FUNIQUE, /* SMBfunique */ + RAW_SEARCH_STANDARD = SMB_FIND_STANDARD, + RAW_SEARCH_EA_SIZE = SMB_FIND_EA_SIZE, + RAW_SEARCH_EA_LIST = SMB_FIND_EA_LIST, + RAW_SEARCH_DIRECTORY_INFO = SMB_FIND_DIRECTORY_INFO, + RAW_SEARCH_FULL_DIRECTORY_INFO = SMB_FIND_FULL_DIRECTORY_INFO, + RAW_SEARCH_NAME_INFO = SMB_FIND_NAME_INFO, + RAW_SEARCH_BOTH_DIRECTORY_INFO = SMB_FIND_BOTH_DIRECTORY_INFO, + RAW_SEARCH_ID_FULL_DIRECTORY_INFO = SMB_FIND_ID_FULL_DIRECTORY_INFO, + RAW_SEARCH_ID_BOTH_DIRECTORY_INFO = SMB_FIND_ID_BOTH_DIRECTORY_INFO, + RAW_SEARCH_UNIX_INFO = SMB_FIND_UNIX_INFO}; + + +/* union for file search */ +union smb_search_first { + struct { + enum smb_search_level level; + } generic; + + /* search (old) findfirst interface. + Also used for ffirst and funique. */ + struct { + enum smb_search_level level; + + struct { + uint16_t max_count; + uint16_t search_attrib; + const char *pattern; + } in; + struct { + int16_t count; + } out; + } search_first; + + /* trans2 findfirst interface */ + struct { + enum smb_search_level level; + + struct { + uint16_t search_attrib; + uint16_t max_count; + uint16_t flags; + uint32_t storage_type; + const char *pattern; + + /* the ea names are only used for RAW_SEARCH_EA_LIST */ + uint_t num_names; + struct ea_name *ea_names; + } in; + struct { + uint16_t handle; + uint16_t count; + uint16_t end_of_search; + } out; + } t2ffirst; +}; + +/* union for file search continue */ +union smb_search_next { + struct { + enum smb_search_level level; + } generic; + + /* search (old) findnext interface. Also used + for ffirst when continuing */ + struct { + enum smb_search_level level; + + struct { + uint16_t max_count; + uint16_t search_attrib; + struct smb_search_id { + uint8_t reserved; + char name[11]; + uint8_t handle; + uint32_t server_cookie; + uint32_t client_cookie; + } id; + } in; + struct { + uint16_t count; + } out; + } search_next; + + /* trans2 findnext interface */ + struct { + enum smb_search_level level; + + struct { + uint16_t handle; + uint16_t max_count; + uint32_t resume_key; + uint16_t flags; + const char *last_name; + + /* the ea names are only used for RAW_SEARCH_EA_LIST */ + uint_t num_names; + struct ea_name *ea_names; + } in; + struct { + uint16_t count; + uint16_t end_of_search; + } out; + } t2fnext; +}; + +/* union for search reply file data */ +union smb_search_data { + /* search (old) findfirst */ + struct { + uint16_t attrib; + time_t write_time; + uint32_t size; + struct smb_search_id id; + const char *name; + } search; + + /* trans2 findfirst RAW_SEARCH_STANDARD level */ + struct { + uint32_t resume_key; + time_t create_time; + time_t access_time; + time_t write_time; + uint32_t size; + uint32_t alloc_size; + uint16_t attrib; + WIRE_STRING name; + } standard; + + /* trans2 findfirst RAW_SEARCH_EA_SIZE level */ + struct { + uint32_t resume_key; + time_t create_time; + time_t access_time; + time_t write_time; + uint32_t size; + uint32_t alloc_size; + uint16_t attrib; + uint32_t ea_size; + WIRE_STRING name; + } ea_size; + + /* trans2 findfirst RAW_SEARCH_EA_LIST level */ + struct { + uint32_t resume_key; + time_t create_time; + time_t access_time; + time_t write_time; + uint32_t size; + uint32_t alloc_size; + uint16_t attrib; + struct smb_ea_list eas; + WIRE_STRING name; + } ea_list; + + /* RAW_SEARCH_DIRECTORY_INFO interface */ + struct { + uint32_t file_index; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t size; + uint64_t alloc_size; + uint32_t attrib; + WIRE_STRING name; + } directory_info; + + /* RAW_SEARCH_FULL_DIRECTORY_INFO interface */ + struct { + uint32_t file_index; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t size; + uint64_t alloc_size; + uint32_t attrib; + uint32_t ea_size; + WIRE_STRING name; + } full_directory_info; + + /* RAW_SEARCH_NAME_INFO interface */ + struct { + uint32_t file_index; + WIRE_STRING name; + } name_info; + + /* RAW_SEARCH_BOTH_DIRECTORY_INFO interface */ + struct { + uint32_t file_index; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t size; + uint64_t alloc_size; + uint32_t attrib; + uint32_t ea_size; + WIRE_STRING short_name; + WIRE_STRING name; + } both_directory_info; + + /* RAW_SEARCH_ID_FULL_DIRECTORY_INFO interface */ + struct { + uint32_t file_index; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t size; + uint64_t alloc_size; + uint32_t attrib; + uint32_t ea_size; + uint64_t file_id; + WIRE_STRING name; + } id_full_directory_info; + + /* RAW_SEARCH_ID_BOTH_DIRECTORY_INFO interface */ + struct { + uint32_t file_index; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t size; + uint64_t alloc_size; + uint32_t attrib; + uint32_t ea_size; + uint64_t file_id; + WIRE_STRING short_name; + WIRE_STRING name; + } id_both_directory_info; + + /* RAW_SEARCH_UNIX_INFO interface */ + struct { + uint32_t file_index; + uint64_t size; + uint64_t alloc_size; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + const char *name; + } unix_info; +}; + + +enum smb_search_close_level {RAW_FINDCLOSE_GENERIC, RAW_FINDCLOSE_FCLOSE, RAW_FINDCLOSE_FINDCLOSE}; + +/* union for file search close */ +union smb_search_close { + struct { + enum smb_search_close_level level; + } generic; + + /* SMBfclose (old search) interface */ + struct { + enum smb_search_close_level level; + + struct { + /* max_count and search_attrib are not used, but are present */ + uint16_t max_count; + uint16_t search_attrib; + struct smb_search_id id; + } in; + } fclose; + + /* SMBfindclose interface */ + struct { + enum smb_search_close_level level; + + struct { + uint16_t handle; + } in; + } findclose; +}; + -- cgit From dfc517b05395d925a4d7b1ce9633a849f9468e70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 15:52:24 +0000 Subject: r13658: More moving around of files: - Collect the generic utility functions into a lib/util/ (a la GLib is for the GNOME folks) - Remove even more files from include/ (This used to be commit ba62880f5b05c2a505dc7f54676b231197a7e707) --- source4/libcli/clifile.c | 1 + source4/libcli/raw/interfaces.h | 2 - source4/libcli/raw/ioctl.h | 33 +++ source4/libcli/raw/signing.h | 4 + source4/libcli/raw/trans2.h | 435 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 473 insertions(+), 2 deletions(-) create mode 100644 source4/libcli/raw/ioctl.h create mode 100644 source4/libcli/raw/trans2.h (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 0b9cac4c07..e8cb548007 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -23,6 +23,7 @@ #include "includes.h" #include "system/filesys.h" #include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" /**************************************************************************** Hard/Symlink a file (UNIX extensions). diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 49fe085f2c..034878a464 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - /* this structure is just a wrapper for a string, the only reason we bother with this is that it allows us to check the length provided on the wire in testsuite test code to ensure that we are diff --git a/source4/libcli/raw/ioctl.h b/source4/libcli/raw/ioctl.h new file mode 100644 index 0000000000..cd658c121b --- /dev/null +++ b/source4/libcli/raw/ioctl.h @@ -0,0 +1,33 @@ +/* + Unix SMB/CIFS implementation. + ioctl and fsctl definitions + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + + +/* ioctl codes */ +#define IOCTL_QUERY_JOB_INFO 0x530060 + + +/* filesystem control codes */ +#define FSCTL_FILESYSTEM 0x90000 +#define FSCTL_SET_SPARSE (FSCTL_FILESYSTEM | (49<<2)) +#define FSCTL_REQUEST_BATCH_OPLOCK (FSCTL_FILESYSTEM | (2<<2)) + +#define FSCTL_NAMED_PIPE 0x110000 +#define FSCTL_NAMED_PIPE_READ_WRITE (FSCTL_NAMED_PIPE | 0xc017) diff --git a/source4/libcli/raw/signing.h b/source4/libcli/raw/signing.h index dfc5a4bd7e..cea8556c2c 100644 --- a/source4/libcli/raw/signing.h +++ b/source4/libcli/raw/signing.h @@ -27,6 +27,10 @@ enum smb_signing_engine_state { SMB_SIGNING_ENGINE_ON }; +enum smb_signing_state { + SMB_SIGNING_OFF, SMB_SIGNING_SUPPORTED, + SMB_SIGNING_REQUIRED, SMB_SIGNING_AUTO}; + struct smb_signing_context { enum smb_signing_engine_state signing_state; DATA_BLOB mac_key; diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h new file mode 100644 index 0000000000..a3f6e28a2a --- /dev/null +++ b/source4/libcli/raw/trans2.h @@ -0,0 +1,435 @@ +/* + Unix SMB/CIFS implementation. + SMB transaction2 handling + Copyright (C) Jeremy Allison 1994-2002. + Copyright (C) Andrew Tridgell 1995-2003. + + 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. +*/ + +#ifndef _TRANS2_H_ +#define _TRANS2_H_ + +/* These are the TRANS2 sub commands */ +#define TRANSACT2_OPEN 0 +#define TRANSACT2_FINDFIRST 1 +#define TRANSACT2_FINDNEXT 2 +#define TRANSACT2_QFSINFO 3 +#define TRANSACT2_SETFSINFO 4 +#define TRANSACT2_QPATHINFO 5 +#define TRANSACT2_SETPATHINFO 6 +#define TRANSACT2_QFILEINFO 7 +#define TRANSACT2_SETFILEINFO 8 +#define TRANSACT2_FSCTL 9 +#define TRANSACT2_IOCTL 0xA +#define TRANSACT2_FINDNOTIFYFIRST 0xB +#define TRANSACT2_FINDNOTIFYNEXT 0xC +#define TRANSACT2_MKDIR 0xD +#define TRANSACT2_SESSION_SETUP 0xE +#define TRANSACT2_GET_DFS_REFERRAL 0x10 +#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 + + +/* trans2 Query FS info levels */ +/* +w2k3 TRANS2ALIASES: +Checking for QFSINFO aliases + Found level 1 (0x001) of size 18 (0x12) + Found level 2 (0x002) of size 12 (0x0c) + Found level 258 (0x102) of size 26 (0x1a) + Found level 259 (0x103) of size 24 (0x18) + Found level 260 (0x104) of size 8 (0x08) + Found level 261 (0x105) of size 20 (0x14) + Found level 1001 (0x3e9) of size 26 (0x1a) + Found level 1003 (0x3eb) of size 24 (0x18) + Found level 1004 (0x3ec) of size 8 (0x08) + Found level 1005 (0x3ed) of size 20 (0x14) + Found level 1006 (0x3ee) of size 48 (0x30) + Found level 1007 (0x3ef) of size 32 (0x20) + Found level 1008 (0x3f0) of size 64 (0x40) +Found 13 levels with success status + Level 261 (0x105) and level 1005 (0x3ed) are possible aliases + Level 260 (0x104) and level 1004 (0x3ec) are possible aliases + Level 259 (0x103) and level 1003 (0x3eb) are possible aliases + Level 258 (0x102) and level 1001 (0x3e9) are possible aliases +Found 4 aliased levels +*/ +#define SMB_QFS_ALLOCATION 1 +#define SMB_QFS_VOLUME 2 +#define SMB_QFS_VOLUME_INFO 0x102 +#define SMB_QFS_SIZE_INFO 0x103 +#define SMB_QFS_DEVICE_INFO 0x104 +#define SMB_QFS_ATTRIBUTE_INFO 0x105 +#define SMB_QFS_UNIX_INFO 0x200 +#define SMB_QFS_POSIX_INFO 0x201 +#define SMB_QFS_VOLUME_INFORMATION 1001 +#define SMB_QFS_SIZE_INFORMATION 1003 +#define SMB_QFS_DEVICE_INFORMATION 1004 +#define SMB_QFS_ATTRIBUTE_INFORMATION 1005 +#define SMB_QFS_QUOTA_INFORMATION 1006 +#define SMB_QFS_FULL_SIZE_INFORMATION 1007 +#define SMB_QFS_OBJECTID_INFORMATION 1008 + + +/* trans2 qfileinfo/qpathinfo */ +/* w2k3 TRANS2ALIASES: +Checking for QPATHINFO aliases +setting up complex file \qpathinfo_aliases.txt + Found level 1 (0x001) of size 22 (0x16) + Found level 2 (0x002) of size 26 (0x1a) + Found level 4 (0x004) of size 41 (0x29) + Found level 6 (0x006) of size 0 (0x00) + Found level 257 (0x101) of size 40 (0x28) + Found level 258 (0x102) of size 24 (0x18) + Found level 259 (0x103) of size 4 (0x04) + Found level 260 (0x104) of size 48 (0x30) + Found level 263 (0x107) of size 126 (0x7e) + Found level 264 (0x108) of size 28 (0x1c) + Found level 265 (0x109) of size 38 (0x26) + Found level 267 (0x10b) of size 16 (0x10) + Found level 1004 (0x3ec) of size 40 (0x28) + Found level 1005 (0x3ed) of size 24 (0x18) + Found level 1006 (0x3ee) of size 8 (0x08) + Found level 1007 (0x3ef) of size 4 (0x04) + Found level 1008 (0x3f0) of size 4 (0x04) + Found level 1009 (0x3f1) of size 48 (0x30) + Found level 1014 (0x3f6) of size 8 (0x08) + Found level 1016 (0x3f8) of size 4 (0x04) + Found level 1017 (0x3f9) of size 4 (0x04) + Found level 1018 (0x3fa) of size 126 (0x7e) + Found level 1021 (0x3fd) of size 28 (0x1c) + Found level 1022 (0x3fe) of size 38 (0x26) + Found level 1028 (0x404) of size 16 (0x10) + Found level 1034 (0x40a) of size 56 (0x38) + Found level 1035 (0x40b) of size 8 (0x08) +Found 27 levels with success status + Level 267 (0x10b) and level 1028 (0x404) are possible aliases + Level 265 (0x109) and level 1022 (0x3fe) are possible aliases + Level 264 (0x108) and level 1021 (0x3fd) are possible aliases + Level 263 (0x107) and level 1018 (0x3fa) are possible aliases + Level 260 (0x104) and level 1009 (0x3f1) are possible aliases + Level 259 (0x103) and level 1007 (0x3ef) are possible aliases + Level 258 (0x102) and level 1005 (0x3ed) are possible aliases + Level 257 (0x101) and level 1004 (0x3ec) are possible aliases +Found 8 aliased levels +*/ +#define SMB_QFILEINFO_STANDARD 1 +#define SMB_QFILEINFO_EA_SIZE 2 +#define SMB_QFILEINFO_EA_LIST 3 +#define SMB_QFILEINFO_ALL_EAS 4 +#define SMB_QFILEINFO_IS_NAME_VALID 6 /* only for QPATHINFO */ +#define SMB_QFILEINFO_BASIC_INFO 0x101 +#define SMB_QFILEINFO_STANDARD_INFO 0x102 +#define SMB_QFILEINFO_EA_INFO 0x103 +#define SMB_QFILEINFO_NAME_INFO 0x104 +#define SMB_QFILEINFO_ALL_INFO 0x107 +#define SMB_QFILEINFO_ALT_NAME_INFO 0x108 +#define SMB_QFILEINFO_STREAM_INFO 0x109 +#define SMB_QFILEINFO_COMPRESSION_INFO 0x10b +#define SMB_QFILEINFO_UNIX_BASIC 0x200 +#define SMB_QFILEINFO_UNIX_LINK 0x201 +#define SMB_QFILEINFO_BASIC_INFORMATION 1004 +#define SMB_QFILEINFO_STANDARD_INFORMATION 1005 +#define SMB_QFILEINFO_INTERNAL_INFORMATION 1006 +#define SMB_QFILEINFO_EA_INFORMATION 1007 +#define SMB_QFILEINFO_ACCESS_INFORMATION 1008 +#define SMB_QFILEINFO_NAME_INFORMATION 1009 +#define SMB_QFILEINFO_POSITION_INFORMATION 1014 +#define SMB_QFILEINFO_MODE_INFORMATION 1016 +#define SMB_QFILEINFO_ALIGNMENT_INFORMATION 1017 +#define SMB_QFILEINFO_ALL_INFORMATION 1018 +#define SMB_QFILEINFO_ALT_NAME_INFORMATION 1021 +#define SMB_QFILEINFO_STREAM_INFORMATION 1022 +#define SMB_QFILEINFO_COMPRESSION_INFORMATION 1028 +#define SMB_QFILEINFO_NETWORK_OPEN_INFORMATION 1034 +#define SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION 1035 + + + +/* trans2 setfileinfo/setpathinfo levels */ +/* +w2k3 TRANS2ALIASES +Checking for SETFILEINFO aliases +setting up complex file \setfileinfo_aliases.txt + Found level 1 (0x001) of size 2 (0x02) + Found level 2 (0x002) of size 2 (0x02) + Found level 257 (0x101) of size 40 (0x28) + Found level 258 (0x102) of size 2 (0x02) + Found level 259 (0x103) of size 8 (0x08) + Found level 260 (0x104) of size 8 (0x08) + Found level 1004 (0x3ec) of size 40 (0x28) + Found level 1010 (0x3f2) of size 2 (0x02) + Found level 1013 (0x3f5) of size 2 (0x02) + Found level 1014 (0x3f6) of size 8 (0x08) + Found level 1016 (0x3f8) of size 4 (0x04) + Found level 1019 (0x3fb) of size 8 (0x08) + Found level 1020 (0x3fc) of size 8 (0x08) + Found level 1023 (0x3ff) of size 8 (0x08) + Found level 1025 (0x401) of size 16 (0x10) + Found level 1029 (0x405) of size 72 (0x48) + Found level 1032 (0x408) of size 56 (0x38) + Found level 1039 (0x40f) of size 8 (0x08) + Found level 1040 (0x410) of size 8 (0x08) +Found 19 valid levels + +Checking for SETPATHINFO aliases + Found level 1004 (0x3ec) of size 40 (0x28) + Found level 1010 (0x3f2) of size 2 (0x02) + Found level 1013 (0x3f5) of size 2 (0x02) + Found level 1014 (0x3f6) of size 8 (0x08) + Found level 1016 (0x3f8) of size 4 (0x04) + Found level 1019 (0x3fb) of size 8 (0x08) + Found level 1020 (0x3fc) of size 8 (0x08) + Found level 1023 (0x3ff) of size 8 (0x08) + Found level 1025 (0x401) of size 16 (0x10) + Found level 1029 (0x405) of size 72 (0x48) + Found level 1032 (0x408) of size 56 (0x38) + Found level 1039 (0x40f) of size 8 (0x08) + Found level 1040 (0x410) of size 8 (0x08) +Found 13 valid levels +*/ +#define SMB_SFILEINFO_STANDARD 1 +#define SMB_SFILEINFO_EA_SET 2 +#define SMB_SFILEINFO_BASIC_INFO 0x101 +#define SMB_SFILEINFO_DISPOSITION_INFO 0x102 +#define SMB_SFILEINFO_ALLOCATION_INFO 0x103 +#define SMB_SFILEINFO_END_OF_FILE_INFO 0x104 +#define SMB_SFILEINFO_UNIX_BASIC 0x200 +#define SMB_SFILEINFO_UNIX_LINK 0x201 +#define SMB_SPATHINFO_UNIX_HLINK 0x203 +#define SMB_SPATHINFO_POSIX_ACL 0x204 +#define SMB_SPATHINFO_XATTR 0x205 +#define SMB_SFILEINFO_ATTR_FLAGS 0x206 +#define SMB_SFILEINFO_BASIC_INFORMATION 1004 +#define SMB_SFILEINFO_RENAME_INFORMATION 1010 +#define SMB_SFILEINFO_DISPOSITION_INFORMATION 1013 +#define SMB_SFILEINFO_POSITION_INFORMATION 1014 +#define SMB_SFILEINFO_MODE_INFORMATION 1016 +#define SMB_SFILEINFO_ALLOCATION_INFORMATION 1019 +#define SMB_SFILEINFO_END_OF_FILE_INFORMATION 1020 + +/* filemon shows FilePipeInformation */ +#define SMB_SFILEINFO_1023 1023 + +/* filemon shows FilePipeRemoteInformation */ +#define SMB_SFILEINFO_1025 1025 + +/* filemon shows CopyOnWriteInformation */ +#define SMB_SFILEINFO_1029 1029 + +/* filemon shows OleClassIdInformation */ +#define SMB_SFILEINFO_1032 1032 + +/* seems to be the file size - perhaps valid data size? + filemon shows 'InheritContentIndexInfo' +*/ +#define SMB_SFILEINFO_1039 1039 + +/* OLE_INFORMATION? */ +#define SMB_SFILEINFO_1040 1040 + + +/* trans2 findfirst levels */ +/* +w2k3 TRANS2ALIASES: +Checking for FINDFIRST aliases + Found level 1 (0x001) of size 68 (0x44) + Found level 2 (0x002) of size 70 (0x46) + Found level 257 (0x101) of size 108 (0x6c) + Found level 258 (0x102) of size 116 (0x74) + Found level 259 (0x103) of size 60 (0x3c) + Found level 260 (0x104) of size 140 (0x8c) + Found level 261 (0x105) of size 124 (0x7c) + Found level 262 (0x106) of size 148 (0x94) +Found 8 levels with success status +Found 0 aliased levels +*/ +#define SMB_FIND_STANDARD 1 +#define SMB_FIND_EA_SIZE 2 +#define SMB_FIND_EA_LIST 3 +#define SMB_FIND_DIRECTORY_INFO 0x101 +#define SMB_FIND_FULL_DIRECTORY_INFO 0x102 +#define SMB_FIND_NAME_INFO 0x103 +#define SMB_FIND_BOTH_DIRECTORY_INFO 0x104 +#define SMB_FIND_ID_FULL_DIRECTORY_INFO 0x105 +#define SMB_FIND_ID_BOTH_DIRECTORY_INFO 0x106 +#define SMB_FIND_UNIX_INFO 0x202 + +/* flags on trans2 findfirst/findnext that control search */ +#define FLAG_TRANS2_FIND_CLOSE 0x1 +#define FLAG_TRANS2_FIND_CLOSE_IF_END 0x2 +#define FLAG_TRANS2_FIND_REQUIRE_RESUME 0x4 +#define FLAG_TRANS2_FIND_CONTINUE 0x8 +#define FLAG_TRANS2_FIND_BACKUP_INTENT 0x10 + +/* + * DeviceType and Characteristics returned in a + * SMB_QFS_DEVICE_INFO call. + */ +#define QFS_DEVICETYPE_CD_ROM 0x2 +#define QFS_DEVICETYPE_CD_ROM_FILE_SYSTEM 0x3 +#define QFS_DEVICETYPE_DISK 0x7 +#define QFS_DEVICETYPE_DISK_FILE_SYSTEM 0x8 +#define QFS_DEVICETYPE_FILE_SYSTEM 0x9 + +/* Characteristics. */ +#define QFS_TYPE_REMOVABLE_MEDIA 0x1 +#define QFS_TYPE_READ_ONLY_DEVICE 0x2 +#define QFS_TYPE_FLOPPY 0x4 +#define QFS_TYPE_WORM 0x8 +#define QFS_TYPE_REMOTE 0x10 +#define QFS_TYPE_MOUNTED 0x20 +#define QFS_TYPE_VIRTUAL 0x40 + + +/* + * Thursby MAC extensions.... + */ + +/* + * MAC CIFS Extensions have the range 0x300 - 0x2FF reserved. + * Supposedly Microsoft have agreed to this. + */ + +#define MIN_MAC_INFO_LEVEL 0x300 +#define MAX_MAC_INFO_LEVEL 0x3FF +#define SMB_QFS_MAC_FS_INFO 0x301 + + + +/* UNIX CIFS Extensions - created by HP */ +/* + * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved. + * Supposedly Microsoft have agreed to this. + */ + +#define MIN_UNIX_INFO_LEVEL 0x200 +#define MAX_UNIX_INFO_LEVEL 0x2FF + +#define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL)) + +#define SMB_QFILEINFO_UNIX_BASIC 0x200 /* UNIX File Info*/ +#define SMB_SFILEINFO_UNIX_BASIC 0x200 + +#define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */ + /* means "don't change it" */ +#define SMB_UID_NO_CHANGE 0xFFFFFFFF +#define SMB_GID_NO_CHANGE 0xFFFFFFFF + +#define SMB_SIZE_NO_CHANGE_LO 0xFFFFFFFF +#define SMB_SIZE_NO_CHANGE_HI 0xFFFFFFFF + +#define SMB_TIME_NO_CHANGE_LO 0xFFFFFFFF +#define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF + +/* +Offset Size Name +0 LARGE_INTEGER EndOfFile File size +8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks). +16 LARGE_INTEGER CreationTime Creation time +24 LARGE_INTEGER LastAccessTime Last access time +32 LARGE_INTEGER LastModificationTime Last modification time +40 LARGE_INTEGER Uid Numeric user id for the owner +48 LARGE_INTEGER Gid Numeric group id of owner +56 ULONG Type Enumeration specifying the pathname type: + 0 -- File + 1 -- Directory + 2 -- Symbolic link + 3 -- Character device + 4 -- Block device + 5 -- FIFO (named pipe) + 6 -- Unix domain socket + +60 LARGE_INTEGER devmajor Major device number if type is device +68 LARGE_INTEGER devminor Minor device number if type is device +76 LARGE_INTEGER uniqueid This is a server-assigned unique id for the file. The client + will typically map this onto an inode number. The scope of + uniqueness is the share. +84 LARGE_INTEGER permissions Standard UNIX file permissions - see below. +92 LARGE_INTEGER nlinks The number of directory entries that map to this entry + (number of hard links) + +100 - end. +*/ + +/* UNIX filetype mappings. */ + +#define UNIX_TYPE_FILE 0 +#define UNIX_TYPE_DIR 1 +#define UNIX_TYPE_SYMLINK 2 +#define UNIX_TYPE_CHARDEV 3 +#define UNIX_TYPE_BLKDEV 4 +#define UNIX_TYPE_FIFO 5 +#define UNIX_TYPE_SOCKET 6 +#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF + +/* + * Oh this is fun. "Standard UNIX permissions" has no + * meaning in POSIX. We need to define the mapping onto + * and off the wire as this was not done in the original HP + * spec. JRA. + */ + +#define UNIX_X_OTH 0000001 +#define UNIX_W_OTH 0000002 +#define UNIX_R_OTH 0000004 +#define UNIX_X_GRP 0000010 +#define UNIX_W_GRP 0000020 +#define UNIX_R_GRP 0000040 +#define UNIX_X_USR 0000100 +#define UNIX_W_USR 0000200 +#define UNIX_R_USR 0000400 +#define UNIX_STICKY 0001000 +#define UNIX_SET_GID 0002000 +#define UNIX_SET_UID 0004000 + +/* Masks for the above */ +#define UNIX_OTH_MASK 0000007 +#define UNIX_GRP_MASK 0000070 +#define UNIX_USR_MASK 0000700 +#define UNIX_PERM_MASK 0000777 +#define UNIX_EXTRA_MASK 0007000 +#define UNIX_ALL_MASK 0007777 + +#define SMB_QFILEINFO_UNIX_LINK 0x201 +#define SMB_SFILEINFO_UNIX_LINK 0x201 +#define SMB_SFILEINFO_UNIX_HLINK 0x203 + +#define SMB_FIND_FILE_UNIX 0x202 + +/* + Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus + 64-bits worth of capability fun :-). +*/ + +#define SMB_QUERY_CIFS_UNIX_INFO 0x200 + +/* Returns the following. + + UINT16 major version number + UINT16 minor version number + LARGE_INTEGER capability bitfield + +*/ + +#define CIFS_UNIX_MAJOR_VERSION 1 +#define CIFS_UNIX_MINOR_VERSION 0 + +#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1 +#define CIFS_UNIX_POSIX_ACLS_CAP 0x2 + +/* ... more as we think of them :-). */ + +#endif -- cgit From af30a32b6924b0f2b701186e435defbca2ebd1aa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Mar 2006 17:15:19 +0000 Subject: r13840: Mark some functions as public. (This used to be commit 9a188eb1f48a50d92a67a4fc2b3899b90074059a) --- source4/libcli/composite/composite.c | 20 +++++++-------- source4/libcli/nbt/nbtname.c | 50 ++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 33b5b77c06..d0d2bc3886 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -30,7 +30,7 @@ /* block until a composite function has completed, then return the status */ -NTSTATUS composite_wait(struct composite_context *c) +_PUBLIC_ NTSTATUS composite_wait(struct composite_context *c) { if (c == NULL) return NT_STATUS_NO_MEMORY; @@ -50,7 +50,7 @@ NTSTATUS composite_wait(struct composite_context *c) * Some composite helpers that are handy if you write larger composite * functions. */ -BOOL composite_is_ok(struct composite_context *ctx) +_PUBLIC_ BOOL composite_is_ok(struct composite_context *ctx) { if (NT_STATUS_IS_OK(ctx->status)) { return True; @@ -85,7 +85,7 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te, } -void composite_error(struct composite_context *ctx, NTSTATUS status) +_PUBLIC_ void composite_error(struct composite_context *ctx, NTSTATUS status) { if (!ctx->used_wait && !ctx->async.fn) { event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); @@ -94,7 +94,7 @@ void composite_error(struct composite_context *ctx, NTSTATUS status) SMB_ASSERT(!composite_is_ok(ctx)); } -BOOL composite_nomem(const void *p, struct composite_context *ctx) +_PUBLIC_ BOOL composite_nomem(const void *p, struct composite_context *ctx) { if (p != NULL) { return False; @@ -103,7 +103,7 @@ BOOL composite_nomem(const void *p, struct composite_context *ctx) return True; } -void composite_done(struct composite_context *ctx) +_PUBLIC_ void composite_done(struct composite_context *ctx) { if (!ctx->used_wait && !ctx->async.fn) { event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); @@ -114,7 +114,7 @@ void composite_done(struct composite_context *ctx) } } -void composite_continue(struct composite_context *ctx, +_PUBLIC_ void composite_continue(struct composite_context *ctx, struct composite_context *new_ctx, void (*continuation)(struct composite_context *), void *private_data) @@ -124,7 +124,7 @@ void composite_continue(struct composite_context *ctx, new_ctx->async.private_data = private_data; } -void composite_continue_rpc(struct composite_context *ctx, +_PUBLIC_ void composite_continue_rpc(struct composite_context *ctx, struct rpc_request *new_req, void (*continuation)(struct rpc_request *), void *private_data) @@ -134,7 +134,7 @@ void composite_continue_rpc(struct composite_context *ctx, new_req->async.private = private_data; } -void composite_continue_irpc(struct composite_context *ctx, +_PUBLIC_ void composite_continue_irpc(struct composite_context *ctx, struct irpc_request *new_req, void (*continuation)(struct irpc_request *), void *private_data) @@ -144,7 +144,7 @@ void composite_continue_irpc(struct composite_context *ctx, new_req->async.private = private_data; } -void composite_continue_smb(struct composite_context *ctx, +_PUBLIC_ void composite_continue_smb(struct composite_context *ctx, struct smbcli_request *new_req, void (*continuation)(struct smbcli_request *), void *private_data) @@ -154,7 +154,7 @@ void composite_continue_smb(struct composite_context *ctx, new_req->async.private = private_data; } -void composite_continue_nbt(struct composite_context *ctx, +_PUBLIC_ void composite_continue_nbt(struct composite_context *ctx, struct nbt_name_request *new_req, void (*continuation)(struct nbt_name_request *), void *private_data) diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index c6fc18f55a..25fd669789 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -32,10 +32,10 @@ /* don't allow an unlimited number of name components */ #define MAX_COMPONENTS 10 -/* +/** print a nbt string */ -void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) +_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) { ndr_print_string(ndr, name, s); } @@ -88,10 +88,10 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, return NT_STATUS_BAD_NETWORK_NAME; } -/* +/** pull a nbt_string from the wire */ -NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) +_PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) { NTSTATUS status; uint32_t offset = ndr->offset; @@ -132,10 +132,10 @@ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s return NT_STATUS_OK; } -/* +/** push a nbt string to the wire */ -NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) +_PUBLIC_ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) { if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; @@ -274,10 +274,10 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, } -/* +/** pull a nbt name from the wire */ -NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) +_PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) { NTSTATUS status; uint8_t *scope; @@ -320,10 +320,10 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name return NT_STATUS_OK; } -/* +/** push a nbt name to the wire */ -NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) +_PUBLIC_ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) { uint8_t *cname, *fullname; NTSTATUS status; @@ -349,10 +349,10 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt } -/* +/** copy a nbt name structure */ -NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname) +_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname) { *newname = *name; newname->name = talloc_strdup(mem_ctx, newname->name); @@ -364,33 +364,33 @@ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_nam return NT_STATUS_OK; } -/* +/** push a nbt name into a blob */ -NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name) +_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name) { return ndr_push_struct_blob(blob, mem_ctx, name, (ndr_push_flags_fn_t)ndr_push_nbt_name); } -/* +/** pull a nbt name from a blob */ -NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) +_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) { return ndr_pull_struct_blob(blob, mem_ctx, name, (ndr_pull_flags_fn_t)ndr_pull_nbt_name); } -/* +/** choose a name to use when calling a server in a NBT session request. we use heuristics to see if the name we have been given is a IP address, or a too-long name. If it is then use *SMBSERVER, or a truncated name */ -void nbt_choose_called_name(TALLOC_CTX *mem_ctx, +_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type) { n->scope = NULL; @@ -450,10 +450,10 @@ static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) } -/* +/** form a string for a NBT name */ -char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) +_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) { TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); char *ret; @@ -471,10 +471,10 @@ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) return ret; } -/* +/** pull a nbt name, WINS Replication uses another on wire format for nbt name */ -NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name **_r) +_PUBLIC_ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name **_r) { struct nbt_name *r; uint8_t *namebuf; @@ -532,10 +532,10 @@ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt return NT_STATUS_OK; } -/* +/** push a nbt name, WINS Replication uses another on wire format for nbt name */ -NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) +_PUBLIC_ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) { uint8_t *namebuf; uint32_t namebuf_len; @@ -587,7 +587,7 @@ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const stru return NT_STATUS_OK; } -void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r) +_PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r) { char *s = nbt_name_string(ndr, r); ndr_print_string(ndr, name, s); -- cgit From c71c86c52458eefae8a34774ec186c2837f473af Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Mar 2006 17:44:16 +0000 Subject: r13842: Make some more functions public. (This used to be commit aac1b99b362993352d80692afa55c38fc851c016) --- source4/libcli/nbt/namequery.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 6566e48a5a..cb3c9e158c 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -23,10 +23,11 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" -/* + +/** send a nbt name query */ -struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, struct nbt_name_query *io) { struct nbt_name_request *req; @@ -67,10 +68,10 @@ failed: return NULL; } -/* +/** wait for a name query reply */ -NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, +_PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_query *io) { NTSTATUS status; @@ -122,10 +123,10 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, return NT_STATUS_OK; } -/* +/** wait for a name query reply */ -NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_query *io) { struct nbt_name_request *req = nbt_name_query_send(nbtsock, io); @@ -133,10 +134,10 @@ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, } -/* +/** send a nbt name status */ -struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, struct nbt_name_status *io) { struct nbt_name_request *req; @@ -171,10 +172,10 @@ failed: return NULL; } -/* +/** wait for a name status reply */ -NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, +_PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_status *io) { NTSTATUS status; @@ -220,10 +221,10 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, return NT_STATUS_OK; } -/* +/** wait for a name status reply */ -NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_status *io) { struct nbt_name_request *req = nbt_name_status_send(nbtsock, io); -- cgit From 77ffddec1911ac5de3a96a36c9476dce6e67f4f4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 5 Mar 2006 23:06:37 +0000 Subject: r13850: Test (and fix) not using SPNEGO at all, but instead using raw NTLMSSP. The switch to turn off SPNEGO in the client is a bit messy, but it works. Andrew Bartlett (This used to be commit 085ba80cc8a954bd84ecf30e5d57a1583f54062f) --- source4/libcli/smb_composite/sesssetup.c | 38 +++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 2edeb76503..bbe6a7edfb 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -317,27 +317,39 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, if (session->transport->negotiate.secblob.length) { chosen_oid = GENSEC_OID_SPNEGO; + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + chosen_oid = GENSEC_OID_NTLMSSP; + status = gensec_start_mech_by_oid(session->gensec, chosen_oid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set (fallback) GENSEC client mechanism %s: %s\n", + gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + return status; + } + } } else { /* without a sec blob, means raw NTLMSSP */ chosen_oid = GENSEC_OID_NTLMSSP; - } - - status = gensec_start_mech_by_oid(session->gensec, chosen_oid); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - chosen_oid = GENSEC_OID_NTLMSSP; status = gensec_start_mech_by_oid(session->gensec, chosen_oid); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set (fallback) GENSEC client mechanism %s: %s\n", + DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); - return status; } } - - status = gensec_update(session->gensec, state, - session->transport->negotiate.secblob, - &state->setup.spnego.in.secblob); + + if (chosen_oid == GENSEC_OID_SPNEGO) { + status = gensec_update(session->gensec, state, + session->transport->negotiate.secblob, + &state->setup.spnego.in.secblob); + } else { + status = gensec_update(session->gensec, state, + data_blob(NULL, 0), + &state->setup.spnego.in.secblob); + + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n", -- cgit From 4ac2be99588b48b0652a524bf12fb1aa9c3f5fbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 11:07:23 +0000 Subject: r13924: Split more prototypes out of include/proto.h + initial work on header file dependencies (This used to be commit 122835876748a3eaf5e8d31ad1abddab9acb8781) --- source4/libcli/auth/config.mk | 1 + source4/libcli/auth/smbencrypt.c | 1 + source4/libcli/cldap/cldap.c | 1 + source4/libcli/cliconnect.c | 1 + source4/libcli/composite/composite.h | 2 + source4/libcli/config.mk | 3 + source4/libcli/dgram/browse.c | 1 + source4/libcli/dgram/netlogon.c | 1 + source4/libcli/dgram/ntlogon.c | 1 + source4/libcli/finddcs.c | 1 + source4/libcli/raw/clisocket.c | 1 + source4/libcli/resolve/bcast.c | 3 + source4/libcli/resolve/nbtlist.c | 2 + source4/libcli/resolve/resolve.c | 1 + source4/libcli/resolve/wins.c | 1 + source4/libcli/security/access_check.c | 1 + source4/libcli/security/config.mk | 1 + source4/libcli/security/sddl.c | 1 + source4/libcli/security/security_descriptor.c | 1 + source4/libcli/security/security_token.c | 1 + source4/libcli/smb2/connect.c | 1 + source4/libcli/smb_composite/appendacl.c | 1 + source4/libcli/smb_composite/connect.c | 1 + source4/libcli/smb_composite/sesssetup.c | 1 + source4/libcli/smb_composite/smb_composite.h | 2 + source4/libcli/util/clilsa.c | 1 + source4/libcli/util/nt_status.h | 127 ++++++++++++++++++++++++++ source4/libcli/wrepl/winsrepl.c | 2 + 28 files changed, 162 insertions(+) create mode 100644 source4/libcli/util/nt_status.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 0d8c21d527..c879c60956 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] +PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = credentials.o \ session.o \ smbencrypt.o diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 12c5d2dfb6..0ebd78fa7f 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -27,6 +27,7 @@ #include "smb.h" #include "auth/ntlmssp/ntlmssp.h" #include "lib/crypto/crypto.h" +#include "libcli/auth/proto.h" #include "pstring.h" /* diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 490a03d50e..9e407ba200 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -38,6 +38,7 @@ #include "libcli/ldap/ldap.h" #include "libcli/cldap/cldap.h" #include "lib/socket/socket.h" +#include "libcli/security/proto.h" /* destroy a pending request diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 8103208a26..8616e42cd4 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" +#include "libcli/auth/proto.h" #include "libcli/smb_composite/smb_composite.h" /* diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 26490f1c4a..d1299d77c1 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -60,3 +60,5 @@ struct composite_context { BOOL used_wait; }; + +#include "libcli/composite/proto.h" diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index b431922de7..71adaaa8c9 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -16,11 +16,13 @@ OBJ_FILES = util/clilsa.o REQUIRED_SUBSYSTEMS = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_COMPOSITE] +PRIVATE_PROTO_HEADER = composite/proto.h OBJ_FILES = \ composite/composite.o REQUIRED_SUBSYSTEMS = LIBEVENTS [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] +PRIVATE_PROTO_HEADER = smb_composite/proto.h OBJ_FILES = \ smb_composite/loadfile.o \ smb_composite/savefile.o \ @@ -80,6 +82,7 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] +PRIVATE_PROTO_HEADER = resolve/resolve.h OBJ_FILES = \ resolve/resolve.o \ resolve/nbtlist.o \ diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 25cee387c4..f67e561afc 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" +#include "libcli/resolve/resolve.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 6ad4c28811..df8c63fa87 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" +#include "libcli/resolve/resolve.h" /* send a netlogon mailslot request diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index ecd6bd4587..84ad814fa0 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" +#include "libcli/resolve/resolve.h" /* send a ntlogon mailslot request diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 9caf9b5578..085aa352ac 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_samr.h" #include "libcli/composite/composite.h" #include "libcli/libcli.h" +#include "libcli/resolve/resolve.h" struct finddcs_state { struct composite_context *ctx; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 40d9d2784a..4b1d70d8d2 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -26,6 +26,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "lib/socket/socket.h" +#include "libcli/resolve/resolve.h" struct sock_connect_state { struct composite_context *ctx; diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index f8ea6b2b3b..1b58918ea7 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -21,6 +21,9 @@ */ #include "includes.h" +#include "libcli/resolve/resolve.h" +#include "system/network.h" +#include "netif/netif.h" /* broadcast name resolution method - async send diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 3af40c1b24..e8473966b4 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -26,6 +26,8 @@ #include "includes.h" #include "libcli/composite/composite.h" +#include "system/network.h" +#include "netif/netif.h" struct nbtlist_state { struct nbt_name name; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index d3d197e567..c3fdf4bc25 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -23,6 +23,7 @@ #include "includes.h" #include "lib/events/events.h" #include "libcli/composite/composite.h" +#include "libcli/resolve/resolve.h" struct resolve_state { struct nbt_name name; diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index b2e0ddae6f..f11033ae4f 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/resolve/resolve.h" /* wins name resolution method - async send diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 00275d8824..9d565363e6 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/security/proto.h" /* diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index a8de499531..3202def26c 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIB_SECURITY [SUBSYSTEM::LIB_SECURITY] +PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = security_token.o \ security_descriptor.o \ dom_sid.o \ diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index c434072529..a1e9985edd 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/iconv.h" +#include "libcli/security/proto.h" struct flag_map { const char *name; diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 64983e20d0..20cdeb0ba7 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/security/proto.h" /* return a blank security descriptor (no owners, dacl or sacl) diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 6774894a86..7760ee7c22 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -23,6 +23,7 @@ #include "includes.h" #include "dsdb/samdb/samdb.h" +#include "libcli/security/proto.h" /* return a blank security token diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index d15f370feb..b185ff7a88 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -25,6 +25,7 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" #include "libcli/composite/composite.h" +#include "libcli/resolve/resolve.h" struct smb2_connect_state { struct cli_credentials *credentials; diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index c68c0a185d..0a5b56b90d 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -1,6 +1,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "libcli/security/proto.h" #include "libcli/smb_composite/smb_composite.h" /* the stages of this call */ diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 785b0d076b..07da2d363a 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -26,6 +26,7 @@ #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "lib/events/events.h" +#include "libcli/resolve/resolve.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index bbe6a7edfb..9e345ab4f8 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -25,6 +25,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" +#include "libcli/auth/proto.h" #include "auth/auth.h" #include "version.h" diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 7ab0127440..ac34ad40ac 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -170,3 +170,5 @@ struct smb_composite_connectmulti { struct smbcli_socket *socket; } out; }; + +#include "libcli/smb_composite/proto.h" diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index bf5048b02a..97aa7e13ac 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -29,6 +29,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" +#include "libcli/security/proto.h" #include "librpc/gen_ndr/ndr_lsa.h" struct smblsa_state { diff --git a/source4/libcli/util/nt_status.h b/source4/libcli/util/nt_status.h new file mode 100644 index 0000000000..a805a1cfbd --- /dev/null +++ b/source4/libcli/util/nt_status.h @@ -0,0 +1,127 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup, plus a whole lot more. + + Copyright (C) Andrew Tridgell 2001 + + 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. +*/ + +#ifndef _NT_STATUS_H +#define _NT_STATUS_H + +/* The Splint code analysis tool doesn't like immediate structures. */ + +#ifdef _SPLINT_ /* http://www.splint.org */ +#undef HAVE_IMMEDIATE_STRUCTURES +#endif + +/* the following rather strange looking definitions of NTSTATUS and WERROR + and there in order to catch common coding errors where different error types + are mixed up. This is especially important as we slowly convert Samba + from using BOOL for internal functions +*/ + +#if defined(HAVE_IMMEDIATE_STRUCTURES) +typedef struct {uint32_t v;} NTSTATUS; +#define NT_STATUS(x) ((NTSTATUS) { x }) +#define NT_STATUS_V(x) ((x).v) +#else +typedef uint32_t NTSTATUS; +#define NT_STATUS(x) (x) +#define NT_STATUS_V(x) (x) +#endif + +#if defined(HAVE_IMMEDIATE_STRUCTURES) +typedef struct {uint32_t v;} WERROR; +#define W_ERROR(x) ((WERROR) { x }) +#define W_ERROR_V(x) ((x).v) +#else +typedef uint32_t WERROR; +#define W_ERROR(x) (x) +#define W_ERROR_V(x) (x) +#endif + +#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) +#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) +/* checking for DOS error mapping here is ugly, but unfortunately the + alternative is a very intrusive rewrite of the torture code */ +#define NT_STATUS_EQUAL(x,y) (NT_STATUS_IS_DOS(x)||NT_STATUS_IS_DOS(y)?ntstatus_dos_equal(x,y):NT_STATUS_V(x) == NT_STATUS_V(y)) + +#define NT_STATUS_HAVE_NO_MEMORY(x) do { \ + if (!(x)) {\ + return NT_STATUS_NO_MEMORY;\ + }\ +} while (0) + +#define NT_STATUS_IS_OK_RETURN(x) do { \ + if (NT_STATUS_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +#define NT_STATUS_NOT_OK_RETURN(x) do { \ + if (!NT_STATUS_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +#define NT_STATUS_IS_ERR_RETURN(x) do { \ + if (NT_STATUS_IS_ERR(x)) {\ + return x;\ + }\ +} while (0) + +#define NT_STATUS_NOT_ERR_RETURN(x) do { \ + if (!NT_STATUS_IS_ERR(x)) {\ + return x;\ + }\ +} while (0) + +#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) +#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) + +#define W_ERROR_HAVE_NO_MEMORY(x) do { \ + if (!(x)) {\ + return WERR_NOMEM;\ + }\ +} while (0) + +#define W_ERROR_IS_OK_RETURN(x) do { \ + if (W_ERROR_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +#define W_ERROR_NOT_OK_RETURN(x) do { \ + if (!W_ERROR_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +/* this defines special NTSTATUS codes to represent DOS errors. I + have chosen this macro to produce status codes in the invalid + NTSTATUS range */ +#define NT_STATUS_DOS(class, code) NT_STATUS(0xF1000000 | ((class)<<16) | code) +#define NT_STATUS_IS_DOS(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF1000000) +#define NT_STATUS_DOS_CLASS(status) ((NT_STATUS_V(status) >> 16) & 0xFF) +#define NT_STATUS_DOS_CODE(status) (NT_STATUS_V(status) & 0xFFFF) + +/* define ldap error codes as NTSTATUS codes */ +#define NT_STATUS_LDAP(code) NT_STATUS(0xF2000000 | code) +#define NT_STATUS_IS_LDAP(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF2000000) +#define NT_STATUS_LDAP_CODE(status) (NT_STATUS_V(status) & ~0xFF000000) + +#endif diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index ba7203c33a..3fb142ea0b 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -27,6 +27,8 @@ #include "libcli/wrepl/winsrepl.h" #include "lib/stream/packet.h" #include "libcli/composite/composite.h" +#include "system/network.h" +#include "netif/netif.h" static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status); -- cgit From 9bd7dd912124d8ffda6f9967d6ba358c16be2aa0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 12:08:58 +0000 Subject: r13926: More header splitups. (This used to be commit 930daa9f416ecba1d75b8ad46bb42e336545672f) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 71adaaa8c9..b24c44977a 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,7 +3,7 @@ include ldap/config.mk include security/config.mk [SUBSYSTEM::LIBCLI_UTILS] -PUBLIC_HEADERS = util/nterr.h util/doserr.h +PUBLIC_HEADERS = util/nterr.h util/doserr.h util/nt_status.h OBJ_FILES = util/asn1.o \ util/doserr.o \ util/errormap.o \ -- cgit From eeaf9650d8ea689ddcfba269bcbb2c2da27638bb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 13:06:59 +0000 Subject: r13935: add dependecies metze (This used to be commit 569275bc2b9e91a944087581d383c2b7d914c481) --- source4/libcli/config.mk | 2 +- source4/libcli/smb2/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index b24c44977a..58e60c286a 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -140,6 +140,6 @@ OBJ_FILES = raw/rawfile.o \ raw/rawacl.o \ raw/rawdate.o \ raw/rawlpq.o -REQUIRED_SUBSYSTEMS = LIBPACKET +REQUIRED_SUBSYSTEMS = LIBPACKET GENSEC include smb2/config.mk diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index dc4715ffe4..391cd10302 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -19,4 +19,4 @@ OBJ_FILES = \ tdis.o \ flush.o \ keepalive.o -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET GENSEC -- cgit From 3d4a22dab4f344c2fae50d1eabe126dd56b8035b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 13:14:30 +0000 Subject: r13936: fix dependecy metze (This used to be commit 9650d15c211988a4f81c546bd47eadb1302b8f9b) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 58e60c286a..abe4c76731 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -89,7 +89,7 @@ OBJ_FILES = \ resolve/bcast.o \ resolve/wins.o \ resolve/host.o -REQUIRED_SUBSYSTEMS = LIBCLI_NBT +REQUIRED_SUBSYSTEMS = LIBCLI_NBT LIBNETIF [SUBSYSTEM::LIBCLI_FINDDCS] OBJ_FILES = \ -- cgit From 17ae598141b44142ad52a66cc4767029e3a73d6c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 13:36:26 +0000 Subject: r13938: Around round of splitups (This used to be commit 2d655f05285a86bb1bbb882e4dd843def15c9dfa) --- source4/libcli/config.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index abe4c76731..7dfa4717d8 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,6 +3,7 @@ include ldap/config.mk include security/config.mk [SUBSYSTEM::LIBCLI_UTILS] +PRIVATE_PROTO_HEADER = util/proto.h PUBLIC_HEADERS = util/nterr.h util/doserr.h util/nt_status.h OBJ_FILES = util/asn1.o \ util/doserr.o \ @@ -92,6 +93,7 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = LIBCLI_NBT LIBNETIF [SUBSYSTEM::LIBCLI_FINDDCS] +PRIVATE_PROTO_HEADER = finddcs.h OBJ_FILES = \ finddcs.o REQUIRED_SUBSYSTEMS = LIBCLI_NBT MESSAGING -- cgit From f8fdbc967c774a1d62f87a534e4990d83ecc6b67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 14:34:32 +0000 Subject: r13944: Yet another round of splitups. (This used to be commit f87debeb12cebd734b47314554ab671c9e06237e) --- source4/libcli/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 7dfa4717d8..548b7e8e40 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -13,6 +13,7 @@ OBJ_FILES = util/asn1.o \ util/smbdes.o [SUBSYSTEM::LIBCLI_LSA] +PRIVATE_PROTO_HEADER = util/clilsa.h OBJ_FILES = util/clilsa.o REQUIRED_SUBSYSTEMS = RPC_NDR_LSA -- cgit From ceb6e9717bf8ea5c83a01e159a7006fd8651620c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 16:41:04 +0000 Subject: r13960: Generate makefile rules for installing/removing shared modules. (This used to be commit 2c746980328431ab04852dc668899e3eb042da99) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 2 +- source4/libcli/ldap/config.mk | 2 +- source4/libcli/smb2/config.mk | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index c879c60956..d11f440864 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -6,6 +6,6 @@ OBJ_FILES = credentials.o \ session.o \ smbencrypt.o REQUIRED_SUBSYSTEMS = \ - AUTH SCHANNELDB gensec_ntlmssp + auth SCHANNELDB gensec_ntlmssp # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 548b7e8e40..1c030e0d0d 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -143,6 +143,6 @@ OBJ_FILES = raw/rawfile.o \ raw/rawacl.o \ raw/rawdate.o \ raw/rawlpq.o -REQUIRED_SUBSYSTEMS = LIBPACKET GENSEC +REQUIRED_SUBSYSTEMS = LIBPACKET gensec include smb2/config.mk diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 59d2d1ea30..c0ad8d157f 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET NDR_SAMR LIBTLS \ +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ LIBPACKET # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 391cd10302..929a6135fa 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -19,4 +19,4 @@ OBJ_FILES = \ tdis.o \ flush.o \ keepalive.o -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET GENSEC +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET gensec -- cgit From 7d8424ede21185a978a222f609263506c0e20f4e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Mar 2006 12:42:45 +0000 Subject: r14064: - split out MSRPC_PARSE into a speperate subsystem - build gensec_ntlmssp always static for now, because torture/auth/ntlmssp.c needs to access functions from it metze (This used to be commit 43733c9556c1c92336780206e3f71bdee6e43eee) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/auth/smbencrypt.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index d11f440864..18983e1644 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -6,6 +6,6 @@ OBJ_FILES = credentials.o \ session.o \ smbencrypt.o REQUIRED_SUBSYSTEMS = \ - auth SCHANNELDB gensec_ntlmssp + auth SCHANNELDB MSRPC_PARSE # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 0ebd78fa7f..f267baa4c0 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -26,6 +26,7 @@ #include "system/time.h" #include "smb.h" #include "auth/ntlmssp/ntlmssp.h" +#include "auth/ntlmssp/msrpc_parse.h" #include "lib/crypto/crypto.h" #include "libcli/auth/proto.h" #include "pstring.h" -- cgit From 2d7353dea47f849ce6f18ecb6f896676f0a167df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 10 Mar 2006 11:47:03 +0000 Subject: r14141: fixed bugzilla 2921, forcing correct alignment when in ascii mode (This used to be commit f432d23b044355ae5214812e3794ab319b01268f) --- source4/libcli/raw/rawfile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 0cc7385cee..2eacd1d22e 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -297,7 +297,7 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr parms->ntcreatex.in.ea_list->eas); } - nt.in.params = data_blob_talloc(mem_ctx, NULL, 54); + nt.in.params = data_blob_talloc(mem_ctx, NULL, 53); if (nt.in.params.data == NULL) { talloc_free(mem_ctx); return NULL; @@ -319,7 +319,9 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr SIVAL(params, 48, parms->ntcreatex.in.impersonation); SCVAL(params, 52, parms->ntcreatex.in.security_flags); SCVAL(params, 53, 0); - + + /* the empty string first forces the correct alignment */ + smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,"", 0); fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params, parms->ntcreatex.in.fname, STR_TERMINATE); -- cgit From 3d9fc634ef8164a34adf14c0f77473c6268d2538 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Mar 2006 15:10:47 +0000 Subject: r14160: don't write behind the buffer metze (This used to be commit bce4db8d1c293d05546dfd1b0229252babdb64b2) --- source4/libcli/raw/rawfile.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 2eacd1d22e..9d2611f7b2 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -318,7 +318,6 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr SIVAL(params, 40, ea_blob.length); SIVAL(params, 48, parms->ntcreatex.in.impersonation); SCVAL(params, 52, parms->ntcreatex.in.security_flags); - SCVAL(params, 53, 0); /* the empty string first forces the correct alignment */ smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,"", 0); -- cgit From 307e43bb5628e8b53a930c2928279af994281ba5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Mar 2006 20:49:20 +0000 Subject: r14173: change smb interface structures to always use a union smb_file, to abtract - const char *path fot qpathinfo and setpathinfo - uint16_t fnum for SMB - smb2_handle handle for SMB2 the idea is to later add a struct ntvfs_handle *ntvfs so that the ntvfs subsystem don't need to know the difference between SMB and SMB2 metze (This used to be commit 2ef3f5970901b5accdb50f0d0115b5d46b0c788f) --- source4/libcli/clifile.c | 44 ++--- source4/libcli/clireadwrite.c | 6 +- source4/libcli/clitrans2.c | 10 +- source4/libcli/raw/interfaces.h | 280 ++++++++++++++++--------------- source4/libcli/raw/rawacl.c | 4 +- source4/libcli/raw/rawfile.c | 67 ++++---- source4/libcli/raw/rawfileinfo.c | 8 +- source4/libcli/raw/rawioctl.c | 4 +- source4/libcli/raw/rawnotify.c | 28 ++-- source4/libcli/raw/rawreadwrite.c | 18 +- source4/libcli/smb2/getinfo.c | 6 +- source4/libcli/smb_composite/appendacl.c | 12 +- source4/libcli/smb_composite/loadfile.c | 8 +- source4/libcli/smb_composite/savefile.c | 8 +- 14 files changed, 252 insertions(+), 251 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index e8cb548007..d3de0dab77 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -38,11 +38,11 @@ static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, if (hard_link) { parms.generic.level = RAW_SFILEINFO_UNIX_HLINK; - parms.unix_hlink.file.fname = fname_src; + parms.unix_hlink.file.path = fname_src; parms.unix_hlink.in.link_dest = fname_dst; } else { parms.generic.level = RAW_SFILEINFO_UNIX_LINK; - parms.unix_link.file.fname = fname_src; + parms.unix_link.file.path = fname_src; parms.unix_link.in.link_dest = fname_dst; } @@ -110,7 +110,7 @@ static NTSTATUS smbcli_unix_chmod_chown_internal(struct smbcli_tree *tree, NTSTATUS status; parms.generic.level = SMB_SFILEINFO_UNIX_BASIC; - parms.unix_basic.file.fname = fname; + parms.unix_basic.file.path = fname; parms.unix_basic.in.uid = uid; parms.unix_basic.in.gid = gid; parms.unix_basic.in.mode = mode; @@ -165,13 +165,13 @@ NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src, ****************************************************************************/ NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname) { - struct smb_unlink parms; + union smb_unlink parms; - parms.in.pattern = fname; + parms.unlink.in.pattern = fname; if (strchr(fname, '*')) { - parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; + parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; } else { - parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; + parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; } return smb_raw_unlink(tree, &parms); @@ -256,7 +256,7 @@ int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname, talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { - return open_parms.ntcreatex.out.fnum; + return open_parms.ntcreatex.file.fnum; } return -1; @@ -323,7 +323,7 @@ int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { - return open_parms.openx.out.fnum; + return open_parms.openx.file.fnum; } return -1; @@ -339,7 +339,7 @@ NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum) NTSTATUS status; close_parms.close.level = RAW_CLOSE_CLOSE; - close_parms.close.in.fnum = fnum; + close_parms.close.file.fnum = fnum; close_parms.close.in.write_time = 0; status = smb_raw_close(tree, &close_parms); return status; @@ -358,7 +358,7 @@ NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum, NTSTATUS status; parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.in.fnum = fnum; + parms.lockx.file.fnum = fnum; parms.lockx.in.mode = locktype; parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; @@ -386,7 +386,7 @@ NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum, NTSTATUS status; parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.in.fnum = fnum; + parms.lockx.file.fnum = fnum; parms.lockx.in.mode = (lock_type == READ_LOCK? 1 : 0); parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; @@ -412,7 +412,7 @@ NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint NTSTATUS status; parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.in.fnum = fnum; + parms.lockx.file.fnum = fnum; parms.lockx.in.mode = 0; parms.lockx.in.timeout = 0; parms.lockx.in.ulock_cnt = 1; @@ -444,7 +444,7 @@ NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, } parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.in.fnum = fnum; + parms.lockx.file.fnum = fnum; ltype = (lock_type == READ_LOCK? 1 : 0); ltype |= LOCKING_ANDX_LARGE_FILES; @@ -478,7 +478,7 @@ NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset, } parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.in.fnum = fnum; + parms.lockx.file.fnum = fnum; parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; parms.lockx.in.timeout = 0; parms.lockx.in.ulock_cnt = 1; @@ -505,7 +505,7 @@ NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum, NTSTATUS status; parms.getattre.level = RAW_FILEINFO_GETATTRE; - parms.getattre.in.fnum = fnum; + parms.getattre.file.fnum = fnum; status = smb_raw_fileinfo(tree, NULL, &parms); @@ -545,7 +545,7 @@ NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname, NTSTATUS status; parms.getattr.level = RAW_FILEINFO_GETATTR; - parms.getattr.in.fname = fname; + parms.getattr.file.path = fname; status = smb_raw_pathinfo(tree, NULL, &parms); @@ -579,9 +579,9 @@ NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mod NTSTATUS status; parms.setattr.level = RAW_SFILEINFO_SETATTR; + parms.setattr.file.path = fname; parms.setattr.in.attrib = mode; parms.setattr.in.write_time = t; - parms.setattr.file.fname = fname; status = smb_raw_setpathinfo(tree, &parms); @@ -594,7 +594,7 @@ NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mod ****************************************************************************/ NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path) { - struct smb_chkpath parms; + union smb_chkpath parms; char *path2; NTSTATUS status; @@ -605,8 +605,8 @@ NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path) path2 = strdup("\\"); } - parms.in.path = path2; - + parms.chkpath.in.path = path2; + status = smb_raw_chkpath(tree, &parms); free(path2); @@ -663,7 +663,7 @@ int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path) } talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { - return open_parms.ctemp.out.fnum; + return open_parms.ctemp.file.fnum; } return -1; } diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 4248ac4286..afffba968a 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -38,7 +38,7 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset } parms.readx.level = RAW_READ_READX; - parms.readx.in.fnum = fnum; + parms.readx.file.fnum = fnum; /* * Set readsize to the maximum size we can handle in one readX, @@ -100,7 +100,7 @@ ssize_t smbcli_write(struct smbcli_tree *tree, parms.writex.level = RAW_WRITE_WRITEX; - parms.writex.in.fnum = fnum; + parms.writex.file.fnum = fnum; parms.writex.in.wmode = write_mode; parms.writex.in.remaining = 0; @@ -144,7 +144,7 @@ ssize_t smbcli_smbwrite(struct smbcli_tree *tree, size_t size = MIN(size1, tree->session->transport->negotiate.max_xmit - 48); if (size > 0xFFFF) size = 0xFFFF; - parms.write.in.fnum = fnum; + parms.write.file.fnum = fnum; parms.write.in.offset = offset; parms.write.in.count = size; parms.write.in.data = buf + total; diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index c440b25e36..f8699e0191 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -36,7 +36,7 @@ NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname, if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.standard.level = RAW_FILEINFO_STANDARD; - parms.standard.in.fname = fname; + parms.standard.file.path = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_free(mem_ctx); @@ -78,7 +78,7 @@ NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname, if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; - parms.all_info.in.fname = fname; + parms.all_info.file.path = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_free(mem_ctx); @@ -121,7 +121,7 @@ NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name) if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.name_info.level = RAW_FILEINFO_NAME_INFO; - parms.name_info.in.fnum = fnum; + parms.name_info.file.fnum = fnum; status = smb_raw_fileinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { @@ -155,7 +155,7 @@ NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum, return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; - parms.all_info.in.fnum = fnum; + parms.all_info.file.fnum = fnum; status = smb_raw_fileinfo(tree, mem_ctx, &parms); talloc_free(mem_ctx); @@ -200,7 +200,7 @@ NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname, NTSTATUS status; parms.alt_name_info.level = RAW_FILEINFO_ALT_NAME_INFO; - parms.alt_name_info.in.fname = fname; + parms.alt_name_info.file.path = fname; mem_ctx = talloc_init("smbcli_qpathinfo_alt_name"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 034878a464..0505078fd4 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -56,6 +56,29 @@ typedef struct { /* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ #define dom_sid28 dom_sid +/* + a generic container for file handles +*/ +union smb_file { + /* + * this is only used for + * the qpathinfo and setpathinfo + * calls + */ + const char *path; + + /* + * this is used as file handle in SMB + */ + uint16_t fnum; + + /* + * this is used as file handle in SMB2 + */ + struct smb2_handle { + uint64_t data[2]; + } handle; +}; /* this header defines the structures and unions used between the SMB @@ -63,32 +86,37 @@ typedef struct { */ /* struct used for SMBlseek call */ -struct smb_seek { - struct { - uint16_t fnum; - uint16_t mode; - int32_t offset; /* signed */ - } in; +union smb_seek { struct { - int32_t offset; - } out; + union smb_file file; + struct { + uint16_t mode; + int32_t offset; /* signed */ + } in; + struct { + int32_t offset; + } out; + } lseek; }; - /* struct used in unlink() call */ -struct smb_unlink { +union smb_unlink { struct { - const char *pattern; - uint16_t attrib; - } in; + struct { + const char *pattern; + uint16_t attrib; + } in; + } unlink; }; /* struct used in chkpath() call */ -struct smb_chkpath { +union smb_chkpath { struct { - const char *path; - } in; + struct { + const char *path; + } in; + } chkpath; }; enum smb_mkdir_level {RAW_MKDIR_GENERIC, RAW_MKDIR_MKDIR, RAW_MKDIR_T2MKDIR}; @@ -326,32 +354,14 @@ enum smb_fileinfo_level { RAW_FILEINFO_SMB2_ALL_INFORMATION = 0x1201 }; -/* - file handles in SMB2 are 16 bytes -*/ -struct smb2_handle { - uint64_t data[2]; -}; - - /* union used in qfileinfo() and qpathinfo() backend calls */ union smb_fileinfo { /* generic interface: * matches RAW_FILEINFO_GENERIC */ struct { enum smb_fileinfo_level level; + union smb_file file; - /* each level can be called on either a pathname or a - filename, in either case the return format is - identical - On SMB2 a 16 byte handle is used - */ - union smb_fileinfo_in { - const char *fname; - uint16_t fnum; - struct smb2_handle handle; - } in; - struct { uint32_t attrib; uint32_t ea_size; @@ -397,7 +407,7 @@ union smb_fileinfo { * matches RAW_FILEINFO_GETATTR */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint16_t attrib; @@ -409,7 +419,7 @@ union smb_fileinfo { /* SMBgetattrE and RAW_FILEINFO_STANDARD interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { time_t create_time; @@ -424,7 +434,7 @@ union smb_fileinfo { /* trans2 RAW_FILEINFO_EA_SIZE interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { time_t create_time; @@ -440,7 +450,7 @@ union smb_fileinfo { /* trans2 RAW_FILEINFO_EA_LIST interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in file; + union smb_file file; struct { uint_t num_names; @@ -458,9 +468,11 @@ union smb_fileinfo { /* trans2 RAW_FILEINFO_ALL_EAS and RAW_FILEINFO_FULL_EA_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; - uint8_t continue_flags; /* SMB2 only - SMB2_CONTINUE_FLAG_* */ - + union smb_file file; + struct { + /* SMB2 only - SMB2_CONTINUE_FLAG_* */ + uint8_t continue_flags; + } in; struct smb_ea_list out; } all_eas; @@ -468,13 +480,13 @@ union smb_fileinfo { only valid for a QPATHNAME call - no returned data */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; } is_name_valid; /* RAW_FILEINFO_BASIC_INFO and RAW_FILEINFO_BASIC_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { NTTIME create_time; @@ -489,7 +501,7 @@ union smb_fileinfo { /* RAW_FILEINFO_STANDARD_INFO and RAW_FILEINFO_STANDARD_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint64_t alloc_size; @@ -503,7 +515,7 @@ union smb_fileinfo { /* RAW_FILEINFO_EA_INFO and RAW_FILEINFO_EA_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint32_t ea_size; @@ -513,7 +525,7 @@ union smb_fileinfo { /* RAW_FILEINFO_NAME_INFO and RAW_FILEINFO_NAME_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { WIRE_STRING fname; @@ -523,7 +535,7 @@ union smb_fileinfo { /* RAW_FILEINFO_ALL_INFO and RAW_FILEINFO_ALL_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { NTTIME create_time; @@ -544,7 +556,7 @@ union smb_fileinfo { /* RAW_FILEINFO_SMB2_ALL_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { NTTIME create_time; @@ -571,7 +583,7 @@ union smb_fileinfo { /* RAW_FILEINFO_ALT_NAME_INFO and RAW_FILEINFO_ALT_NAME_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { WIRE_STRING fname; @@ -581,7 +593,7 @@ union smb_fileinfo { /* RAW_FILEINFO_STREAM_INFO and RAW_FILEINFO_STREAM_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct stream_information { uint_t num_streams; @@ -592,7 +604,7 @@ union smb_fileinfo { /* RAW_FILEINFO_COMPRESSION_INFO and RAW_FILEINFO_COMPRESSION_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint64_t compressed_size; @@ -606,7 +618,7 @@ union smb_fileinfo { /* RAW_FILEINFO_UNIX_BASIC interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint64_t end_of_file; @@ -628,7 +640,7 @@ union smb_fileinfo { /* RAW_FILEINFO_UNIX_LINK interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { WIRE_STRING link_dest; @@ -638,7 +650,7 @@ union smb_fileinfo { /* RAW_FILEINFO_INTERNAL_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint64_t file_id; @@ -648,7 +660,7 @@ union smb_fileinfo { /* RAW_FILEINFO_ACCESS_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint32_t access_flags; @@ -658,7 +670,7 @@ union smb_fileinfo { /* RAW_FILEINFO_POSITION_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint64_t position; @@ -668,7 +680,7 @@ union smb_fileinfo { /* RAW_FILEINFO_MODE_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint32_t mode; @@ -678,7 +690,7 @@ union smb_fileinfo { /* RAW_FILEINFO_ALIGNMENT_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint32_t alignment_requirement; @@ -688,7 +700,7 @@ union smb_fileinfo { /* RAW_FILEINFO_NETWORK_OPEN_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { NTTIME create_time; @@ -705,7 +717,7 @@ union smb_fileinfo { /* RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; + union smb_file file; struct { uint32_t attrib; @@ -716,8 +728,10 @@ union smb_fileinfo { /* RAW_FILEINFO_SEC_DESC */ struct { enum smb_fileinfo_level level; - union smb_fileinfo_in in; - uint32_t secinfo_flags; + union smb_file file; + struct { + uint32_t secinfo_flags; + } in; struct { struct security_descriptor *sd; } out; @@ -760,19 +774,13 @@ union smb_setfileinfo { struct { enum smb_setfileinfo_level level; - /* we are combining setfileinfo and setpathinfo into one - interface */ - union setfileinfo_file { - const char *fname; - uint16_t fnum; - struct smb2_handle handle; /* only for SMB2 */ - } file; + union smb_file file; } generic; /* RAW_SFILEINFO_SETATTR (SMBsetatr) interface - only via setpathinfo() */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; + union smb_file file; struct { uint16_t attrib; time_t write_time; @@ -783,8 +791,7 @@ union smb_setfileinfo { also RAW_SFILEINFO_STANDARD */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { time_t create_time; time_t access_time; @@ -797,7 +804,7 @@ union smb_setfileinfo { /* RAW_SFILEINFO_EA_SET interface */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; + union smb_file file; struct { uint_t num_eas; struct ea_struct *eas; @@ -808,8 +815,7 @@ union smb_setfileinfo { RAW_SFILEINFO_BASIC_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { NTTIME create_time; NTTIME access_time; @@ -823,8 +829,7 @@ union smb_setfileinfo { RAW_SFILEINFO_DISPOSITION_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { BOOL delete_on_close; } in; @@ -834,8 +839,7 @@ union smb_setfileinfo { RAW_SFILEINFO_ALLOCATION_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { /* w2k3 rounds this up to nearest 4096 */ uint64_t alloc_size; @@ -846,8 +850,7 @@ union smb_setfileinfo { RAW_SFILEINFO_END_OF_FILE_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { uint64_t size; } in; @@ -856,8 +859,7 @@ union smb_setfileinfo { /* RAW_SFILEINFO_RENAME_INFORMATION interface */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct smb_rename_information { uint8_t overwrite; uint32_t root_fid; @@ -868,8 +870,7 @@ union smb_setfileinfo { /* RAW_SFILEINFO_POSITION_INFORMATION interface */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { uint64_t position; } in; @@ -878,8 +879,7 @@ union smb_setfileinfo { /* RAW_SFILEINFO_MODE_INFORMATION interface */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; - + union smb_file file; struct { /* valid values seem to be 0, 2, 4 and 6 */ uint32_t mode; @@ -891,7 +891,7 @@ union smb_setfileinfo { /* RAW_SFILEINFO_UNIX_BASIC interface */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; + union smb_file file; struct { uint32_t mode; /* yuck - this field remains to fix compile of libcli/clifile.c */ uint64_t end_of_file; @@ -913,7 +913,7 @@ union smb_setfileinfo { /* RAW_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK interface */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; + union smb_file file; struct { const char *link_dest; } in; @@ -922,7 +922,7 @@ union smb_setfileinfo { /* RAW_FILEINFO_SET_SEC_DESC */ struct { enum smb_setfileinfo_level level; - union setfileinfo_file file; + union smb_file file; struct { uint32_t secinfo_flags; struct security_descriptor *sd; @@ -1131,6 +1131,8 @@ union smb_open { /* SMBNTCreateX interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint32_t flags; @@ -1156,7 +1158,6 @@ union smb_open { struct { uint8_t oplock_level; - uint16_t fnum; uint32_t create_action; NTTIME create_time; NTTIME access_time; @@ -1174,6 +1175,8 @@ union smb_open { /* TRANS2_OPEN interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t flags; @@ -1190,7 +1193,6 @@ union smb_open { } in; struct { - uint16_t fnum; uint16_t attrib; time_t write_time; uint32_t size; @@ -1205,14 +1207,16 @@ union smb_open { /* SMBopen interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t open_mode; uint16_t search_attrs; const char *fname; } in; + struct { - uint16_t fnum; uint16_t attrib; time_t write_time; uint32_t size; @@ -1223,6 +1227,8 @@ union smb_open { /* SMBopenX interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t flags; @@ -1238,7 +1244,6 @@ union smb_open { const char *fname; } in; struct { - uint16_t fnum; uint16_t attrib; time_t write_time; uint32_t size; @@ -1255,20 +1260,21 @@ union smb_open { /* SMBmknew interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t attrib; time_t write_time; const char *fname; } in; - struct { - uint16_t fnum; - } out; } mknew, create; /* SMBctemp interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t attrib; @@ -1276,7 +1282,6 @@ union smb_open { const char *directory; } in; struct { - uint16_t fnum; /* temp name, relative to directory */ char *name; } out; @@ -1285,21 +1290,22 @@ union smb_open { /* SMBsplopen interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t setup_length; uint16_t mode; const char *ident; } in; - struct { - uint16_t fnum; - } out; } splopen; /* chained OpenX/ReadX interface */ struct { enum smb_open_level level; + /* this is the output file handle */ + union smb_file file; struct { uint16_t flags; @@ -1321,7 +1327,6 @@ union smb_open { uint16_t remaining; } in; struct { - uint16_t fnum; uint16_t attrib; time_t write_time; uint32_t size; @@ -1357,9 +1362,9 @@ union smb_read { /* SMBreadX (and generic) interface */ struct { enum smb_read_level level; + union smb_file file; struct { - uint16_t fnum; uint64_t offset; uint16_t mincnt; uint32_t maxcnt; @@ -1376,9 +1381,9 @@ union smb_read { /* SMBreadbraw interface */ struct { enum smb_read_level level; + union smb_file file; struct { - uint16_t fnum; uint64_t offset; uint16_t maxcnt; uint16_t mincnt; @@ -1394,9 +1399,9 @@ union smb_read { /* SMBlockandread interface */ struct { enum smb_read_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1410,9 +1415,9 @@ union smb_read { /* SMBread interface */ struct { enum smb_read_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1437,9 +1442,9 @@ union smb_write { /* SMBwriteX interface */ struct { enum smb_write_level level; + union smb_file file; struct { - uint16_t fnum; uint64_t offset; uint16_t wmode; uint16_t remaining; @@ -1455,9 +1460,9 @@ union smb_write { /* SMBwriteunlock interface */ struct { enum smb_write_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1471,9 +1476,9 @@ union smb_write { /* SMBwrite interface */ struct { enum smb_write_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1487,9 +1492,9 @@ union smb_write { /* SMBwriteclose interface */ struct { enum smb_write_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t count; uint32_t offset; time_t mtime; @@ -1503,9 +1508,9 @@ union smb_write { /* SMBsplwrite interface */ struct { enum smb_write_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t count; const uint8_t *data; } in; @@ -1524,9 +1529,9 @@ union smb_lock { /* SMBlockingX (and generic) interface */ struct { enum smb_lock_level level; + union smb_file file; struct { - uint16_t fnum; uint16_t mode; uint32_t timeout; uint16_t ulock_cnt; @@ -1542,9 +1547,9 @@ union smb_lock { /* SMBlock and SMBunlock interface */ struct { enum smb_lock_level level; + union smb_file file; struct { - uint16_t fnum; uint32_t count; uint32_t offset; } in; @@ -1563,9 +1568,9 @@ union smb_close { /* SMBclose (and generic) interface */ struct { enum smb_close_level level; + union smb_file file; struct { - uint16_t fnum; time_t write_time; } in; } close, generic; @@ -1573,10 +1578,7 @@ union smb_close { /* SMBsplclose interface - empty! */ struct { enum smb_close_level level; - - struct { - uint16_t fnum; - } in; + union smb_file file; } splclose; }; @@ -1625,14 +1627,15 @@ union smb_ioctl { /* generic interface */ struct { enum smb_ioctl_level level; + union smb_file file; } generic; /* struct for SMBioctl */ struct { enum smb_ioctl_level level; + union smb_file file; struct { - uint16_t fnum; uint32_t request; } in; struct { @@ -1644,9 +1647,9 @@ union smb_ioctl { /* struct for NT ioctl call */ struct { enum smb_ioctl_level level; + union smb_file file; struct { uint32_t function; - uint16_t fnum; BOOL fsctl; uint8_t filter; } in; @@ -1657,10 +1660,10 @@ union smb_ioctl { }; /* struct for SMBflush */ -struct smb_flush { +union smb_flush { struct { - uint16_t fnum; - } in; + union smb_file file; + } flush; }; @@ -1725,24 +1728,25 @@ struct smb_nttrans { /* struct for nttrans change notify call */ -struct smb_notify { +union smb_notify { struct { - uint32_t buffer_size; - uint32_t completion_filter; - uint16_t fnum; - BOOL recursive; - } in; + union smb_file file; + struct { + uint32_t buffer_size; + uint32_t completion_filter; + BOOL recursive; + } in; - struct { - uint32_t num_changes; - struct notify_changes { - uint32_t action; - WIRE_STRING name; - } *changes; - } out; + struct { + uint32_t num_changes; + struct notify_changes { + uint32_t action; + WIRE_STRING name; + } *changes; + } out; + } notify; }; - enum smb_search_level {RAW_SEARCH_GENERIC = 0xF000, RAW_SEARCH_SEARCH, /* SMBsearch */ RAW_SEARCH_FFIRST, /* SMBffirst */ diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 08515eadde..7c0c17b4d7 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -38,9 +38,9 @@ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; nt.in.setup = NULL; - SSVAL(params, 0, io->query_secdesc.in.fnum); + SSVAL(params, 0, io->query_secdesc.file.fnum); SSVAL(params, 2, 0); /* padding */ - SIVAL(params, 4, io->query_secdesc.secinfo_flags); + SIVAL(params, 4, io->query_secdesc.in.secinfo_flags); nt.in.params.data = params; nt.in.params.length = 8; diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 9d2611f7b2..0e63fa656f 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -78,14 +78,14 @@ NTSTATUS smb_raw_rename(struct smbcli_tree *tree, Delete a file - async interface ****************************************************************************/ struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree, - struct smb_unlink *parms) + union smb_unlink *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBunlink, 1, 0); - SSVAL(req->out.vwv, VWV(0), parms->in.attrib); - smbcli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE); + SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib); + smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -98,7 +98,7 @@ struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree, delete a file - sync interface */ NTSTATUS smb_raw_unlink(struct smbcli_tree *tree, - struct smb_unlink *parms) + union smb_unlink *parms) { struct smbcli_request *req = smb_raw_unlink_send(tree, parms); return smbcli_request_simple_recv(req); @@ -234,7 +234,7 @@ static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req, params = nt.out.params.data; parms->ntcreatex.out.oplock_level = CVAL(params, 0); - parms->ntcreatex.out.fnum = SVAL(params, 2); + parms->ntcreatex.file.fnum = SVAL(params, 2); parms->ntcreatex.out.create_action = IVAL(params, 4); parms->ntcreatex.out.create_time = smbcli_pull_nttime(params, 12); parms->ntcreatex.out.access_time = smbcli_pull_nttime(params, 20); @@ -406,7 +406,7 @@ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ return NT_STATUS_INFO_LENGTH_MISMATCH; } - parms->t2open.out.fnum = SVAL(t2.out.params.data, VWV(0)); + parms->t2open.file.fnum = SVAL(t2.out.params.data, VWV(0)); parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1)); parms->t2open.out.write_time = raw_pull_dos_date3(transport, t2.out.params.data + VWV(2)); parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4)); @@ -572,7 +572,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_OPEN: SMBCLI_CHECK_WCT(req, 7); - parms->openold.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->openold.file.fnum = SVAL(req->in.vwv, VWV(0)); parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1)); parms->openold.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(2)); @@ -582,7 +582,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_OPENX: SMBCLI_CHECK_MIN_WCT(req, 15); - parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2)); + parms->openx.file.fnum = SVAL(req->in.vwv, VWV(2)); parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3)); parms->openx.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(4)); @@ -603,29 +603,29 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_MKNEW: SMBCLI_CHECK_WCT(req, 1); - parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->mknew.file.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_CREATE: SMBCLI_CHECK_WCT(req, 1); - parms->create.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->create.file.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_CTEMP: SMBCLI_CHECK_WCT(req, 1); - parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->ctemp.file.fnum = SVAL(req->in.vwv, VWV(0)); smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); break; case RAW_OPEN_SPLOPEN: SMBCLI_CHECK_WCT(req, 1); - parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0)); + parms->splopen.file.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_NTCREATEX: SMBCLI_CHECK_MIN_WCT(req, 34); parms->ntcreatex.out.oplock_level = CVAL(req->in.vwv, 4); - parms->ntcreatex.out.fnum = SVAL(req->in.vwv, 5); + parms->ntcreatex.file.fnum = SVAL(req->in.vwv, 5); parms->ntcreatex.out.create_action = IVAL(req->in.vwv, 7); parms->ntcreatex.out.create_time = smbcli_pull_nttime(req->in.vwv, 11); parms->ntcreatex.out.access_time = smbcli_pull_nttime(req->in.vwv, 19); @@ -644,7 +644,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_OPENX_READX: SMBCLI_CHECK_MIN_WCT(req, 15); - parms->openxreadx.out.fnum = SVAL(req->in.vwv, VWV(2)); + parms->openxreadx.file.fnum = SVAL(req->in.vwv, VWV(2)); parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3)); parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(4)); @@ -706,14 +706,14 @@ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_cl switch (parms->generic.level) { case RAW_CLOSE_CLOSE: SETUP_REQUEST(SMBclose, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->close.file.fnum); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->close.in.write_time); break; case RAW_CLOSE_SPLCLOSE: SETUP_REQUEST(SMBsplclose, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->splclose.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->splclose.file.fnum); SIVAL(req->out.vwv, VWV(1), 0); /* reserved */ break; } @@ -749,14 +749,14 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc switch (parms->generic.level) { case RAW_LOCK_LOCK: SETUP_REQUEST(SMBlock, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->lock.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->lock.in.count); SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset); break; case RAW_LOCK_UNLOCK: SETUP_REQUEST(SMBunlock, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->unlock.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->unlock.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count); SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset); break; @@ -770,7 +770,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - SSVAL(req->out.vwv, VWV(2), parms->lockx.in.fnum); + SSVAL(req->out.vwv, VWV(2), parms->lockx.file.fnum); SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode); SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout); SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt); @@ -816,13 +816,13 @@ NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms) /**************************************************************************** Check for existence of a dir - async send ****************************************************************************/ -struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb_chkpath *parms) +struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, union smb_chkpath *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBchkpth, 0, 0); - smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->chkpath.in.path, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -835,25 +835,22 @@ struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb /**************************************************************************** Check for existence of a dir - sync interface ****************************************************************************/ -NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, struct smb_chkpath *parms) +NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms) { struct smbcli_request *req = smb_raw_chkpath_send(tree, parms); return smbcli_request_simple_recv(req); } - - - /**************************************************************************** flush a file - async send a flush to fnum 0xFFFF will flush all files ****************************************************************************/ -struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_flush *parms) +struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBflush, 1, 0); - SSVAL(req->out.vwv, VWV(0), parms->in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->flush.file.fnum); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -867,7 +864,7 @@ struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_f /**************************************************************************** flush a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms) +NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms) { struct smbcli_request *req = smb_raw_flush_send(tree, parms); return smbcli_request_simple_recv(req); @@ -878,15 +875,15 @@ NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms) seek a file - async send ****************************************************************************/ struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree, - struct smb_seek *parms) + union smb_seek *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBlseek, 4, 0); - SSVAL(req->out.vwv, VWV(0), parms->in.fnum); - SSVAL(req->out.vwv, VWV(1), parms->in.mode); - SIVALS(req->out.vwv, VWV(2), parms->in.offset); + SSVAL(req->out.vwv, VWV(0), parms->lseek.file.fnum); + SSVAL(req->out.vwv, VWV(1), parms->lseek.in.mode); + SIVALS(req->out.vwv, VWV(2), parms->lseek.in.offset); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -899,7 +896,7 @@ struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree, seek a file - async receive ****************************************************************************/ NTSTATUS smb_raw_seek_recv(struct smbcli_request *req, - struct smb_seek *parms) + union smb_seek *parms) { if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { @@ -907,7 +904,7 @@ NTSTATUS smb_raw_seek_recv(struct smbcli_request *req, } SMBCLI_CHECK_WCT(req, 2); - parms->out.offset = IVAL(req->in.vwv, VWV(0)); + parms->lseek.out.offset = IVAL(req->in.vwv, VWV(0)); failed: return smbcli_request_destroy(req); @@ -917,7 +914,7 @@ failed: seek a file - sync interface */ NTSTATUS smb_raw_seek(struct smbcli_tree *tree, - struct smb_seek *parms) + union smb_seek *parms) { struct smbcli_request *req = smb_raw_seek_send(tree, parms); return smb_raw_seek_recv(req, parms); diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 92d31b30ef..b50a330093 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -536,7 +536,7 @@ static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree, req = smbcli_request_setup(tree, SMBgetatr, 0, 0); if (!req) return NULL; - smbcli_req_append_ascii4(req, parms->getattr.in.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->getattr.file.path, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -579,7 +579,7 @@ static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree, req = smbcli_request_setup(tree, SMBgetattrE, 1, 0); if (!req) return NULL; - SSVAL(req->out.vwv, VWV(0), parms->getattre.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->getattre.file.fnum); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; @@ -647,7 +647,7 @@ struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree, } req = smb_raw_fileinfo_blob_send(tree, - parms->generic.in.fnum, + parms->generic.file.fnum, parms->generic.level, data); data_blob_free(&data); @@ -722,7 +722,7 @@ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, } } - req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname, + req = smb_raw_pathinfo_blob_send(tree, parms->generic.file.path, parms->generic.level, data); data_blob_free(&data); diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 874d055013..28b58ff2a3 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -37,7 +37,7 @@ static struct smbcli_request *smb_raw_smbioctl_send(struct smbcli_tree *tree, SETUP_REQUEST(SMBioctl, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->ioctl.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->ioctl.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->ioctl.in.request); if (!smbcli_request_send(req)) { @@ -81,7 +81,7 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, nt.in.setup_count = 4; nt.in.setup = setup; SIVAL(setup, 0, parms->ntioctl.in.function); - SSVAL(setup, 4, parms->ntioctl.in.fnum); + SSVAL(setup, 4, parms->ntioctl.file.fnum); SCVAL(setup, 6, parms->ntioctl.in.fsctl); SCVAL(setup, 7, parms->ntioctl.in.filter); nt.in.function = NT_TRANSACT_IOCTL; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 1215a93f59..3adb1b000b 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -25,19 +25,19 @@ /**************************************************************************** change notify (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struct smb_notify *parms) +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) { struct smb_nttrans nt; uint16_t setup[4]; nt.in.max_setup = 0; - nt.in.max_param = parms->in.buffer_size; + nt.in.max_param = parms->notify.in.buffer_size; nt.in.max_data = 0; nt.in.setup_count = 4; nt.in.setup = setup; - SIVAL(setup, 0, parms->in.completion_filter); - SSVAL(setup, 4, parms->in.fnum); - SSVAL(setup, 6, parms->in.recursive); + SIVAL(setup, 0, parms->notify.in.completion_filter); + SSVAL(setup, 4, parms->notify.file.fnum); + SSVAL(setup, 6, parms->notify.in.recursive); nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; nt.in.params = data_blob(NULL, 0); nt.in.data = data_blob(NULL, 0); @@ -49,7 +49,7 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struc change notify (async recv) ****************************************************************************/ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, - TALLOC_CTX *mem_ctx, struct smb_notify *parms) + TALLOC_CTX *mem_ctx, union smb_notify *parms) { struct smb_nttrans nt; NTSTATUS status; @@ -61,28 +61,28 @@ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, return status; } - parms->out.changes = NULL; - parms->out.num_changes = 0; + parms->notify.out.changes = NULL; + parms->notify.out.num_changes = 0; /* count them */ for (ofs=0; nt.out.params.length - ofs > 12; ) { uint32_t next = IVAL(nt.out.params.data, ofs); - parms->out.num_changes++; + parms->notify.out.num_changes++; if (next == 0 || ofs + next >= nt.out.params.length) break; ofs += next; } /* allocate array */ - parms->out.changes = talloc_array(mem_ctx, struct notify_changes, parms->out.num_changes); - if (!parms->out.changes) { + parms->notify.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->notify.out.num_changes); + if (!parms->notify.out.changes) { return NT_STATUS_NO_MEMORY; } - for (i=ofs=0; iout.num_changes; i++) { - parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); + for (i=ofs=0; inotify.out.num_changes; i++) { + parms->notify.out.changes[i].action = IVAL(nt.out.params.data, ofs+4); smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, - &parms->out.changes[i].name, + &parms->notify.out.changes[i].name, ofs+8, ofs+12, STR_UNICODE); ofs += IVAL(nt.out.params.data, ofs); } diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index d9fe3fdce0..00dc71971e 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -41,7 +41,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea bigoffset = True; } SETUP_REQUEST(SMBreadbraw, bigoffset? 10:8, 0); - SSVAL(req->out.vwv, VWV(0), parms->readbraw.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->readbraw.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->readbraw.in.offset); SSVAL(req->out.vwv, VWV(3), parms->readbraw.in.maxcnt); SSVAL(req->out.vwv, VWV(4), parms->readbraw.in.mincnt); @@ -54,7 +54,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea case RAW_READ_LOCKREAD: SETUP_REQUEST(SMBlockread, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->lockread.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->lockread.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->lockread.in.count); SIVAL(req->out.vwv, VWV(2), parms->lockread.in.offset); SSVAL(req->out.vwv, VWV(4), parms->lockread.in.remaining); @@ -62,7 +62,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea case RAW_READ_READ: SETUP_REQUEST(SMBread, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->read.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->read.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->read.in.count); SIVAL(req->out.vwv, VWV(2), parms->read.in.offset); SSVAL(req->out.vwv, VWV(4), parms->read.in.remaining); @@ -75,7 +75,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - SSVAL(req->out.vwv, VWV(2), parms->readx.in.fnum); + SSVAL(req->out.vwv, VWV(2), parms->readx.file.fnum); SIVAL(req->out.vwv, VWV(3), parms->readx.in.offset); SSVAL(req->out.vwv, VWV(5), parms->readx.in.maxcnt & 0xFFFF); SSVAL(req->out.vwv, VWV(6), parms->readx.in.mincnt); @@ -183,7 +183,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr switch (parms->generic.level) { case RAW_WRITE_WRITEUNLOCK: SETUP_REQUEST(SMBwriteunlock, 5, 3 + parms->writeunlock.in.count); - SSVAL(req->out.vwv, VWV(0), parms->writeunlock.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->writeunlock.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeunlock.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeunlock.in.offset); SSVAL(req->out.vwv, VWV(4), parms->writeunlock.in.remaining); @@ -197,7 +197,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_WRITE: SETUP_REQUEST(SMBwrite, 5, 3 + parms->write.in.count); - SSVAL(req->out.vwv, VWV(0), parms->write.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->write.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->write.in.count); SIVAL(req->out.vwv, VWV(2), parms->write.in.offset); SSVAL(req->out.vwv, VWV(4), parms->write.in.remaining); @@ -210,7 +210,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_WRITECLOSE: SETUP_REQUEST(SMBwriteclose, 6, 1 + parms->writeclose.in.count); - SSVAL(req->out.vwv, VWV(0), parms->writeclose.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->writeclose.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeclose.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeclose.in.offset); raw_push_dos_date3(tree->session->transport, @@ -229,7 +229,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - SSVAL(req->out.vwv, VWV(2), parms->writex.in.fnum); + SSVAL(req->out.vwv, VWV(2), parms->writex.file.fnum); SIVAL(req->out.vwv, VWV(3), parms->writex.in.offset); SIVAL(req->out.vwv, VWV(5), 0); /* reserved */ SSVAL(req->out.vwv, VWV(7), parms->writex.in.wmode); @@ -247,7 +247,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_SPLWRITE: SETUP_REQUEST(SMBsplwr, 1, parms->splwrite.in.count); - SSVAL(req->out.vwv, VWV(0), parms->splwrite.in.fnum); + SSVAL(req->out.vwv, VWV(0), parms->splwrite.file.fnum); if (parms->splwrite.in.count > 0) { memcpy(req->out.data, parms->splwrite.in.data, parms->splwrite.in.count); } diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index e406fdf45c..3710fdfa08 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -118,14 +118,14 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi ZERO_STRUCT(b); b.in.max_response_size = 0x10000; - b.in.handle = io->generic.in.handle; + b.in.handle = io->generic.file.handle; b.in.level = smb2_level; if (io->generic.level == RAW_FILEINFO_SEC_DESC) { - b.in.flags = io->query_secdesc.secinfo_flags; + b.in.flags = io->query_secdesc.in.secinfo_flags; } if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) { - b.in.flags2 = io->all_eas.continue_flags; + b.in.flags2 = io->all_eas.in.continue_flags; } return smb2_getinfo_send(tree, &b); diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index 0a5b56b90d..b09acfaf63 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -37,8 +37,8 @@ static NTSTATUS appendacl_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; - state->io_fileinfo->query_secdesc.in.fnum = state->io_open->ntcreatex.out.fnum; - state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; + state->io_fileinfo->query_secdesc.file.fnum = state->io_open->ntcreatex.file.fnum; + state->io_fileinfo->query_secdesc.in.secinfo_flags = SECINFO_DACL; state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); NT_STATUS_HAVE_NO_MEMORY(state->req); @@ -69,7 +69,7 @@ static NTSTATUS appendacl_get(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo); state->io_setfileinfo->set_secdesc.level = RAW_SFILEINFO_SEC_DESC; - state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.in.fnum; + state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.file.fnum; state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL; state->io_setfileinfo->set_secdesc.in.sd = state->io_fileinfo->query_secdesc.out.sd; @@ -115,8 +115,8 @@ static NTSTATUS appendacl_set(struct composite_context *c, state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; - state->io_fileinfo->query_secdesc.in.fnum = state->io_setfileinfo->set_secdesc.file.fnum; - state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL; + state->io_fileinfo->query_secdesc.file.fnum = state->io_setfileinfo->set_secdesc.file.fnum; + state->io_fileinfo->query_secdesc.in.secinfo_flags = SECINFO_DACL; state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); NT_STATUS_HAVE_NO_MEMORY(state->req); @@ -150,7 +150,7 @@ static NTSTATUS appendacl_getagain(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_close); io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = state->io_fileinfo->query_secdesc.in.fnum; + io_close->close.file.fnum = state->io_fileinfo->query_secdesc.file.fnum; io_close->close.in.write_time = 0; state->req = smb_raw_close_send(tree, io_close); diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index 2551b6da9e..9a593c0726 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -54,7 +54,7 @@ static NTSTATUS setup_close(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_close); io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = fnum; + io_close->close.file.fnum = fnum; io_close->close.in.write_time = 0; state->req = smb_raw_close_send(tree, io_close); @@ -93,7 +93,7 @@ static NTSTATUS loadfile_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io->out.data); if (io->out.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); + return setup_close(c, tree, state->io_open->ntcreatex.file.fnum); } /* setup for the read */ @@ -101,7 +101,7 @@ static NTSTATUS loadfile_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(state->io_read); state->io_read->readx.level = RAW_READ_READX; - state->io_read->readx.in.fnum = state->io_open->ntcreatex.out.fnum; + state->io_read->readx.file.fnum = state->io_open->ntcreatex.file.fnum; state->io_read->readx.in.offset = 0; state->io_read->readx.in.mincnt = MIN(32768, io->out.size); state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; @@ -139,7 +139,7 @@ static NTSTATUS loadfile_read(struct composite_context *c, /* we might be done */ if (state->io_read->readx.in.offset + state->io_read->readx.out.nread == io->out.size) { - return setup_close(c, tree, state->io_read->readx.in.fnum); + return setup_close(c, tree, state->io_read->readx.file.fnum); } /* setup for the next read */ diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c index 9600af97d2..89a2d26c0c 100644 --- a/source4/libcli/smb_composite/savefile.c +++ b/source4/libcli/smb_composite/savefile.c @@ -55,7 +55,7 @@ static NTSTATUS setup_close(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_close); io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = fnum; + io_close->close.file.fnum = fnum; io_close->close.in.write_time = 0; state->req = smb_raw_close_send(tree, io_close); @@ -86,7 +86,7 @@ static NTSTATUS savefile_open(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); if (io->in.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); + return setup_close(c, tree, state->io_open->ntcreatex.file.fnum); } /* setup for the first write */ @@ -94,7 +94,7 @@ static NTSTATUS savefile_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_write); io_write->writex.level = RAW_WRITE_WRITEX; - io_write->writex.in.fnum = state->io_open->ntcreatex.out.fnum; + io_write->writex.file.fnum = state->io_open->ntcreatex.file.fnum; io_write->writex.in.offset = 0; io_write->writex.in.wmode = 0; io_write->writex.in.remaining = 0; @@ -135,7 +135,7 @@ static NTSTATUS savefile_write(struct composite_context *c, /* we might be done */ if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count || state->total_written == io->in.size) { - return setup_close(c, tree, state->io_write->writex.in.fnum); + return setup_close(c, tree, state->io_write->writex.file.fnum); } /* setup for the next write */ -- cgit From e5e10ca55ce94d371dc507b2cbb23e70440c9332 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Mar 2006 21:38:07 +0000 Subject: r14174: fix typos metze (This used to be commit 29240bae4488749b3f8a2b49bccad1601d1aa184) --- source4/libcli/raw/rawsetfileinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 5779cf33fb..73fcd82802 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -283,7 +283,7 @@ static struct smbcli_request *smb_raw_setattr_send(struct smbcli_tree *tree, raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->setattr.in.write_time); memset(req->out.vwv + VWV(3), 0, 10); /* reserved */ - smbcli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->setattr.file.path, STR_TERMINATE); smbcli_req_append_ascii4(req, "", STR_TERMINATE); if (!smbcli_request_send(req)) { @@ -399,7 +399,7 @@ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, /* send request and process the output */ req = smb_raw_setpathinfo_blob_send(tree, mem_ctx, - parms->generic.file.fname, + parms->generic.file.path, parms->generic.level, &blob); -- cgit From 32b0bb64bcb91a3f08fcaea72b89bf6409d0e67c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 11 Mar 2006 10:25:59 +0000 Subject: r14205: move smb specific stuff out of includes.h (finally!!!:-) all this changes really help ccache to speed up the samba4 build:-) metze (This used to be commit 180a79d1036e54fc0c50572b820818e9aafa28e9) --- source4/libcli/raw/interfaces.h | 71 ++++++++++++-------------------- source4/libcli/raw/raweas.c | 1 + source4/libcli/raw/rawlpq.c | 1 + source4/libcli/raw/rawrequest.c | 4 +- source4/libcli/smb_composite/fetchfile.c | 1 + 5 files changed, 32 insertions(+), 46 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 0505078fd4..e476a00b68 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -34,27 +34,10 @@ is always determined by NULL or packet termination a normal char* is used in the structure definition. */ -typedef struct { +struct smb_wire_string { uint32_t private_length; const char *s; -} WIRE_STRING; - - -/* - use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really - just a dom sid, but with the sub_auths represented as a conformant - array. As with all in-structure conformant arrays, the array length - is placed before the start of the structure. That's what gives rise - to the extra num_auths elemenent. We don't want the Samba code to - have to bother with such esoteric NDR details, so its easier to just - define it as a dom_sid and use pidl magic to make it all work. It - just means you need to mark a sid as a "dom_sid2" in the IDL when you - know it is of the conformant array variety -*/ -#define dom_sid2 dom_sid - -/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ -#define dom_sid28 dom_sid +}; /* a generic container for file handles @@ -368,7 +351,7 @@ union smb_fileinfo { uint_t num_eas; struct ea_struct { uint8_t flags; - WIRE_STRING name; + struct smb_wire_string name; DATA_BLOB value; } *eas; NTTIME create_time; @@ -378,8 +361,8 @@ union smb_fileinfo { uint64_t alloc_size; uint64_t size; uint32_t nlink; - WIRE_STRING fname; - WIRE_STRING alt_fname; + struct smb_wire_string fname; + struct smb_wire_string alt_fname; uint8_t delete_pending; uint8_t directory; uint64_t compressed_size; @@ -397,7 +380,7 @@ union smb_fileinfo { struct stream_struct { uint64_t size; uint64_t alloc_size; - WIRE_STRING stream_name; + struct smb_wire_string stream_name; } *streams; } out; } generic; @@ -455,7 +438,7 @@ union smb_fileinfo { struct { uint_t num_names; struct ea_name { - WIRE_STRING name; + struct smb_wire_string name; } *ea_names; } in; @@ -528,7 +511,7 @@ union smb_fileinfo { union smb_file file; struct { - WIRE_STRING fname; + struct smb_wire_string fname; } out; } name_info; @@ -549,7 +532,7 @@ union smb_fileinfo { uint8_t delete_pending; uint8_t directory; uint32_t ea_size; - WIRE_STRING fname; + struct smb_wire_string fname; } out; } all_info; @@ -576,7 +559,7 @@ union smb_fileinfo { uint32_t access_mask; uint64_t position; uint64_t mode; - WIRE_STRING fname; + struct smb_wire_string fname; } out; } all_info2; @@ -586,7 +569,7 @@ union smb_fileinfo { union smb_file file; struct { - WIRE_STRING fname; + struct smb_wire_string fname; } out; } alt_name_info; @@ -643,7 +626,7 @@ union smb_fileinfo { union smb_file file; struct { - WIRE_STRING link_dest; + struct smb_wire_string link_dest; } out; } unix_link_info; @@ -1009,7 +992,7 @@ union smb_fsinfo { struct { uint32_t serial_number; - WIRE_STRING volume_name; + struct smb_wire_string volume_name; } out; } volume; @@ -1021,7 +1004,7 @@ union smb_fsinfo { struct { NTTIME create_time; uint32_t serial_number; - WIRE_STRING volume_name; + struct smb_wire_string volume_name; } out; } volume_info; @@ -1058,7 +1041,7 @@ union smb_fsinfo { struct { uint32_t fs_attr; uint32_t max_file_component_length; - WIRE_STRING fs_type; + struct smb_wire_string fs_type; } out; } attribute_info; @@ -1741,7 +1724,7 @@ union smb_notify { uint32_t num_changes; struct notify_changes { uint32_t action; - WIRE_STRING name; + struct smb_wire_string name; } *changes; } out; } notify; @@ -1876,7 +1859,7 @@ union smb_search_data { uint32_t size; uint32_t alloc_size; uint16_t attrib; - WIRE_STRING name; + struct smb_wire_string name; } standard; /* trans2 findfirst RAW_SEARCH_EA_SIZE level */ @@ -1889,7 +1872,7 @@ union smb_search_data { uint32_t alloc_size; uint16_t attrib; uint32_t ea_size; - WIRE_STRING name; + struct smb_wire_string name; } ea_size; /* trans2 findfirst RAW_SEARCH_EA_LIST level */ @@ -1902,7 +1885,7 @@ union smb_search_data { uint32_t alloc_size; uint16_t attrib; struct smb_ea_list eas; - WIRE_STRING name; + struct smb_wire_string name; } ea_list; /* RAW_SEARCH_DIRECTORY_INFO interface */ @@ -1915,7 +1898,7 @@ union smb_search_data { uint64_t size; uint64_t alloc_size; uint32_t attrib; - WIRE_STRING name; + struct smb_wire_string name; } directory_info; /* RAW_SEARCH_FULL_DIRECTORY_INFO interface */ @@ -1929,13 +1912,13 @@ union smb_search_data { uint64_t alloc_size; uint32_t attrib; uint32_t ea_size; - WIRE_STRING name; + struct smb_wire_string name; } full_directory_info; /* RAW_SEARCH_NAME_INFO interface */ struct { uint32_t file_index; - WIRE_STRING name; + struct smb_wire_string name; } name_info; /* RAW_SEARCH_BOTH_DIRECTORY_INFO interface */ @@ -1949,8 +1932,8 @@ union smb_search_data { uint64_t alloc_size; uint32_t attrib; uint32_t ea_size; - WIRE_STRING short_name; - WIRE_STRING name; + struct smb_wire_string short_name; + struct smb_wire_string name; } both_directory_info; /* RAW_SEARCH_ID_FULL_DIRECTORY_INFO interface */ @@ -1965,7 +1948,7 @@ union smb_search_data { uint32_t attrib; uint32_t ea_size; uint64_t file_id; - WIRE_STRING name; + struct smb_wire_string name; } id_full_directory_info; /* RAW_SEARCH_ID_BOTH_DIRECTORY_INFO interface */ @@ -1980,8 +1963,8 @@ union smb_search_data { uint32_t attrib; uint32_t ea_size; uint64_t file_id; - WIRE_STRING short_name; - WIRE_STRING name; + struct smb_wire_string short_name; + struct smb_wire_string name; } id_both_directory_info; /* RAW_SEARCH_UNIX_INFO interface */ diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 4ab3344135..4c609aa593 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "smb.h" /* work out how many bytes on the wire a ea list will consume. diff --git a/source4/libcli/raw/rawlpq.c b/source4/libcli/raw/rawlpq.c index 40669e51de..882ed3c302 100644 --- a/source4/libcli/raw/rawlpq.c +++ b/source4/libcli/raw/rawlpq.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "smb.h" /**************************************************************************** lpq - async send diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index cd76e0e438..b07a92e3fa 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -827,7 +827,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, } /* - pull a string from a blob, returning a talloced WIRE_STRING + pull a string from a blob, returning a talloced struct smb_wire_string the string length is limited by the 3 things: - the data size in the blob @@ -843,7 +843,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, size_t smbcli_blob_pull_string(struct smbcli_session *session, TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - WIRE_STRING *dest, + struct smb_wire_string *dest, uint16_t len_offset, uint16_t str_offset, uint_t flags) { diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 5783a3258f..6ad70a3af7 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "smb.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" -- cgit From 7f0c7702f6b9db216fcd6c29165b2a11ea1f24a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Mar 2006 12:58:36 +0000 Subject: r14208: removed use of req->flags2 inside the ntvfs layer. This should help metze on his quest to unify the ntvfs strucures for the smb and smb2 servers. The only place we needed flags2 inside ntvfs was for the FLAGS2_READ_PERMIT_EXECUTE bit, which only affects readx, so I added a readx.in.read_for_execute flag instead. (This used to be commit b78abbbce60ab0009da19a72dd769800c44298a2) --- source4/libcli/clireadwrite.c | 1 + source4/libcli/raw/interfaces.h | 1 + source4/libcli/raw/rawreadwrite.c | 3 +++ source4/libcli/smb_composite/loadfile.c | 1 + 4 files changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index afffba968a..03d1864a5d 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -56,6 +56,7 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset parms.readx.in.mincnt = readsize; parms.readx.in.maxcnt = readsize; parms.readx.in.remaining = size - total; + parms.readx.in.read_for_execute = False; parms.readx.out.data = buf + total; status = smb_raw_read(tree, &parms); diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index e476a00b68..086686b9e9 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1352,6 +1352,7 @@ union smb_read { uint16_t mincnt; uint32_t maxcnt; uint16_t remaining; + BOOL read_for_execute; } in; struct { uint8_t *data; diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 00dc71971e..c4e2ab2498 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -84,6 +84,9 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea if (bigoffset) { SIVAL(req->out.vwv, VWV(10),parms->readx.in.offset>>32); } + if (parms->readx.in.read_for_execute) { + req->flags2 |= FLAGS2_READ_PERMIT_EXECUTE; + } break; } diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index 9a593c0726..db074bfd2b 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -106,6 +106,7 @@ static NTSTATUS loadfile_open(struct composite_context *c, state->io_read->readx.in.mincnt = MIN(32768, io->out.size); state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; state->io_read->readx.in.remaining = 0; + state->io_read->readx.in.read_for_execute = False; state->io_read->readx.out.data = io->out.data; state->req = smb_raw_read_send(tree, state->io_read); -- cgit From 66e3a63c19b3541c439778ad3d8cab1d8acf29d4 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Sun, 12 Mar 2006 13:14:21 +0000 Subject: r14239: Fix indentation. rafal (This used to be commit 7aa90f58b9beb410a188fd229c539f2315c81a38) --- source4/libcli/composite/composite.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index d0d2bc3886..c8d6cd136a 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -115,9 +115,9 @@ _PUBLIC_ void composite_done(struct composite_context *ctx) } _PUBLIC_ void composite_continue(struct composite_context *ctx, - struct composite_context *new_ctx, - void (*continuation)(struct composite_context *), - void *private_data) + struct composite_context *new_ctx, + void (*continuation)(struct composite_context *), + void *private_data) { if (composite_nomem(new_ctx, ctx)) return; new_ctx->async.fn = continuation; @@ -125,9 +125,9 @@ _PUBLIC_ void composite_continue(struct composite_context *ctx, } _PUBLIC_ void composite_continue_rpc(struct composite_context *ctx, - struct rpc_request *new_req, - void (*continuation)(struct rpc_request *), - void *private_data) + struct rpc_request *new_req, + void (*continuation)(struct rpc_request *), + void *private_data) { if (composite_nomem(new_req, ctx)) return; new_req->async.callback = continuation; @@ -135,9 +135,9 @@ _PUBLIC_ void composite_continue_rpc(struct composite_context *ctx, } _PUBLIC_ void composite_continue_irpc(struct composite_context *ctx, - struct irpc_request *new_req, - void (*continuation)(struct irpc_request *), - void *private_data) + struct irpc_request *new_req, + void (*continuation)(struct irpc_request *), + void *private_data) { if (composite_nomem(new_req, ctx)) return; new_req->async.fn = continuation; @@ -145,9 +145,9 @@ _PUBLIC_ void composite_continue_irpc(struct composite_context *ctx, } _PUBLIC_ void composite_continue_smb(struct composite_context *ctx, - struct smbcli_request *new_req, - void (*continuation)(struct smbcli_request *), - void *private_data) + struct smbcli_request *new_req, + void (*continuation)(struct smbcli_request *), + void *private_data) { if (composite_nomem(new_req, ctx)) return; new_req->async.fn = continuation; @@ -155,9 +155,9 @@ _PUBLIC_ void composite_continue_smb(struct composite_context *ctx, } _PUBLIC_ void composite_continue_nbt(struct composite_context *ctx, - struct nbt_name_request *new_req, - void (*continuation)(struct nbt_name_request *), - void *private_data) + struct nbt_name_request *new_req, + void (*continuation)(struct nbt_name_request *), + void *private_data) { if (composite_nomem(new_req, ctx)) return; new_req->async.fn = continuation; -- cgit From a1b295ed4823ce8d06f830b8db9a5d965c934b54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Mar 2006 22:48:25 +0000 Subject: r14256: - rename smb_file -> smb_handle - move it into the in/out substructs again - allow file.path only on smb_fileinfo/smb_setfileinfo metze (This used to be commit be6d5298a2cdb7e7c61d70471bad445645af5963) --- source4/libcli/clifile.c | 32 ++-- source4/libcli/clireadwrite.c | 6 +- source4/libcli/clitrans2.c | 10 +- source4/libcli/raw/interfaces.h | 291 +++++++++++++++++-------------- source4/libcli/raw/rawacl.c | 4 +- source4/libcli/raw/rawfile.c | 34 ++-- source4/libcli/raw/rawfileinfo.c | 8 +- source4/libcli/raw/rawioctl.c | 4 +- source4/libcli/raw/rawnotify.c | 2 +- source4/libcli/raw/rawreadwrite.c | 18 +- source4/libcli/raw/rawsetfileinfo.c | 8 +- source4/libcli/smb2/getinfo.c | 2 +- source4/libcli/smb2/setinfo.c | 2 +- source4/libcli/smb_composite/appendacl.c | 8 +- source4/libcli/smb_composite/loadfile.c | 8 +- source4/libcli/smb_composite/savefile.c | 8 +- 16 files changed, 237 insertions(+), 208 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index d3de0dab77..cc0c14a2e8 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -38,11 +38,11 @@ static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, if (hard_link) { parms.generic.level = RAW_SFILEINFO_UNIX_HLINK; - parms.unix_hlink.file.path = fname_src; + parms.unix_hlink.in.file.path = fname_src; parms.unix_hlink.in.link_dest = fname_dst; } else { parms.generic.level = RAW_SFILEINFO_UNIX_LINK; - parms.unix_link.file.path = fname_src; + parms.unix_link.in.file.path = fname_src; parms.unix_link.in.link_dest = fname_dst; } @@ -110,7 +110,7 @@ static NTSTATUS smbcli_unix_chmod_chown_internal(struct smbcli_tree *tree, NTSTATUS status; parms.generic.level = SMB_SFILEINFO_UNIX_BASIC; - parms.unix_basic.file.path = fname; + parms.unix_basic.in.file.path = fname; parms.unix_basic.in.uid = uid; parms.unix_basic.in.gid = gid; parms.unix_basic.in.mode = mode; @@ -213,7 +213,7 @@ NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum, BOOL flag NTSTATUS status; parms.disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFO; - parms.disposition_info.file.fnum = fnum; + parms.disposition_info.in.file.fnum = fnum; parms.disposition_info.in.delete_on_close = flag; status = smb_raw_setfileinfo(tree, &parms); @@ -256,7 +256,7 @@ int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname, talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { - return open_parms.ntcreatex.file.fnum; + return open_parms.ntcreatex.out.file.fnum; } return -1; @@ -323,7 +323,7 @@ int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { - return open_parms.openx.file.fnum; + return open_parms.openx.out.file.fnum; } return -1; @@ -339,7 +339,7 @@ NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum) NTSTATUS status; close_parms.close.level = RAW_CLOSE_CLOSE; - close_parms.close.file.fnum = fnum; + close_parms.close.in.file.fnum = fnum; close_parms.close.in.write_time = 0; status = smb_raw_close(tree, &close_parms); return status; @@ -358,7 +358,7 @@ NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum, NTSTATUS status; parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.file.fnum = fnum; + parms.lockx.in.file.fnum = fnum; parms.lockx.in.mode = locktype; parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; @@ -386,7 +386,7 @@ NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum, NTSTATUS status; parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.file.fnum = fnum; + parms.lockx.in.file.fnum = fnum; parms.lockx.in.mode = (lock_type == READ_LOCK? 1 : 0); parms.lockx.in.timeout = timeout; parms.lockx.in.ulock_cnt = 0; @@ -412,7 +412,7 @@ NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint NTSTATUS status; parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.file.fnum = fnum; + parms.lockx.in.file.fnum = fnum; parms.lockx.in.mode = 0; parms.lockx.in.timeout = 0; parms.lockx.in.ulock_cnt = 1; @@ -444,7 +444,7 @@ NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, } parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.file.fnum = fnum; + parms.lockx.in.file.fnum = fnum; ltype = (lock_type == READ_LOCK? 1 : 0); ltype |= LOCKING_ANDX_LARGE_FILES; @@ -478,7 +478,7 @@ NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset, } parms.lockx.level = RAW_LOCK_LOCKX; - parms.lockx.file.fnum = fnum; + parms.lockx.in.file.fnum = fnum; parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; parms.lockx.in.timeout = 0; parms.lockx.in.ulock_cnt = 1; @@ -505,7 +505,7 @@ NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum, NTSTATUS status; parms.getattre.level = RAW_FILEINFO_GETATTRE; - parms.getattre.file.fnum = fnum; + parms.getattre.in.file.fnum = fnum; status = smb_raw_fileinfo(tree, NULL, &parms); @@ -545,7 +545,7 @@ NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname, NTSTATUS status; parms.getattr.level = RAW_FILEINFO_GETATTR; - parms.getattr.file.path = fname; + parms.getattr.in.file.path = fname; status = smb_raw_pathinfo(tree, NULL, &parms); @@ -579,7 +579,7 @@ NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mod NTSTATUS status; parms.setattr.level = RAW_SFILEINFO_SETATTR; - parms.setattr.file.path = fname; + parms.setattr.in.file.path = fname; parms.setattr.in.attrib = mode; parms.setattr.in.write_time = t; @@ -663,7 +663,7 @@ int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path) } talloc_free(mem_ctx); if (NT_STATUS_IS_OK(status)) { - return open_parms.ctemp.file.fnum; + return open_parms.ctemp.out.file.fnum; } return -1; } diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 03d1864a5d..afffeadeff 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -38,7 +38,7 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset } parms.readx.level = RAW_READ_READX; - parms.readx.file.fnum = fnum; + parms.readx.in.file.fnum = fnum; /* * Set readsize to the maximum size we can handle in one readX, @@ -101,7 +101,7 @@ ssize_t smbcli_write(struct smbcli_tree *tree, parms.writex.level = RAW_WRITE_WRITEX; - parms.writex.file.fnum = fnum; + parms.writex.in.file.fnum = fnum; parms.writex.in.wmode = write_mode; parms.writex.in.remaining = 0; @@ -145,7 +145,7 @@ ssize_t smbcli_smbwrite(struct smbcli_tree *tree, size_t size = MIN(size1, tree->session->transport->negotiate.max_xmit - 48); if (size > 0xFFFF) size = 0xFFFF; - parms.write.file.fnum = fnum; + parms.write.in.file.fnum = fnum; parms.write.in.offset = offset; parms.write.in.count = size; parms.write.in.data = buf + total; diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index f8699e0191..9418c10538 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -36,7 +36,7 @@ NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname, if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.standard.level = RAW_FILEINFO_STANDARD; - parms.standard.file.path = fname; + parms.standard.in.file.path = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_free(mem_ctx); @@ -78,7 +78,7 @@ NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname, if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; - parms.all_info.file.path = fname; + parms.all_info.in.file.path = fname; status = smb_raw_pathinfo(tree, mem_ctx, &parms); talloc_free(mem_ctx); @@ -121,7 +121,7 @@ NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name) if (!mem_ctx) return NT_STATUS_NO_MEMORY; parms.name_info.level = RAW_FILEINFO_NAME_INFO; - parms.name_info.file.fnum = fnum; + parms.name_info.in.file.fnum = fnum; status = smb_raw_fileinfo(tree, mem_ctx, &parms); if (!NT_STATUS_IS_OK(status)) { @@ -155,7 +155,7 @@ NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum, return NT_STATUS_NO_MEMORY; parms.all_info.level = RAW_FILEINFO_ALL_INFO; - parms.all_info.file.fnum = fnum; + parms.all_info.in.file.fnum = fnum; status = smb_raw_fileinfo(tree, mem_ctx, &parms); talloc_free(mem_ctx); @@ -200,7 +200,7 @@ NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname, NTSTATUS status; parms.alt_name_info.level = RAW_FILEINFO_ALT_NAME_INFO; - parms.alt_name_info.file.path = fname; + parms.alt_name_info.in.file.path = fname; mem_ctx = talloc_init("smbcli_qpathinfo_alt_name"); if (!mem_ctx) return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 086686b9e9..20b729caba 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -40,16 +40,45 @@ struct smb_wire_string { }; /* - a generic container for file handles + * SMB2 uses a 16Byte handle, + * (we can maybe use struct GUID later) + */ +struct smb2_handle { + uint64_t data[2]; +}; + +/* + * a generic container for file handles or file pathes + * for qfileinfo/setfileinfo and qpathinfo/setpathinfo */ -union smb_file { +union smb_handle_or_path { /* - * this is only used for + * this is used for * the qpathinfo and setpathinfo * calls */ const char *path; + /* + * this is used as file handle in SMB + */ + uint16_t fnum; + /* + * this is used as file handle in SMB2 + */ + struct smb2_handle handle; +}; + +/* + a generic container for file handles +*/ +union smb_handle { + /* + * this is used for + * the qpathinfo and setpathinfo + * calls + */ + const char *path; /* * this is used as file handle in SMB */ @@ -58,9 +87,7 @@ union smb_file { /* * this is used as file handle in SMB2 */ - struct smb2_handle { - uint64_t data[2]; - } handle; + struct smb2_handle handle; }; /* @@ -71,8 +98,8 @@ union smb_file { /* struct used for SMBlseek call */ union smb_seek { struct { - union smb_file file; struct { + union smb_handle file; uint16_t mode; int32_t offset; /* signed */ } in; @@ -343,8 +370,9 @@ union smb_fileinfo { * matches RAW_FILEINFO_GENERIC */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint32_t attrib; uint32_t ea_size; @@ -390,8 +418,9 @@ union smb_fileinfo { * matches RAW_FILEINFO_GETATTR */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint16_t attrib; uint32_t size; @@ -402,8 +431,9 @@ union smb_fileinfo { /* SMBgetattrE and RAW_FILEINFO_STANDARD interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { time_t create_time; time_t access_time; @@ -417,8 +447,9 @@ union smb_fileinfo { /* trans2 RAW_FILEINFO_EA_SIZE interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { time_t create_time; time_t access_time; @@ -433,9 +464,8 @@ union smb_fileinfo { /* trans2 RAW_FILEINFO_EA_LIST interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - struct { + union smb_handle_or_path file; uint_t num_names; struct ea_name { struct smb_wire_string name; @@ -451,8 +481,8 @@ union smb_fileinfo { /* trans2 RAW_FILEINFO_ALL_EAS and RAW_FILEINFO_FULL_EA_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; /* SMB2 only - SMB2_CONTINUE_FLAG_* */ uint8_t continue_flags; } in; @@ -463,14 +493,17 @@ union smb_fileinfo { only valid for a QPATHNAME call - no returned data */ struct { enum smb_fileinfo_level level; - union smb_file file; + struct { + union smb_handle_or_path file; + } in; } is_name_valid; /* RAW_FILEINFO_BASIC_INFO and RAW_FILEINFO_BASIC_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { NTTIME create_time; NTTIME access_time; @@ -484,8 +517,9 @@ union smb_fileinfo { /* RAW_FILEINFO_STANDARD_INFO and RAW_FILEINFO_STANDARD_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint64_t alloc_size; uint64_t size; @@ -498,8 +532,9 @@ union smb_fileinfo { /* RAW_FILEINFO_EA_INFO and RAW_FILEINFO_EA_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint32_t ea_size; } out; @@ -508,8 +543,9 @@ union smb_fileinfo { /* RAW_FILEINFO_NAME_INFO and RAW_FILEINFO_NAME_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { struct smb_wire_string fname; } out; @@ -518,8 +554,9 @@ union smb_fileinfo { /* RAW_FILEINFO_ALL_INFO and RAW_FILEINFO_ALL_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { NTTIME create_time; NTTIME access_time; @@ -539,8 +576,9 @@ union smb_fileinfo { /* RAW_FILEINFO_SMB2_ALL_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { NTTIME create_time; NTTIME access_time; @@ -561,13 +599,14 @@ union smb_fileinfo { uint64_t mode; struct smb_wire_string fname; } out; - } all_info2; + } all_info2; /* RAW_FILEINFO_ALT_NAME_INFO and RAW_FILEINFO_ALT_NAME_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { struct smb_wire_string fname; } out; @@ -576,8 +615,9 @@ union smb_fileinfo { /* RAW_FILEINFO_STREAM_INFO and RAW_FILEINFO_STREAM_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct stream_information { uint_t num_streams; struct stream_struct *streams; @@ -587,8 +627,9 @@ union smb_fileinfo { /* RAW_FILEINFO_COMPRESSION_INFO and RAW_FILEINFO_COMPRESSION_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint64_t compressed_size; uint16_t format; @@ -601,8 +642,9 @@ union smb_fileinfo { /* RAW_FILEINFO_UNIX_BASIC interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint64_t end_of_file; uint64_t num_bytes; @@ -623,8 +665,9 @@ union smb_fileinfo { /* RAW_FILEINFO_UNIX_LINK interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { struct smb_wire_string link_dest; } out; @@ -633,8 +676,9 @@ union smb_fileinfo { /* RAW_FILEINFO_INTERNAL_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint64_t file_id; } out; @@ -643,8 +687,9 @@ union smb_fileinfo { /* RAW_FILEINFO_ACCESS_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint32_t access_flags; } out; @@ -653,8 +698,9 @@ union smb_fileinfo { /* RAW_FILEINFO_POSITION_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint64_t position; } out; @@ -663,8 +709,9 @@ union smb_fileinfo { /* RAW_FILEINFO_MODE_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint32_t mode; } out; @@ -673,8 +720,9 @@ union smb_fileinfo { /* RAW_FILEINFO_ALIGNMENT_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint32_t alignment_requirement; } out; @@ -683,8 +731,9 @@ union smb_fileinfo { /* RAW_FILEINFO_NETWORK_OPEN_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { NTTIME create_time; NTTIME access_time; @@ -700,8 +749,9 @@ union smb_fileinfo { /* RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION interface */ struct { enum smb_fileinfo_level level; - union smb_file file; - + struct { + union smb_handle_or_path file; + } in; struct { uint32_t attrib; uint32_t reparse_tag; @@ -711,8 +761,8 @@ union smb_fileinfo { /* RAW_FILEINFO_SEC_DESC */ struct { enum smb_fileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint32_t secinfo_flags; } in; struct { @@ -756,15 +806,16 @@ union smb_setfileinfo { /* generic interface */ struct { enum smb_setfileinfo_level level; - - union smb_file file; + struct { + union smb_handle_or_path file; + } in; } generic; /* RAW_SFILEINFO_SETATTR (SMBsetatr) interface - only via setpathinfo() */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint16_t attrib; time_t write_time; } in; @@ -774,8 +825,8 @@ union smb_setfileinfo { also RAW_SFILEINFO_STANDARD */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; time_t create_time; time_t access_time; time_t write_time; @@ -787,8 +838,8 @@ union smb_setfileinfo { /* RAW_SFILEINFO_EA_SET interface */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint_t num_eas; struct ea_struct *eas; } in; @@ -798,8 +849,8 @@ union smb_setfileinfo { RAW_SFILEINFO_BASIC_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; NTTIME create_time; NTTIME access_time; NTTIME write_time; @@ -812,8 +863,8 @@ union smb_setfileinfo { RAW_SFILEINFO_DISPOSITION_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; BOOL delete_on_close; } in; } disposition_info; @@ -822,8 +873,8 @@ union smb_setfileinfo { RAW_SFILEINFO_ALLOCATION_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; /* w2k3 rounds this up to nearest 4096 */ uint64_t alloc_size; } in; @@ -833,8 +884,8 @@ union smb_setfileinfo { RAW_SFILEINFO_END_OF_FILE_INFORMATION interfaces */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint64_t size; } in; } end_of_file_info; @@ -842,8 +893,8 @@ union smb_setfileinfo { /* RAW_SFILEINFO_RENAME_INFORMATION interface */ struct { enum smb_setfileinfo_level level; - union smb_file file; - struct smb_rename_information { + struct { + union smb_handle_or_path file; uint8_t overwrite; uint32_t root_fid; const char *new_name; @@ -853,8 +904,8 @@ union smb_setfileinfo { /* RAW_SFILEINFO_POSITION_INFORMATION interface */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint64_t position; } in; } position_information; @@ -862,8 +913,8 @@ union smb_setfileinfo { /* RAW_SFILEINFO_MODE_INFORMATION interface */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; /* valid values seem to be 0, 2, 4 and 6 */ uint32_t mode; } in; @@ -874,8 +925,8 @@ union smb_setfileinfo { /* RAW_SFILEINFO_UNIX_BASIC interface */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint32_t mode; /* yuck - this field remains to fix compile of libcli/clifile.c */ uint64_t end_of_file; uint64_t num_bytes; @@ -896,8 +947,8 @@ union smb_setfileinfo { /* RAW_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK interface */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; const char *link_dest; } in; } unix_link, unix_hlink; @@ -905,8 +956,8 @@ union smb_setfileinfo { /* RAW_FILEINFO_SET_SEC_DESC */ struct { enum smb_setfileinfo_level level; - union smb_file file; struct { + union smb_handle_or_path file; uint32_t secinfo_flags; struct security_descriptor *sd; } in; @@ -1114,9 +1165,6 @@ union smb_open { /* SMBNTCreateX interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint32_t flags; uint32_t root_fid; @@ -1138,8 +1186,8 @@ union smb_open { struct security_descriptor *sec_desc; struct smb_ea_list *ea_list; } in; - struct { + union smb_handle file; uint8_t oplock_level; uint32_t create_action; NTTIME create_time; @@ -1158,9 +1206,6 @@ union smb_open { /* TRANS2_OPEN interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t flags; uint16_t open_mode; @@ -1174,8 +1219,8 @@ union smb_open { uint_t num_eas; struct ea_struct *eas; } in; - struct { + union smb_handle file; uint16_t attrib; time_t write_time; uint32_t size; @@ -1190,16 +1235,13 @@ union smb_open { /* SMBopen interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t open_mode; uint16_t search_attrs; const char *fname; } in; - struct { + union smb_handle file; uint16_t attrib; time_t write_time; uint32_t size; @@ -1210,9 +1252,6 @@ union smb_open { /* SMBopenX interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t flags; uint16_t open_mode; @@ -1227,6 +1266,7 @@ union smb_open { const char *fname; } in; struct { + union smb_handle file; uint16_t attrib; time_t write_time; uint32_t size; @@ -1243,28 +1283,26 @@ union smb_open { /* SMBmknew interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t attrib; time_t write_time; const char *fname; } in; + struct { + union smb_handle file; + } out; } mknew, create; /* SMBctemp interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t attrib; time_t write_time; const char *directory; } in; struct { + union smb_handle file; /* temp name, relative to directory */ char *name; } out; @@ -1273,23 +1311,20 @@ union smb_open { /* SMBsplopen interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t setup_length; uint16_t mode; const char *ident; } in; + struct { + union smb_handle file; + } out; } splopen; /* chained OpenX/ReadX interface */ struct { enum smb_open_level level; - /* this is the output file handle */ - union smb_file file; - struct { uint16_t flags; uint16_t open_mode; @@ -1310,6 +1345,7 @@ union smb_open { uint16_t remaining; } in; struct { + union smb_handle file; uint16_t attrib; time_t write_time; uint32_t size; @@ -1345,9 +1381,8 @@ union smb_read { /* SMBreadX (and generic) interface */ struct { enum smb_read_level level; - union smb_file file; - struct { + union smb_handle file; uint64_t offset; uint16_t mincnt; uint32_t maxcnt; @@ -1365,9 +1400,8 @@ union smb_read { /* SMBreadbraw interface */ struct { enum smb_read_level level; - union smb_file file; - struct { + union smb_handle file; uint64_t offset; uint16_t maxcnt; uint16_t mincnt; @@ -1383,9 +1417,8 @@ union smb_read { /* SMBlockandread interface */ struct { enum smb_read_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1399,9 +1432,8 @@ union smb_read { /* SMBread interface */ struct { enum smb_read_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1426,9 +1458,8 @@ union smb_write { /* SMBwriteX interface */ struct { enum smb_write_level level; - union smb_file file; - struct { + union smb_handle file; uint64_t offset; uint16_t wmode; uint16_t remaining; @@ -1444,9 +1475,8 @@ union smb_write { /* SMBwriteunlock interface */ struct { enum smb_write_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1460,9 +1490,8 @@ union smb_write { /* SMBwrite interface */ struct { enum smb_write_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t count; uint32_t offset; uint16_t remaining; @@ -1476,9 +1505,8 @@ union smb_write { /* SMBwriteclose interface */ struct { enum smb_write_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t count; uint32_t offset; time_t mtime; @@ -1492,9 +1520,8 @@ union smb_write { /* SMBsplwrite interface */ struct { enum smb_write_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t count; const uint8_t *data; } in; @@ -1513,9 +1540,8 @@ union smb_lock { /* SMBlockingX (and generic) interface */ struct { enum smb_lock_level level; - union smb_file file; - struct { + union smb_handle file; uint16_t mode; uint32_t timeout; uint16_t ulock_cnt; @@ -1531,9 +1557,8 @@ union smb_lock { /* SMBlock and SMBunlock interface */ struct { enum smb_lock_level level; - union smb_file file; - struct { + union smb_handle file; uint32_t count; uint32_t offset; } in; @@ -1552,9 +1577,8 @@ union smb_close { /* SMBclose (and generic) interface */ struct { enum smb_close_level level; - union smb_file file; - struct { + union smb_handle file; time_t write_time; } in; } close, generic; @@ -1562,7 +1586,9 @@ union smb_close { /* SMBsplclose interface - empty! */ struct { enum smb_close_level level; - union smb_file file; + struct { + union smb_handle file; + } in; } splclose; }; @@ -1611,15 +1637,16 @@ union smb_ioctl { /* generic interface */ struct { enum smb_ioctl_level level; - union smb_file file; - + struct { + union smb_handle file; + } in; } generic; /* struct for SMBioctl */ struct { enum smb_ioctl_level level; - union smb_file file; struct { + union smb_handle file; uint32_t request; } in; struct { @@ -1631,8 +1658,8 @@ union smb_ioctl { /* struct for NT ioctl call */ struct { enum smb_ioctl_level level; - union smb_file file; struct { + union smb_handle file; uint32_t function; BOOL fsctl; uint8_t filter; @@ -1646,7 +1673,9 @@ union smb_ioctl { /* struct for SMBflush */ union smb_flush { struct { - union smb_file file; + struct { + union smb_handle file; + } in; } flush; }; @@ -1714,8 +1743,8 @@ struct smb_nttrans { /* struct for nttrans change notify call */ union smb_notify { struct { - union smb_file file; struct { + union smb_handle file; uint32_t buffer_size; uint32_t completion_filter; BOOL recursive; diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 7c0c17b4d7..59ac65a340 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -38,7 +38,7 @@ struct smbcli_request *smb_raw_query_secdesc_send(struct smbcli_tree *tree, nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC; nt.in.setup = NULL; - SSVAL(params, 0, io->query_secdesc.file.fnum); + SSVAL(params, 0, io->query_secdesc.in.file.fnum); SSVAL(params, 2, 0); /* padding */ SIVAL(params, 4, io->query_secdesc.in.secinfo_flags); @@ -123,7 +123,7 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, nt.in.function = NT_TRANSACT_SET_SECURITY_DESC; nt.in.setup = NULL; - SSVAL(params, 0, io->set_secdesc.file.fnum); + SSVAL(params, 0, io->set_secdesc.in.file.fnum); SSVAL(params, 2, 0); /* padding */ SIVAL(params, 4, io->set_secdesc.in.secinfo_flags); diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 0e63fa656f..6f8befebfe 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -234,7 +234,7 @@ static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req, params = nt.out.params.data; parms->ntcreatex.out.oplock_level = CVAL(params, 0); - parms->ntcreatex.file.fnum = SVAL(params, 2); + parms->ntcreatex.out.file.fnum = SVAL(params, 2); parms->ntcreatex.out.create_action = IVAL(params, 4); parms->ntcreatex.out.create_time = smbcli_pull_nttime(params, 12); parms->ntcreatex.out.access_time = smbcli_pull_nttime(params, 20); @@ -406,7 +406,7 @@ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ return NT_STATUS_INFO_LENGTH_MISMATCH; } - parms->t2open.file.fnum = SVAL(t2.out.params.data, VWV(0)); + parms->t2open.out.file.fnum = SVAL(t2.out.params.data, VWV(0)); parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1)); parms->t2open.out.write_time = raw_pull_dos_date3(transport, t2.out.params.data + VWV(2)); parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4)); @@ -572,7 +572,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_OPEN: SMBCLI_CHECK_WCT(req, 7); - parms->openold.file.fnum = SVAL(req->in.vwv, VWV(0)); + parms->openold.out.file.fnum = SVAL(req->in.vwv, VWV(0)); parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1)); parms->openold.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(2)); @@ -582,7 +582,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_OPENX: SMBCLI_CHECK_MIN_WCT(req, 15); - parms->openx.file.fnum = SVAL(req->in.vwv, VWV(2)); + parms->openx.out.file.fnum = SVAL(req->in.vwv, VWV(2)); parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3)); parms->openx.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(4)); @@ -603,29 +603,29 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_MKNEW: SMBCLI_CHECK_WCT(req, 1); - parms->mknew.file.fnum = SVAL(req->in.vwv, VWV(0)); + parms->mknew.out.file.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_CREATE: SMBCLI_CHECK_WCT(req, 1); - parms->create.file.fnum = SVAL(req->in.vwv, VWV(0)); + parms->create.out.file.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_CTEMP: SMBCLI_CHECK_WCT(req, 1); - parms->ctemp.file.fnum = SVAL(req->in.vwv, VWV(0)); + parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0)); smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); break; case RAW_OPEN_SPLOPEN: SMBCLI_CHECK_WCT(req, 1); - parms->splopen.file.fnum = SVAL(req->in.vwv, VWV(0)); + parms->splopen.out.file.fnum = SVAL(req->in.vwv, VWV(0)); break; case RAW_OPEN_NTCREATEX: SMBCLI_CHECK_MIN_WCT(req, 34); parms->ntcreatex.out.oplock_level = CVAL(req->in.vwv, 4); - parms->ntcreatex.file.fnum = SVAL(req->in.vwv, 5); + parms->ntcreatex.out.file.fnum = SVAL(req->in.vwv, 5); parms->ntcreatex.out.create_action = IVAL(req->in.vwv, 7); parms->ntcreatex.out.create_time = smbcli_pull_nttime(req->in.vwv, 11); parms->ntcreatex.out.access_time = smbcli_pull_nttime(req->in.vwv, 19); @@ -644,7 +644,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_OPENX_READX: SMBCLI_CHECK_MIN_WCT(req, 15); - parms->openxreadx.file.fnum = SVAL(req->in.vwv, VWV(2)); + parms->openxreadx.out.file.fnum = SVAL(req->in.vwv, VWV(2)); parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3)); parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport, req->in.vwv + VWV(4)); @@ -706,14 +706,14 @@ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_cl switch (parms->generic.level) { case RAW_CLOSE_CLOSE: SETUP_REQUEST(SMBclose, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->close.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->close.in.file.fnum); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->close.in.write_time); break; case RAW_CLOSE_SPLCLOSE: SETUP_REQUEST(SMBsplclose, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->splclose.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum); SIVAL(req->out.vwv, VWV(1), 0); /* reserved */ break; } @@ -749,14 +749,14 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc switch (parms->generic.level) { case RAW_LOCK_LOCK: SETUP_REQUEST(SMBlock, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->lock.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->lock.in.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->lock.in.count); SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset); break; case RAW_LOCK_UNLOCK: SETUP_REQUEST(SMBunlock, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->unlock.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->unlock.in.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count); SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset); break; @@ -770,7 +770,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - SSVAL(req->out.vwv, VWV(2), parms->lockx.file.fnum); + SSVAL(req->out.vwv, VWV(2), parms->lockx.in.file.fnum); SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode); SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout); SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt); @@ -850,7 +850,7 @@ struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_fl struct smbcli_request *req; SETUP_REQUEST(SMBflush, 1, 0); - SSVAL(req->out.vwv, VWV(0), parms->flush.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->flush.in.file.fnum); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -881,7 +881,7 @@ struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree, SETUP_REQUEST(SMBlseek, 4, 0); - SSVAL(req->out.vwv, VWV(0), parms->lseek.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->lseek.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->lseek.in.mode); SIVALS(req->out.vwv, VWV(2), parms->lseek.in.offset); diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index b50a330093..cf8f2f71b4 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -536,7 +536,7 @@ static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree, req = smbcli_request_setup(tree, SMBgetatr, 0, 0); if (!req) return NULL; - smbcli_req_append_ascii4(req, parms->getattr.file.path, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); @@ -579,7 +579,7 @@ static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree, req = smbcli_request_setup(tree, SMBgetattrE, 1, 0); if (!req) return NULL; - SSVAL(req->out.vwv, VWV(0), parms->getattre.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->getattre.in.file.fnum); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; @@ -647,7 +647,7 @@ struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree, } req = smb_raw_fileinfo_blob_send(tree, - parms->generic.file.fnum, + parms->generic.in.file.fnum, parms->generic.level, data); data_blob_free(&data); @@ -722,7 +722,7 @@ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, } } - req = smb_raw_pathinfo_blob_send(tree, parms->generic.file.path, + req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path, parms->generic.level, data); data_blob_free(&data); diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 28b58ff2a3..db980a55d6 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -37,7 +37,7 @@ static struct smbcli_request *smb_raw_smbioctl_send(struct smbcli_tree *tree, SETUP_REQUEST(SMBioctl, 3, 0); - SSVAL(req->out.vwv, VWV(0), parms->ioctl.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->ioctl.in.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->ioctl.in.request); if (!smbcli_request_send(req)) { @@ -81,7 +81,7 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, nt.in.setup_count = 4; nt.in.setup = setup; SIVAL(setup, 0, parms->ntioctl.in.function); - SSVAL(setup, 4, parms->ntioctl.file.fnum); + SSVAL(setup, 4, parms->ntioctl.in.file.fnum); SCVAL(setup, 6, parms->ntioctl.in.fsctl); SCVAL(setup, 7, parms->ntioctl.in.filter); nt.in.function = NT_TRANSACT_IOCTL; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 3adb1b000b..c06f0a59f7 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -36,7 +36,7 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union nt.in.setup_count = 4; nt.in.setup = setup; SIVAL(setup, 0, parms->notify.in.completion_filter); - SSVAL(setup, 4, parms->notify.file.fnum); + SSVAL(setup, 4, parms->notify.in.file.fnum); SSVAL(setup, 6, parms->notify.in.recursive); nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; nt.in.params = data_blob(NULL, 0); diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index c4e2ab2498..7f1aaf26d4 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -41,7 +41,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea bigoffset = True; } SETUP_REQUEST(SMBreadbraw, bigoffset? 10:8, 0); - SSVAL(req->out.vwv, VWV(0), parms->readbraw.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->readbraw.in.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->readbraw.in.offset); SSVAL(req->out.vwv, VWV(3), parms->readbraw.in.maxcnt); SSVAL(req->out.vwv, VWV(4), parms->readbraw.in.mincnt); @@ -54,7 +54,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea case RAW_READ_LOCKREAD: SETUP_REQUEST(SMBlockread, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->lockread.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->lockread.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->lockread.in.count); SIVAL(req->out.vwv, VWV(2), parms->lockread.in.offset); SSVAL(req->out.vwv, VWV(4), parms->lockread.in.remaining); @@ -62,7 +62,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea case RAW_READ_READ: SETUP_REQUEST(SMBread, 5, 0); - SSVAL(req->out.vwv, VWV(0), parms->read.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->read.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->read.in.count); SIVAL(req->out.vwv, VWV(2), parms->read.in.offset); SSVAL(req->out.vwv, VWV(4), parms->read.in.remaining); @@ -75,7 +75,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - SSVAL(req->out.vwv, VWV(2), parms->readx.file.fnum); + SSVAL(req->out.vwv, VWV(2), parms->readx.in.file.fnum); SIVAL(req->out.vwv, VWV(3), parms->readx.in.offset); SSVAL(req->out.vwv, VWV(5), parms->readx.in.maxcnt & 0xFFFF); SSVAL(req->out.vwv, VWV(6), parms->readx.in.mincnt); @@ -186,7 +186,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr switch (parms->generic.level) { case RAW_WRITE_WRITEUNLOCK: SETUP_REQUEST(SMBwriteunlock, 5, 3 + parms->writeunlock.in.count); - SSVAL(req->out.vwv, VWV(0), parms->writeunlock.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->writeunlock.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeunlock.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeunlock.in.offset); SSVAL(req->out.vwv, VWV(4), parms->writeunlock.in.remaining); @@ -200,7 +200,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_WRITE: SETUP_REQUEST(SMBwrite, 5, 3 + parms->write.in.count); - SSVAL(req->out.vwv, VWV(0), parms->write.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->write.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->write.in.count); SIVAL(req->out.vwv, VWV(2), parms->write.in.offset); SSVAL(req->out.vwv, VWV(4), parms->write.in.remaining); @@ -213,7 +213,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_WRITECLOSE: SETUP_REQUEST(SMBwriteclose, 6, 1 + parms->writeclose.in.count); - SSVAL(req->out.vwv, VWV(0), parms->writeclose.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->writeclose.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeclose.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeclose.in.offset); raw_push_dos_date3(tree->session->transport, @@ -232,7 +232,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); - SSVAL(req->out.vwv, VWV(2), parms->writex.file.fnum); + SSVAL(req->out.vwv, VWV(2), parms->writex.in.file.fnum); SIVAL(req->out.vwv, VWV(3), parms->writex.in.offset); SIVAL(req->out.vwv, VWV(5), 0); /* reserved */ SSVAL(req->out.vwv, VWV(7), parms->writex.in.wmode); @@ -250,7 +250,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_SPLWRITE: SETUP_REQUEST(SMBsplwr, 1, parms->splwrite.in.count); - SSVAL(req->out.vwv, VWV(0), parms->splwrite.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->splwrite.in.file.fnum); if (parms->splwrite.in.count > 0) { memcpy(req->out.data, parms->splwrite.in.data, parms->splwrite.in.count); } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 73fcd82802..46480c636e 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -283,7 +283,7 @@ static struct smbcli_request *smb_raw_setattr_send(struct smbcli_tree *tree, raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->setattr.in.write_time); memset(req->out.vwv + VWV(3), 0, 10); /* reserved */ - smbcli_req_append_ascii4(req, parms->setattr.file.path, STR_TERMINATE); + smbcli_req_append_ascii4(req, parms->setattr.in.file.path, STR_TERMINATE); smbcli_req_append_ascii4(req, "", STR_TERMINATE); if (!smbcli_request_send(req)) { @@ -305,7 +305,7 @@ static struct smbcli_request *smb_raw_setattrE_send(struct smbcli_tree *tree, req = smbcli_request_setup(tree, SMBsetattrE, 7, 0); if (!req) return NULL; - SSVAL(req->out.vwv, VWV(0), parms->setattre.file.fnum); + SSVAL(req->out.vwv, VWV(0), parms->setattre.in.file.fnum); raw_push_dos_date2(tree->session->transport, req->out.vwv, VWV(1), parms->setattre.in.create_time); raw_push_dos_date2(tree->session->transport, @@ -352,7 +352,7 @@ struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree, /* send request and process the output */ req = smb_raw_setfileinfo_blob_send(tree, mem_ctx, - parms->generic.file.fnum, + parms->generic.in.file.fnum, parms->generic.level, &blob); @@ -399,7 +399,7 @@ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, /* send request and process the output */ req = smb_raw_setpathinfo_blob_send(tree, mem_ctx, - parms->generic.file.path, + parms->generic.in.file.path, parms->generic.level, &blob); diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 3710fdfa08..d52ff03922 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -118,7 +118,7 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi ZERO_STRUCT(b); b.in.max_response_size = 0x10000; - b.in.handle = io->generic.file.handle; + b.in.handle = io->generic.in.file.handle; b.in.level = smb2_level; if (io->generic.level == RAW_FILEINFO_SEC_DESC) { diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index ce03a69482..c445880440 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -92,7 +92,7 @@ struct smb2_request *smb2_setinfo_file_send(struct smb2_tree *tree, union smb_se ZERO_STRUCT(b); b.in.level = smb2_level; - b.in.handle = io->generic.file.handle; + b.in.handle = io->generic.in.file.handle; if (!smb_raw_setfileinfo_passthru(tree, io->generic.level, io, &b.in.blob)) { return NULL; } diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index b09acfaf63..55aa727729 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -37,7 +37,7 @@ static NTSTATUS appendacl_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo); state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; - state->io_fileinfo->query_secdesc.file.fnum = state->io_open->ntcreatex.file.fnum; + state->io_fileinfo->query_secdesc.in.file.fnum = state->io_open->ntcreatex.out.file.fnum; state->io_fileinfo->query_secdesc.in.secinfo_flags = SECINFO_DACL; state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); @@ -69,7 +69,7 @@ static NTSTATUS appendacl_get(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo); state->io_setfileinfo->set_secdesc.level = RAW_SFILEINFO_SEC_DESC; - state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.file.fnum; + state->io_setfileinfo->set_secdesc.in.file.fnum = state->io_fileinfo->query_secdesc.in.file.fnum; state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL; state->io_setfileinfo->set_secdesc.in.sd = state->io_fileinfo->query_secdesc.out.sd; @@ -115,7 +115,7 @@ static NTSTATUS appendacl_set(struct composite_context *c, state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC; - state->io_fileinfo->query_secdesc.file.fnum = state->io_setfileinfo->set_secdesc.file.fnum; + state->io_fileinfo->query_secdesc.in.file.fnum = state->io_setfileinfo->set_secdesc.in.file.fnum; state->io_fileinfo->query_secdesc.in.secinfo_flags = SECINFO_DACL; state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo); @@ -150,7 +150,7 @@ static NTSTATUS appendacl_getagain(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_close); io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.file.fnum = state->io_fileinfo->query_secdesc.file.fnum; + io_close->close.in.file.fnum = state->io_fileinfo->query_secdesc.in.file.fnum; io_close->close.in.write_time = 0; state->req = smb_raw_close_send(tree, io_close); diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index db074bfd2b..8582b71ef4 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -54,7 +54,7 @@ static NTSTATUS setup_close(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_close); io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.file.fnum = fnum; + io_close->close.in.file.fnum = fnum; io_close->close.in.write_time = 0; state->req = smb_raw_close_send(tree, io_close); @@ -93,7 +93,7 @@ static NTSTATUS loadfile_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io->out.data); if (io->out.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.file.fnum); + return setup_close(c, tree, state->io_open->ntcreatex.out.file.fnum); } /* setup for the read */ @@ -101,7 +101,7 @@ static NTSTATUS loadfile_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(state->io_read); state->io_read->readx.level = RAW_READ_READX; - state->io_read->readx.file.fnum = state->io_open->ntcreatex.file.fnum; + state->io_read->readx.in.file.fnum = state->io_open->ntcreatex.out.file.fnum; state->io_read->readx.in.offset = 0; state->io_read->readx.in.mincnt = MIN(32768, io->out.size); state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; @@ -140,7 +140,7 @@ static NTSTATUS loadfile_read(struct composite_context *c, /* we might be done */ if (state->io_read->readx.in.offset + state->io_read->readx.out.nread == io->out.size) { - return setup_close(c, tree, state->io_read->readx.file.fnum); + return setup_close(c, tree, state->io_read->readx.in.file.fnum); } /* setup for the next read */ diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c index 89a2d26c0c..d355cf1e26 100644 --- a/source4/libcli/smb_composite/savefile.c +++ b/source4/libcli/smb_composite/savefile.c @@ -55,7 +55,7 @@ static NTSTATUS setup_close(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_close); io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.file.fnum = fnum; + io_close->close.in.file.fnum = fnum; io_close->close.in.write_time = 0; state->req = smb_raw_close_send(tree, io_close); @@ -86,7 +86,7 @@ static NTSTATUS savefile_open(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); if (io->in.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.file.fnum); + return setup_close(c, tree, state->io_open->ntcreatex.out.file.fnum); } /* setup for the first write */ @@ -94,7 +94,7 @@ static NTSTATUS savefile_open(struct composite_context *c, NT_STATUS_HAVE_NO_MEMORY(io_write); io_write->writex.level = RAW_WRITE_WRITEX; - io_write->writex.file.fnum = state->io_open->ntcreatex.file.fnum; + io_write->writex.in.file.fnum = state->io_open->ntcreatex.out.file.fnum; io_write->writex.in.offset = 0; io_write->writex.in.wmode = 0; io_write->writex.in.remaining = 0; @@ -135,7 +135,7 @@ static NTSTATUS savefile_write(struct composite_context *c, /* we might be done */ if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count || state->total_written == io->in.size) { - return setup_close(c, tree, state->io_write->writex.file.fnum); + return setup_close(c, tree, state->io_write->writex.in.file.fnum); } /* setup for the next write */ -- cgit From 3ea60662fd687124483cad2f56f787c3b3d73f22 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Mar 2006 05:02:49 +0000 Subject: r14297: make sure we can go through the loop for than once (This used to be commit 6a84940bd3f310344641474dac984b262413943b) --- source4/libcli/dgram/mailslot.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 33bca166ce..467289bcee 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -137,7 +137,9 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms } dgmslot = dgram_mailslot_listen(dgmsock, name, handler, private); talloc_free(name); - return dgmslot; + if (dgmslot != NULL) { + return dgmslot; + } } DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name)); return NULL; -- cgit From e153a8099e9a187e6bcac6507ed4b1ddfe7cb764 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Mar 2006 16:32:44 +0000 Subject: r14327: Replace MAJOR_VERSION/MINOR_VERSION/RELEASE_VERSION with two parameters: - VERSION: should contain the current version. Will be made part of the filename. - SO_VERSION: should contain the latest version that this on is compatible to. Will be used for setting the soname of the shared library. Fix sonames and use them on platforms that support them Remove symlinking code. ldconfig will take care of creating the symlinks now that we set the soname. (This used to be commit 7871b07e21c85c63d0ecac4c31b98dc112d18af5) --- source4/libcli/config.mk | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 1c030e0d0d..41faf36237 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -39,9 +39,8 @@ REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE OBJ_FILES = nbt/nbtname.o\ [LIBRARY::LIBCLI_NBT] -MAJOR_VERSION = 0 -MINOR_VERSION = 0 -RELEASE_VERSION = 1 +VERSION = 0.0.1 +SO_VERSION = 0.0.1 DESCRIPTION = NetBios over TCP/IP client library PRIVATE_PROTO_HEADER = nbt/nbt_proto.h OBJ_FILES = \ @@ -64,9 +63,8 @@ NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT [LIBRARY::LIBCLI_CLDAP] -MAJOR_VERSION = 0 -MINOR_VERSION = 0 -RELEASE_VERSION = 1 +VERSION = 0.0.1 +SO_VERSION = 0.0.1 DESCRIPTION = CLDAP client library OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h @@ -75,9 +73,8 @@ REQUIRED_SUBSYSTEMS = LIBCLI_LDAP [LIBRARY::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h -MAJOR_VERSION = 0 -MINOR_VERSION = 0 -RELEASE_VERSION = 1 +VERSION = 0.0.1 +SO_VERSION = 0.0.1 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o @@ -100,9 +97,8 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = LIBCLI_NBT MESSAGING [LIBRARY::LIBCLI] -MAJOR_VERSION = 0 -MINOR_VERSION = 0 -RELEASE_VERSION = 1 +VERSION = 0.0.1 +SO_VERSION = 0.0.1 DESCRIPTION = SMB/CIFS client library REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ -- cgit From 7a121583b496a8fc0c1fcf44504d814700273e40 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Mar 2006 22:36:07 +0000 Subject: r14349: Kill proto.h! Prototypes are now spread over multiple headers, usually one per subsystem. This change is required to allow proper header dependencies later on, without recompiling Samba each time the mtime of any source file changes. (This used to be commit 3da79bf909f801386a52e6013db399c384d0401c) --- source4/libcli/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 41faf36237..0ccf1d7126 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -36,7 +36,8 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE [SUBSYSTEM::NDR_NBT_BUF] -OBJ_FILES = nbt/nbtname.o\ +PRIVATE_PROTO_HEADER = nbt/nbtname.h +OBJ_FILES = nbt/nbtname.o [LIBRARY::LIBCLI_NBT] VERSION = 0.0.1 -- cgit From 3f16241a1d3243447d0244ebac05b447aec94df8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 01:29:56 +0000 Subject: r14363: Remove credentials.h from the global includes. (This used to be commit 98c4c3051391c6f89df5d133665f51bef66b1563) --- source4/libcli/auth/smbencrypt.c | 1 + source4/libcli/cliconnect.c | 1 + source4/libcli/smb_composite/connect.c | 1 + source4/libcli/smb_composite/sesssetup.c | 1 + 4 files changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index f267baa4c0..587fb98920 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -28,6 +28,7 @@ #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/msrpc_parse.h" #include "lib/crypto/crypto.h" +#include "auth/credentials/credentials.h" #include "libcli/auth/proto.h" #include "pstring.h" diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 8616e42cd4..a718f43d96 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" +#include "auth/credentials/credentials.h" #include "libcli/auth/proto.h" #include "libcli/smb_composite/smb_composite.h" diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 07da2d363a..b36e37a1a4 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -27,6 +27,7 @@ #include "libcli/smb_composite/smb_composite.h" #include "lib/events/events.h" #include "libcli/resolve/resolve.h" +#include "auth/credentials/credentials.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 9e345ab4f8..a62386b672 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -25,6 +25,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" +#include "auth/credentials/credentials.h" #include "libcli/auth/proto.h" #include "auth/auth.h" #include "version.h" -- cgit From add7ba54c1cbf0c2d3d6ef3230903a08522e8c33 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Mar 2006 12:56:59 +0000 Subject: r14372: fix bug found by sparse metze (This used to be commit da1ac9b2243d0217c2d29879d885d62be9ddd290) --- source4/libcli/raw/clisocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 4b1d70d8d2..0631d55a9c 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -242,7 +242,7 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); - return False; + return NULL; } status = smbcli_sock_connect(mem_ctx, address, port, name, event_ctx, -- cgit From e3f2414cf9e582a4e4deecc662b64a7bb2679a34 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 15:03:25 +0000 Subject: r14380: Reduce the size of structs.h (This used to be commit 1a16a6f1dfa66499af43a6b88b3ea69a6a75f1fe) --- source4/libcli/auth/libcli_auth.h | 25 +++++++++++++++++++++++++ source4/libcli/auth/smbencrypt.c | 3 +-- source4/libcli/cliconnect.c | 3 +-- source4/libcli/composite/composite.h | 3 +++ source4/libcli/libcli.h | 5 +++++ source4/libcli/smb_composite/sesssetup.c | 3 +-- source4/libcli/smb_composite/smb_composite.h | 2 ++ 7 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 source4/libcli/auth/libcli_auth.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/libcli_auth.h b/source4/libcli/auth/libcli_auth.h new file mode 100644 index 0000000000..f8f07e8337 --- /dev/null +++ b/source4/libcli/auth/libcli_auth.h @@ -0,0 +1,25 @@ +/* + samba -- Unix SMB/CIFS implementation. + + 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. +*/ +#ifndef __LIBCLI_AUTH_H__ +#define __LIBCLI_AUTH_H__ + +#include "librpc/gen_ndr/netlogon.h" +#include "auth/credentials/credentials.h" +#include "libcli/auth/proto.h" + +#endif /* __LIBCLI_AUTH_H__ */ diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 587fb98920..24fdeff33f 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -28,8 +28,7 @@ #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/msrpc_parse.h" #include "lib/crypto/crypto.h" -#include "auth/credentials/credentials.h" -#include "libcli/auth/proto.h" +#include "libcli/auth/libcli_auth.h" #include "pstring.h" /* diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index a718f43d96..d89d6a1568 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -24,8 +24,7 @@ #include "includes.h" #include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" -#include "auth/credentials/credentials.h" -#include "libcli/auth/proto.h" +#include "libcli/auth/libcli_auth.h" #include "libcli/smb_composite/smb_composite.h" /* diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index d1299d77c1..6210b2b227 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -61,4 +61,7 @@ struct composite_context { BOOL used_wait; }; +struct irpc_request; +struct smbcli_request; + #include "libcli/composite/proto.h" diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index 76fa13525e..c358ac5752 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -19,6 +19,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef __LIBCLI_H__ +#define __LIBCLI_H__ + #include "smb.h" /* @@ -47,3 +50,5 @@ struct nbt_dc_name { }; #include "libcli/libcli_proto.h" + +#endif /* __LIBCLI_H__ */ diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index a62386b672..318fc9fbed 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -25,8 +25,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" -#include "auth/credentials/credentials.h" -#include "libcli/auth/proto.h" +#include "libcli/auth/libcli_auth.h" #include "auth/auth.h" #include "version.h" diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index ac34ad40ac..a7a82965e6 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -171,4 +171,6 @@ struct smb_composite_connectmulti { } out; }; +struct smbcli_session; + #include "libcli/smb_composite/proto.h" -- cgit From 1060f6b3f621cb70b075a879f129e57f10fdbf8a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 23:35:30 +0000 Subject: r14402: Generate seperate headers for RPC client functions. (This used to be commit 7054ebf0249930843a2baf4d023ae8f62cedb109) --- source4/libcli/util/clilsa.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 97aa7e13ac..7cafef829a 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -31,6 +31,7 @@ #include "libcli/libcli.h" #include "libcli/security/proto.h" #include "librpc/gen_ndr/ndr_lsa.h" +#include "librpc/gen_ndr/ndr_lsa_c.h" struct smblsa_state { struct dcerpc_pipe *pipe; -- cgit From f479571502750c2399103bbdd104966125ce3818 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 02:41:57 +0000 Subject: r14413: don't do memcpy of length 0 (This used to be commit c43a7ec7ac3bcb3001d046615ca17a9ce083a2b0) --- source4/libcli/raw/rawtrans.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 207b5bee08..53e80d4753 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -340,7 +340,10 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, SSVAL(req2->out.vwv,VWV(7), data_disp); SSVAL(req2->out.vwv,VWV(8), 0xFFFF); - memcpy(req2->out.data, parms->in.data.data + data_disp, data_length); + if (data_length != 0) { + memcpy(req2->out.data, parms->in.data.data + data_disp, + data_length); + } data_disp += data_length; -- cgit From 72a7052fa76777390c3cb45e035e7d8c557af84d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 02:42:21 +0000 Subject: r14414: added some error checks (This used to be commit cd9f3adc759f1dc29043c435febfe78e56fece1b) --- source4/libcli/smb_composite/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 318fc9fbed..0f00d5f9c0 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -178,6 +178,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, &state->setup.nt1.in.password1, &state->setup.nt1.in.password2, NULL, &session_key); + NT_STATUS_NOT_OK_RETURN(nt_status); smbcli_transport_simple_set_signing(session->transport, session_key, state->setup.nt1.in.password2); @@ -241,6 +242,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, &state->setup.old.in.password, NULL, NULL, &session_key); + NT_STATUS_NOT_OK_RETURN(nt_status); set_user_session_key(session, &session_key); data_blob_free(&session_key); -- cgit From f9827c2ad157b9a5d26028ea6f3e7e1cec871ca1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:30:39 +0000 Subject: r14423: don't die on no controls (This used to be commit 9787fb8e917c22ffe910062630dc4f32473a9fab) --- source4/libcli/ldap/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 42cad3a63e..c1fc461b5f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1332,7 +1332,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } - ctrl[i] = NULL; + if (ctrl != NULL) { + ctrl[i] = NULL; + } msg->controls = ctrl; -- cgit From 07fd3bd5121aa9b81b6c7a14910f09f64ab4bad9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:31:51 +0000 Subject: r14424: another empty controls case (This used to be commit 7d0eb678bf3649fb4e09da039dd1b716ea3df2cc) --- source4/libcli/ldap/ldap_controls.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 373b71d370..ccb1b74a55 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -137,7 +137,9 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } } - lssc[num] = NULL; + if (lssc != NULL) { + lssc[num] = NULL; + } if (!asn1_end_tag(&data)) { return False; -- cgit From baa62e5637b24bccbfe41fc5ec8e4eafc0b92191 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:52:45 +0000 Subject: r14434: use the right enum type (This used to be commit 507def57cb83a3e12a3c8d60eb833fe47e9ec9e8) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 9fe9ad12fa..1f3e2f54e4 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -124,7 +124,7 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req) DLIST_REMOVE(req->transport->pending_recv, req); } - if (req->state == SMBCLI_REQUEST_ERROR && + if (req->state == SMB2_REQUEST_ERROR && NT_STATUS_IS_OK(req->status)) { req->status = NT_STATUS_INTERNAL_ERROR; } -- cgit From 57026269068b035a2f32e971784ab31883854398 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:53:15 +0000 Subject: r14435: return after an error (This used to be commit 40e5bfdb0fadedb81d8fbd7e8cc578ef2ea12b13) --- source4/libcli/smb2/session.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 208e2a94de..1d1b97600a 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -170,6 +170,7 @@ static void session_request_handler(struct smb2_request *req) state->req = smb2_session_setup_send(session, &state->io); if (state->req == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); + return; } state->req->async.fn = session_request_handler; -- cgit From 8528016978b084213ef53d66e1b6e831b1a01acc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 00:23:11 +0000 Subject: r14464: Don't include ndr_BASENAME.h files unless strictly required, instead try to include just the BASENAME.h files (containing only structs) (This used to be commit 3dd477ca5147f28a962b8437e2611a8222d706bd) --- source4/libcli/auth/credentials.h | 2 +- source4/libcli/cldap/cldap.c | 1 + source4/libcli/cldap/cldap.h | 2 +- source4/libcli/dgram/browse.c | 1 + source4/libcli/dgram/dgramsocket.c | 1 + source4/libcli/dgram/libdgram.h | 2 +- source4/libcli/dgram/netlogon.c | 1 + source4/libcli/dgram/ntlogon.c | 1 + source4/libcli/finddcs.c | 2 +- source4/libcli/nbt/libnbt.h | 2 +- source4/libcli/nbt/nameregister.c | 1 + source4/libcli/nbt/nbtsocket.c | 1 + source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/libcliraw.h | 2 +- source4/libcli/raw/rawacl.c | 1 + source4/libcli/raw/rawfile.c | 1 + source4/libcli/raw/rawfileinfo.c | 1 + source4/libcli/resolve/host.c | 1 + source4/libcli/resolve/nbtlist.c | 1 + source4/libcli/resolve/resolve.c | 1 + source4/libcli/security/sddl.c | 1 + source4/libcli/security/security_token.c | 1 + source4/libcli/smb_composite/connect.c | 1 + source4/libcli/util/clilsa.c | 1 + source4/libcli/wrepl/winsrepl.c | 1 + source4/libcli/wrepl/winsrepl.h | 4 ++-- 26 files changed, 27 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 27c5a4e689..2e781f701f 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "librpc/gen_ndr/ndr_netlogon.h" +#include "librpc/gen_ndr/netlogon.h" struct creds_CredentialState { uint32_t negotiate_flags; diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 9e407ba200..2773dba1d7 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -39,6 +39,7 @@ #include "libcli/cldap/cldap.h" #include "lib/socket/socket.h" #include "libcli/security/proto.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* destroy a pending request diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 944510077b..98cb54dded 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -21,7 +21,7 @@ */ #include "libcli/util/asn_1.h" -#include "librpc/gen_ndr/ndr_nbt.h" +#include "librpc/gen_ndr/nbt.h" struct ldap_message; diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index f67e561afc..18ab398c79 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -25,6 +25,7 @@ #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" +#include "librpc/gen_ndr/ndr_nbt.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 326ec7e908..16bb9d2fb7 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -25,6 +25,7 @@ #include "dlinklist.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 830d81257d..26675cb420 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "librpc/gen_ndr/ndr_nbt.h" +#include "librpc/gen_ndr/nbt.h" /* a datagram name request diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index df8c63fa87..08b9b0e641 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -24,6 +24,7 @@ #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* send a netlogon mailslot request diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 84ad814fa0..f480212b79 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -24,6 +24,7 @@ #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* send a ntlogon mailslot request diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 085aa352ac..9ed20b77ba 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -24,7 +24,7 @@ #include "include/includes.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_irpc.h" -#include "librpc/gen_ndr/ndr_samr.h" +#include "librpc/gen_ndr/samr.h" #include "libcli/composite/composite.h" #include "libcli/libcli.h" #include "libcli/resolve/resolve.h" diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index b4411d6fe6..e828beb29f 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -23,7 +23,7 @@ #ifndef __LIBNBT_H__ #define __LIBNBT_H__ -#include "librpc/gen_ndr/ndr_nbt.h" +#include "librpc/gen_ndr/nbt.h" /* possible states for pending requests diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 5c7e86367f..957f87abfd 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -24,6 +24,7 @@ #include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" #include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* send a nbt name registration request diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 42b92b14cc..eca5253113 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -25,6 +25,7 @@ #include "dlinklist.h" #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" #define NBT_MAX_REPLIES 1000 diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index df5c608d08..2ad155e9b9 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -26,6 +26,7 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/stream/packet.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 96a06b9bec..f115a18d23 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -22,7 +22,7 @@ #include "libcli/raw/request.h" #include "smb.h" -#include "librpc/gen_ndr/ndr_nbt.h" +#include "librpc/gen_ndr/nbt.h" struct smbcli_tree; /* forward declare */ struct smbcli_request; /* forward declare */ diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 59ac65a340..6f35b7f829 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_security.h" /**************************************************************************** fetch file ACL (async send) diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 6f8befebfe..d889b500fb 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -23,6 +23,7 @@ #include "includes.h" #include "smb.h" #include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_security.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index cf8f2f71b4..b33d0df828 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_security.h" /* local macros to make the code more readable */ #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \ diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index c283f0fda1..781ea957df 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -34,6 +34,7 @@ #include "system/network.h" #include "system/filesys.h" #include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_nbt.h" struct host_state { struct nbt_name name; diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index e8473966b4..7188faba7b 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -28,6 +28,7 @@ #include "libcli/composite/composite.h" #include "system/network.h" #include "netif/netif.h" +#include "librpc/gen_ndr/ndr_nbt.h" struct nbtlist_state { struct nbt_name name; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index c3fdf4bc25..8bacab8cd7 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -24,6 +24,7 @@ #include "lib/events/events.h" #include "libcli/composite/composite.h" #include "libcli/resolve/resolve.h" +#include "librpc/gen_ndr/ndr_nbt.h" struct resolve_state { struct nbt_name name; diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index a1e9985edd..862a25e20d 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -23,6 +23,7 @@ #include "includes.h" #include "system/iconv.h" #include "libcli/security/proto.h" +#include "librpc/gen_ndr/ndr_security.h" struct flag_map { const char *name; diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 7760ee7c22..1391a4654d 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -24,6 +24,7 @@ #include "includes.h" #include "dsdb/samdb/samdb.h" #include "libcli/security/proto.h" +#include "librpc/gen_ndr/ndr_security.h" /* return a blank security token diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index b36e37a1a4..a28d33cf7f 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -28,6 +28,7 @@ #include "lib/events/events.h" #include "libcli/resolve/resolve.h" #include "auth/credentials/credentials.h" +#include "librpc/gen_ndr/ndr_nbt.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 7cafef829a..f1f0f01c1d 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -31,6 +31,7 @@ #include "libcli/libcli.h" #include "libcli/security/proto.h" #include "librpc/gen_ndr/ndr_lsa.h" +#include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_lsa_c.h" struct smblsa_state { diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 3fb142ea0b..c37d5f9873 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -25,6 +25,7 @@ #include "dlinklist.h" #include "lib/socket/socket.h" #include "libcli/wrepl/winsrepl.h" +#include "librpc/gen_ndr/ndr_winsrepl.h" #include "lib/stream/packet.h" #include "libcli/composite/composite.h" #include "system/network.h" diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 2fea11bd63..3ea672327b 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -20,8 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "librpc/gen_ndr/ndr_nbt.h" -#include "librpc/gen_ndr/ndr_winsrepl.h" +#include "librpc/gen_ndr/nbt.h" +#include "librpc/gen_ndr/winsrepl.h" /* main context structure for the wins replication client library -- cgit From 4f1c8daa36a7a0372c5fd9eab51f3c16ee81c49d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 12:43:28 +0000 Subject: r14470: Remove some unnecessary headers. (This used to be commit f7312dab3b9aba2b2b82e8a6e0c483a32a03a63a) --- source4/libcli/util/clilsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index f1f0f01c1d..fab392ac04 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -30,8 +30,8 @@ #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" #include "libcli/security/proto.h" -#include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_lsa_c.h" struct smblsa_state { -- cgit From 2438b90b32716a07589ccb5d747969c2bce974de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 13:19:31 +0000 Subject: r14473: Modern splint has no problems with immediate structures. (This used to be commit 6046dd822078cf5daa1a00c90fab998608e6872a) --- source4/libcli/util/nt_status.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nt_status.h b/source4/libcli/util/nt_status.h index a805a1cfbd..fe1dbf866d 100644 --- a/source4/libcli/util/nt_status.h +++ b/source4/libcli/util/nt_status.h @@ -22,37 +22,19 @@ #ifndef _NT_STATUS_H #define _NT_STATUS_H -/* The Splint code analysis tool doesn't like immediate structures. */ - -#ifdef _SPLINT_ /* http://www.splint.org */ -#undef HAVE_IMMEDIATE_STRUCTURES -#endif - /* the following rather strange looking definitions of NTSTATUS and WERROR and there in order to catch common coding errors where different error types are mixed up. This is especially important as we slowly convert Samba from using BOOL for internal functions */ -#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} NTSTATUS; #define NT_STATUS(x) ((NTSTATUS) { x }) #define NT_STATUS_V(x) ((x).v) -#else -typedef uint32_t NTSTATUS; -#define NT_STATUS(x) (x) -#define NT_STATUS_V(x) (x) -#endif -#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} WERROR; #define W_ERROR(x) ((WERROR) { x }) #define W_ERROR_V(x) ((x).v) -#else -typedef uint32_t WERROR; -#define W_ERROR(x) (x) -#define W_ERROR_V(x) (x) -#endif #define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) #define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) -- cgit From 71b4fd97922933b24424924acee606389bfecb2d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 13:56:14 +0000 Subject: r14477: Remove the NOPROTO property - it's no longer used as proto.h is gone. (This used to be commit 9c37f847d32d2f327a88c53a90af0c73126b76be) --- source4/libcli/config.mk | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0ccf1d7126..6d88b3bd06 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -60,7 +60,6 @@ OBJ_FILES = \ dgram/netlogon.o \ dgram/ntlogon.o \ dgram/browse.o -NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT [LIBRARY::LIBCLI_CLDAP] @@ -69,7 +68,6 @@ SO_VERSION = 0.0.1 DESCRIPTION = CLDAP client library OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h -NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_LDAP [LIBRARY::LIBCLI_WREPL] -- cgit From 83d8fd3dcfb326354173b585905c4438405d2a74 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 17:51:04 +0000 Subject: r14484: Install more headers (This used to be commit 430c6516d383bfd7f27287394bf8eef9f174b3e6) --- source4/libcli/auth/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 18983e1644..26e6913c18 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] +PUBLIC_HEADERS = credentials.h PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = credentials.o \ session.o \ -- cgit From b785a7c40c185512207ef8da837a766933073032 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 21:36:36 +0000 Subject: r14492: Fix shared libs - set SO_VERSION to 0 everywhere for now. (This used to be commit 4682bc5ce047d81586447b9df82c91ed1fe677cf) --- source4/libcli/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 6d88b3bd06..b214803215 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -41,7 +41,7 @@ OBJ_FILES = nbt/nbtname.o [LIBRARY::LIBCLI_NBT] VERSION = 0.0.1 -SO_VERSION = 0.0.1 +SO_VERSION = 0 DESCRIPTION = NetBios over TCP/IP client library PRIVATE_PROTO_HEADER = nbt/nbt_proto.h OBJ_FILES = \ @@ -64,7 +64,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT [LIBRARY::LIBCLI_CLDAP] VERSION = 0.0.1 -SO_VERSION = 0.0.1 +SO_VERSION = 0 DESCRIPTION = CLDAP client library OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h @@ -73,7 +73,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_LDAP [LIBRARY::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h VERSION = 0.0.1 -SO_VERSION = 0.0.1 +SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o @@ -97,7 +97,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_NBT MESSAGING [LIBRARY::LIBCLI] VERSION = 0.0.1 -SO_VERSION = 0.0.1 +SO_VERSION = 0 DESCRIPTION = SMB/CIFS client library REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ -- cgit From 2d558d5e195bc35f7af2bd1d2150bf9882d0cc24 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 17 Mar 2006 01:36:32 +0000 Subject: r14498: Revert part of my commit that removed support for compilers that don't support immediate structures (This used to be commit 657a893b25bc6669f016a9d251e07120d025f436) --- source4/libcli/util/nt_status.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nt_status.h b/source4/libcli/util/nt_status.h index fe1dbf866d..06aeaa3dac 100644 --- a/source4/libcli/util/nt_status.h +++ b/source4/libcli/util/nt_status.h @@ -28,13 +28,25 @@ from using BOOL for internal functions */ +#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} NTSTATUS; #define NT_STATUS(x) ((NTSTATUS) { x }) #define NT_STATUS_V(x) ((x).v) +#else +typedef uint32_t NTSTATUS; +#define NT_STATUS(x) (x) +#define NT_STATUS_V(x) (x) +#endif +#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} WERROR; #define W_ERROR(x) ((WERROR) { x }) #define W_ERROR_V(x) ((x).v) +#else +typedef uint32_t WERROR; +#define W_ERROR(x) (x) +#define W_ERROR_V(x) (x) +#endif #define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) #define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) -- cgit From 5b0051e0325aea7e46715aa61bba0a1dc025132c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 17 Mar 2006 13:55:10 +0000 Subject: r14511: Install more headers (This used to be commit e1f896948fad8cf5a1aec300865c250c5721ee7d) --- source4/libcli/config.mk | 3 ++- source4/libcli/ldap/config.mk | 3 ++- source4/libcli/libcli.h | 6 +++++- source4/libcli/raw/interfaces.h | 6 ++++++ source4/libcli/raw/libcliraw.h | 7 ++++++- source4/libcli/smb2/smb2.h | 2 -- source4/libcli/smb2/smb2_calls.h | 1 + 7 files changed, 22 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index b214803215..465146ec17 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -96,6 +96,7 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = LIBCLI_NBT MESSAGING [LIBRARY::LIBCLI] +PUBLIC_HEADERS = libcli.h VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = SMB/CIFS client library @@ -105,7 +106,7 @@ REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ [SUBSYSTEM::LIBSMB] REQUIRED_SUBSYSTEMS = LIBCLI SOCKET -PRIVATE_PROTO_HEADER = libcli_proto.h +PUBLIC_PROTO_HEADER = libcli_proto.h OBJ_FILES = clireadwrite.o \ cliconnect.o \ clifile.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index c0ad8d157f..624b2603ec 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,8 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -PRIVATE_PROTO_HEADER = ldap_proto.h +PUBLIC_PROTO_HEADER = ldap_proto.h +PUBLIC_HEADERS = ldap.h OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index c358ac5752..c104fcf80e 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -22,7 +22,8 @@ #ifndef __LIBCLI_H__ #define __LIBCLI_H__ -#include "smb.h" +#include +#include "librpc/gen_ndr/nbt.h" /* smbcli_state: internal state used in libcli library for single-threaded callers, @@ -49,6 +50,9 @@ struct nbt_dc_name { const char *name; }; +struct cli_credentials; +struct event_context; +#include "libcli/raw/libcliraw.h" #include "libcli/libcli_proto.h" #endif /* __LIBCLI_H__ */ diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 20b729caba..d662b9f5ae 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -19,6 +19,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef __LIBCLI_RAW_INTERFACES_H__ +#define __LIBCLI_RAW_INTERFACES_H__ + +#include "smb.h" + /* this structure is just a wrapper for a string, the only reason we bother with this is that it allows us to check the length provided on the wire in testsuite test code to ensure that we are @@ -2048,3 +2053,4 @@ union smb_search_close { } findclose; }; +#endif /* __LIBCLI_RAW_INTERFACES_H__ */ diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index f115a18d23..21d0b0dcdb 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef __LIBCLI_RAW_H__ +#define __LIBCLI_RAW_H__ + #include "libcli/raw/request.h" -#include "smb.h" #include "librpc/gen_ndr/nbt.h" struct smbcli_tree; /* forward declare */ @@ -271,4 +273,7 @@ struct smbcli_request { goto failed; \ } +#include "libcli/raw/interfaces.h" #include "libcli/raw/raw_proto.h" + +#endif /* __LIBCLI_RAW__H__ */ diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 913d58409b..ceafacf9d4 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -20,8 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "smb.h" - struct smb2_options { uint32_t timeout; }; diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 7349b609cb..af1730aeee 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "libcli/raw/interfaces.h" struct smb2_negprot { struct { -- cgit From 9225c02aee19478fc4825c4b798a6757d140b5c0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Mar 2006 09:07:47 +0000 Subject: r14539: get rid of a pointless union layer in struct smb_notify (This used to be commit 1e1c5593817e84c59c1a10b5a3c1957e363e5198) --- source4/libcli/raw/interfaces.h | 28 +++++++++++++--------------- source4/libcli/raw/rawnotify.c | 28 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d662b9f5ae..88daf304cf 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1746,23 +1746,21 @@ struct smb_nttrans { /* struct for nttrans change notify call */ -union smb_notify { +struct smb_notify { struct { - struct { - union smb_handle file; - uint32_t buffer_size; - uint32_t completion_filter; - BOOL recursive; - } in; + union smb_handle file; + uint32_t buffer_size; + uint32_t completion_filter; + BOOL recursive; + } in; - struct { - uint32_t num_changes; - struct notify_changes { - uint32_t action; - struct smb_wire_string name; - } *changes; - } out; - } notify; + struct { + uint32_t num_changes; + struct notify_changes { + uint32_t action; + struct smb_wire_string name; + } *changes; + } out; }; enum smb_search_level {RAW_SEARCH_GENERIC = 0xF000, diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index c06f0a59f7..8ae5098c01 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -25,19 +25,19 @@ /**************************************************************************** change notify (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struct smb_notify *parms) { struct smb_nttrans nt; uint16_t setup[4]; nt.in.max_setup = 0; - nt.in.max_param = parms->notify.in.buffer_size; + nt.in.max_param = parms->in.buffer_size; nt.in.max_data = 0; nt.in.setup_count = 4; nt.in.setup = setup; - SIVAL(setup, 0, parms->notify.in.completion_filter); - SSVAL(setup, 4, parms->notify.in.file.fnum); - SSVAL(setup, 6, parms->notify.in.recursive); + SIVAL(setup, 0, parms->in.completion_filter); + SSVAL(setup, 4, parms->in.file.fnum); + SSVAL(setup, 6, parms->in.recursive); nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; nt.in.params = data_blob(NULL, 0); nt.in.data = data_blob(NULL, 0); @@ -49,7 +49,7 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union change notify (async recv) ****************************************************************************/ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, - TALLOC_CTX *mem_ctx, union smb_notify *parms) + TALLOC_CTX *mem_ctx, struct smb_notify *parms) { struct smb_nttrans nt; NTSTATUS status; @@ -61,28 +61,28 @@ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, return status; } - parms->notify.out.changes = NULL; - parms->notify.out.num_changes = 0; + parms->out.changes = NULL; + parms->out.num_changes = 0; /* count them */ for (ofs=0; nt.out.params.length - ofs > 12; ) { uint32_t next = IVAL(nt.out.params.data, ofs); - parms->notify.out.num_changes++; + parms->out.num_changes++; if (next == 0 || ofs + next >= nt.out.params.length) break; ofs += next; } /* allocate array */ - parms->notify.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->notify.out.num_changes); - if (!parms->notify.out.changes) { + parms->out.changes = talloc_array(mem_ctx, struct notify_changes, parms->out.num_changes); + if (!parms->out.changes) { return NT_STATUS_NO_MEMORY; } - for (i=ofs=0; inotify.out.num_changes; i++) { - parms->notify.out.changes[i].action = IVAL(nt.out.params.data, ofs+4); + for (i=ofs=0; iout.num_changes; i++) { + parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, - &parms->notify.out.changes[i].name, + &parms->out.changes[i].name, ofs+8, ofs+12, STR_UNICODE); ofs += IVAL(nt.out.params.data, ofs); } -- cgit From 35349a58df5b69446607fbd742a05f57f3515319 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Mar 2006 15:42:57 +0000 Subject: r14542: Remove librpc, libndr and libnbt from includes.h (This used to be commit 51b4270513752d2eafbe77f9de598de16ef84a1f) --- source4/libcli/composite/composite.c | 2 ++ source4/libcli/composite/composite.h | 2 ++ source4/libcli/config.mk | 2 +- source4/libcli/ldap/ldap.h | 4 ++++ source4/libcli/raw/libcliraw.h | 2 ++ source4/libcli/resolve/nbtlist.c | 1 + source4/libcli/resolve/resolve.h | 29 +++++++++++++++++++++++++++ source4/libcli/resolve/wins.c | 1 + source4/libcli/security/access_check.c | 1 + source4/libcli/security/dom_sid.c | 1 + source4/libcli/security/privilege.c | 1 + source4/libcli/security/sddl.c | 2 +- source4/libcli/security/security_descriptor.c | 1 + source4/libcli/smb2/smb2_calls.h | 2 ++ 14 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 source4/libcli/resolve/resolve.h (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index c8d6cd136a..9a745e3013 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -26,6 +26,8 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "lib/messaging/irpc.h" +#include "librpc/rpc/dcerpc.h" +#include "libcli/nbt/libnbt.h" /* block until a composite function has completed, then return the status diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 6210b2b227..dc04f5a883 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -63,5 +63,7 @@ struct composite_context { struct irpc_request; struct smbcli_request; +struct rpc_request; +struct nbt_name_request; #include "libcli/composite/proto.h" diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 465146ec17..dbeae51807 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -80,7 +80,7 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] -PRIVATE_PROTO_HEADER = resolve/resolve.h +PRIVATE_PROTO_HEADER = resolve/proto.h OBJ_FILES = \ resolve/resolve.o \ resolve/nbtlist.o \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 1deabf0b10..ba0f801832 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -247,6 +247,10 @@ struct ldap_message { struct ldb_control **controls; }; +struct event_context; +struct cli_credentials; +struct dom_sid; + #include "libcli/ldap/ldap_proto.h" #endif diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 21d0b0dcdb..2b856aa52b 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -31,6 +31,8 @@ struct smbcli_request; /* forward declare */ struct smbcli_session; /* forward declare */ struct smbcli_transport; /* forward declare */ +struct cli_credentials; + /* default timeout for all smb requests */ #define SMB_REQUEST_TIMEOUT 60 diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 7188faba7b..a8ca2ced8b 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -29,6 +29,7 @@ #include "system/network.h" #include "netif/netif.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "libcli/nbt/libnbt.h" struct nbtlist_state { struct nbt_name name; diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h new file mode 100644 index 0000000000..ad479bab4b --- /dev/null +++ b/source4/libcli/resolve/resolve.h @@ -0,0 +1,29 @@ +/* + Unix SMB/CIFS implementation. + + general name resolution interface + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +#ifndef __RESOLVE_H__ +#define __RESOLVE_H__ + +#include "libcli/nbt/libnbt.h" +#include "libcli/resolve/proto.h" + +#endif /* __RESOLVE_H__ */ diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index f11033ae4f..6478710682 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/nbt/libnbt.h" #include "libcli/resolve/resolve.h" /* diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 9d565363e6..1617963998 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/security.h" #include "libcli/security/proto.h" diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index b5ced9fcc2..131d1afa9c 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/security.h" /***************************************************************** Compare the auth portion of two sids. diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index fec8c1278c..202a418f6b 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/security.h" static const struct { diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 862a25e20d..38192fc60c 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -22,8 +22,8 @@ #include "includes.h" #include "system/iconv.h" -#include "libcli/security/proto.h" #include "librpc/gen_ndr/ndr_security.h" +#include "libcli/security/proto.h" struct flag_map { const char *name; diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 20cdeb0ba7..1da3e2e750 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/security.h" #include "libcli/security/proto.h" /* diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index af1730aeee..b6f8fdef71 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -363,4 +363,6 @@ struct smb2_flush { } in; }; +struct cli_credentials; +struct event_context; #include "libcli/smb2/smb2_proto.h" -- cgit From b7f5078864186cae4a02d2b8c960b2c4bd3aeb91 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Mar 2006 14:08:59 +0000 Subject: r14641: fix typo metze (This used to be commit 0ad464f686dddc5befdf1ec8d20101ee0ad83585) --- source4/libcli/security/security_token.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 1391a4654d..7ee3a68916 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -192,11 +192,11 @@ BOOL is_anonymous_token(struct security_token *token) return False; } -BOOL is_authenticated_token(struct security_token *token) +BOOL is_authenticated_token(struct security_token *token) { TALLOC_CTX *mem_ctx = talloc_new(token); int i; - struct dom_sid *authenticated = dom_sid_parse_talloc(mem_ctx, SID_NT_ANONYMOUS); + struct dom_sid *authenticated = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHENTICATED_USERS); for (i = 0; i < token->num_sids; i++) { if (dom_sid_equal(token->sids[i], authenticated)) { talloc_free(mem_ctx); -- cgit From 935af3eb1963761b4c8fd9e0e9902ad592f948bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 25 Mar 2006 18:47:47 +0000 Subject: r14724: Rearrange some source files, install more headers. (This used to be commit 7146c1600f29c349e5bb78f810e7e170b535dd37) --- source4/libcli/auth/config.mk | 3 +- source4/libcli/auth/credentials.c | 1 + source4/libcli/auth/session.c | 1 + source4/libcli/auth/smbdes.c | 381 ++++++++++++++++++++++++++++++++++++++ source4/libcli/config.mk | 17 +- source4/libcli/ldap/config.mk | 4 +- source4/libcli/ldap/ldap.h | 1 + source4/libcli/util/asn_1.h | 2 + source4/libcli/util/error.h | 27 +++ source4/libcli/util/smbdes.c | 381 -------------------------------------- 10 files changed, 427 insertions(+), 391 deletions(-) create mode 100644 source4/libcli/auth/smbdes.c create mode 100644 source4/libcli/util/error.h delete mode 100644 source4/libcli/util/smbdes.c (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 26e6913c18..3f036fbfd4 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -5,7 +5,8 @@ PUBLIC_HEADERS = credentials.h PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = credentials.o \ session.o \ - smbencrypt.o + smbencrypt.o \ + smbdes.o REQUIRED_SUBSYSTEMS = \ auth SCHANNELDB MSRPC_PARSE # End SUBSYSTEM LIBCLI_AUTH diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 3f055a657d..5bae30f580 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -25,6 +25,7 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" +#include "libcli/auth/libcli_auth.h" /* initialise the credentials state for old-style 64 bit session keys diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 22146cbfb3..afa7afbd0f 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libcli/auth/libcli_auth.h" /* encrypt or decrypt a blob of data using the user session key diff --git a/source4/libcli/auth/smbdes.c b/source4/libcli/auth/smbdes.c new file mode 100644 index 0000000000..d392109b1e --- /dev/null +++ b/source4/libcli/auth/smbdes.c @@ -0,0 +1,381 @@ +/* + Unix SMB/CIFS implementation. + + a partial implementation of DES designed for use in the + SMB authentication protocol + + Copyright (C) Andrew Tridgell 1998 + + 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" + +/* NOTES: + + This code makes no attempt to be fast! In fact, it is a very + slow implementation + + This code is NOT a complete DES implementation. It implements only + the minimum necessary for SMB authentication, as used by all SMB + products (including every copy of Microsoft Windows95 ever sold) + + In particular, it can only do a unchained forward DES pass. This + means it is not possible to use this code for encryption/decryption + of data, instead it is only useful as a "hash" algorithm. + + There is no entry point into this code that allows normal DES operation. + + I believe this means that this code does not come under ITAR + regulations but this is NOT a legal opinion. If you are concerned + about the applicability of ITAR regulations to this code then you + should confirm it for yourself (and maybe let me know if you come + up with a different answer to the one above) +*/ + + +static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4}; + +static const uint8_t perm2[48] = {14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32}; + +static const uint8_t perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7}; + +static const uint8_t perm4[48] = { 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1}; + +static const uint8_t perm5[32] = { 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25}; + + +static const uint8_t perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25}; + + +static const uint8_t sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + +static const uint8_t sbox[8][4][16] = { + {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; + +static void permute(char *out, const char *in, const uint8_t *p, int n) +{ + int i; + for (i=0;i>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } +} + +/* + basic des crypt using a 56 bit (7 byte) key +*/ +void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw) +{ + int i; + char outb[64]; + char inb[64]; + char keyb[64]; + uint8_t key2[8]; + + str_to_key(key, key2); + + for (i=0;i<64;i++) { + inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + outb[i] = 0; + } + + dohash(outb, inb, keyb, forw); + + for (i=0;i<8;i++) { + out[i] = 0; + } + + for (i=0;i<64;i++) { + if (outb[i]) + out[i/8] |= (1<<(7-(i%8))); + } +} + +void E_P16(const uint8_t *p14,uint8_t *p16) +{ + const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + des_crypt56(p16, sp8, p14, 1); + des_crypt56(p16+8, sp8, p14+7, 1); +} + +void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) +{ + des_crypt56(p24, c8, p21, 1); + des_crypt56(p24+8, c8, p21+7, 1); + des_crypt56(p24+16, c8, p21+14, 1); +} + +void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out) +{ + des_crypt56(out, in, p14, 0); + des_crypt56(out+8, in+8, p14+7, 0); +} + +void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) +{ + des_crypt56(out, in, p14, 1); + des_crypt56(out+8, in+8, p14+7, 1); +} + +/* des encryption with a 128 bit key */ +void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) +{ + uint8_t buf[8]; + des_crypt56(buf, in, key, 1); + des_crypt56(out, buf, key+9, 1); +} + +/* des encryption with a 64 bit key */ +void des_crypt64(uint8_t out[8], const uint8_t in[8], const uint8_t key[8], int forw) +{ + uint8_t buf[8]; + uint8_t key2[8]; + ZERO_STRUCT(key2); + des_crypt56(buf, in, key, forw); + key2[0] = key[7]; + des_crypt56(out, buf, key2, forw); +} + +/* des encryption with a 112 bit (14 byte) key */ +void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw) +{ + uint8_t buf[8]; + des_crypt56(buf, in, key, forw); + des_crypt56(out, buf, key+7, forw); +} + +/* des encryption of a 16 byte lump of data with a 112 bit key */ +void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int forw) +{ + des_crypt56(out, in, key, forw); + des_crypt56(out + 8, in + 8, key+7, forw); +} + +/* Decode a sam password hash into a password. The password hash is the + same method used to store passwords in the NT registry. The DES key + used is based on the RID of the user. */ +void sam_rid_crypt(uint_t rid, const uint8_t *in, uint8_t *out, int forw) +{ + uint8_t s[14]; + + s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF); + s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF); + s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); + s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); + + des_crypt56(out, in, s, forw); + des_crypt56(out+8, in+8, s+7, forw); +} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index dbeae51807..380beac287 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -2,15 +2,18 @@ include auth/config.mk include ldap/config.mk include security/config.mk -[SUBSYSTEM::LIBCLI_UTILS] -PRIVATE_PROTO_HEADER = util/proto.h -PUBLIC_HEADERS = util/nterr.h util/doserr.h util/nt_status.h -OBJ_FILES = util/asn1.o \ - util/doserr.o \ +[SUBSYSTEM::LIBSAMBA-ERRORS] +PUBLIC_PROTO_HEADER = util/proto.h +PUBLIC_HEADERS = util/error.h util/nterr.h util/doserr.h util/nt_status.h +OBJ_FILES = util/doserr.o \ util/errormap.o \ util/clierror.o \ util/nterr.o \ - util/smbdes.o + +[SUBSYSTEM::ASN1_UTIL] +PUBLIC_PROTO_HEADER = util/asn1_proto.h +PUBLIC_HEADERS = util/asn_1.h +OBJ_FILES = util/asn1.o [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h @@ -100,7 +103,7 @@ PUBLIC_HEADERS = libcli.h VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = SMB/CIFS client library -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \ +REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 624b2603ec..f59da733eb 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,7 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ - LIBPACKET +REQUIRED_SUBSYSTEMS = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ + LIBPACKET ASN1_UTIL # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index ba0f801832..30c5acc6fb 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -250,6 +250,7 @@ struct ldap_message { struct event_context; struct cli_credentials; struct dom_sid; +struct asn1_data; #include "libcli/ldap/ldap_proto.h" diff --git a/source4/libcli/util/asn_1.h b/source4/libcli/util/asn_1.h index 2dc9bef06d..7033f92a7f 100644 --- a/source4/libcli/util/asn_1.h +++ b/source4/libcli/util/asn_1.h @@ -50,4 +50,6 @@ struct asn1_data { #define ASN1_MAX_OIDS 20 +#include "libcli/util/asn1_proto.h" + #endif /* _ASN_1_H */ diff --git a/source4/libcli/util/error.h b/source4/libcli/util/error.h new file mode 100644 index 0000000000..4aa1ff6a40 --- /dev/null +++ b/source4/libcli/util/error.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + Error handling code + + 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. +*/ + +#ifndef _SAMBA_ERROR_H_ +#define _SAMBA_ERROR_H_ + +#include "libcli/util/nterr.h" +#include "libcli/util/doserr.h" +#include "libcli/util/proto.h" + +#endif /* _SAMBA_ERROR_H */ diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c deleted file mode 100644 index d392109b1e..0000000000 --- a/source4/libcli/util/smbdes.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a partial implementation of DES designed for use in the - SMB authentication protocol - - Copyright (C) Andrew Tridgell 1998 - - 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" - -/* NOTES: - - This code makes no attempt to be fast! In fact, it is a very - slow implementation - - This code is NOT a complete DES implementation. It implements only - the minimum necessary for SMB authentication, as used by all SMB - products (including every copy of Microsoft Windows95 ever sold) - - In particular, it can only do a unchained forward DES pass. This - means it is not possible to use this code for encryption/decryption - of data, instead it is only useful as a "hash" algorithm. - - There is no entry point into this code that allows normal DES operation. - - I believe this means that this code does not come under ITAR - regulations but this is NOT a legal opinion. If you are concerned - about the applicability of ITAR regulations to this code then you - should confirm it for yourself (and maybe let me know if you come - up with a different answer to the one above) -*/ - - -static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4}; - -static const uint8_t perm2[48] = {14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32}; - -static const uint8_t perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7}; - -static const uint8_t perm4[48] = { 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1}; - -static const uint8_t perm5[32] = { 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25}; - - -static const uint8_t perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25}; - - -static const uint8_t sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; - -static const uint8_t sbox[8][4][16] = { - {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, - {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, - {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, - - {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, - {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, - {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - - {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, - {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, - {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - - {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, - {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, - {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - - {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, - {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, - {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - - {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, - {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, - {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - - {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, - {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, - {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - - {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, - {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, - {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; - -static void permute(char *out, const char *in, const uint8_t *p, int n) -{ - int i; - for (i=0;i>1; - key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); - key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); - key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); - key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); - key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); - key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); - key[7] = str[6]&0x7F; - for (i=0;i<8;i++) { - key[i] = (key[i]<<1); - } -} - -/* - basic des crypt using a 56 bit (7 byte) key -*/ -void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw) -{ - int i; - char outb[64]; - char inb[64]; - char keyb[64]; - uint8_t key2[8]; - - str_to_key(key, key2); - - for (i=0;i<64;i++) { - inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - outb[i] = 0; - } - - dohash(outb, inb, keyb, forw); - - for (i=0;i<8;i++) { - out[i] = 0; - } - - for (i=0;i<64;i++) { - if (outb[i]) - out[i/8] |= (1<<(7-(i%8))); - } -} - -void E_P16(const uint8_t *p14,uint8_t *p16) -{ - const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - des_crypt56(p16, sp8, p14, 1); - des_crypt56(p16+8, sp8, p14+7, 1); -} - -void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) -{ - des_crypt56(p24, c8, p21, 1); - des_crypt56(p24+8, c8, p21+7, 1); - des_crypt56(p24+16, c8, p21+14, 1); -} - -void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out) -{ - des_crypt56(out, in, p14, 0); - des_crypt56(out+8, in+8, p14+7, 0); -} - -void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) -{ - des_crypt56(out, in, p14, 1); - des_crypt56(out+8, in+8, p14+7, 1); -} - -/* des encryption with a 128 bit key */ -void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) -{ - uint8_t buf[8]; - des_crypt56(buf, in, key, 1); - des_crypt56(out, buf, key+9, 1); -} - -/* des encryption with a 64 bit key */ -void des_crypt64(uint8_t out[8], const uint8_t in[8], const uint8_t key[8], int forw) -{ - uint8_t buf[8]; - uint8_t key2[8]; - ZERO_STRUCT(key2); - des_crypt56(buf, in, key, forw); - key2[0] = key[7]; - des_crypt56(out, buf, key2, forw); -} - -/* des encryption with a 112 bit (14 byte) key */ -void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw) -{ - uint8_t buf[8]; - des_crypt56(buf, in, key, forw); - des_crypt56(out, buf, key+7, forw); -} - -/* des encryption of a 16 byte lump of data with a 112 bit key */ -void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int forw) -{ - des_crypt56(out, in, key, forw); - des_crypt56(out + 8, in + 8, key+7, forw); -} - -/* Decode a sam password hash into a password. The password hash is the - same method used to store passwords in the NT registry. The DES key - used is based on the RID of the user. */ -void sam_rid_crypt(uint_t rid, const uint8_t *in, uint8_t *out, int forw) -{ - uint8_t s[14]; - - s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF); - s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF); - s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); - s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); - - des_crypt56(out, in, s, forw); - des_crypt56(out+8, in+8, s+7, forw); -} -- cgit From 8cd973decdc72b852417c55b913faad2a1f52183 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Mar 2006 11:05:33 +0000 Subject: r14840: - rename some functions - stack specific functions on top of generic ones metze (This used to be commit e391f3c98aae600c5f64d5975dd55567a09c3100) --- source4/libcli/security/security_token.c | 72 ++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 31 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 7ee3a68916..5fcde246ef 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -170,55 +170,65 @@ void security_token_debug(int dbg_lev, const struct security_token *token) /* These really should be cheaper... */ -BOOL is_system_token(struct security_token *token) +BOOL security_token_is_sid(struct security_token *token, const struct dom_sid *sid) { - TALLOC_CTX *mem_ctx = talloc_new(token); - if (dom_sid_equal(token->user_sid, dom_sid_parse_talloc(mem_ctx, SID_NT_SYSTEM))) { - talloc_free(mem_ctx); + if (dom_sid_equal(token->user_sid, sid)) { return True; } - talloc_free(mem_ctx); return False; } -BOOL is_anonymous_token(struct security_token *token) +BOOL security_token_is_sid_string(struct security_token *token, const char *sid_string) { - TALLOC_CTX *mem_ctx = talloc_new(token); - if (dom_sid_equal(token->user_sid, dom_sid_parse_talloc(mem_ctx, SID_NT_ANONYMOUS))) { - talloc_free(mem_ctx); - return True; - } - talloc_free(mem_ctx); - return False; + BOOL ret; + struct dom_sid *sid = dom_sid_parse_talloc(token, sid_string); + if (!sid) return False; + + ret = security_token_is_sid(token, sid); + + talloc_free(sid); + return ret; } -BOOL is_authenticated_token(struct security_token *token) +BOOL security_token_is_system(struct security_token *token) { - TALLOC_CTX *mem_ctx = talloc_new(token); - int i; - struct dom_sid *authenticated = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHENTICATED_USERS); - for (i = 0; i < token->num_sids; i++) { - if (dom_sid_equal(token->sids[i], authenticated)) { - talloc_free(mem_ctx); - return True; - } - } - talloc_free(mem_ctx); - return False; + return security_token_is_sid_string(token, SID_NT_SYSTEM); } -BOOL is_administrator_token(struct security_token *token) +BOOL security_token_is_anonymous(struct security_token *token) +{ + return security_token_is_sid_string(token, SID_NT_ANONYMOUS); +} + +BOOL security_token_has_sid(struct security_token *token, struct dom_sid *sid) { - TALLOC_CTX *mem_ctx = talloc_new(token); int i; - struct dom_sid *administrators = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN_ADMINISTRATORS); for (i = 0; i < token->num_sids; i++) { - if (dom_sid_equal(token->sids[i], administrators)) { - talloc_free(mem_ctx); + if (dom_sid_equal(token->sids[i], sid)) { return True; } } - talloc_free(mem_ctx); return False; } +BOOL security_token_has_sid_string(struct security_token *token, const char *sid_string) +{ + BOOL ret; + struct dom_sid *sid = dom_sid_parse_talloc(token, sid_string); + if (!sid) return False; + + ret = security_token_has_sid(token, sid); + + talloc_free(sid); + return ret; +} + +BOOL security_token_has_builtin_administrators(struct security_token *token) +{ + return security_token_has_sid_string(token, SID_BUILTIN_ADMINISTRATORS); +} + +BOOL security_token_has_nt_authenticated_users(struct security_token *token) +{ + return security_token_has_sid_string(token, SID_NT_AUTHENTICATED_USERS); +} -- cgit From 508ba6026a0c958ac71762d36086742ec4825143 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 2 Apr 2006 11:19:21 +0000 Subject: r14859: fix bugs noticed by the ibm code checker metze (This used to be commit afa8f944a7c572becd011b8c248eef13d7495ac7) --- source4/libcli/raw/rawrequest.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index b07a92e3fa..24390cd9e7 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -850,13 +850,17 @@ size_t smbcli_blob_pull_string(struct smbcli_session *session, int extra; dest->s = NULL; - /* this is here to cope with SMB2 calls using the SMB - parsers. SMB2 will pass smbcli_session==NULL, which forces - unicode on (as used by SMB2) */ - if (session == NULL && !(flags & STR_ASCII)) { - flags |= STR_UNICODE; + if (!(flags & STR_ASCII)) { + /* this is here to cope with SMB2 calls using the SMB + parsers. SMB2 will pass smbcli_session==NULL, which forces + unicode on (as used by SMB2) */ + if (session == NULL) { + flags |= STR_UNICODE; + } else if (session->transport->negotiate.capabilities & CAP_UNICODE) { + flags |= STR_UNICODE; + } } - + if (flags & STR_LEN8BIT) { if (len_offset > blob->length-1) { return 0; @@ -870,9 +874,7 @@ size_t smbcli_blob_pull_string(struct smbcli_session *session, } extra = 0; dest->s = NULL; - if (!(flags & STR_ASCII) && - ((flags & STR_UNICODE) || - (session->transport->negotiate.capabilities & CAP_UNICODE))) { + if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) { int align = 0; if ((str_offset&1) && !(flags & STR_NOALIGN)) { align = 1; -- cgit From 1af925f394b1084779f5b1b5a10c2ec512d7e5be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 2 Apr 2006 12:02:01 +0000 Subject: r14860: create libcli/security/security.h metze (This used to be commit 9ec706238c173992dc938d537bdf1103bf519dbf) --- source4/libcli/cldap/cldap.c | 2 +- source4/libcli/security/access_check.c | 3 +-- source4/libcli/security/sddl.c | 2 +- source4/libcli/security/security.h | 22 ++++++++++++++++++++++ source4/libcli/security/security_descriptor.c | 3 +-- source4/libcli/security/security_token.c | 2 +- source4/libcli/smb_composite/appendacl.c | 2 +- source4/libcli/util/clilsa.c | 2 +- 8 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 source4/libcli/security/security.h (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 2773dba1d7..7a484607a7 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -38,7 +38,7 @@ #include "libcli/ldap/ldap.h" #include "libcli/cldap/cldap.h" #include "lib/socket/socket.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_nbt.h" /* diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index 1617963998..cd877db9c5 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -21,8 +21,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/security.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" /* diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 38192fc60c..46183ce237 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -23,7 +23,7 @@ #include "includes.h" #include "system/iconv.h" #include "librpc/gen_ndr/ndr_security.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" struct flag_map { const char *name; diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h new file mode 100644 index 0000000000..eca6878031 --- /dev/null +++ b/source4/libcli/security/security.h @@ -0,0 +1,22 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2006 + + 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 "librpc/gen_ndr/security.h" +#include "libcli/security/proto.h" diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 1da3e2e750..f7972f57ac 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -21,8 +21,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/security.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" /* return a blank security descriptor (no owners, dacl or sacl) diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 5fcde246ef..6e380a62ad 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -23,7 +23,7 @@ #include "includes.h" #include "dsdb/samdb/samdb.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" /* diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index 55aa727729..f82714de5b 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -1,7 +1,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "libcli/smb_composite/smb_composite.h" /* the stages of this call */ diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index fab392ac04..f5e49dd577 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -29,7 +29,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_lsa_c.h" -- cgit From 69e40fa99af88f5cf78409c6ac5ebe8ca611ccb2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Apr 2006 06:43:30 +0000 Subject: r14876: added ENOSYS to unix error mapping (This used to be commit 77f32a273541afcd07f6da8a26315bf21ea05c51) --- source4/libcli/util/errormap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index bbaac629e4..f4feaeffc5 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1337,6 +1337,9 @@ const struct unix_error_map unix_nt_errmap[] = { #endif #ifdef ENODEV { ENODEV, NT_STATUS_NO_SUCH_DEVICE }, +#endif +#ifdef ENOSYS + { ENOSYS, NT_STATUS_INVALID_SYSTEM_SERVICE }, #endif { 0, NT_STATUS_UNSUCCESSFUL } }; -- cgit From 5559f5e3e5b283a4fe85984589d61598b14fcfff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 3 Apr 2006 14:39:46 +0000 Subject: r14891: fix a bug found by the ibm checker the problem was that we shift with <<= (privilege-1) and we called the function with privilege=0 add some checks to catch invalid privilege values and hide the mask representation in privilege.c metze (This used to be commit a69f000324764bcd4cf420f2ecba1aca788258e4) --- source4/libcli/security/privilege.c | 53 +++++++++++++++++++++++++++----- source4/libcli/security/security_token.c | 17 +--------- 2 files changed, 46 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 202a418f6b..f81ff6dccc 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -130,7 +130,7 @@ static const struct { /* map a privilege id to the wire string constant */ -const char *sec_privilege_name(unsigned int privilege) +const char *sec_privilege_name(enum sec_privilege privilege) { int i; for (i=0;i 64) { + return NULL; + } for (i=0;i 64) { + return 0; + } + mask <<= (privilege-1); return mask; } @@ -186,9 +194,15 @@ uint64_t sec_privilege_mask(unsigned int privilege) /* return True if a security_token has a particular privilege bit set */ -BOOL sec_privilege_check(const struct security_token *token, unsigned int privilege) +BOOL sec_privilege_check(const struct security_token *token, enum sec_privilege privilege) { - uint64_t mask = sec_privilege_mask(privilege); + uint64_t mask; + + if (privilege < 1 || privilege > 64) { + return False; + } + + mask = sec_privilege_mask(privilege); if (token->privilege_mask & mask) { return True; } @@ -198,7 +212,30 @@ BOOL sec_privilege_check(const struct security_token *token, unsigned int privil /* set a bit in the privilege mask */ -void sec_privilege_set(struct security_token *token, unsigned int privilege) +void sec_privilege_set(struct security_token *token, enum sec_privilege privilege) { + if (privilege < 1 || privilege > 64) { + return; + } token->privilege_mask |= sec_privilege_mask(privilege); } + +void sec_privilege_debug(int dbg_lev, const struct security_token *token) +{ + DEBUGADD(dbg_lev, (" Privileges (0x%16llX):\n", + (unsigned long long) token->privilege_mask)); + + if (token->privilege_mask) { + int i = 0; + uint_t privilege; + + for (privilege = 1; privilege <= 64; privilege++) { + uint64_t mask = sec_privilege_mask(privilege); + + if (token->privilege_mask & mask) { + DEBUGADD(dbg_lev, (" Privilege[%3lu]: %s\n", (unsigned long)i++, + sec_privilege_name(privilege))); + } + } + } +} diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 6e380a62ad..80644e1f2d 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -128,7 +128,6 @@ void security_token_debug(int dbg_lev, const struct security_token *token) { TALLOC_CTX *mem_ctx; int i; - uint_t privilege; if (!token) { DEBUG(dbg_lev, ("Security token: (NULL)\n")); @@ -149,21 +148,7 @@ void security_token_debug(int dbg_lev, const struct security_token *token) dom_sid_string(mem_ctx, token->sids[i]))); } - DEBUGADD(dbg_lev, (" Privileges (0x%08X%08X):\n", - (uint32_t)((token->privilege_mask & 0xFFFFFFFF00000000LL) >> 32), - (uint32_t)(token->privilege_mask & 0x00000000FFFFFFFFLL))); - - if (token->privilege_mask) { - i = 0; - for (privilege = 0; privilege < 64; privilege++) { - uint64_t mask = sec_privilege_mask(privilege); - - if (token->privilege_mask & mask) { - DEBUGADD(dbg_lev, (" Privilege[%3lu]: %s\n", (unsigned long)i++, - sec_privilege_name(privilege))); - } - } - } + sec_privilege_debug(dbg_lev, token); talloc_free(mem_ctx); } -- cgit From 1ac990ddcf8501ce551c87e70cb3722ae9f4f34b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 3 Apr 2006 15:18:12 +0000 Subject: r14894: - add some 'const' - remove sid_active_in_token() was the same as security_token_has_sid() - rename some functions metze (This used to be commit 81390dcda50f53d61e70059fb33014de0d283dc5) --- source4/libcli/security/access_check.c | 30 +++++++----------------------- source4/libcli/security/privilege.c | 6 +++--- source4/libcli/security/security_token.c | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 37 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index cd877db9c5..f0a46cc23d 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -24,22 +24,6 @@ #include "libcli/security/security.h" -/* - check if a sid is in the supplied token -*/ -static BOOL sid_active_in_token(const struct dom_sid *sid, - const struct security_token *token) -{ - int i; - for (i=0;inum_sids;i++) { - if (dom_sid_equal(sid, token->sids[i])) { - return True; - } - } - return False; -} - - /* perform a SEC_FLAG_MAXIMUM_ALLOWED access check */ @@ -49,9 +33,9 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, uint32_t denied = 0, granted = 0; unsigned i; - if (sid_active_in_token(sd->owner_sid, token)) { + if (security_token_has_sid(token, sd->owner_sid)) { granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE; - } else if (sec_privilege_check(token, SEC_PRIV_RESTORE)) { + } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) { granted |= SEC_STD_DELETE; } @@ -62,7 +46,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, continue; } - if (!sid_active_in_token(&ace->trustee, token)) { + if (!security_token_has_sid(token, &ace->trustee)) { continue; } @@ -105,7 +89,7 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, } if (access_desired & SEC_FLAG_SYSTEM_SECURITY) { - if (sec_privilege_check(token, SEC_PRIV_SECURITY)) { + if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) { bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; } else { return NT_STATUS_ACCESS_DENIED; @@ -125,11 +109,11 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */ if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) && - sid_active_in_token(sd->owner_sid, token)) { + security_token_has_sid(token, sd->owner_sid)) { bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE); } if ((bits_remaining & SEC_STD_DELETE) && - sec_privilege_check(token, SEC_PRIV_RESTORE)) { + security_token_has_privilege(token, SEC_PRIV_RESTORE)) { bits_remaining &= ~SEC_STD_DELETE; } @@ -141,7 +125,7 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, continue; } - if (!sid_active_in_token(&ace->trustee, token)) { + if (!security_token_has_sid(token, &ace->trustee)) { continue; } diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index f81ff6dccc..b4855b59e2 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -194,7 +194,7 @@ static uint64_t sec_privilege_mask(enum sec_privilege privilege) /* return True if a security_token has a particular privilege bit set */ -BOOL sec_privilege_check(const struct security_token *token, enum sec_privilege privilege) +BOOL security_token_has_privilege(const struct security_token *token, enum sec_privilege privilege) { uint64_t mask; @@ -212,7 +212,7 @@ BOOL sec_privilege_check(const struct security_token *token, enum sec_privilege /* set a bit in the privilege mask */ -void sec_privilege_set(struct security_token *token, enum sec_privilege privilege) +void security_token_set_privilege(struct security_token *token, enum sec_privilege privilege) { if (privilege < 1 || privilege > 64) { return; @@ -220,7 +220,7 @@ void sec_privilege_set(struct security_token *token, enum sec_privilege privileg token->privilege_mask |= sec_privilege_mask(privilege); } -void sec_privilege_debug(int dbg_lev, const struct security_token *token) +void security_token_debug_privileges(int dbg_lev, const struct security_token *token) { DEBUGADD(dbg_lev, (" Privileges (0x%16llX):\n", (unsigned long long) token->privilege_mask)); diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 80644e1f2d..d872376bff 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -148,14 +148,14 @@ void security_token_debug(int dbg_lev, const struct security_token *token) dom_sid_string(mem_ctx, token->sids[i]))); } - sec_privilege_debug(dbg_lev, token); + security_token_debug_privileges(dbg_lev, token); talloc_free(mem_ctx); } /* These really should be cheaper... */ -BOOL security_token_is_sid(struct security_token *token, const struct dom_sid *sid) +BOOL security_token_is_sid(const struct security_token *token, const struct dom_sid *sid) { if (dom_sid_equal(token->user_sid, sid)) { return True; @@ -163,10 +163,10 @@ BOOL security_token_is_sid(struct security_token *token, const struct dom_sid *s return False; } -BOOL security_token_is_sid_string(struct security_token *token, const char *sid_string) +BOOL security_token_is_sid_string(const struct security_token *token, const char *sid_string) { BOOL ret; - struct dom_sid *sid = dom_sid_parse_talloc(token, sid_string); + struct dom_sid *sid = dom_sid_parse_talloc(NULL, sid_string); if (!sid) return False; ret = security_token_is_sid(token, sid); @@ -175,17 +175,17 @@ BOOL security_token_is_sid_string(struct security_token *token, const char *sid_ return ret; } -BOOL security_token_is_system(struct security_token *token) +BOOL security_token_is_system(const struct security_token *token) { return security_token_is_sid_string(token, SID_NT_SYSTEM); } -BOOL security_token_is_anonymous(struct security_token *token) +BOOL security_token_is_anonymous(const struct security_token *token) { return security_token_is_sid_string(token, SID_NT_ANONYMOUS); } -BOOL security_token_has_sid(struct security_token *token, struct dom_sid *sid) +BOOL security_token_has_sid(const struct security_token *token, const struct dom_sid *sid) { int i; for (i = 0; i < token->num_sids; i++) { @@ -196,10 +196,10 @@ BOOL security_token_has_sid(struct security_token *token, struct dom_sid *sid) return False; } -BOOL security_token_has_sid_string(struct security_token *token, const char *sid_string) +BOOL security_token_has_sid_string(const struct security_token *token, const char *sid_string) { BOOL ret; - struct dom_sid *sid = dom_sid_parse_talloc(token, sid_string); + struct dom_sid *sid = dom_sid_parse_talloc(NULL, sid_string); if (!sid) return False; ret = security_token_has_sid(token, sid); @@ -208,12 +208,12 @@ BOOL security_token_has_sid_string(struct security_token *token, const char *sid return ret; } -BOOL security_token_has_builtin_administrators(struct security_token *token) +BOOL security_token_has_builtin_administrators(const struct security_token *token) { return security_token_has_sid_string(token, SID_BUILTIN_ADMINISTRATORS); } -BOOL security_token_has_nt_authenticated_users(struct security_token *token) +BOOL security_token_has_nt_authenticated_users(const struct security_token *token) { return security_token_has_sid_string(token, SID_NT_AUTHENTICATED_USERS); } -- cgit From fd25c102849779fd5f0153d34c8ac3b82ddeca0c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 03:31:31 +0000 Subject: r14938: add smbcli_fsetatr() as a convenient interface to a setfileinfo for torture testing. Used by RAW-NOTIFY. (This used to be commit 517db1b1b0061be57c67ea02d42000fb8ace844d) --- source4/libcli/clifile.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index cc0c14a2e8..3acd215f3e 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -588,6 +588,29 @@ NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mod return status; } +/**************************************************************************** + Do a setfileinfo basic_info call. +****************************************************************************/ +NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode, + NTTIME create_time, NTTIME access_time, + NTTIME write_time, NTTIME change_time) +{ + union smb_setfileinfo parms; + NTSTATUS status; + + parms.basic_info.level = RAW_SFILEINFO_BASIC_INFO; + parms.basic_info.in.file.fnum = fnum; + parms.basic_info.in.attrib = mode; + parms.basic_info.in.create_time = create_time; + parms.basic_info.in.access_time = access_time; + parms.basic_info.in.write_time = write_time; + parms.basic_info.in.change_time = change_time; + + status = smb_raw_setfileinfo(tree, &parms); + + return status; +} + /**************************************************************************** Check for existence of a dir. -- cgit From 8be91f2d0fa38e0dbc19ce8a6bcb382a989459ab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 11:06:28 +0000 Subject: r14946: added a smbcli_ftruncate() call, useful for torture testing (This used to be commit b8b9acc60003c86fb1f0377b46f65155c3b898a9) --- source4/libcli/clifile.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 3acd215f3e..ce49cdea70 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -576,16 +576,13 @@ NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mod time_t t) { union smb_setfileinfo parms; - NTSTATUS status; parms.setattr.level = RAW_SFILEINFO_SETATTR; parms.setattr.in.file.path = fname; parms.setattr.in.attrib = mode; parms.setattr.in.write_time = t; - status = smb_raw_setpathinfo(tree, &parms); - - return status; + return smb_raw_setpathinfo(tree, &parms); } /**************************************************************************** @@ -596,7 +593,6 @@ NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode, NTTIME write_time, NTTIME change_time) { union smb_setfileinfo parms; - NTSTATUS status; parms.basic_info.level = RAW_SFILEINFO_BASIC_INFO; parms.basic_info.in.file.fnum = fnum; @@ -606,9 +602,22 @@ NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode, parms.basic_info.in.write_time = write_time; parms.basic_info.in.change_time = change_time; - status = smb_raw_setfileinfo(tree, &parms); + return smb_raw_setfileinfo(tree, &parms); +} - return status; + +/**************************************************************************** + truncate a file to a given size +****************************************************************************/ +NTSTATUS smbcli_ftruncate(struct smbcli_tree *tree, int fnum, uint64_t size) +{ + union smb_setfileinfo parms; + + parms.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFO; + parms.end_of_file_info.in.file.fnum = fnum; + parms.end_of_file_info.in.size = size; + + return smb_raw_setfileinfo(tree, &parms); } -- cgit From 7789fa412d3dcb70ed06fdccbda65f2a3eef06ee Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Apr 2006 02:33:24 +0000 Subject: r14973: req cannot be NULL in smb_raw_t2open_recv() (found by IBM checker) (This used to be commit c2cde823ee004b53707acd1390d25fa9856b5179) --- source4/libcli/raw/rawfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index d889b500fb..2873011aa2 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -396,7 +396,7 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, ****************************************************************************/ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) { - struct smbcli_transport *transport = req?req->transport:NULL; + struct smbcli_transport *transport = req->transport; struct smb_trans2 t2; NTSTATUS status; -- cgit From eae0b77a6e4ef80f7dd0749db5cfa15902e857ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Apr 2006 02:35:00 +0000 Subject: r14974: work around an ibm checker bug (This used to be commit 2031e07a8a14d83ab621f8baaae6b4e1425667d7) --- source4/libcli/raw/rawioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index db980a55d6..d4a299fe02 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -73,13 +73,13 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, union smb_ioctl *parms) { struct smb_nttrans nt; - uint16_t setup[4]; + uint8_t setup[8]; nt.in.max_setup = 0; nt.in.max_param = 0; nt.in.max_data = 0; nt.in.setup_count = 4; - nt.in.setup = setup; + nt.in.setup = (uint16_t *)setup; SIVAL(setup, 0, parms->ntioctl.in.function); SSVAL(setup, 4, parms->ntioctl.in.file.fnum); SCVAL(setup, 6, parms->ntioctl.in.fsctl); -- cgit From 3f9628ac7c613def7dcce740e88964638b4b6102 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Apr 2006 13:53:27 +0000 Subject: r15079: w2k3 returns NT_STATUS_PRIVILEGE_NOT_HELD if SEC_FLAG_SYSTEM_SECURITY is desired but SeSecurityPrivilege isn't granted metze (This used to be commit be7285bdebd58e7a86fcc64f7b22b9f533bcc4f5) --- source4/libcli/security/access_check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index f0a46cc23d..ea63369303 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -92,7 +92,7 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) { bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; } else { - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_PRIVILEGE_NOT_HELD; } } -- cgit From acc051674226d60a4d9739d883b2261ce98d651c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 18 Apr 2006 13:05:24 +0000 Subject: r15121: fix pushing of the FLAGS2_READ_PERMIT_EXECUTE flag in the "readx.read_for_execute = True" case. metze (This used to be commit f30f9cd3285f75ac8cbbe8dc5a476fe6a714a2e3) --- source4/libcli/raw/rawreadwrite.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 7f1aaf26d4..7b424df6df 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -85,7 +85,9 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea SIVAL(req->out.vwv, VWV(10),parms->readx.in.offset>>32); } if (parms->readx.in.read_for_execute) { - req->flags2 |= FLAGS2_READ_PERMIT_EXECUTE; + uint16_t flags2 = SVAL(req->out.hdr, HDR_FLG2); + flags2 |= FLAGS2_READ_PERMIT_EXECUTE; + SSVAL(req->out.hdr, HDR_FLG2, flags2); } break; } -- cgit From 60f3ef505238aaceb40101d5e839d2e303c9c7bd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 23 Apr 2006 17:22:32 +0000 Subject: r15181: Don't try kerberos sign/seal when in SSL (This used to be commit 3be3b1130c41e8e372531c137c46f91c5c0acf98) --- source4/libcli/ldap/ldap_bind.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index cacb0d150e..585bdbb234 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -25,6 +25,7 @@ #include "includes.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" +#include "lib/tls/tls.h" #include "auth/auth.h" static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, @@ -173,7 +174,11 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } - gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + /* require Kerberos SIGN/SEAL only if we don't use SSL + * Windows seem not to like double encryption */ + if (conn->tls == NULL || (! tls_enabled(conn->tls))) { + gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + } status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { -- cgit From 6ab33938d5239e8688440f65e802f627622d301b Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 24 Apr 2006 00:16:51 +0000 Subject: r15186: Introduce ISDOT and ISDOTDOT macros for testing whether a filename is "." for "..". These express the intention better that strcmp or strequal and improve searchability via cscope/ctags. (This used to be commit 7e4ad7e8e5ec266b969e3075c4ad7f021571f24e) --- source4/libcli/clideltree.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 0c65d993c8..51b4e6568d 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" +#include "system/dir.h" struct delete_state { struct smbcli_tree *tree; @@ -35,8 +36,9 @@ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *s { struct delete_state *dstate = state; char *s, *n; - if (strcmp(finfo->name, ".") == 0 || - strcmp(finfo->name, "..") == 0) return; + if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { + return; + } n = strdup(name); n[strlen(n)-1] = 0; -- cgit From 0eddf14b307e905663b95296aa695a10d3fb90f7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 09:36:09 +0000 Subject: r15191: Avoid uint_t as it's not standard. (This used to be commit 7af59357b94e3819415b3a9257be0ced745ce130) --- source4/libcli/raw/raweas.c | 4 ++-- source4/libcli/raw/rawnotify.c | 2 +- source4/libcli/raw/rawrequest.c | 6 +++--- source4/libcli/raw/request.h | 8 ++++---- source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/smb2/request.c | 2 +- source4/libcli/smb2/smb2.h | 8 ++++---- 7 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 4c609aa593..26b04838d6 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -26,7 +26,7 @@ This assumes the names are strict ascii, which should be a reasonable assumption */ -uint_t ea_list_size(uint_t num_eas, struct ea_struct *eas) +size_t ea_list_size(uint_t num_eas, struct ea_struct *eas) { uint_t total = 4; int i; @@ -54,7 +54,7 @@ static uint_t ea_name_list_size(uint_t num_names, struct ea_name *eas) This assumes the names are strict ascii, which should be a reasonable assumption */ -uint_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas) +size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas) { uint_t total = 0; int i; diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 8ae5098c01..f4d4164016 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -96,7 +96,7 @@ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, we need to do find out to what request the reply belongs ****************************************************************************/ struct smbcli_request *smbcli_handle_ntcancel_reply(struct smbcli_request *req, - uint_t len, const uint8_t *hdr) + size_t len, const uint8_t *hdr) { struct smbcli_request *ntcancel; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 24390cd9e7..f042c7b581 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -64,7 +64,7 @@ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) low-level function to setup a request buffer for a non-SMB packet at the transport level */ -struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, uint_t size) +struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, size_t size) { struct smbcli_request *req; @@ -147,7 +147,7 @@ struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *t way. This interface is used before a session is setup. */ struct smbcli_request *smbcli_request_setup_session(struct smbcli_session *session, - uint8_t command, uint_t wct, uint_t buflen) + uint8_t command, uint_t wct, size_t buflen) { struct smbcli_request *req; @@ -254,7 +254,7 @@ static void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size) */ NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req, uint8_t command, - uint_t wct, uint_t buflen) + uint_t wct, size_t buflen) { uint_t new_size = 1 + (wct*2) + 2 + buflen; diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h index 4a569cfe66..fedebf4c8d 100644 --- a/source4/libcli/raw/request.h +++ b/source4/libcli/raw/request.h @@ -32,12 +32,12 @@ struct request_buffer { uint8_t *buffer; /* the size of the raw buffer, including 4 byte header */ - uint_t size; + size_t size; /* how much has been allocated - on reply the buffer is over-allocated to prevent too many realloc() calls */ - uint_t allocated; + size_t allocated; /* the start of the SMB header - this is always buffer+4 */ uint8_t *hdr; @@ -45,11 +45,11 @@ struct request_buffer { /* the command words and command word count. vwv points into the raw buffer */ uint8_t *vwv; - uint_t wct; + size_t wct; /* the data buffer and size. data points into the raw buffer */ uint8_t *data; - uint_t data_size; + size_t data_size; /* ptr is used as a moving pointer into the data area * of the packet. The reason its here and not a local diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index a73db78f7b..541fd1fb8c 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -101,7 +101,7 @@ BOOL signing_good(struct smb_signing_context *sign_info, return True; } -void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_t seq_num) +void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) { uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1f3e2f54e4..2476270d49 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -168,7 +168,7 @@ BOOL smb2_request_is_ok(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) +BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) { /* be careful with wraparound! */ if (ptr < buf->body || diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index ceafacf9d4..33df4daabe 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -75,19 +75,19 @@ struct smb2_request_buffer { uint8_t *buffer; /* the size of the raw buffer, including 4 byte header */ - uint_t size; + size_t size; /* how much has been allocated - on reply the buffer is over-allocated to prevent too many realloc() calls */ - uint_t allocated; + size_t allocated; /* the start of the SMB2 header - this is always buffer+4 */ uint8_t *hdr; /* the packet body */ uint8_t *body; - uint_t body_size; + size_t body_size; /* this point to the next dynamic byte that can be used * this will be moved when some dynamic data is pushed @@ -183,7 +183,7 @@ struct smb2_request { check that a body has the expected size */ #define SMB2_CHECK_PACKET_RECV(req, size, dynamic) do { \ - uint_t is_size = req->in.body_size; \ + size_t is_size = req->in.body_size; \ uint16_t field_size = SVAL(req->in.body, 0); \ uint16_t want_size = ((dynamic)?(size)+1:(size)); \ if (is_size < (size)) { \ -- cgit From 69b51f702af1ded825d5c17bdb97014cac12e752 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 15:47:59 +0000 Subject: r15207: Introduce PRIVATE_DEPENDENCIES and PUBLIC_DEPENDENCIES as replacement for REQUIRED_SUBSYSTEMS. (This used to be commit adc8a019b6da256f104abed1b82bfde6998a2ac9) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 26 +++++++++++++------------- source4/libcli/ldap/config.mk | 2 +- source4/libcli/security/config.mk | 2 +- source4/libcli/smb2/config.mk | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 3f036fbfd4..756ea0ecbf 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -7,7 +7,7 @@ OBJ_FILES = credentials.o \ session.o \ smbencrypt.o \ smbdes.o -REQUIRED_SUBSYSTEMS = \ +PUBLIC_DEPENDENCIES = \ auth SCHANNELDB MSRPC_PARSE # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 380beac287..e646985a78 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -18,13 +18,13 @@ OBJ_FILES = util/asn1.o [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h OBJ_FILES = util/clilsa.o -REQUIRED_SUBSYSTEMS = RPC_NDR_LSA +PUBLIC_DEPENDENCIES = RPC_NDR_LSA [SUBSYSTEM::LIBCLI_COMPOSITE] PRIVATE_PROTO_HEADER = composite/proto.h OBJ_FILES = \ composite/composite.o -REQUIRED_SUBSYSTEMS = LIBEVENTS +PUBLIC_DEPENDENCIES = LIBEVENTS [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] PRIVATE_PROTO_HEADER = smb_composite/proto.h @@ -36,7 +36,7 @@ OBJ_FILES = \ smb_composite/fetchfile.o \ smb_composite/appendacl.o \ smb_composite/fsinfo.o -REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE +PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h @@ -53,7 +53,7 @@ OBJ_FILES = \ nbt/nameregister.o \ nbt/namerefresh.o \ nbt/namerelease.o -REQUIRED_SUBSYSTEMS = LIBNDR NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY [SUBSYSTEM::LIBCLI_DGRAM] @@ -63,7 +63,7 @@ OBJ_FILES = \ dgram/netlogon.o \ dgram/ntlogon.o \ dgram/browse.o -REQUIRED_SUBSYSTEMS = LIBCLI_NBT +PUBLIC_DEPENDENCIES = LIBCLI_NBT [LIBRARY::LIBCLI_CLDAP] VERSION = 0.0.1 @@ -71,7 +71,7 @@ SO_VERSION = 0 DESCRIPTION = CLDAP client library OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h -REQUIRED_SUBSYSTEMS = LIBCLI_LDAP +PUBLIC_DEPENDENCIES = LIBCLI_LDAP [LIBRARY::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h @@ -80,7 +80,7 @@ SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o -REQUIRED_SUBSYSTEMS = NDR_WINSREPL SOCKET LIBEVENTS +PUBLIC_DEPENDENCIES = NDR_WINSREPL SOCKET LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h @@ -90,25 +90,25 @@ OBJ_FILES = \ resolve/bcast.o \ resolve/wins.o \ resolve/host.o -REQUIRED_SUBSYSTEMS = LIBCLI_NBT LIBNETIF +PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNETIF [SUBSYSTEM::LIBCLI_FINDDCS] PRIVATE_PROTO_HEADER = finddcs.h OBJ_FILES = \ finddcs.o -REQUIRED_SUBSYSTEMS = LIBCLI_NBT MESSAGING +PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING [LIBRARY::LIBCLI] PUBLIC_HEADERS = libcli.h VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = SMB/CIFS client library -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ +PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS [SUBSYSTEM::LIBSMB] -REQUIRED_SUBSYSTEMS = LIBCLI SOCKET +PUBLIC_DEPENDENCIES = LIBCLI SOCKET PUBLIC_PROTO_HEADER = libcli_proto.h OBJ_FILES = clireadwrite.o \ cliconnect.o \ @@ -120,7 +120,7 @@ OBJ_FILES = clireadwrite.o \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -REQUIRED_SUBSYSTEMS = LIBCLI_RAW_KRB5 +PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ raw/clisocket.o \ @@ -142,6 +142,6 @@ OBJ_FILES = raw/rawfile.o \ raw/rawacl.o \ raw/rawdate.o \ raw/rawlpq.o -REQUIRED_SUBSYSTEMS = LIBPACKET gensec +PUBLIC_DEPENDENCIES = LIBPACKET gensec include smb2/config.mk diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index f59da733eb..26f230d7ef 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,7 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -REQUIRED_SUBSYSTEMS = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ LIBPACKET ASN1_UTIL # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 3202def26c..fb4f1f71b7 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -8,6 +8,6 @@ OBJ_FILES = security_token.o \ access_check.o \ privilege.o \ sddl.o -REQUIRED_SUBSYSTEMS = NDR_SECURITY +PUBLIC_DEPENDENCIES = NDR_SECURITY # End SUBSYSTEM LIB_SECURITY ################################# diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 929a6135fa..4e2e7bb468 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -19,4 +19,4 @@ OBJ_FILES = \ tdis.o \ flush.o \ keepalive.o -REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET gensec +PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec -- cgit From cc11de1e3e938fc65e99e2c597e6f25659371e87 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Apr 2006 06:53:28 +0000 Subject: r15225: Use talloc_zero() to avoid use of uninitialised values later on. Andrew Bartlett (This used to be commit e312cddafd7e00680dd059fad7ef7e5ecdbbb484) --- source4/libcli/finddcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 9ed20b77ba..aa755b5749 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -70,7 +70,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, struct finddcs_state *state; struct nbt_name name; - result = talloc(mem_ctx, struct composite_context); + result = talloc_zero(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; -- cgit From 8f164299473553ee28f4fbf1d9a120840c5e5feb Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 25 Apr 2006 11:50:32 +0000 Subject: r15238: Add some code to automatically reconnect if we want to. (This used to be commit e2102999e26566543162455b34adbd2b0486b74d) --- source4/libcli/ldap/ldap_bind.c | 53 ++++++++++++++++++++++++++ source4/libcli/ldap/ldap_client.c | 78 ++++++++++++++++++++++++++++++++++----- source4/libcli/ldap/ldap_client.h | 14 ++++++- 3 files changed, 134 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 585bdbb234..c33d53f775 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -28,6 +28,39 @@ #include "lib/tls/tls.h" #include "auth/auth.h" +struct ldap_simple_creds { + const char *dn; + const char *pw; +}; + +NTSTATUS ldap_rebind(struct ldap_connection *conn) +{ + NTSTATUS status; + struct ldap_simple_creds *creds; + + switch (conn->bind.type) { + case LDAP_BIND_SASL: + status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds); + break; + + case LDAP_BIND_SIMPLE: + creds = (struct ldap_simple_creds *)conn->bind.creds; + + if (creds == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + + status = ldap_bind_simple(conn, creds->dn, creds->pw); + break; + + default: + return NT_STATUS_UNSUCCESSFUL; + } + + return status; +} + + static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, const char *dn, const char *pw) { @@ -110,6 +143,20 @@ NTSTATUS ldap_bind_simple(struct ldap_connection *conn, talloc_free(req); + if (NT_STATUS_IS_OK(status)) { + struct ldap_simple_creds *creds = talloc(conn, struct ldap_simple_creds); + if (creds == NULL) { + return NT_STATUS_NO_MEMORY; + } + creds->dn = talloc_strdup(creds, dn); + creds->pw = talloc_strdup(creds, pw); + if (creds->dn == NULL || creds->pw == NULL) { + return NT_STATUS_NO_MEMORY; + } + conn->bind.type = LDAP_BIND_SIMPLE; + conn->bind.creds = creds; + } + return status; } @@ -325,6 +372,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } talloc_free(tmp_ctx); + + if (NT_STATUS_IS_OK(status)) { + conn->bind.type = LDAP_BIND_SASL; + conn->bind.creds = creds; + } + return status; failed: diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 364961cf47..344605f4ec 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -33,6 +33,7 @@ #include "libcli/composite/composite.h" #include "lib/stream/packet.h" #include "auth/gensec/gensec.h" +#include "system/time.h" /* @@ -62,10 +63,12 @@ struct ldap_connection *ldap_new_connection(TALLOC_CTX *mem_ctx, /* set a reasonable request timeout */ conn->timeout = 60; + /* explicitly avoid reconnections by default */ + conn->reconnect.max_retries = 0; + return conn; } - /* the connection is dead */ @@ -73,6 +76,7 @@ static void ldap_connection_dead(struct ldap_connection *conn) { struct ldap_request *req; + /* return an error for any pending request ... */ while (conn->pending) { req = conn->pending; DLIST_REMOVE(req->conn->pending, req); @@ -84,9 +88,16 @@ static void ldap_connection_dead(struct ldap_connection *conn) } talloc_free(conn->tls); + talloc_free(conn->sock); /* this will also free event.fde */ + talloc_free(conn->packet); conn->tls = NULL; + conn->sock = NULL; + conn->event.fde = NULL; + conn->packet = NULL; } +static void ldap_reconnect(struct ldap_connection *conn); + /* handle packet errors */ @@ -95,6 +106,9 @@ static void ldap_error_handler(void *private_data, NTSTATUS status) struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); ldap_connection_dead(conn); + + /* but try to reconnect so that the ldb client can go on */ + ldap_reconnect(conn); } @@ -325,6 +339,11 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, struct composite_context *result, *ctx; struct ldap_connect_state *state; + if (conn->reconnect.url == NULL) { + conn->reconnect.url = talloc_strdup(conn, url); + if (conn->reconnect.url == NULL) goto failed; + } + result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; @@ -419,6 +438,40 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) return ldap_connect_recv(ctx); } +/* Actually this function is NOT ASYNC safe, FIXME? */ +static void ldap_reconnect(struct ldap_connection *conn) +{ + NTSTATUS status; + time_t now = time(NULL); + + /* do we have set up reconnect ? */ + if (conn->reconnect.max_retries == 0) return; + + /* is the retry time expired ? */ + if (now > conn->reconnect.previous + 30) { + conn->reconnect.retries = 0; + conn->reconnect.previous = now; + } + + /* are we reconnectind too often and too fast? */ + if (conn->reconnect.retries > conn->reconnect.max_retries) return; + + /* keep track of the number of reconnections */ + conn->reconnect.retries++; + + /* reconnect */ + status = ldap_connect(conn, conn->reconnect.url); + if ( ! NT_STATUS_IS_OK(status)) { + return; + } + + /* rebind */ + status = ldap_rebind(conn); + if ( ! NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); + } +} + /* destroy an open ldap request */ static int ldap_request_destructor(void *ptr) { @@ -466,15 +519,16 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; - NTSTATUS status; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + req = talloc_zero(conn, struct ldap_request); + if (req == NULL) return NULL; if (conn->tls == NULL) { - return NULL; + status = NT_STATUS_INVALID_CONNECTION; + goto failed; } - req = talloc_zero(conn, struct ldap_request); - if (req == NULL) goto failed; - req->state = LDAP_REQUEST_SEND; req->conn = conn; req->messageid = conn->next_messageid++; @@ -541,8 +595,12 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, return req; failed: - talloc_free(req); - return NULL; + req->status = status; + req->state = LDAP_REQUEST_ERROR; + event_add_timed(conn->event.event_ctx, req, timeval_zero(), + ldap_request_complete, req); + + return req; } @@ -552,7 +610,7 @@ failed: */ NTSTATUS ldap_request_wait(struct ldap_request *req) { - while (req->state != LDAP_REQUEST_DONE) { + while (req->state <= LDAP_REQUEST_DONE) { if (event_loop_once(req->conn->event.event_ctx) != 0) { req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; @@ -665,7 +723,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms NT_STATUS_HAVE_NO_MEMORY(req); - while (req->state != LDAP_REQUEST_DONE && n >= req->num_replies) { + while (req->state <= LDAP_REQUEST_DONE && n >= req->num_replies) { if (event_loop_once(req->conn->event.event_ctx) != 0) { return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 3f71c42f22..7801f8b6bc 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -23,7 +23,7 @@ #include "libcli/ldap/ldap.h" -enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE}; +enum ldap_request_state { LDAP_REQUEST_SEND=1, LDAP_REQUEST_PENDING=2, LDAP_REQUEST_DONE=3, LDAP_REQUEST_ERROR=4 }; /* this is the handle that the caller gets when an async ldap message is sent */ @@ -60,6 +60,18 @@ struct ldap_connection { const char *auth_dn; const char *simple_pw; + struct { + char *url; + int max_retries; + int retries; + time_t previous; + } reconnect; + + struct { + enum { LDAP_BIND_SIMPLE, LDAP_BIND_SASL } type; + void *creds; + } bind; + /* next message id to assign */ unsigned next_messageid; -- cgit From 13f17436ea98544315dcf119b0a395a8359fb3e9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 25 Apr 2006 12:34:13 +0000 Subject: r15241: Add helper function to set reconnect status defaults (This used to be commit 6fff8f871a607e561531e2aabef37f3469aa85e9) --- source4/libcli/ldap/ldap_client.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 344605f4ec..74ac64a68d 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -438,6 +438,17 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) return ldap_connect_recv(ctx); } +/* set reconnect parameters */ + +void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries) +{ + if (conn) { + conn->reconnect.max_retries = max_retries; + conn->reconnect.retries = 0; + conn->reconnect.previous = time(NULL); + } +} + /* Actually this function is NOT ASYNC safe, FIXME? */ static void ldap_reconnect(struct ldap_connection *conn) { -- cgit From 886329898c3e6184642a6e454fd10802c388dc7e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 26 Apr 2006 16:52:45 +0000 Subject: r15288: fix some problems (This used to be commit d448389be88b3bb9d6f9a3b8a1e1597c4988a0ff) --- source4/libcli/ldap/ldap_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 74ac64a68d..27cab38916 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -88,7 +88,7 @@ static void ldap_connection_dead(struct ldap_connection *conn) } talloc_free(conn->tls); - talloc_free(conn->sock); /* this will also free event.fde */ +/* talloc_free(conn->sock); this will also free event.fde */ talloc_free(conn->packet); conn->tls = NULL; conn->sock = NULL; @@ -621,7 +621,7 @@ failed: */ NTSTATUS ldap_request_wait(struct ldap_request *req) { - while (req->state <= LDAP_REQUEST_DONE) { + while (req->state < LDAP_REQUEST_DONE) { if (event_loop_once(req->conn->event.event_ctx) != 0) { req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; @@ -734,7 +734,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms NT_STATUS_HAVE_NO_MEMORY(req); - while (req->state <= LDAP_REQUEST_DONE && n >= req->num_replies) { + while (req->state < LDAP_REQUEST_DONE && n >= req->num_replies) { if (event_loop_once(req->conn->event.event_ctx) != 0) { return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } -- cgit From 710ea949886dd57c66dc6d397e0ea41c89736107 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 16:09:17 +0000 Subject: r15297: Move create_security_token() to samdb as it requires SAMDB (and the rest of LIBSECURITY doesn't) Make the ldb password_hash module only depend on some keys manipulation code, not full heimdal Some other dependency fixes (This used to be commit 5b3ab728edfc9cdd9eee16ad0fe6dfd4b5ced630) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 2 +- source4/libcli/ldap/config.mk | 5 ++- source4/libcli/security/config.mk | 8 ++-- source4/libcli/security/security_token.c | 74 -------------------------------- 5 files changed, 9 insertions(+), 82 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 756ea0ecbf..5a0b7e14dc 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -8,6 +8,6 @@ OBJ_FILES = credentials.o \ smbencrypt.o \ smbdes.o PUBLIC_DEPENDENCIES = \ - auth SCHANNELDB MSRPC_PARSE + SCHANNELDB MSRPC_PARSE # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e646985a78..c62f30dd20 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -104,7 +104,7 @@ VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = SMB/CIFS client library PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ - LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIB_SECURITY LIBCLI_RESOLVE \ + LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS [SUBSYSTEM::LIBSMB] diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 26f230d7ef..ec5c48b48c 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,8 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ - LIBPACKET ASN1_UTIL +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET NDR_SAMR LIBTLS ASN1_UTIL +#PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index fb4f1f71b7..e19947203d 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,6 +1,6 @@ ################################# -# Start SUBSYSTEM LIB_SECURITY -[SUBSYSTEM::LIB_SECURITY] +# Start SUBSYSTEM LIBSECURITY +[SUBSYSTEM::LIBSECURITY] PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = security_token.o \ security_descriptor.o \ @@ -8,6 +8,6 @@ OBJ_FILES = security_token.o \ access_check.o \ privilege.o \ sddl.o -PUBLIC_DEPENDENCIES = NDR_SECURITY -# End SUBSYSTEM LIB_SECURITY +PUBLIC_DEPENDENCIES = NDR_SECURITY +# End SUBSYSTEM LIBSECURITY ################################# diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index d872376bff..0043678144 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -47,80 +47,6 @@ struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx) return st; } -/**************************************************************************** - Create the SID list for this user. -****************************************************************************/ -NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, - struct dom_sid *user_sid, - struct dom_sid *group_sid, - int n_groupSIDs, - struct dom_sid **groupSIDs, - BOOL is_authenticated, - struct security_token **token) -{ - struct security_token *ptoken; - int i; - NTSTATUS status; - - ptoken = security_token_initialise(mem_ctx); - NT_STATUS_HAVE_NO_MEMORY(ptoken); - - ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); - - ptoken->user_sid = talloc_reference(ptoken, user_sid); - ptoken->group_sid = talloc_reference(ptoken, group_sid); - ptoken->privilege_mask = 0; - - ptoken->sids[0] = ptoken->user_sid; - ptoken->sids[1] = ptoken->group_sid; - - /* - * Finally add the "standard" SIDs. - * The only difference between guest and "anonymous" - * is the addition of Authenticated_Users. - */ - ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); - ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]); - ptoken->num_sids = 4; - - if (is_authenticated) { - ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); - ptoken->num_sids++; - } - - for (i = 0; i < n_groupSIDs; i++) { - size_t check_sid_idx; - for (check_sid_idx = 1; - check_sid_idx < ptoken->num_sids; - check_sid_idx++) { - if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { - break; - } - } - - if (check_sid_idx == ptoken->num_sids) { - ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); - } - } - - /* setup the privilege mask for this token */ - status = samdb_privilege_setup(ptoken); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(ptoken); - return status; - } - - security_token_debug(10, ptoken); - - *token = ptoken; - - return NT_STATUS_OK; -} - /**************************************************************************** prints a struct security_token to debug output. ****************************************************************************/ -- cgit From 620d759f49f4b648d0fa4a84e67f1cecbbdd0f06 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 19:50:13 +0000 Subject: r15298: Fix the build using a few hacks in the build system. Recursive dependencies are now forbidden (the build system will bail out if there are any). I've split up auth_sam.c into auth_sam.c and sam.c. Andrew, please rename sam.c / move its contents to whatever/wherever you think suits best. (This used to be commit 6646384aaf3e7fa2aa798c3e564b94b0617ec4d0) --- source4/libcli/config.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c62f30dd20..a75cf3bace 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -86,11 +86,12 @@ PUBLIC_DEPENDENCIES = NDR_WINSREPL SOCKET LIBEVENTS PRIVATE_PROTO_HEADER = resolve/proto.h OBJ_FILES = \ resolve/resolve.o \ - resolve/nbtlist.o \ resolve/bcast.o \ + resolve/nbtlist.o \ resolve/wins.o \ resolve/host.o -PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNETIF +PUBLIC_DEPENDENCIES = LIBNETIF +PRIVATE_DEPENDENCIES = LIBCLI_NBT [SUBSYSTEM::LIBCLI_FINDDCS] PRIVATE_PROTO_HEADER = finddcs.h @@ -120,6 +121,7 @@ OBJ_FILES = clireadwrite.o \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ -- cgit From b00c2369069c41880598ff430776cc26e8f7b916 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 21:46:44 +0000 Subject: r15301: Use static libraries internally. This required a few hacks in the build system - these should be removed later on. (This used to be commit 06547391669e064d2b92f5841b7df5f101a34cb9) --- source4/libcli/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index a75cf3bace..e0bb50647d 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -123,6 +123,7 @@ OBJ_FILES = clireadwrite.o \ PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 +LDFLAGS = -lcli_smb_composite OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ raw/clisocket.o \ -- cgit From 9220144604e0050cd823fd107c311bf9013cd5a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 02:45:34 +0000 Subject: r15313: Fix some dependencies in dso mode (This used to be commit f0afe9e2ff16515df1b3226b479b19ea3e9c3d0c) --- source4/libcli/config.mk | 10 +++++----- source4/libcli/ldap/config.mk | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e0bb50647d..6e7f8b70e3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -53,8 +53,8 @@ OBJ_FILES = \ nbt/nameregister.o \ nbt/namerefresh.o \ nbt/namerelease.o -PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT SOCKET LIBCLI_COMPOSITE LIBEVENTS \ - NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ + NDR_SECURITY SOCKET [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ @@ -80,7 +80,7 @@ SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o -PUBLIC_DEPENDENCIES = NDR_WINSREPL SOCKET LIBEVENTS +PUBLIC_DEPENDENCIES = NDR_WINSREPL SOCKET LIBCLI_RESOLVE LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h @@ -109,7 +109,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS [SUBSYSTEM::LIBSMB] -PUBLIC_DEPENDENCIES = LIBCLI SOCKET +PUBLIC_DEPENDENCIES = LIBCLI SOCKET LIBCLI_RESOLVE PUBLIC_PROTO_HEADER = libcli_proto.h OBJ_FILES = clireadwrite.o \ cliconnect.o \ @@ -123,7 +123,7 @@ OBJ_FILES = clireadwrite.o \ PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 -LDFLAGS = -lcli_smb_composite +LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ raw/clisocket.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index ec5c48b48c..167a07eddd 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From e002300f238dd0937dd9f768e366c006945e8baa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 17:34:49 +0000 Subject: r15328: Move some functions around, remove dependencies. Remove some autogenerated headers (which had prototypes now autogenerated by pidl) Remove ndr_security.h from a few places - it's no longer necessary (This used to be commit c19c2b51d3e1ad347120b06a22bda5ec586c22e8) --- source4/libcli/security/config.mk | 2 +- source4/libcli/security/dom_sid.c | 32 ++++++++++++++++++++++++++++++++ source4/libcli/security/sddl.c | 2 +- source4/libcli/security/security_token.c | 1 - source4/libcli/util/clilsa.c | 1 - 5 files changed, 34 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index e19947203d..3c97ec4264 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -8,6 +8,6 @@ OBJ_FILES = security_token.o \ access_check.o \ privilege.o \ sddl.o -PUBLIC_DEPENDENCIES = NDR_SECURITY +PUBLIC_DEPENDENCIES = NDR_MISC # End SUBSYSTEM LIBSECURITY ################################# diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 131d1afa9c..39841e5a70 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -240,3 +240,35 @@ BOOL dom_sid_in_domain(const struct dom_sid *domain_sid, return dom_sid_compare_auth(domain_sid, sid) == 0; } + +/* + convert a dom_sid to a string +*/ +char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +{ + int i, ofs, maxlen; + uint32_t ia; + char *ret; + + if (!sid) { + return talloc_strdup(mem_ctx, "(NULL SID)"); + } + + maxlen = sid->num_auths * 11 + 25; + ret = talloc_size(mem_ctx, maxlen); + if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); + + ia = (sid->id_auth[5]) + + (sid->id_auth[4] << 8 ) + + (sid->id_auth[3] << 16) + + (sid->id_auth[2] << 24); + + ofs = snprintf(ret, maxlen, "S-%u-%lu", + (uint_t)sid->sid_rev_num, (unsigned long)ia); + + for (i = 0; i < sid->num_auths; i++) { + ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); + } + + return ret; +} diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 46183ce237..97e811f151 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -22,8 +22,8 @@ #include "includes.h" #include "system/iconv.h" -#include "librpc/gen_ndr/ndr_security.h" #include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_misc.h" struct flag_map { const char *name; diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 0043678144..28339c969d 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -24,7 +24,6 @@ #include "includes.h" #include "dsdb/samdb/samdb.h" #include "libcli/security/security.h" -#include "librpc/gen_ndr/ndr_security.h" /* return a blank security token diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index f5e49dd577..e491d1c9ee 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -30,7 +30,6 @@ #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" #include "libcli/security/security.h" -#include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_lsa_c.h" -- cgit From f7c86b912dd8033837a8411c7b99c9436de079c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 23:22:54 +0000 Subject: r15331: Integrate LIBSMB and LIBCLI into new LIBCLI_SMB (This used to be commit 4ec89bce8715f35f21fe05bb738dae13fc6c3066) --- source4/libcli/config.mk | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 6e7f8b70e3..e68bdf1f45 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -99,18 +99,12 @@ OBJ_FILES = \ finddcs.o PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING -[LIBRARY::LIBCLI] +[LIBRARY::LIBCLI_SMB] PUBLIC_HEADERS = libcli.h +PUBLIC_PROTO_HEADER = libcli_proto.h VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = SMB/CIFS client library -PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ - LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS - -[SUBSYSTEM::LIBSMB] -PUBLIC_DEPENDENCIES = LIBCLI SOCKET LIBCLI_RESOLVE -PUBLIC_PROTO_HEADER = libcli_proto.h OBJ_FILES = clireadwrite.o \ cliconnect.o \ clifile.o \ @@ -118,6 +112,9 @@ OBJ_FILES = clireadwrite.o \ clitrans2.o \ climessage.o \ clideltree.o +PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ + LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ + LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -- cgit From 20b3b0f2e316f1689ea30e1901d97bdf86a71fa0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 00:00:28 +0000 Subject: r15338: Fix build of most things with shared libs enabled. (This used to be commit 8985093d3fba90287bd739aaaa0fbfdadca2b999) --- source4/libcli/config.mk | 10 +++++----- source4/libcli/raw/clioplock.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e68bdf1f45..533266dca8 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -42,10 +42,10 @@ PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE PRIVATE_PROTO_HEADER = nbt/nbtname.h OBJ_FILES = nbt/nbtname.o -[LIBRARY::LIBCLI_NBT] -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = NetBios over TCP/IP client library +[SUBSYSTEM::LIBCLI_NBT] +#VERSION = 0.0.1 +#SO_VERSION = 0 +#DESCRIPTION = NetBios over TCP/IP client library PRIVATE_PROTO_HEADER = nbt/nbt_proto.h OBJ_FILES = \ nbt/nbtsocket.o \ @@ -142,6 +142,6 @@ OBJ_FILES = raw/rawfile.o \ raw/rawacl.o \ raw/rawdate.o \ raw/rawlpq.o -PUBLIC_DEPENDENCIES = LIBPACKET gensec +PUBLIC_DEPENDENCIES = LIBPACKET gensec LIBCRYPTO include smb2/config.mk diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index f26aa0c5f2..f004532b26 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -24,7 +24,7 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ -BOOL smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_level) +_PUBLIC_ BOOL smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_level) { BOOL ret; struct smbcli_request *req; @@ -53,7 +53,7 @@ BOOL smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_lev /**************************************************************************** set the oplock handler for a connection ****************************************************************************/ -void smbcli_oplock_handler(struct smbcli_transport *transport, +_PUBLIC_ void smbcli_oplock_handler(struct smbcli_transport *transport, BOOL (*handler)(struct smbcli_transport *, uint16_t, uint16_t, uint8_t, void *), void *private) { -- cgit From 1f5a8f892ff09f2633610c0f520d96f892674933 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 00:40:04 +0000 Subject: r15344: Fix shared library build (This used to be commit 7113a16309a83225f3ab6ccbfe48778ae8fc52e8) --- source4/libcli/config.mk | 7 +++---- source4/libcli/nbt/nbtsocket.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 533266dca8..418794ec86 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -114,12 +114,12 @@ OBJ_FILES = clireadwrite.o \ clideltree.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS + LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS SOCKET [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE -PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE +PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 SOCKET LIBPACKET gensec LIBCRYPTO LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ @@ -142,6 +142,5 @@ OBJ_FILES = raw/rawfile.o \ raw/rawacl.o \ raw/rawdate.o \ raw/rawlpq.o -PUBLIC_DEPENDENCIES = LIBPACKET gensec LIBCRYPTO include smb2/config.mk diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index eca5253113..1e808e698d 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -302,7 +302,7 @@ static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *f initialise a nbt_name_socket. The event_ctx is optional, if provided then operations will use that event context */ -struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, +_PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx) { struct nbt_name_socket *nbtsock; -- cgit From 30e8599538a44de87e4603d3c6ea1798a2df8d39 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 02:07:33 +0000 Subject: r15350: Remove empty subsystem, don't install .a files of subsystems (This used to be commit 087188cfc4a38d92b13fc8e58e1f408306442055) --- source4/libcli/config.m4 | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 source4/libcli/config.m4 (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 deleted file mode 100644 index feb9e79d38..0000000000 --- a/source4/libcli/config.m4 +++ /dev/null @@ -1,8 +0,0 @@ -dnl # LIBCLI subsystem - -LIBCLI_RAW_LIBS= -if test x"$with_ads_support" = x"yes"; then - LIBCLI_RAW_LIBS="KRB5" -fi - -SMB_SUBSYSTEM(LIBCLI_RAW_KRB5, [], [${LIBCLI_RAW_LIBS}]) -- cgit From e48fdb255a8768b2b016ce874dfeec9bf4a19d70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 02:23:10 +0000 Subject: r15352: Remove reference to just-removed subsystem (This used to be commit ccb86ab15986fa642d412432bfd4f8f2f280e13d) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 418794ec86..cc8ea52ed0 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -119,7 +119,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE -PUBLIC_DEPENDENCIES = LIBCLI_RAW_KRB5 SOCKET LIBPACKET gensec LIBCRYPTO +PUBLIC_DEPENDENCIES = SOCKET LIBPACKET gensec LIBCRYPTO LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ -- cgit From c2cc10c7869221c7f43cbbb151feb4c4db173cb9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Apr 2006 05:58:31 +0000 Subject: r15356: Remove unused 'flags' argument from socket_send() and friends. This is in preperation for making TLS a socket library. Andrew Bartlett (This used to be commit a312812b92f5ac7e6bd2c4af725dbbbc900d4452) --- source4/libcli/cldap/cldap.c | 6 +++--- source4/libcli/dgram/dgramsocket.c | 4 ++-- source4/libcli/nbt/nbtsocket.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 7a484607a7..58beb1b642 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -83,7 +83,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) return; } - status = socket_recvfrom(cldap->sock, blob.data, blob.length, &nread, 0, + status = socket_recvfrom(cldap->sock, blob.data, blob.length, &nread, tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); @@ -156,7 +156,7 @@ static void cldap_request_timeout(struct event_context *event_ctx, req->num_retries--; - socket_sendto(req->cldap->sock, &req->encoded, &len, 0, + socket_sendto(req->cldap->sock, &req->encoded, &len, req->dest); req->te = event_add_timed(req->cldap->event_ctx, req, @@ -183,7 +183,7 @@ static void cldap_socket_send(struct cldap_socket *cldap) size_t len; len = req->encoded.length; - status = socket_sendto(cldap->sock, &req->encoded, &len, 0, + status = socket_sendto(cldap->sock, &req->encoded, &len, req->dest); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send cldap request of length %u to %s:%d\n", diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 16bb9d2fb7..e7eb01b7e9 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -53,7 +53,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) return; } - status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, 0, + status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); @@ -113,7 +113,7 @@ static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) size_t len; len = req->encoded.length; - status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0, + status = socket_sendto(dgmsock->sock, &req->encoded, &len, req->dest); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send datagram of length %u to %s:%d: %s\n", diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1e808e698d..50da8168e0 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -73,7 +73,7 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) size_t len; len = req->encoded.length; - status = socket_sendto(nbtsock->sock, &req->encoded, &len, 0, + status = socket_sendto(nbtsock->sock, &req->encoded, &len, req->dest); if (NT_STATUS_IS_ERR(status)) goto failed; @@ -172,7 +172,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) return; } - status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, + status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); -- cgit From cf0f4ec073b694e43daeeddf9aab51cd3e51fd2b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 13:54:03 +0000 Subject: r15358: Fix some compiler warnings / type safety. Found by tcc (This used to be commit 12ba42de5886f9f4f9b1698476557e0c217d06f3) --- source4/libcli/ldap/ldap_controls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index ccb1b74a55..47b1262aea 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -127,9 +127,11 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { - if (!asn1_read_BOOLEAN(&data, &(lssc[num]->reverse))) { + bool reverse; + if (!asn1_read_BOOLEAN(&data, &reverse)) { return False; } + lssc[num]->reverse = reverse; } if (!asn1_end_tag(&data)) { @@ -902,9 +904,11 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - if (!asn1_read_BOOLEAN(data, &(ctrl->critical))) { + bool critical; + if (!asn1_read_BOOLEAN(data, &critical)) { return False; } + critical = ctrl->critical; } else { ctrl->critical = False; } -- cgit From 37e94956e0a976b6d144b5885b2ef18bb8e4b39b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 20:00:37 +0000 Subject: r15365: Fix error in my previous commit, caught by metze. (This used to be commit 0d99397007960e555f562f1498a202407e235f36) --- source4/libcli/ldap/ldap_controls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 47b1262aea..f4f54ec2e2 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -127,7 +127,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { - bool reverse; + BOOL reverse; if (!asn1_read_BOOLEAN(&data, &reverse)) { return False; } @@ -904,11 +904,11 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - bool critical; + BOOL critical; if (!asn1_read_BOOLEAN(data, &critical)) { return False; } - critical = ctrl->critical; + ctrl->critical = critical; } else { ctrl->critical = False; } -- cgit From 6275553baee5593f9e13a0635755b2deb275c3be Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 12:54:36 +0000 Subject: r15373: Rename SOCKET to LIBSAMBA-SOCKET to prevent name clashes with -lsocket on SUN boxes. (This used to be commit c95ad11307dc89384c10bd5919817bf12d9c1ed9) --- source4/libcli/config.mk | 8 ++++---- source4/libcli/ldap/config.mk | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index cc8ea52ed0..0e680215d3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -54,7 +54,7 @@ OBJ_FILES = \ nbt/namerefresh.o \ nbt/namerelease.o PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ - NDR_SECURITY SOCKET + NDR_SECURITY LIBSAMBA-SOCKET [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ @@ -80,7 +80,7 @@ SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o -PUBLIC_DEPENDENCIES = NDR_WINSREPL SOCKET LIBCLI_RESOLVE LIBEVENTS +PUBLIC_DEPENDENCIES = NDR_WINSREPL LIBSAMBA-SOCKET LIBCLI_RESOLVE LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h @@ -114,12 +114,12 @@ OBJ_FILES = clireadwrite.o \ clideltree.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS SOCKET + LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS LIBSAMBA-SOCKET [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE -PUBLIC_DEPENDENCIES = SOCKET LIBPACKET gensec LIBCRYPTO +PUBLIC_DEPENDENCIES = LIBSAMBA-SOCKET LIBPACKET gensec LIBCRYPTO LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 167a07eddd..c1c74cd168 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LIBSAMBA-SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 5c3a1d76ffc7b9e41846f7eaf6039f58184737a0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 18:11:15 +0000 Subject: r15379: Fix shared library build's unresolved dependencies (This used to be commit 0fafa2e59566f8f892d7dfd7dd33d0100b96a780) --- source4/libcli/raw/rawioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index d4a299fe02..49237fe9da 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -147,7 +147,7 @@ NTSTATUS smb_raw_ioctl_recv(struct smbcli_request *req, /* send a raw ioctl - sync interface */ -NTSTATUS smb_raw_ioctl(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_ioctl(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { struct smbcli_request *req; -- cgit From 46f627ea7afb0ad006efadf593bf202cea05194e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 22:07:12 +0000 Subject: r15384: Improve naming of socket library, disable Requires(.private)? fields in pkg-config files for now as they break external projects. (This used to be commit f919fd6655f00361691e676d260bd40e0b8ddcc7) --- source4/libcli/config.mk | 8 ++++---- source4/libcli/ldap/config.mk | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0e680215d3..f3e9be7f63 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -54,7 +54,7 @@ OBJ_FILES = \ nbt/namerefresh.o \ nbt/namerelease.o PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ - NDR_SECURITY LIBSAMBA-SOCKET + NDR_SECURITY samba-socket [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ @@ -80,7 +80,7 @@ SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o -PUBLIC_DEPENDENCIES = NDR_WINSREPL LIBSAMBA-SOCKET LIBCLI_RESOLVE LIBEVENTS +PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h @@ -114,12 +114,12 @@ OBJ_FILES = clireadwrite.o \ clideltree.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS LIBSAMBA-SOCKET + LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE -PUBLIC_DEPENDENCIES = LIBSAMBA-SOCKET LIBPACKET gensec LIBCRYPTO +PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index c1c74cd168..88ebc3256f 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LIBSAMBA-SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 8bab9322825090952b25aa7e54c9bcd2f367de8d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 23:03:32 +0000 Subject: r15387: Fix installation of dcerpc headers, remove more instances of uint_t (This used to be commit 9e9bfd04c6db013453b900e201df9c09e8777a22) --- source4/libcli/nbt/libnbt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index e828beb29f..521c4f52bd 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -74,7 +74,7 @@ struct nbt_name_request { /* shall we allow multiple replies? */ BOOL allow_multiple_replies; - uint_t num_replies; + unsigned int num_replies; struct nbt_name_reply { struct nbt_name_packet *packet; struct socket_address *dest; -- cgit From ce3293c5b6864dd4e04638bf819cf0269b761fce Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 May 2006 10:59:31 +0000 Subject: r15391: Wrap up the nbt_name_query() function as a bit of an experiment. It seemed to work quite well and this technique might be good for generating an interface to use for automated testing. Tested by doing a nbt lookup against smbd. (This used to be commit 11150b3140c91459f17c767adf07a54524338c18) --- source4/libcli/config.mk | 5 ++ source4/libcli/swig/libcli_nbt.i | 136 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 source4/libcli/swig/libcli_nbt.i (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index f3e9be7f63..46f3336fd1 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -56,6 +56,11 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket +[LIBRARY::swig_libcli_nbt] +LIBRARY_REALNAME = swig/_libcli_nbt.$(SHLIBEXT) +OBJ_FILES = swig/libcli_nbt_wrap.o +PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-CONFIG + [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ dgram/dgramsocket.o \ diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i new file mode 100644 index 0000000000..54fbf56839 --- /dev/null +++ b/source4/libcli/swig/libcli_nbt.i @@ -0,0 +1,136 @@ +/* + Unix SMB/CIFS implementation. + + Swig interface to libcli_nbt library. + + Copyright (C) 2006 Tim Potter + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +%module libcli_nbt + +%{ + +#include "includes.h" +#include "lib/talloc/talloc.h" +#include "lib/events/events.h" +#include "libcli/nbt/libnbt.h" + +/* Undo strcpy safety macro as it's used by swig )-: */ + +#undef strcpy + +%} + +%apply bool { BOOL }; +%apply int { uint8_t }; +%apply int { int8_t }; +%apply unsigned int { uint16_t }; +%apply int { int16_t }; + +%typemap(in) uint32_t { + if (PyLong_Check($input)) + $1 = PyLong_AsUnsignedLong($input); + else if (PyInt_Check($input)) + $1 = PyInt_AsLong($input); + else { + PyErr_SetString(PyExc_TypeError,"Expected a long or an int"); + return NULL; + } +} + +%typemap(out) uint32_t { + $result = PyLong_FromUnsignedLong($1); +} + +%apply unsigned long long { uint64_t }; +%apply long long { int64_t }; + +%typemap(in) NTSTATUS { + if (PyLong_Check($input)) + $1 = NT_STATUS(PyLong_AsUnsignedLong($input)); + else if (PyInt_Check($input)) + $1 = NT_STATUS(PyInt_AsLong($input)); + else { + PyErr_SetString(PyExc_TypeError, "Expected a long or an int"); + return NULL; + } +} + +%typemap(out) NTSTATUS { + $result = PyLong_FromUnsignedLong(NT_STATUS_V($1)); +} + +TALLOC_CTX *talloc_init(char *name); +int talloc_free(TALLOC_CTX *ptr); + +/* Function prototypes */ + +struct event_context *event_context_init(TALLOC_CTX *mem_ctx); + +struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx); + +enum nbt_name_type { + NBT_NAME_CLIENT=0x00, + NBT_NAME_MS=0x01, + NBT_NAME_USER=0x03, + NBT_NAME_SERVER=0x20, + NBT_NAME_PDC=0x1B, + NBT_NAME_LOGON=0x1C, + NBT_NAME_MASTER=0x1D, + NBT_NAME_BROWSER=0x1E +}; + +struct nbt_name { + const char *name; + const char *scope; + enum nbt_name_type type; +}; + +%rename(data_in) in; +%rename(data_out) out; + +struct nbt_name_query { + struct { + struct nbt_name name; + const char *dest_addr; + BOOL broadcast; + BOOL wins_lookup; + int timeout; /* in seconds */ + int retries; + } in; + struct { + const char *reply_from; + struct nbt_name name; + int16_t num_addrs; + const char **reply_addrs; + } out; +}; + +%include "carrays.i" +%array_functions(char *, char_ptr_array); + +%rename(do_nbt_name_query) nbt_name_query; + +NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io); + +void lp_load(void); -- cgit From 0b673b79997365abddac49b51aacfd78b96b7ec2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 May 2006 19:00:19 +0000 Subject: r15395: Fix build by adding another copy of the Python detection m4 fragment. This stuff should be common somewhere. (This used to be commit e906781cbd7a9d782e028fb0497de739ac6fb797) --- source4/libcli/config.m4 | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 source4/libcli/config.m4 (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 new file mode 100644 index 0000000000..3327c178c7 --- /dev/null +++ b/source4/libcli/config.m4 @@ -0,0 +1,31 @@ +AC_MSG_CHECKING([for Python (libcli_nbt)]) + +PYTHON= + +AC_ARG_WITH(python, +[ --with-python=PYTHONNAME build Python libraries], +[ case "${withval-python}" in + yes) + PYTHON=python + ;; + no) + PYTHON= + ;; + *) + PYTHON=${withval-python} + ;; + esac ]) + +if test x"$PYTHON" != "x"; then + incdir=`python -c 'import sys; print "%s/include/python%d.%d" % (sys.prefix, sys.version_info[[0]], sys.version_info[[1]])'` + CPPFLAGS="$CPPFLAGS -I $incdir" +fi + +if test x"$PYTHON" != "x"; then + AC_MSG_RESULT([${withval-python}]) +else + AC_MSG_RESULT(no) + SMB_ENABLE(swig_libli_nbt, NO) +fi + +AC_SUBST(PYTHON) -- cgit From 49994442bbb035b2c438a33f411d6b5a8b2313df Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 May 2006 19:20:49 +0000 Subject: r15397: Fix typo. (This used to be commit 74bd8170fc9d53403899721bc4b620121946e4d2) --- source4/libcli/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 3327c178c7..e31359fdaa 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -25,7 +25,7 @@ if test x"$PYTHON" != "x"; then AC_MSG_RESULT([${withval-python}]) else AC_MSG_RESULT(no) - SMB_ENABLE(swig_libli_nbt, NO) + SMB_ENABLE(swig_libcli_nbt, NO) fi AC_SUBST(PYTHON) -- cgit From 742c110cd67f4995639822981e8bfcb1f652f2c4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 2 May 2006 20:15:47 +0000 Subject: r15400: Move the TLS code behind the socket interface. This reduces caller complexity, because the TLS code is now called just like any other socket. (A new socket context is returned by the tls_init_server and tls_init_client routines). When TLS is not available, the original socket is returned. Andrew Bartlett (This used to be commit 09b2f30dfa7a640f5187b4933204e9680be61497) --- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/ldap/ldap_client.c | 39 +++++++++++++++++++++------------------ source4/libcli/ldap/ldap_client.h | 1 - 3 files changed, 22 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c33d53f775..6714d68b0e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -223,7 +223,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr /* require Kerberos SIGN/SEAL only if we don't use SSL * Windows seem not to like double encryption */ - if (conn->tls == NULL || (! tls_enabled(conn->tls))) { + if (!tls_enabled(conn->sock)) { gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 27cab38916..8d815c7103 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -32,6 +32,7 @@ #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" +#include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "system/time.h" @@ -85,12 +86,10 @@ static void ldap_connection_dead(struct ldap_connection *conn) if (req->async.fn) { req->async.fn(req); } - } + } - talloc_free(conn->tls); -/* talloc_free(conn->sock); this will also free event.fde */ + talloc_free(conn->sock); /* this will also free event.fde */ talloc_free(conn->packet); - conn->tls = NULL; conn->sock = NULL; conn->event.fde = NULL; conn->packet = NULL; @@ -270,7 +269,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, struct ldap_connection); if (flags & EVENT_FD_WRITE) { packet_queue_run(conn->packet); - if (conn->tls == NULL) return; + if (!tls_enabled(conn->sock)) return; } if (flags & EVENT_FD_READ) { packet_recv(conn->packet); @@ -339,11 +338,6 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, struct composite_context *result, *ctx; struct ldap_connect_state *state; - if (conn->reconnect.url == NULL) { - conn->reconnect.url = talloc_strdup(conn, url); - if (conn->reconnect.url == NULL) goto failed; - } - result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; @@ -357,6 +351,11 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, state->conn = conn; + if (conn->reconnect.url == NULL) { + conn->reconnect.url = talloc_strdup(conn, url); + if (conn->reconnect.url == NULL) goto failed; + } + state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, &conn->port, &conn->ldaps); if (!NT_STATUS_IS_OK(state->ctx->status)) { @@ -379,6 +378,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, static void ldap_connect_recv_conn(struct composite_context *ctx) { + struct socket_context *initial_socket; struct ldap_connect_state *state = talloc_get_type(ctx->async.private_data, struct ldap_connect_state); @@ -398,21 +398,24 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) return; } - conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); - if (conn->tls == NULL) { - talloc_free(conn->sock); - return; + talloc_steal(conn, conn->sock); + initial_socket = conn->sock; + if (conn->ldaps) { + conn->sock = tls_init_client(conn->sock, conn->event.fde); + if (conn->sock == NULL) { + talloc_free(initial_socket); + return; + } } - talloc_steal(conn, conn->tls); - talloc_steal(conn->tls, conn->sock); conn->packet = packet_init(conn); if (conn->packet == NULL) { talloc_free(conn->sock); return; } + packet_set_private(conn->packet, conn); - packet_set_tls(conn->packet, conn->tls); + packet_set_socket(conn->packet, conn->sock); packet_set_callback(conn->packet, ldap_recv_handler); packet_set_full_request(conn->packet, ldap_complete_packet); packet_set_error_handler(conn->packet, ldap_error_handler); @@ -535,7 +538,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, req = talloc_zero(conn, struct ldap_request); if (req == NULL) return NULL; - if (conn->tls == NULL) { + if (conn->sock == NULL) { status = NT_STATUS_INVALID_CONNECTION; goto failed; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 7801f8b6bc..28b9f2763c 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -51,7 +51,6 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { - struct tls_context *tls; struct socket_context *sock; char *host; uint16_t port; -- cgit From ed752c800425ffd3db39a770ddaee3ad2d73c494 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 May 2006 14:54:57 +0000 Subject: r15415: Use Jelmer's new credentials 'wrong password' code to give the user 3 attempts for the password, when talking to a remote CIFS server. Andrew Bartlett (This used to be commit 3a4ddc8f5978210ab3ad79f0332cee80a0d6e6c9) --- source4/libcli/smb_composite/sesssetup.c | 53 +++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 0f00d5f9c0..f2d1dcd87d 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -36,6 +36,18 @@ struct sesssetup_state { struct smbcli_request *req; }; +static NTSTATUS session_setup_old(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req); +static NTSTATUS session_setup_nt1(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req); +static NTSTATUS session_setup_spnego(struct composite_context *c, + struct smbcli_session *session, + struct smb_composite_sesssetup *io, + struct smbcli_request **req); /* store the user session key for a transport @@ -58,21 +70,60 @@ static void request_handler(struct smbcli_request *req) struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); - NTSTATUS session_key_err; + NTSTATUS session_key_err, nt_status; c->status = smb_raw_sesssetup_recv(req, state, &state->setup); switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: state->io->out.vuid = state->setup.old.out.vuid; + if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { + if (cli_credentials_wrong_password(state->io->in.credentials)) { + nt_status = session_setup_old(c, session, + state->io, + &state->req); + if (NT_STATUS_IS_OK(nt_status)) { + c->status = nt_status; + state->req->async.fn = request_handler; + state->req->async.private = c; + return; + } + } + } break; case RAW_SESSSETUP_NT1: state->io->out.vuid = state->setup.nt1.out.vuid; + if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { + if (cli_credentials_wrong_password(state->io->in.credentials)) { + nt_status = session_setup_nt1(c, session, + state->io, + &state->req); + if (NT_STATUS_IS_OK(nt_status)) { + c->status = nt_status; + state->req->async.fn = request_handler; + state->req->async.private = c; + return; + } + } + } break; case RAW_SESSSETUP_SPNEGO: session->vuid = state->io->out.vuid = state->setup.spnego.out.vuid; + if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { + if (cli_credentials_wrong_password(state->io->in.credentials)) { + nt_status = session_setup_spnego(c, session, + state->io, + &state->req); + if (NT_STATUS_IS_OK(nt_status)) { + c->status = nt_status; + state->req->async.fn = request_handler; + state->req->async.private = c; + return; + } + } + } if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(c->status)) { break; -- cgit From 5d689a5de2d6ddfbab1753ff219d9d55cb009cac Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 May 2006 14:59:55 +0000 Subject: r15416: Point out that this doesn't work, but for servers this old, I just don't care... Andrew Bartlett (This used to be commit 8abe7ba619a9499229937435b66005e278bcbf38) --- source4/libcli/smb_composite/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index f2d1dcd87d..1b7756a3f4 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -77,6 +77,8 @@ static void request_handler(struct smbcli_request *req) switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: state->io->out.vuid = state->setup.old.out.vuid; + /* This doesn't work, as this only happens on old + * protocols, where this comparison won't match. */ if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_old(c, session, -- cgit From b56789c3491d227dd4107a37de701101c780a0f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 5 May 2006 13:02:14 +0000 Subject: r15457: Get rid of more usages of uint_t (This used to be commit 849818dcdeb8eaf2eb22fea3896a4f7c777d8c5f) --- source4/libcli/security/dom_sid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 39841e5a70..951c0f5956 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -264,7 +264,7 @@ char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) (sid->id_auth[2] << 24); ofs = snprintf(ret, maxlen, "S-%u-%lu", - (uint_t)sid->sid_rev_num, (unsigned long)ia); + (unsigned int)sid->sid_rev_num, (unsigned long)ia); for (i = 0; i < sid->num_auths; i++) { ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); -- cgit From c3958aa23112ba7ad1663e798d5226d1167639fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 7 May 2006 20:53:45 +0000 Subject: r15505: - add 'generic' alias to smb_seek and smb_flush - add struct ntvfs_handle pointer to smb_file, this will later be used by the ntvfs backends metze (This used to be commit 8322fc70adbb951ad72b97dfcc91467c1d906afe) --- source4/libcli/raw/interfaces.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 88daf304cf..f715c10e11 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -52,6 +52,8 @@ struct smb2_handle { uint64_t data[2]; }; +struct ntvfs_handle; + /* * a generic container for file handles or file pathes * for qfileinfo/setfileinfo and qpathinfo/setpathinfo @@ -72,18 +74,17 @@ union smb_handle_or_path { * this is used as file handle in SMB2 */ struct smb2_handle handle; + + /* + * this is used as generic file handle for the NTVFS layer + */ + struct ntvfs_handle *ntvfs; }; /* a generic container for file handles */ union smb_handle { - /* - * this is used for - * the qpathinfo and setpathinfo - * calls - */ - const char *path; /* * this is used as file handle in SMB */ @@ -93,6 +94,11 @@ union smb_handle { * this is used as file handle in SMB2 */ struct smb2_handle handle; + + /* + * this is used as generic file handle for the NTVFS layer + */ + struct ntvfs_handle *ntvfs; }; /* @@ -111,7 +117,7 @@ union smb_seek { struct { int32_t offset; } out; - } lseek; + } lseek, generic; }; /* struct used in unlink() call */ @@ -1681,7 +1687,7 @@ union smb_flush { struct { union smb_handle file; } in; - } flush; + } flush, generic; }; -- cgit From dc86ab3e454d7219608d01879145dec5609acaa3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 May 2006 10:47:37 +0000 Subject: r15532: add a BOOL body_dynamic_present, because the body_dynamic_size can be 0 also if the dynamic flag should be set metze (This used to be commit 7829100e1ee79f4f5d24004af221288e19c09b3e) --- source4/libcli/smb2/close.c | 2 +- source4/libcli/smb2/create.c | 2 +- source4/libcli/smb2/find.c | 2 +- source4/libcli/smb2/flush.c | 2 +- source4/libcli/smb2/getinfo.c | 2 +- source4/libcli/smb2/ioctl.c | 2 +- source4/libcli/smb2/keepalive.c | 2 +- source4/libcli/smb2/logoff.c | 2 +- source4/libcli/smb2/negprot.c | 2 +- source4/libcli/smb2/read.c | 2 +- source4/libcli/smb2/request.c | 17 ++++++++++++++--- source4/libcli/smb2/session.c | 2 +- source4/libcli/smb2/setinfo.c | 2 +- source4/libcli/smb2/tcon.c | 2 +- source4/libcli/smb2/tdis.c | 2 +- source4/libcli/smb2/write.c | 2 +- 16 files changed, 29 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 3e559fe893..4483f3c75b 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18, 0); + req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18, False, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.flags); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index c7bb190559..339258a0df 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -67,7 +67,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); - req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, 1); + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, True, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.oplock_flags); diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index aa14347022..e811095f42 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -33,7 +33,7 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io struct smb2_request *req; NTSTATUS status; - req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, 1); + req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, True, 0); if (req == NULL) return NULL; SCVAL(req->out.body, 0x02, io->in.level); diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index d9178aeb9f..596eb26009 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush * { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, 0); + req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, False, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); /* pad? */ diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index d52ff03922..57a363b63f 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, 0); + req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, False, 0); if (req == NULL) return NULL; /* this seems to be a bug, they use 0x29 but only send 0x28 bytes */ diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index 533f12c9d3..ffe029e16e 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_ioctl_send(struct smb2_tree *tree, struct smb2_ioctl * NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_IOCTL, 0x38, + req = smb2_request_init_tree(tree, SMB2_OP_IOCTL, 0x38, True, io->in.in.length+io->in.out.length); if (req == NULL) return NULL; diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index b800bdb3b1..ac31afd4dc 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport) { struct smb2_request *req; - req = smb2_request_init(transport, SMB2_OP_KEEPALIVE, 0x04, 0); + req = smb2_request_init(transport, SMB2_OP_KEEPALIVE, 0x04, False, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index 977c1e57af..cfaa389ef8 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session) { struct smb2_request *req; - req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, 0); + req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, False, 0); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index a3cf8eb018..c3b72186a9 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -33,7 +33,7 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, { struct smb2_request *req; - req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26, 0); + req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26, False, 0); if (req == NULL) return NULL; /* this seems to be a bug, they use 0x24 but the length is 0x26 */ diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index da2d3bb7c9..82e9b13280 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31, 0); + req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31, False, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); /* pad */ diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2476270d49..136b81e977 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -31,10 +31,19 @@ initialise a smb2 request */ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode, - uint16_t body_fixed_size, uint32_t body_dynamic_size) + uint16_t body_fixed_size, BOOL body_dynamic_present, + uint32_t body_dynamic_size) { struct smb2_request *req; + if (body_dynamic_present) { + if (body_dynamic_size == 0) { + body_dynamic_size = 1; + } + } else { + body_dynamic_size = 0; + } + req = talloc(transport, struct smb2_request); if (req == NULL) return NULL; @@ -95,10 +104,12 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ initialise a smb2 request for tree operations */ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode, - uint16_t body_fixed_size, uint32_t body_dynamic_size) + uint16_t body_fixed_size, BOOL body_dynamic_present, + uint32_t body_dynamic_size) { struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, - body_fixed_size, body_dynamic_size); + body_fixed_size, body_dynamic_present, + body_dynamic_size); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 1d1b97600a..83e6d1ae00 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -69,7 +69,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, NTSTATUS status; req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, - 0x10, io->in.secblob.length); + 0x10, True, io->in.secblob.length); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index c445880440..432034b13b 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -33,7 +33,7 @@ struct smb2_request *smb2_setinfo_send(struct smb2_tree *tree, struct smb2_setin NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_SETINFO, 0x20, io->in.blob.length); + req = smb2_request_init_tree(tree, SMB2_OP_SETINFO, 0x20, True, io->in.blob.length); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.level); diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 3fc14075a5..8b94936c42 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -54,7 +54,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, NTSTATUS status; req = smb2_request_init(tree->session->transport, SMB2_OP_TCON, - 0x08, 1); + 0x08, True, 0); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c index 9ea58113b3..f89e5c8e90 100644 --- a/source4/libcli/smb2/tdis.c +++ b/source4/libcli/smb2/tdis.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_tdis_send(struct smb2_tree *tree) { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_TDIS, 0x04, 0); + req = smb2_request_init_tree(tree, SMB2_OP_TDIS, 0x04, False, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index adf690c1b3..1edce3f773 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, io->in.data.length); + req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, True, io->in.data.length); if (req == NULL) return NULL; status = smb2_push_o16s32_blob(&req->out, 0x02, io->in.data); -- cgit From 172a83d72491f90f6191be1040ef8b2e1789bd2e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 13 May 2006 19:14:12 +0000 Subject: r15573: Fix build of systems that have iconv headers in non-standard locations Split of system/locale.h header from system/iconv.h Previously, iconv wasn't being used on these systems (This used to be commit aa6d66fda69779d1c2948a1aca85dbd5208f1cba) --- source4/libcli/ldap/ldap.c | 1 - source4/libcli/ldap/ldap_controls.c | 1 - source4/libcli/nbt/nbtname.c | 2 +- source4/libcli/security/sddl.c | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c1fc461b5f..6f475478b1 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -24,7 +24,6 @@ */ #include "includes.h" -#include "system/iconv.h" #include "libcli/util/asn_1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index f4f54ec2e2..ee8f9d4bb1 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "system/iconv.h" #include "libcli/util/asn_1.h" #include "libcli/ldap/ldap.h" #include "lib/ldb/include/ldb.h" diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 25fd669789..871e29794d 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -25,9 +25,9 @@ */ #include "includes.h" -#include "system/iconv.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "librpc/gen_ndr/ndr_misc.h" +#include "system/locale.h" /* don't allow an unlimited number of name components */ #define MAX_COMPONENTS 10 diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 97e811f151..14dd7e0917 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -21,9 +21,9 @@ */ #include "includes.h" -#include "system/iconv.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_misc.h" +#include "system/locale.h" struct flag_map { const char *name; -- cgit From bb58d8497abe7178677c58e9dae307c44babbcef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 May 2006 16:28:36 +0000 Subject: r15638: add a usefull macro to get a pointer the smb_handle union of smb_open, as it's not nicely alligned for all levels, If someone has an idea for a better solution where we can access it via op->generic.out.file.* please let me know:-) metze (This used to be commit d0a7408280c35dc4a5a21cbbded895c6c83819e6) --- source4/libcli/raw/interfaces.h | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index f715c10e11..d9387cc6e2 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1173,6 +1173,48 @@ enum smb_open_level { /* union for open() backend call */ union smb_open { +/* + * because the *.out.file structs are not aligned to the same offset for each level + * we provide a hepler macro that should be used to find the current smb_handle structure + */ +#define SMB_OPEN_OUT_FILE(op, file) do { \ + switch (op->generic.level) { \ + case RAW_OPEN_OPEN: \ + file = &op->openold.out.file; \ + break; \ + case RAW_OPEN_OPENX: \ + file = &op->openx.out.file; \ + break; \ + case RAW_OPEN_MKNEW: \ + file = &op->mknew.out.file; \ + break; \ + case RAW_OPEN_CREATE: \ + file = &op->create.out.file; \ + break; \ + case RAW_OPEN_CTEMP: \ + file = &op->ctemp.out.file; \ + break; \ + case RAW_OPEN_SPLOPEN: \ + file = &op->splopen.out.file; \ + break; \ + case RAW_OPEN_NTCREATEX: \ + file = &op->ntcreatex.out.file; \ + break; \ + case RAW_OPEN_T2OPEN: \ + file = &op->t2open.out.file; \ + break; \ + case RAW_OPEN_NTTRANS_CREATE: \ + file = &op->nttrans.out.file; \ + break; \ + case RAW_OPEN_OPENX_READX: \ + file = &op->openxreadx.out.file; \ + break; \ + default: \ + /* this must be a programmer error */ \ + file = NULL; \ + break; \ + } \ +} while (0) /* SMBNTCreateX interface */ struct { enum smb_open_level level; @@ -1212,7 +1254,7 @@ union smb_open { uint16_t ipc_state; uint8_t is_directory; } out; - } ntcreatex, generic; + } ntcreatex, nttrans, generic; /* TRANS2_OPEN interface */ struct { -- cgit From 410fb90322cf47780a9af4f5e38e57fcfa528471 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 May 2006 16:50:50 +0000 Subject: r15640: - NT IOCTL calls also have an 'in' data_blob - fix the receive code of NT IOCTL's we only need the NTTRANS data payload not the SMB payload here metze (This used to be commit 358d03143f0a78344c1af720e33ebe2619df09df) --- source4/libcli/raw/interfaces.h | 1 + source4/libcli/raw/rawioctl.c | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d9387cc6e2..e0696b45ec 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1716,6 +1716,7 @@ union smb_ioctl { uint32_t function; BOOL fsctl; uint8_t filter; + DATA_BLOB blob; } in; struct { DATA_BLOB blob; diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 49237fe9da..77c8c80158 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -86,7 +86,7 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, SCVAL(setup, 7, parms->ntioctl.in.filter); nt.in.function = NT_TRANSACT_IOCTL; nt.in.params = data_blob(NULL, 0); - nt.in.data = data_blob(NULL, 0); + nt.in.data = parms->ntioctl.in.blob; return smb_raw_nttrans_send(tree, &nt); } @@ -98,13 +98,22 @@ static NTSTATUS smb_raw_ntioctl_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { - if (!smbcli_request_receive(req) || - smbcli_request_is_error(req)) { - return smbcli_request_destroy(req); - } + NTSTATUS status; + struct smb_nttrans nt; + TALLOC_CTX *tmp_mem; - parms->ntioctl.out.blob = smbcli_req_pull_blob(req, mem_ctx, req->in.data, -1); - return smbcli_request_destroy(req); + tmp_mem = talloc_new(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(tmp_mem); + + status = smb_raw_nttrans_recv(req, tmp_mem, &nt); + if (!NT_STATUS_IS_OK(status)) goto fail; + + parms->ntioctl.out.blob = nt.out.data; + talloc_steal(mem_ctx, parms->ntioctl.out.blob.data); + +fail: + talloc_free(tmp_mem); + return status; } -- cgit From 7e7a760b4b89db9db3afd6b292c99914c7c768f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 May 2006 16:59:08 +0000 Subject: r15643: add some FSCTL_ codes metze (This used to be commit 47dc1ed25323e76b93d9cef2a389726734d2e735) --- source4/libcli/raw/ioctl.h | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/ioctl.h b/source4/libcli/raw/ioctl.h index cd658c121b..2f0886e43e 100644 --- a/source4/libcli/raw/ioctl.h +++ b/source4/libcli/raw/ioctl.h @@ -25,9 +25,36 @@ /* filesystem control codes */ -#define FSCTL_FILESYSTEM 0x90000 -#define FSCTL_SET_SPARSE (FSCTL_FILESYSTEM | (49<<2)) -#define FSCTL_REQUEST_BATCH_OPLOCK (FSCTL_FILESYSTEM | (2<<2)) +#define FSCTL_METHOD_BUFFERED 0x00000000 +#define FSCTL_METHOD_IN_DIRECT 0x00000001 +#define FSCTL_METHOD_OUT_DIRECT 0x00000002 +#define FSCTL_METHOD_NEITHER 0x00000003 -#define FSCTL_NAMED_PIPE 0x110000 -#define FSCTL_NAMED_PIPE_READ_WRITE (FSCTL_NAMED_PIPE | 0xc017) +#define FSCTL_ACCESS_ANY 0x00000000 +#define FSCTL_ACCESS_READ 0x00004000 +#define FSCTL_ACCESS_WRITE 0x00008000 + +#define FSCTL_FILESYSTEM 0x00090000 +#define FSCTL_REQUEST_OPLOCK_LEVEL_1 (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0000 | FSCTL_METHOD_BUFFERED) +#define FSCTL_REQUEST_OPLOCK_LEVEL_2 (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0004 | FSCTL_METHOD_BUFFERED) +#define FSCTL_REQUEST_BATCH_OPLOCK (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0008 | FSCTL_METHOD_BUFFERED) +#define FSCTL_OPLOCK_BREAK_ACKNOWLEDGE (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x000C | FSCTL_METHOD_BUFFERED) +#define FSCTL_OPBATCH_ACK_CLOSE_PENDING (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0010 | FSCTL_METHOD_BUFFERED) +#define FSCTL_OPLOCK_BREAK_NOTIFY (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0014 | FSCTL_METHOD_BUFFERED) +#define FSCTL_FILESYS_GET_STATISTICS (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0060 | FSCTL_METHOD_BUFFERED) +#define FSCTL_GET_NTFS_VOLUME_DATA (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0064 | FSCTL_METHOD_BUFFERED) +#define FSCTL_FIND_FILES_BY_SID (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x008C | FSCTL_METHOD_NEITHER) +#define FSCTL_SET_OBJECT_ID (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0098 | FSCTL_METHOD_BUFFERED) +#define FSCTL_GET_OBJECT_ID (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x009C | FSCTL_METHOD_BUFFERED) +#define FSCTL_DELETE_OBJECT_ID (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x00A0 | FSCTL_METHOD_BUFFERED) +#define FSCTL_SET_REPARSE_POINT (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x00A4 | FSCTL_METHOD_BUFFERED) +#define FSCTL_GET_REPARSE_POINT (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x00A8 | FSCTL_METHOD_BUFFERED) +#define FSCTL_DELETE_REPARSE_POINT (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x00AC | FSCTL_METHOD_BUFFERED) +#define FSCTL_CREATE_OR_GET_OBJECT_ID (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x00C0 | FSCTL_METHOD_BUFFERED) +#define FSCTL_SET_SPARSE (FSCTL_FILESYSTEM | FSCTL_ACCESS_ANY | 0x00C4 | FSCTL_METHOD_BUFFERED) + +#define FSCTL_NAMED_PIPE 0x00110000 +#define FSCTL_NAMED_PIPE_READ_WRITE (FSCTL_NAMED_PIPE | FSCTL_ACCESS_ANY | 0xC014 | FSCTL_METHOD_NEITHER) + +#define FSCTL_NETWORK_FILESYSTEM 0x00140000 +#define FSCTL_GET_SHADOW_COPY_DATA (FSCTL_NETWORK_FILESYSTEM | FSCTL_ACCESS_READ | 0x0064 | FSCTL_METHOD_BUFFERED) -- cgit From 5ff4b74df3f32192c9828233295d9f8fedcceb23 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 May 2006 09:52:14 +0000 Subject: r15656: for NT IOCTL's we need to control the max_data field for some calls metze (This used to be commit 3cab02f6f513cf7eb3d8863e62952766bb4d908f) --- source4/libcli/raw/interfaces.h | 1 + source4/libcli/raw/rawioctl.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index e0696b45ec..d98b5de370 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1716,6 +1716,7 @@ union smb_ioctl { uint32_t function; BOOL fsctl; uint8_t filter; + uint32_t max_data; DATA_BLOB blob; } in; struct { diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 77c8c80158..356852edd8 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -77,7 +77,7 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, nt.in.max_setup = 0; nt.in.max_param = 0; - nt.in.max_data = 0; + nt.in.max_data = parms->ntioctl.in.max_data; nt.in.setup_count = 4; nt.in.setup = (uint16_t *)setup; SIVAL(setup, 0, parms->ntioctl.in.function); -- cgit From edee7dd8fd07659458cfc6d0e656a93a607a8e33 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 May 2006 15:16:46 +0000 Subject: r15661: add NT_STATUS_OBJECTID_NOT_FOUND metze (This used to be commit 2c9db9429106094b8ee9fa45e6f9a89af7c3725f) --- source4/libcli/util/nterr.c | 1 + source4/libcli/util/nterr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 45d0181103..ef53e030c7 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -544,6 +544,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, + { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, diff --git a/source4/libcli/util/nterr.h b/source4/libcli/util/nterr.h index 08e3fa2db0..29afa511d4 100644 --- a/source4/libcli/util/nterr.h +++ b/source4/libcli/util/nterr.h @@ -575,6 +575,7 @@ #define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266) #define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) +#define NT_STATUS_OBJECTID_NOT_FOUND NT_STATUS(0xC0000000 | 0x02F0) #define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ #define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) #define NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX NT_STATUS(0xC0000000 | 0x20026) -- cgit From c18cd54bad426d8d83af1e320bd2bf499d8d6089 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 May 2006 11:15:18 +0000 Subject: r15688: windows sends 4 as max_setup count on NT IOCTL metze (This used to be commit 0d983fa46fff588cf94e58732e36e324e2f0478a) --- source4/libcli/raw/rawioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 356852edd8..af48fcb566 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -75,7 +75,7 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, struct smb_nttrans nt; uint8_t setup[8]; - nt.in.max_setup = 0; + nt.in.max_setup = 4; nt.in.max_param = 0; nt.in.max_data = parms->ntioctl.in.max_data; nt.in.setup_count = 4; -- cgit From 7f0e17e9030ad734977f66c2cc27faec501154a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 May 2006 15:10:39 +0000 Subject: r15718: - split the SMBflush with the 0xFFFF wildcard fnum into a different level metze (This used to be commit 95bf41b4d4ec96349802955e364fe44ef85f9077) --- source4/libcli/raw/interfaces.h | 7 +++++++ source4/libcli/raw/rawfile.c | 12 +++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d98b5de370..84f897172e 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1725,13 +1725,20 @@ union smb_ioctl { } ntioctl; }; +enum smb_flush_level {RAW_FLUSH_FLUSH, RAW_FLUSH_ALL}; + /* struct for SMBflush */ union smb_flush { struct { + enum smb_ioctl_level level; struct { union smb_handle file; } in; } flush, generic; + + struct { + enum smb_ioctl_level level; + } flush_all; }; diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 2873011aa2..fb3035c0a8 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -849,9 +849,19 @@ NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms) struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms) { struct smbcli_request *req; + uint16_t fnum; + + switch (parms->generic.level) { + case RAW_FLUSH_FLUSH: + fnum = parms->flush.in.file.fnum; + break; + case RAW_FLUSH_ALL: + fnum = 0xFFFF; + break; + } SETUP_REQUEST(SMBflush, 1, 0); - SSVAL(req->out.vwv, VWV(0), parms->flush.in.file.fnum); + SSVAL(req->out.vwv, VWV(0), fnum); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); -- cgit From b77eaaa3bc7cd27320496440deda8a6ca62f7f5a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 09:38:59 +0000 Subject: r15737: fix a typos and comment metze (This used to be commit 1f50b2e0534ee25861b6812b64d91f63cbb118ad) --- source4/libcli/raw/interfaces.h | 4 ++-- source4/libcli/raw/rawfile.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 84f897172e..588237acb0 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1730,14 +1730,14 @@ enum smb_flush_level {RAW_FLUSH_FLUSH, RAW_FLUSH_ALL}; /* struct for SMBflush */ union smb_flush { struct { - enum smb_ioctl_level level; + enum smb_flush_level level; struct { union smb_handle file; } in; } flush, generic; struct { - enum smb_ioctl_level level; + enum smb_flush_level level; } flush_all; }; diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index fb3035c0a8..faa2cdbeb4 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -844,7 +844,7 @@ NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms) /**************************************************************************** flush a file - async send - a flush to fnum 0xFFFF will flush all files + a flush with RAW_FLUSH_ALL will flush all files ****************************************************************************/ struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms) { -- cgit From 2de1d5f7a8c2a3a815d81c217c274d2d5f1768cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 10:40:10 +0000 Subject: r15740: add TODO, that we should check if the server supports large offsets, before sending large offset requests metze (This used to be commit b9ba2b8c5a314ba9e559e50bea4deb692dc0f3ec) --- source4/libcli/raw/rawreadwrite.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 7b424df6df..63a60ad545 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -81,6 +81,10 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea SSVAL(req->out.vwv, VWV(6), parms->readx.in.mincnt); SIVAL(req->out.vwv, VWV(7), parms->readx.in.maxcnt >> 16); SSVAL(req->out.vwv, VWV(9), parms->readx.in.remaining); + /* + * TODO: give an error when the offset is 64 bit + * and the server doesn't support it + */ if (bigoffset) { SIVAL(req->out.vwv, VWV(10),parms->readx.in.offset>>32); } -- cgit From e306c5bf129a981693bd251d45597f1e584ee850 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 10:46:38 +0000 Subject: r15741: move smb2 request structures into the main smb request structs as new levels metze (This used to be commit 91806353174704857dfcc15a730af7232cfde660) --- source4/libcli/raw/clisession.c | 7 + source4/libcli/raw/clitree.c | 7 + source4/libcli/raw/interfaces.h | 364 +++++++++++++++++++++++++++++-- source4/libcli/raw/rawfile.c | 10 + source4/libcli/raw/rawioctl.c | 6 + source4/libcli/raw/rawreadwrite.c | 13 ++ source4/libcli/raw/rawsearch.c | 1 + source4/libcli/smb2/close.c | 2 +- source4/libcli/smb2/create.c | 2 +- source4/libcli/smb2/find.c | 2 +- source4/libcli/smb2/flush.c | 2 +- source4/libcli/smb2/ioctl.c | 4 +- source4/libcli/smb2/read.c | 2 +- source4/libcli/smb2/smb2_calls.h | 265 ---------------------- source4/libcli/smb2/write.c | 2 +- source4/libcli/smb_composite/sesssetup.c | 5 + 16 files changed, 403 insertions(+), 291 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 2942279b12..9e114aece8 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -137,6 +137,9 @@ struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session, smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE); break; + + case RAW_SESSSETUP_SMB2: + return NULL; } if (!smbcli_request_send(req)) { @@ -213,6 +216,10 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE); break; + + case RAW_SESSSETUP_SMB2: + req->status = NT_STATUS_INTERNAL_ERROR; + break; } failed: diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 6e120ed615..51f2e12457 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -79,6 +79,9 @@ struct smbcli_request *smb_raw_tcon_send(struct smbcli_tree *tree, smbcli_req_append_string(req, parms->tconx.in.path, STR_TERMINATE | STR_UPPER); smbcli_req_append_string(req, parms->tconx.in.device, STR_TERMINATE | STR_ASCII); break; + + case RAW_TCON_SMB2: + return NULL; } if (!smbcli_request_send(req)) { @@ -125,6 +128,10 @@ NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type, p, -1, STR_TERMINATE); break; + + case RAW_TCON_SMB2: + req->status = NT_STATUS_INTERNAL_ERROR; + break; } failed: diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 588237acb0..5fe64f064c 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -207,7 +207,11 @@ union smb_rename { } ntrename; }; -enum smb_tcon_level {RAW_TCON_TCON, RAW_TCON_TCONX}; +enum smb_tcon_level { + RAW_TCON_TCON, + RAW_TCON_TCONX, + RAW_TCON_SMB2 +}; /* union used in tree connect call */ union smb_tcon { @@ -248,10 +252,42 @@ union smb_tcon { uint16_t tid; } out; } tconx; + + /* SMB2 TreeConnect */ + struct smb2_tree_connect { + enum smb_tcon_level level; + + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + uint16_t unknown1; /* 0x0000 */ + /* uint16_t path_ofs */ + /* uint16_t path_size */ + + /* dynamic body */ + const char *path; /* as non-terminated UTF-16 on the wire */ + } in; + struct { + /* static body buffer 16 (0x10) bytes */ + /* uint16_t buffer_code; 0x10 */ + uint16_t unknown1; /* 0x02 */ + uint32_t unknown2; /* 0x00 */ + uint32_t unknown3; /* 0x00 */ + uint32_t access_mask; + + /* extracted from the SMB2 header */ + uint32_t tid; + } out; + } smb2; }; -enum smb_sesssetup_level {RAW_SESSSETUP_OLD, RAW_SESSSETUP_NT1, RAW_SESSSETUP_SPNEGO}; +enum smb_sesssetup_level { + RAW_SESSSETUP_OLD, + RAW_SESSSETUP_NT1, + RAW_SESSSETUP_SPNEGO, + RAW_SESSSETUP_SMB2 +}; /* union used in session_setup call */ union smb_sesssetup { @@ -330,6 +366,37 @@ union smb_sesssetup { uint16_t vuid; } out; } spnego; + + /* SMB2 SessionSetup */ + struct smb2_session_setup { + enum smb_sesssetup_level level; + + struct { + /* static body buffer 16 (0x10) bytes */ + /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ + uint16_t _pad; + uint32_t unknown2; /* 0xF */ + uint32_t unknown3; /* 0x00 */ + /* uint16_t secblob_ofs */ + /* uint16_t secblob_size */ + + /* dynamic body */ + DATA_BLOB secblob; + } in; + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 +1 */ + uint16_t _pad; + /* uint16_t secblob_ofs */ + /* uint16_t secblob_size */ + + /* dynamic body */ + DATA_BLOB secblob; + + /* extracted from the SMB2 header */ + uint64_t uid; + } out; + } smb2; }; /* Note that the specified enum values are identical to the actual info-levels used @@ -1161,12 +1228,18 @@ union smb_fsinfo { enum smb_open_level { - RAW_OPEN_OPEN, RAW_OPEN_OPENX, - RAW_OPEN_MKNEW, RAW_OPEN_CREATE, - RAW_OPEN_CTEMP, RAW_OPEN_SPLOPEN, - RAW_OPEN_NTCREATEX, RAW_OPEN_T2OPEN, - RAW_OPEN_NTTRANS_CREATE, - RAW_OPEN_OPENX_READX}; + RAW_OPEN_OPEN, + RAW_OPEN_OPENX, + RAW_OPEN_MKNEW, + RAW_OPEN_CREATE, + RAW_OPEN_CTEMP, + RAW_OPEN_SPLOPEN, + RAW_OPEN_NTCREATEX, + RAW_OPEN_T2OPEN, + RAW_OPEN_NTTRANS_CREATE, + RAW_OPEN_OPENX_READX, + RAW_OPEN_SMB2 +}; /* the generic interface is defined to be equal to the NTCREATEX interface */ #define RAW_OPEN_GENERIC RAW_OPEN_NTCREATEX @@ -1417,11 +1490,73 @@ union smb_open { uint16_t nread; } out; } openxreadx; + +#define SMB2_CREATE_FLAG_REQUEST_OPLOCK 0x0100 +#define SMB2_CREATE_FLAG_REQUEST_EXCLUSIVE_OPLOCK 0x0800 +#define SMB2_CREATE_FLAG_GRANT_OPLOCK 0x0001 +#define SMB2_CREATE_FLAG_GRANT_EXCLUSIVE_OPLOCK 0x0080 + + /* SMB2 Create */ + struct smb2_create { + enum smb_open_level level; + struct { + /* static body buffer 56 (0x38) bytes */ + /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ + uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint32_t impersonation; + uint32_t unknown3[4]; + uint32_t access_mask; + + uint32_t file_attr; + uint32_t share_access; + uint32_t open_disposition; + uint32_t create_options; + + /* uint16_t fname_ofs */ + /* uint16_t fname_size */ + /* uint32_t blob_ofs; */ + /* uint32_t blob_size; */ + + /* dynamic body */ + const char *fname; + + /* optional list of extended attributes */ + struct smb_ea_list eas; + } in; + struct { + union smb_handle file; + + /* static body buffer 88 (0x58) bytes */ + /* uint16_t buffer_code; 0x59 = 0x58 + 1 */ + uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint32_t create_action; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t file_attr; + uint32_t _pad; + /* struct smb2_handle handle;*/ + /* uint32_t blob_ofs; */ + /* uint32_t blob_size; */ + + /* dynamic body */ + DATA_BLOB blob; + } out; + } smb2; }; -enum smb_read_level {RAW_READ_READBRAW, RAW_READ_LOCKREAD, RAW_READ_READ, RAW_READ_READX}; +enum smb_read_level { + RAW_READ_READBRAW, + RAW_READ_LOCKREAD, + RAW_READ_READ, + RAW_READ_READX, + RAW_READ_SMB2 +}; #define RAW_READ_GENERIC RAW_READ_READX @@ -1496,12 +1631,45 @@ union smb_read { uint16_t nread; } out; } read; + + /* SMB2 Read */ + struct smb2_read { + enum smb_read_level level; + struct { + union smb_handle file; + + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ + uint16_t _pad; + uint32_t length; + uint64_t offset; + /* struct smb2_handle handle; */ + uint64_t unknown1; /* 0x0000000000000000 */ + uint64_t unknown2; /* 0x0000000000000000 */ + uint8_t _bug; + } in; + struct { + /* static body buffer 16 (0x10) bytes */ + /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ + /* uint16_t data_ofs; */ + /* uint32_t data_size; */ + uint64_t unknown1; /* 0x0000000000000000 */ + + /* dynamic body */ + DATA_BLOB data; + } out; + } smb2; }; -enum smb_write_level {RAW_WRITE_WRITEUNLOCK, RAW_WRITE_WRITE, - RAW_WRITE_WRITEX, RAW_WRITE_WRITECLOSE, - RAW_WRITE_SPLWRITE}; +enum smb_write_level { + RAW_WRITE_WRITEUNLOCK, + RAW_WRITE_WRITE, + RAW_WRITE_WRITEX, + RAW_WRITE_WRITECLOSE, + RAW_WRITE_SPLWRITE, + RAW_WRITE_SMB2 +}; #define RAW_WRITE_GENERIC RAW_WRITE_WRITEX @@ -1579,6 +1747,34 @@ union smb_write { const uint8_t *data; } in; } splwrite; + + /* SMB2 Write */ + struct smb2_write { + enum smb_write_level level; + struct { + union smb_handle file; + + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ + /* uint16_t data_ofs; */ + /* uint32_t data_size; */ + uint64_t offset; + /* struct smb2_handle handle; */ + uint64_t unknown1; /* 0xFFFFFFFFFFFFFFFF */ + uint64_t unknown2; /* 0xFFFFFFFFFFFFFFFF */ + + /* dynamic body */ + DATA_BLOB data; + } in; + struct { + /* static body buffer 17 (0x11) bytes */ + /* uint16_t buffer_code; 0x11 */ + uint16_t _pad; + uint32_t nwritten; + uint64_t unknown1; /* 0x0000000000000000 */ + uint8_t _bug; + } out; + } smb2; }; @@ -1619,7 +1815,11 @@ union smb_lock { }; -enum smb_close_level {RAW_CLOSE_CLOSE, RAW_CLOSE_SPLCLOSE}; +enum smb_close_level { + RAW_CLOSE_CLOSE, + RAW_CLOSE_SPLCLOSE, + RAW_CLOSE_SMB2 +}; #define RAW_CLOSE_GENERIC RAW_CLOSE_CLOSE @@ -1643,6 +1843,33 @@ union smb_close { union smb_handle file; } in; } splclose; + + /* SMB2 Close */ + struct smb2_close { + enum smb_close_level level; + struct { + union smb_handle file; + + /* static body buffer 24 (0x18) bytes */ + /* uint16_t buffer_code; 0x18 */ +#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0) + uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ + uint32_t _pad; + } in; + struct { + /* static body buffer 60 (0x3C) bytes */ + /* uint16_t buffer_code; 0x3C */ + uint16_t flags; + uint32_t _pad; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t file_attr; + } out; + } smb2; }; @@ -1681,7 +1908,11 @@ union smb_lpq { } retq; }; -enum smb_ioctl_level {RAW_IOCTL_IOCTL, RAW_IOCTL_NTIOCTL}; +enum smb_ioctl_level { + RAW_IOCTL_IOCTL, + RAW_IOCTL_NTIOCTL, + RAW_IOCTL_SMB2 +}; /* union for ioctl() backend @@ -1723,12 +1954,60 @@ union smb_ioctl { DATA_BLOB blob; } out; } ntioctl; + + /* SMB2 Ioctl */ + struct smb2_ioctl { + enum smb_ioctl_level level; + struct { + union smb_handle file; + + /* static body buffer 56 (0x38) bytes */ + /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ + uint16_t _pad; + uint32_t function; + /*struct smb2_handle handle;*/ + /* uint32_t out_ofs; */ + /* uint32_t out_size; */ + uint32_t unknown2; + /* uint32_t in_ofs; */ + /* uint32_t in_size; */ + uint32_t max_response_size; + uint64_t flags; + + /* dynamic body */ + DATA_BLOB out; + DATA_BLOB in; + } in; + struct { + union smb_handle file; + + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ + uint16_t _pad; + uint32_t function; + /* struct smb2_handle handle; */ + /* uint32_t in_ofs; */ + /* uint32_t in_size; */ + /* uint32_t out_ofs; */ + /* uint32_t out_size; */ + uint32_t unknown2; + uint32_t unknown3; + + /* dynamic body */ + DATA_BLOB in; + DATA_BLOB out; + } out; + } smb2; }; -enum smb_flush_level {RAW_FLUSH_FLUSH, RAW_FLUSH_ALL}; +enum smb_flush_level { + RAW_FLUSH_FLUSH, + RAW_FLUSH_ALL, + RAW_FLUSH_SMB2 +}; -/* struct for SMBflush */ union smb_flush { + /* struct for SMBflush */ struct { enum smb_flush_level level; struct { @@ -1736,11 +2015,20 @@ union smb_flush { } in; } flush, generic; + /* SMBflush with 0xFFFF wildcard fnum */ struct { enum smb_flush_level level; } flush_all; -}; + /* SMB2 Flush */ + struct smb2_flush { + enum smb_flush_level level; + struct { + union smb_handle file; + uint32_t unknown; + } in; + } smb2; +}; /* struct for SMBcopy */ struct smb_copy { @@ -1823,7 +2111,8 @@ struct smb_notify { enum smb_search_level {RAW_SEARCH_GENERIC = 0xF000, RAW_SEARCH_SEARCH, /* SMBsearch */ RAW_SEARCH_FFIRST, /* SMBffirst */ - RAW_SEARCH_FUNIQUE, /* SMBfunique */ + RAW_SEARCH_FUNIQUE, /* SMBfunique */ + RAW_SEARCH_SMB2, /* SMB2 Find */ RAW_SEARCH_STANDARD = SMB_FIND_STANDARD, RAW_SEARCH_EA_SIZE = SMB_FIND_EA_SIZE, RAW_SEARCH_EA_LIST = SMB_FIND_EA_LIST, @@ -1878,6 +2167,45 @@ union smb_search_first { uint16_t end_of_search; } out; } t2ffirst; + +/* + SMB2 uses different level numbers for the same old SMB search levels +*/ +#define SMB2_FIND_DIRECTORY_INFO 0x01 +#define SMB2_FIND_FULL_DIRECTORY_INFO 0x02 +#define SMB2_FIND_BOTH_DIRECTORY_INFO 0x03 +#define SMB2_FIND_NAME_INFO 0x0C +#define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25 +#define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26 + /* SMB2 Find */ + struct smb2_find { + enum smb_search_level level; + struct { + union smb_handle file; + + /* static body buffer 32 (0x20) bytes */ + /* uint16_t buffer_code; 0x21 = 0x20 + 1 */ + uint8_t level; + uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */ + uint32_t unknown; /* perhaps a continue token? */ + /* struct smb2_handle handle; */ + /* uint16_t pattern_ofs; */ + /* uint32_t pattern_size; */ + uint32_t max_response_size; + + /* dynamic body */ + const char *pattern; + } in; + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x08 */ + /* uint16_t blob_ofs; */ + /* uint32_t blob_size; */ + + /* dynamic body */ + DATA_BLOB blob; + } out; + } smb2; }; /* union for file search continue */ diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index faa2cdbeb4..3aad05a748 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -545,6 +545,8 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32); } break; + case RAW_OPEN_SMB2: + return NULL; } if (!smbcli_request_send(req)) { @@ -680,6 +682,9 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio req->status = NT_STATUS_BUFFER_TOO_SMALL; } break; + case RAW_OPEN_SMB2: + req->status = NT_STATUS_INTERNAL_ERROR; + break; } failed: @@ -717,6 +722,9 @@ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_cl SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum); SIVAL(req->out.vwv, VWV(1), 0); /* reserved */ break; + + case RAW_CLOSE_SMB2: + return NULL; } if (!req) return NULL; @@ -858,6 +866,8 @@ struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_fl case RAW_FLUSH_ALL: fnum = 0xFFFF; break; + case RAW_FLUSH_SMB2: + return NULL; } SETUP_REQUEST(SMBflush, 1, 0); diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index af48fcb566..0bd37785ac 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -132,6 +132,9 @@ struct smbcli_request *smb_raw_ioctl_send(struct smbcli_tree *tree, union smb_io case RAW_IOCTL_NTIOCTL: req = smb_raw_ntioctl_send(tree, parms); break; + + case RAW_IOCTL_SMB2: + return NULL; } return req; @@ -149,6 +152,9 @@ NTSTATUS smb_raw_ioctl_recv(struct smbcli_request *req, case RAW_IOCTL_NTIOCTL: return smb_raw_ntioctl_recv(req, mem_ctx, parms); + + case RAW_IOCTL_SMB2: + break; } return NT_STATUS_INVALID_LEVEL; } diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 63a60ad545..7a47ce66f4 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -94,6 +94,9 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea SSVAL(req->out.hdr, HDR_FLG2, flags2); } break; + + case RAW_READ_SMB2: + return NULL; } if (!smbcli_request_send(req)) { @@ -165,6 +168,10 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) req->status = NT_STATUS_BUFFER_TOO_SMALL; } break; + + case RAW_READ_SMB2: + req->status = NT_STATUS_INTERNAL_ERROR; + break; } failed: @@ -261,6 +268,9 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr memcpy(req->out.data, parms->splwrite.in.data, parms->splwrite.in.count); } break; + + case RAW_WRITE_SMB2: + return NULL; } if (!smbcli_request_send(req)) { @@ -303,6 +313,9 @@ NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms) break; case RAW_WRITE_SPLWRITE: break; + case RAW_WRITE_SMB2: + req->status = NT_STATUS_INTERNAL_ERROR; + break; } failed: diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index e844a33358..5e05d7c3c5 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -482,6 +482,7 @@ static int parse_trans2_search(struct smbcli_tree *tree, case RAW_SEARCH_SEARCH: case RAW_SEARCH_FFIRST: case RAW_SEARCH_FUNIQUE: + case RAW_SEARCH_SMB2: /* handled elsewhere */ return -1; diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 4483f3c75b..9156e7d10d 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -37,7 +37,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * SSVAL(req->out.body, 0x02, io->in.flags); SIVAL(req->out.body, 0x04, 0); /* pad */ - smb2_push_handle(req->out.body+0x08, &io->in.handle); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); smb2_transport_send(req); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 339258a0df..da21d090fd 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -144,7 +144,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); io->out._pad = IVAL(req->in.body, 0x3C); - smb2_pull_handle(req->in.body+0x40, &io->out.handle); + smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index e811095f42..8f4d6c8301 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -39,7 +39,7 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io SCVAL(req->out.body, 0x02, io->in.level); SCVAL(req->out.body, 0x03, io->in.continue_flags); SIVAL(req->out.body, 0x04, io->in.unknown); - smb2_push_handle(req->out.body+0x08, &io->in.handle); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); status = smb2_push_o16s16_string(&req->out, 0x18, io->in.pattern); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index 596eb26009..0eb5ed7a3b 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -36,7 +36,7 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush * SSVAL(req->out.body, 0x02, 0); /* pad? */ SIVAL(req->out.body, 0x04, io->in.unknown); - smb2_push_handle(req->out.body+0x08, &io->in.handle); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); smb2_transport_send(req); diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index ffe029e16e..a3ac2d9f47 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -38,7 +38,7 @@ struct smb2_request *smb2_ioctl_send(struct smb2_tree *tree, struct smb2_ioctl * SSVAL(req->out.body, 0x02, 0); /* pad */ SIVAL(req->out.body, 0x04, io->in.function); - smb2_push_handle(req->out.body+0x08, &io->in.handle); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); status = smb2_push_o32s32_blob(&req->out, 0x18, io->in.out); if (!NT_STATUS_IS_OK(status)) { @@ -80,7 +80,7 @@ NTSTATUS smb2_ioctl_recv(struct smb2_request *req, io->out._pad = SVAL(req->in.body, 0x02); io->out.function = IVAL(req->in.body, 0x04); - smb2_pull_handle(req->in.body+0x08, &io->out.handle); + smb2_pull_handle(req->in.body+0x08, &io->out.file.handle); status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x18, &io->out.in); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index 82e9b13280..6806adb8f6 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -37,7 +37,7 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io SSVAL(req->out.body, 0x02, 0); /* pad */ SIVAL(req->out.body, 0x04, io->in.length); SBVAL(req->out.body, 0x08, io->in.offset); - smb2_push_handle(req->out.body+0x10, &io->in.handle); + smb2_push_handle(req->out.body+0x10, &io->in.file.handle); SBVAL(req->out.body, 0x20, io->in.unknown1); SBVAL(req->out.body, 0x28, io->in.unknown2); SCVAL(req->out.body, 0x30, io->in._bug); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index b6f8fdef71..6bee0dec91 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -52,138 +52,6 @@ struct smb2_negprot { } out; }; -struct smb2_session_setup { - struct { - /* static body buffer 16 (0x10) bytes */ - /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ - uint16_t _pad; - uint32_t unknown2; /* 0xF */ - uint32_t unknown3; /* 0x00 */ - /* uint16_t secblob_ofs */ - /* uint16_t secblob_size */ - - /* dynamic body */ - DATA_BLOB secblob; - } in; - struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 +1 */ - uint16_t _pad; - /* uint16_t secblob_ofs */ - /* uint16_t secblob_size */ - - /* dynamic body */ - DATA_BLOB secblob; - - /* extracted from the SMB2 header */ - uint64_t uid; - } out; -}; - -struct smb2_tree_connect { - struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ - uint16_t unknown1; /* 0x0000 */ - /* uint16_t path_ofs */ - /* uint16_t path_size */ - - /* dynamic body */ - const char *path; /* as non-terminated UTF-16 on the wire */ - } in; - struct { - /* static body buffer 16 (0x10) bytes */ - /* uint16_t buffer_code; 0x10 */ - uint16_t unknown1; /* 0x02 */ - uint32_t unknown2; /* 0x00 */ - uint32_t unknown3; /* 0x00 */ - uint32_t access_mask; - - /* extracted from the SMB2 header */ - uint32_t tid; - } out; -}; - -#define SMB2_CREATE_FLAG_REQUEST_OPLOCK 0x0100 -#define SMB2_CREATE_FLAG_REQUEST_EXCLUSIVE_OPLOCK 0x0800 -#define SMB2_CREATE_FLAG_GRANT_OPLOCK 0x0001 -#define SMB2_CREATE_FLAG_GRANT_EXCLUSIVE_OPLOCK 0x0080 - -struct smb2_create { - struct { - /* static body buffer 56 (0x38) bytes */ - /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ - uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ - uint32_t impersonation; - uint32_t unknown3[4]; - uint32_t access_mask; - - uint32_t file_attr; - uint32_t share_access; - uint32_t open_disposition; - uint32_t create_options; - - /* uint16_t fname_ofs */ - /* uint16_t fname_size */ - /* uint32_t blob_ofs; */ - /* uint32_t blob_size; */ - - /* dynamic body */ - const char *fname; - - /* optional list of extended attributes */ - struct smb_ea_list eas; - } in; - - struct { - /* static body buffer 88 (0x58) bytes */ - /* uint16_t buffer_code; 0x59 = 0x58 + 1 */ - uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ - uint32_t create_action; - NTTIME create_time; - NTTIME access_time; - NTTIME write_time; - NTTIME change_time; - uint64_t alloc_size; - uint64_t size; - uint32_t file_attr; - uint32_t _pad; - struct smb2_handle handle; - /* uint32_t blob_ofs; */ - /* uint32_t blob_size; */ - - /* dynamic body */ - DATA_BLOB blob; - } out; -}; - - -#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0) - -struct smb2_close { - struct { - /* static body buffer 24 (0x18) bytes */ - /* uint16_t buffer_code; 0x18 */ - uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ - uint32_t _pad; - struct smb2_handle handle; - } in; - - struct { - /* static body buffer 60 (0x3C) bytes */ - /* uint16_t buffer_code; 0x3C */ - uint16_t flags; - uint32_t _pad; - NTTIME create_time; - NTTIME access_time; - NTTIME write_time; - NTTIME change_time; - uint64_t alloc_size; - uint64_t size; - uint32_t file_attr; - } out; -}; - /* getinfo classes */ #define SMB2_GETINFO_FILE 0x01 #define SMB2_GETINFO_FS 0x02 @@ -230,139 +98,6 @@ struct smb2_setinfo { } in; }; -struct smb2_write { - struct { - /* static body buffer 48 (0x30) bytes */ - /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ - /* uint16_t data_ofs; */ - /* uint32_t data_size; */ - uint64_t offset; - struct smb2_handle handle; - uint64_t unknown1; /* 0xFFFFFFFFFFFFFFFF */ - uint64_t unknown2; /* 0xFFFFFFFFFFFFFFFF */ - - /* dynamic body */ - DATA_BLOB data; - } in; - - struct { - /* static body buffer 17 (0x11) bytes */ - /* uint16_t buffer_code; 0x11 */ - uint16_t _pad; - uint32_t nwritten; - uint64_t unknown1; /* 0x0000000000000000 */ - uint8_t _bug; - } out; -}; - -struct smb2_read { - struct { - /* static body buffer 48 (0x30) bytes */ - /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ - uint16_t _pad; - uint32_t length; - uint64_t offset; - struct smb2_handle handle; - uint64_t unknown1; /* 0x0000000000000000 */ - uint64_t unknown2; /* 0x0000000000000000 */ - uint8_t _bug; - } in; - - struct { - /* static body buffer 16 (0x10) bytes */ - /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ - /* uint16_t data_ofs; */ - /* uint32_t data_size; */ - uint64_t unknown1; /* 0x0000000000000000 */ - - /* dynamic body */ - DATA_BLOB data; - } out; -}; - -/* - SMB2 uses different level numbers for the same old SMB search levels -*/ -#define SMB2_FIND_DIRECTORY_INFO 0x01 -#define SMB2_FIND_FULL_DIRECTORY_INFO 0x02 -#define SMB2_FIND_BOTH_DIRECTORY_INFO 0x03 -#define SMB2_FIND_NAME_INFO 0x0C -#define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25 -#define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26 - -struct smb2_find { - struct { - /* static body buffer 32 (0x20) bytes */ - /* uint16_t buffer_code; 0x21 = 0x20 + 1 */ - uint8_t level; - uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */ - uint32_t unknown; /* perhaps a continue token? */ - struct smb2_handle handle; - /* uint16_t pattern_ofs; */ - /* uint32_t pattern_size; */ - uint32_t max_response_size; - - /* dynamic body */ - const char *pattern; - } in; - - struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x08 */ - /* uint16_t blob_ofs; */ - /* uint32_t blob_size; */ - - /* dynamic body */ - DATA_BLOB blob; - } out; -}; - -struct smb2_ioctl { - struct { - /* static body buffer 56 (0x38) bytes */ - /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ - uint16_t _pad; - uint32_t function; - struct smb2_handle handle; - /* uint32_t out_ofs; */ - /* uint32_t out_size; */ - uint32_t unknown2; - /* uint32_t in_ofs; */ - /* uint32_t in_size; */ - uint32_t max_response_size; - uint64_t flags; - - /* dynamic body */ - DATA_BLOB out; - DATA_BLOB in; - } in; - - struct { - /* static body buffer 48 (0x30) bytes */ - /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ - uint16_t _pad; - uint32_t function; - struct smb2_handle handle; - /* uint32_t in_ofs; */ - /* uint32_t in_size; */ - /* uint32_t out_ofs; */ - /* uint32_t out_size; */ - uint32_t unknown2; - uint32_t unknown3; - - /* dynamic body */ - DATA_BLOB in; - DATA_BLOB out; - } out; -}; - -struct smb2_flush { - struct { - uint32_t unknown; - struct smb2_handle handle; - } in; -}; - struct cli_credentials; struct event_context; #include "libcli/smb2/smb2_proto.h" diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index 1edce3f773..760aadcd8e 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -42,7 +42,7 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * } SBVAL(req->out.body, 0x08, io->in.offset); - smb2_push_handle(req->out.body+0x10, &io->in.handle); + smb2_push_handle(req->out.body+0x10, &io->in.file.handle); SBVAL(req->out.body, 0x20, io->in.unknown1); SBVAL(req->out.body, 0x28, io->in.unknown2); diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 1b7756a3f4..0bad2ff1ad 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -165,6 +165,11 @@ static void request_handler(struct smbcli_request *req) state->req->async.private = c; return; } + break; + + case RAW_SESSSETUP_SMB2: + c->status = NT_STATUS_INTERNAL_ERROR; + break; } /* enforce the local signing required flag */ -- cgit From 6885c6253e81fca9633c9396a5669fc7fe27ef7d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 11:50:10 +0000 Subject: r15744: convert_string_talloc() handles src_len == 0 as error but it's valid in this case metze (This used to be commit 92c19b1ba4e89bd1e973e084b254087c98ceac18) --- source4/libcli/smb2/request.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 136b81e977..e631375a52 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -522,6 +522,14 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me status = smb2_pull_o16s16_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); + if (blob.length == 0) { + char *s; + s = talloc_strdup(mem_ctx, ""); + NT_STATUS_HAVE_NO_MEMORY(s); + *str = s; + return NT_STATUS_OK; + } + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); -- cgit From 26047265cce081d0190ac781f3eba60fc12a4b60 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 18:34:59 +0000 Subject: r15756: handle RAW_OPEN_SMB2 metze (This used to be commit 8aebd7adc9a0288ebf6b8d84fc376d699054a520) --- source4/libcli/raw/interfaces.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 5fe64f064c..49ac702e45 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1282,6 +1282,9 @@ union smb_open { case RAW_OPEN_OPENX_READX: \ file = &op->openxreadx.out.file; \ break; \ + case RAW_OPEN_SMB2: \ + file = &op->smb2.out.file; \ + break; \ default: \ /* this must be a programmer error */ \ file = NULL; \ -- cgit From 1911475976de4a54787ac263eb4b15cb3db5eea3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 10:13:49 +0000 Subject: r15770: when there's a dynamic body, we need to send the first byte even if the dynamic size if 0 metze (This used to be commit c7e8e79d75fd53fa37e9220e5bc9cac7ab574ff6) --- source4/libcli/smb2/request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index e631375a52..43445575f0 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -94,6 +94,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ * which is always be part of the packet is initialized */ if (body_dynamic_size) { + req->out.size += 1; SCVAL(req->out.dynamic, 0, 0); } -- cgit From 39fd6db42b4186f573ab4728509d6b8a7c8a6973 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 12:57:36 +0000 Subject: r15775: add some privilege related WERROR codes metze (This used to be commit 4e8c9bbd768a0d3f8719d8f2005d9b1b527c44fd) --- source4/libcli/util/doserr.c | 2 ++ source4/libcli/util/doserr.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index e1ef9d930a..65e9470280 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -74,6 +74,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_INVALID_COMPUTERNAME", WERR_INVALID_COMPUTERNAME }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, + { "WERR_NO_SUCH_PRIVILEGE", WERR_NO_SUCH_PRIVILEGE }, + { "WERR_PRIVILEGE_NOT_HELD", WERR_PRIVILEGE_NOT_HELD }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_DS_SERVICE_BUSY", WERR_DS_SERVICE_BUSY }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 5b8ff1dd3d..601320f6fe 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -192,6 +192,8 @@ #define WERR_UNKNOWN_REVISION W_ERROR(1305) #define WERR_REVISION_MISMATCH W_ERROR(1306) #define WERR_INVALID_OWNER W_ERROR(1307) +#define WERR_NO_SUCH_PRIVILEGE W_ERROR(1313) +#define WERR_PRIVILEGE_NOT_HELD W_ERROR(1314) #define WERR_NO_SUCH_USER W_ERROR(1317) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) #define WERR_NO_SUCH_DOMAIN W_ERROR(1355) -- cgit From 79183f68fc2bbe9094f9ab4e1bf7c5a3c8d5dd07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 May 2006 02:07:11 +0000 Subject: r15794: fixed a problem with DOS status codes - found by kukks (thanks!) (This used to be commit 1a57b16715bf8b82e8f9118c3ab401acf081d02c) --- source4/libcli/util/errormap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index f4feaeffc5..e6a1c0e71c 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1198,6 +1198,11 @@ void ntstatus_to_dos(NTSTATUS ntstatus, uint8_t *eclass, uint32_t *ecode) *ecode = 0; return; } + if (NT_STATUS_IS_DOS(ntstatus)) { + *eclass = NT_STATUS_DOS_CLASS(ntstatus); + *ecode = NT_STATUS_DOS_CODE(ntstatus); + return; + } for (i=0; NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus); i++) { if (NT_STATUS_V(ntstatus) == NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus)) { -- cgit From d9bdfb0a0720907151b71086be289a0f6ec2bb98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 May 2006 17:21:38 +0000 Subject: r15814: add SMB2 Lock interface structure metze (This used to be commit 8f1850ef65dc8c860912639d787d82399d015f13) --- source4/libcli/raw/interfaces.h | 34 +++++++++++++++++++++++++++++++++- source4/libcli/raw/rawfile.c | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 49ac702e45..8b144779f4 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1781,7 +1781,12 @@ union smb_write { }; -enum smb_lock_level {RAW_LOCK_LOCK, RAW_LOCK_UNLOCK, RAW_LOCK_LOCKX}; +enum smb_lock_level { + RAW_LOCK_LOCK, + RAW_LOCK_UNLOCK, + RAW_LOCK_LOCKX, + RAW_LOCK_SMB2 +}; /* the generic interface is defined to be equal to the lockingX interface */ #define RAW_LOCK_GENERIC RAW_LOCK_LOCKX @@ -1815,6 +1820,33 @@ union smb_lock { uint32_t offset; } in; } lock, unlock; + + /* SMB2 Lock */ + struct smb2_lock { + enum smb_lock_level level; + struct { + union smb_handle file; + + /* static body buffer 48 (0x30) bytes */ + /* uint16_t buffer_code; 0x30 */ + uint16_t unknown1; /* must be 0x0001 */ + uint32_t unknown2; + /* struct smb2_handle handle; */ + uint64_t offset; + uint64_t count; + uint32_t unknown5; +#define SMB2_LOCK_FLAG_NONE 0x00000000 +#define SMB2_LOCK_FLAG_EXCLUSIV 0x00000002 +#define SMB2_LOCK_FLAG_UNLOCK 0x00000004 +#define SMB2_LOCK_FLAGS_MASK 0x00000006 + uint32_t flags; + } in; + struct { + /* static body buffer 4 (0x04) bytes */ + /* uint16_t buffer_code; 0x04 */ + uint16_t unknown1; + } out; + } smb2; }; diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 3aad05a748..5a38d4083d 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -802,6 +802,8 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc } } } + case RAW_LOCK_SMB2: + return NULL; } if (!smbcli_request_send(req)) { -- cgit From a2f463bb3a66393f3934b465e73caab191277c6d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 May 2006 17:33:39 +0000 Subject: r15815: add SMB2 Lock client code metze (This used to be commit 4a307d7185862675fee23f55d3f85950a76f551d) --- source4/libcli/smb2/config.mk | 1 + source4/libcli/smb2/lock.c | 77 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 source4/libcli/smb2/lock.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 4e2e7bb468..33ef633e1f 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -18,5 +18,6 @@ OBJ_FILES = \ logoff.o \ tdis.o \ flush.o \ + lock.o \ keepalive.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c new file mode 100644 index 0000000000..73cc30c162 --- /dev/null +++ b/source4/libcli/smb2/lock.c @@ -0,0 +1,77 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client lock handling + + Copyright (C) Stefan Metzmacher 2006 + + 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 "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a lock request +*/ +struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, False, 0); + if (req == NULL) return NULL; + + SIVAL(req->out.hdr, SMB2_HDR_PID, io->in.unknown2); + + SSVAL(req->out.body, 0x02, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.unknown2); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); + SBVAL(req->out.body, 0x18, io->in.offset); + SBVAL(req->out.body, 0x20, io->in.count); + SIVAL(req->out.body, 0x28, io->in.unknown5); + SIVAL(req->out.body, 0x28, io->in.flags); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a lock reply +*/ +NTSTATUS smb2_lock_recv(struct smb2_request *req, struct smb2_lock *io) +{ + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x04, False); + + io->out.unknown1 = SVAL(req->in.body, 0x02); + + return smb2_request_destroy(req); +} + +/* + sync lock request +*/ +NTSTATUS smb2_lock(struct smb2_tree *tree, struct smb2_lock *io) +{ + struct smb2_request *req = smb2_lock_send(tree, io); + return smb2_lock_recv(req, io); +} -- cgit From e982523bc0581906741ad45dea4126ae8a11731c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 May 2006 19:13:57 +0000 Subject: r15820: this line was just for testing metze (This used to be commit 1a9bfa2ac96d09d34d3c974ec5d89dc23bf3e153) --- source4/libcli/smb2/lock.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c index 73cc30c162..c06c10a806 100644 --- a/source4/libcli/smb2/lock.c +++ b/source4/libcli/smb2/lock.c @@ -34,8 +34,6 @@ struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, False, 0); if (req == NULL) return NULL; - SIVAL(req->out.hdr, SMB2_HDR_PID, io->in.unknown2); - SSVAL(req->out.body, 0x02, io->in.unknown1); SIVAL(req->out.body, 0x04, io->in.unknown2); smb2_push_handle(req->out.body+0x08, &io->in.file.handle); -- cgit From e5e9bcd39842e3b24460d9dcbfea079ed8d3c804 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 May 2006 06:52:22 +0000 Subject: r15834: fixed a memory leak in the session code (This used to be commit 8a7047c102cdbcf746dcdf8a52554816b7770026) --- source4/libcli/auth/session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index afa7afbd0f..280a0d282c 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -151,7 +151,7 @@ DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_ return data_blob(NULL, 0); } - ret = data_blob(NULL, 8+dlen); + ret = data_blob_talloc(mem_ctx, NULL, 8+dlen); if (!ret.data) { data_blob_free(&src); return data_blob(NULL, 0); -- cgit From 0b56e916a762d77cb7dd06a4130ad78d33d57b53 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 May 2006 09:27:58 +0000 Subject: r15835: fixed locking in the client library (This used to be commit 7ea51fb624ded55f69f235a6791de871f754e8fa) --- source4/libcli/raw/rawfile.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 5a38d4083d..f8b5e90e4b 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -801,6 +801,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc SIVAL(p, 6, lockp[i].count); } } + break; } case RAW_LOCK_SMB2: return NULL; -- cgit From 971d30bb201f5c3faff5f575d26882eb79f7955a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:34:11 +0000 Subject: r15854: more talloc_set_destructor() typesafe fixes (This used to be commit 61c6100617589ac6df4f527877241464cacbf8b3) --- source4/libcli/cldap/cldap.c | 3 +-- source4/libcli/dgram/mailslot.c | 5 +---- source4/libcli/ldap/ldap_client.c | 3 +-- source4/libcli/nbt/nbtsocket.c | 6 ++---- source4/libcli/raw/clitransport.c | 7 ++----- source4/libcli/resolve/host.c | 3 +-- source4/libcli/smb2/transport.c | 6 ++---- source4/libcli/wrepl/winsrepl.c | 9 +++------ 8 files changed, 13 insertions(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 58beb1b642..03e690ef18 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -44,9 +44,8 @@ /* destroy a pending request */ -static int cldap_request_destructor(void *ptr) +static int cldap_request_destructor(struct cldap_request *req) { - struct cldap_request *req = talloc_get_type(ptr, struct cldap_request); if (req->state == CLDAP_REQUEST_SEND) { DLIST_REMOVE(req->cldap->send_queue, req); } diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 467289bcee..775f662370 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -41,11 +41,8 @@ /* destroy a mailslot handler */ -static int dgram_mailslot_destructor(void *ptr) +static int dgram_mailslot_destructor(struct dgram_mailslot_handler *dgmslot) { - struct dgram_mailslot_handler *dgmslot = - talloc_get_type(ptr, struct dgram_mailslot_handler); - DLIST_REMOVE(dgmslot->dgmsock->mailslot_handlers, dgmslot); return 0; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8d815c7103..07b7f2b412 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -487,9 +487,8 @@ static void ldap_reconnect(struct ldap_connection *conn) } /* destroy an open ldap request */ -static int ldap_request_destructor(void *ptr) +static int ldap_request_destructor(struct ldap_request *req) { - struct ldap_request *req = talloc_get_type(ptr, struct ldap_request); if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); } diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 50da8168e0..7bdeb834f9 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -32,10 +32,8 @@ /* destroy a pending request */ -static int nbt_name_request_destructor(void *ptr) -{ - struct nbt_name_request *req = talloc_get_type(ptr, struct nbt_name_request); - +static int nbt_name_request_destructor(struct nbt_name_request *req) +{ if (req->state == NBT_REQUEST_SEND) { DLIST_REMOVE(req->nbtsock->send_queue, req); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 2ad155e9b9..fc257b9098 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -50,10 +50,8 @@ static void smbcli_transport_event_handler(struct event_context *ev, /* destroy a transport */ -static int transport_destructor(void *ptr) +static int transport_destructor(struct smbcli_transport *transport) { - struct smbcli_transport *transport = ptr; - smbcli_transport_dead(transport); return 0; } @@ -538,9 +536,8 @@ static void smbcli_timeout_handler(struct event_context *ev, struct timed_event /* destroy a request */ -static int smbcli_request_destructor(void *ptr) +static int smbcli_request_destructor(struct smbcli_request *req) { - struct smbcli_request *req = talloc_get_type(ptr, struct smbcli_request); if (req->state == SMBCLI_REQUEST_RECV) { DLIST_REMOVE(req->transport->pending_recv, req); } diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 781ea957df..18188f7c1c 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -51,9 +51,8 @@ struct host_state { name resolution without leaving a potentially blocking call running in a child */ -static int host_destructor(void *ptr) +static int host_destructor(struct host_state *state) { - struct host_state *state = talloc_get_type(ptr, struct host_state); close(state->child_fd); if (state->child != (pid_t)-1) { kill(state->child, SIGTERM); diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 6567ad4de7..9b6a39171d 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -51,9 +51,8 @@ static void smb2_transport_event_handler(struct event_context *ev, /* destroy a transport */ -static int transport_destructor(void *ptr) +static int transport_destructor(struct smb2_transport *transport) { - struct smb2_transport *transport = ptr; smb2_transport_dead(transport); return 0; } @@ -254,9 +253,8 @@ static void smb2_timeout_handler(struct event_context *ev, struct timed_event *t /* destroy a request */ -static int smb2_request_destructor(void *ptr) +static int smb2_request_destructor(struct smb2_request *req) { - struct smb2_request *req = talloc_get_type(ptr, struct smb2_request); if (req->state == SMB2_REQUEST_RECV) { DLIST_REMOVE(req->transport->pending_recv, req); } diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index c37d5f9873..a1735c547c 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -144,9 +144,8 @@ static void wrepl_error(void *private, NTSTATUS status) /* destroy a wrepl_socket destructor */ -static int wrepl_socket_destructor(void *ptr) +static int wrepl_socket_destructor(struct wrepl_socket *sock) { - struct wrepl_socket *sock = talloc_get_type(ptr, struct wrepl_socket); if (sock->dead) { sock->free_skipped = True; return -1; @@ -244,9 +243,8 @@ failed: /* destroy a wrepl_request */ -static int wrepl_request_destructor(void *ptr) +static int wrepl_request_destructor(struct wrepl_request *req) { - struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request); if (req->state == WREPL_REQUEST_RECV) { DLIST_REMOVE(req->wrepl_socket->recv_queue, req); } @@ -431,9 +429,8 @@ struct wrepl_send_ctrl_state { struct wrepl_socket *wrepl_sock; }; -static int wrepl_send_ctrl_destructor(void *ptr) +static int wrepl_send_ctrl_destructor(struct wrepl_send_ctrl_state *s) { - struct wrepl_send_ctrl_state *s = talloc_get_type(ptr, struct wrepl_send_ctrl_state); struct wrepl_request *req = s->wrepl_sock->recv_queue; /* check if the request is still in WREPL_STATE_RECV, -- cgit From c38f24b0210cb98b5062f3e0c92be9a9177e1bb7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 7 Jun 2006 04:23:42 +0000 Subject: r16073: On an incoming wildcard search, it is critical that the size be correct, or we try and do a memcmp on the trailing '\0'. This happens because we now use memcmp for the prefix matching. I just wish I had a test other than a particular invocation of the OSX client. (I've tried and failed so far) Andrew Bartlett (This used to be commit 36aa8390807581442c68ac3ee9dd6eb05d89b86d) --- source4/libcli/ldap/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6f475478b1..6a0b86f78b 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -548,9 +548,9 @@ static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_va if (chunks[chunk_num]->data == NULL) { return NULL; } - chunks[chunk_num]->length = strlen(value) + 1; + chunks[chunk_num]->length = strlen(value); - chunks[chunk_num + 1] = NULL; + chunks[chunk_num + 1] = '\0'; return chunks; } -- cgit From 7613015f47f6e45ee9ac4f652f773bd2980fc788 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 Jun 2006 07:11:25 +0000 Subject: r16091: Without this patch Samba3 will not accept this, and simply setting the "92" to "100" will give funny permissions... Volker (This used to be commit b76a3d4f590963d48eae8a9899d17ae3833c3dfa) --- source4/libcli/raw/rawsetfileinfo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 46480c636e..030779ad14 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -138,7 +138,7 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, parms, blob); case RAW_SFILEINFO_UNIX_BASIC: - NEED_BLOB(92); + NEED_BLOB(100); SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file); SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes); smbcli_push_nttime(blob->data, 16, parms->unix_basic.in.status_change_time); @@ -150,7 +150,8 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, SBVAL(blob->data, 60, parms->unix_basic.in.dev_major); SBVAL(blob->data, 68, parms->unix_basic.in.dev_minor); SBVAL(blob->data, 76, parms->unix_basic.in.unique_id); - SBVAL(blob->data, 84, parms->unix_basic.in.nlink); + SBVAL(blob->data, 84, parms->unix_basic.in.permissions); + SBVAL(blob->data, 92, parms->unix_basic.in.nlink); return True; case RAW_SFILEINFO_DISPOSITION_INFO: -- cgit From e3a6c6be79326578a1e9c7cb8547234eab62235f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Jun 2006 15:20:05 +0000 Subject: r16100: Patch from Michael Wood : s/then/than/ for correct grammar (This used to be commit 26a2fa97e4c819e630bc9b50e11c8d5328c7b8c8) --- source4/libcli/dgram/mailslot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 775f662370..c59cab79da 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -22,10 +22,10 @@ /* This implements "Class 2 mailslots", i.e. the communication mechanism - used for all mailslot packets smaller then 425 bytes. + used for all mailslot packets smaller than 425 bytes. "Class 1 mailslots" (which use SMB) are used for messages larger - then 426 bytes and are supported on some systems. These are not implemented + than 426 bytes and are supported on some systems. These are not implemented in Samba4 yet, as there don't appear to be any core services that use them. -- cgit From d3b3436ce1a71464b0f1a9ffa69643cd5c816004 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Jun 2006 07:03:53 +0000 Subject: r16406: use the generic smb_handle in smb2_getinfo/smb2_setinfo metze (This used to be commit dcc02df8297162a7fd913560194d9e821798dbe0) --- source4/libcli/smb2/getinfo.c | 6 +++--- source4/libcli/smb2/setinfo.c | 4 ++-- source4/libcli/smb2/smb2_calls.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 57a363b63f..2af8032938 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -44,7 +44,7 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin SIVAL(req->out.body, 0x0C, io->in.unknown2); SIVAL(req->out.body, 0x10, io->in.flags); SIVAL(req->out.body, 0x14, io->in.flags2); - smb2_push_handle(req->out.body+0x18, &io->in.handle); + smb2_push_handle(req->out.body+0x18, &io->in.file.handle); smb2_transport_send(req); @@ -118,7 +118,7 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi ZERO_STRUCT(b); b.in.max_response_size = 0x10000; - b.in.handle = io->generic.in.file.handle; + b.in.file.handle = io->generic.in.file.handle; b.in.level = smb2_level; if (io->generic.level == RAW_FILEINFO_SEC_DESC) { @@ -174,7 +174,7 @@ struct smb2_request *smb2_getinfo_fs_send(struct smb2_tree *tree, union smb_fsin ZERO_STRUCT(b); b.in.max_response_size = 0x10000; - b.in.handle = io->generic.handle; + b.in.file.handle = io->generic.handle; b.in.level = smb2_level; return smb2_getinfo_send(tree, &b); diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index 432034b13b..c5fc0577d6 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -45,7 +45,7 @@ struct smb2_request *smb2_setinfo_send(struct smb2_tree *tree, struct smb2_setin } SIVAL(req->out.body, 0x0C, io->in.flags); - smb2_push_handle(req->out.body+0x10, &io->in.handle); + smb2_push_handle(req->out.body+0x10, &io->in.file.handle); smb2_transport_send(req); @@ -92,7 +92,7 @@ struct smb2_request *smb2_setinfo_file_send(struct smb2_tree *tree, union smb_se ZERO_STRUCT(b); b.in.level = smb2_level; - b.in.handle = io->generic.in.file.handle; + b.in.file.handle = io->generic.in.file.handle; if (!smb_raw_setfileinfo_passthru(tree, io->generic.level, io, &b.in.blob)) { return NULL; } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 6bee0dec91..f870ddb38a 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -75,7 +75,7 @@ struct smb2_getinfo { uint32_t unknown2; uint32_t flags; /* level specific */ uint32_t flags2; /* used by all_eas level */ - struct smb2_handle handle; + union smb_handle file; } in; struct { @@ -93,7 +93,7 @@ struct smb2_setinfo { struct { uint16_t level; uint32_t flags; - struct smb2_handle handle; + union smb_handle file; DATA_BLOB blob; } in; }; -- cgit From 7bf085571eba5f321d35ff449d68da39ec303dab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jun 2006 17:06:36 +0000 Subject: r16464: split client and server min/max protocol settings metze (This used to be commit 6164d1e22e0545f558315591d49f862de06ea945) --- source4/libcli/cliconnect.c | 2 +- source4/libcli/smb_composite/connect.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index d89d6a1568..45f44adba1 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -57,7 +57,7 @@ BOOL smbcli_transport_establish(struct smbcli_state *cli, /* wrapper around smb_raw_negotiate() */ NTSTATUS smbcli_negprot(struct smbcli_state *cli) { - return smb_raw_negotiate(cli->transport, lp_maxprotocol()); + return smb_raw_negotiate(cli->transport, lp_cli_maxprotocol()); } /* wrapper around smb_raw_sesssetup() */ diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index a28d33cf7f..7d4960d7d5 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -63,7 +63,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - state->req = smb_raw_negotiate_send(state->transport, lp_maxprotocol()); + state->req = smb_raw_negotiate_send(state->transport, lp_cli_maxprotocol()); NT_STATUS_HAVE_NO_MEMORY(state->req); state->req->async.fn = request_handler; -- cgit From 7dc22bf3e019d2f68e52cbeab8eb3ad14d903cff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Jun 2006 17:16:14 +0000 Subject: r16566: add pull function for a site32/offset32 blob metze (This used to be commit 81702c36c28e9e32860c5d91887d2ad2121ce306) --- source4/libcli/smb2/request.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 43445575f0..2f1117cf30 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -508,6 +508,30 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } +/* + pull a uint32_t length/ uint32_t ofs/blob triple from a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +{ + uint32_t ofs, size; + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + size = IVAL(ptr, 0); + ofs = IVAL(ptr, 4); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; +} + /* pull a string in a uint16_t ofs/ uint16_t length/blob format UTF-16 without termination -- cgit From 0646a91bc9e004340026f2dbe082e057416eb1e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Jun 2006 17:55:02 +0000 Subject: r16569: - use push_string() metze (This used to be commit f099fcb6e3a38d6df22cb3a0c7c666333e41f11b) --- source4/libcli/auth/smbencrypt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 24fdeff33f..98f98a4986 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -91,10 +91,10 @@ BOOL E_deshash(const char *passwd, uint8_t p16[16]) BOOL ret = True; fstring dospwd; ZERO_STRUCT(dospwd); - + /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - + push_string(dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const uint8_t *)dospwd, p16); -- cgit From 332f5b19a101115ce920b9291d10e78fbea8db62 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Jun 2006 07:02:14 +0000 Subject: r16667: - use ndr_pull_struct_blob() to make the RAW_FILEINFO_SEC_DESC pull code simpler - use ndr_push_struct_blob() for RAW_SFILEINFO_SEC_DESC metze (This used to be commit 79e51f033e680303431e56e818346b66a836d044) --- source4/libcli/raw/rawfileinfo.c | 21 +++++++++------------ source4/libcli/raw/rawsetfileinfo.c | 14 +++++++++++++- 2 files changed, 22 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index b33d0df828..67cad83c6d 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -244,20 +244,17 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ return NT_STATUS_OK; case RAW_FILEINFO_SEC_DESC: { - struct ndr_pull *ndr; NTSTATUS status; - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } + parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor); - if (parms->query_secdesc.out.sd == NULL) { - return NT_STATUS_NO_MEMORY; - } - status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, - parms->query_secdesc.out.sd); - talloc_free(ndr); - return status; + NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd); + + status = ndr_pull_struct_blob(blob, mem_ctx, + parms->query_secdesc.out.sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; } default: diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 030779ad14..0daf14e0cc 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "librpc/gen_ndr/ndr_security.h" /* @@ -83,7 +84,18 @@ BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, NEED_BLOB(4); SIVAL(blob->data, 0, parms->mode_information.in.mode); return True; - + + case RAW_FILEINFO_SEC_DESC: { + NTSTATUS status; + + status = ndr_push_struct_blob(blob, mem_ctx, + parms->set_secdesc.in.sd, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NT_STATUS_IS_OK(status)) return False; + + return True; + } + /* Unhandled levels */ case RAW_SFILEINFO_1023: case RAW_SFILEINFO_1025: -- cgit From bd1efc1235b647f6845fb7d6218cf2b4068e9f0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Jun 2006 11:08:27 +0000 Subject: r16669: this calls don't expect any valid error codes than NT_STATUS_OK metze (This used to be commit 429215113bd999466141df0a2e3b3097d677df1f) --- source4/libcli/smb2/close.c | 2 +- source4/libcli/smb2/flush.c | 2 +- source4/libcli/smb2/keepalive.c | 2 +- source4/libcli/smb2/logoff.c | 2 +- source4/libcli/smb2/setinfo.c | 2 +- source4/libcli/smb2/tdis.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 9156e7d10d..1e2ef3afb1 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -51,7 +51,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) { if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index 0eb5ed7a3b..531322ec4f 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -50,7 +50,7 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush * NTSTATUS smb2_flush_recv(struct smb2_request *req, struct smb2_flush *io) { if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index ac31afd4dc..75161d8fb5 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -48,7 +48,7 @@ struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport) NTSTATUS smb2_keepalive_recv(struct smb2_request *req) { if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index cfaa389ef8..67129319fb 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -50,7 +50,7 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session) NTSTATUS smb2_logoff_recv(struct smb2_request *req) { if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index c5fc0577d6..4b1d4ab608 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -59,7 +59,7 @@ struct smb2_request *smb2_setinfo_send(struct smb2_tree *tree, struct smb2_setin NTSTATUS smb2_setinfo_recv(struct smb2_request *req) { if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c index f89e5c8e90..1c6b3e978e 100644 --- a/source4/libcli/smb2/tdis.c +++ b/source4/libcli/smb2/tdis.c @@ -48,7 +48,7 @@ struct smb2_request *smb2_tdis_send(struct smb2_tree *tree) NTSTATUS smb2_tdis_recv(struct smb2_request *req) { if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } -- cgit From d63dd113ae2c7f4f6d64def00a488548e805bc7e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Jun 2006 22:16:58 +0000 Subject: r16699: the layout of SMB2 Read and Write is identical... so we know that the 9th bytes is just uninitialized padding metze (This used to be commit f97a21b970ed23973cced2c67b5bc9ecd7afee88) --- source4/libcli/raw/interfaces.h | 4 +--- source4/libcli/smb2/read.c | 3 +-- source4/libcli/smb2/write.c | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 8b144779f4..3665af9548 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1649,7 +1649,6 @@ union smb_read { /* struct smb2_handle handle; */ uint64_t unknown1; /* 0x0000000000000000 */ uint64_t unknown2; /* 0x0000000000000000 */ - uint8_t _bug; } in; struct { /* static body buffer 16 (0x10) bytes */ @@ -1771,11 +1770,10 @@ union smb_write { } in; struct { /* static body buffer 17 (0x11) bytes */ - /* uint16_t buffer_code; 0x11 */ + /* uint16_t buffer_code; 0x11 = 0x10 + 1*/ uint16_t _pad; uint32_t nwritten; uint64_t unknown1; /* 0x0000000000000000 */ - uint8_t _bug; } out; } smb2; }; diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index 6806adb8f6..eb935fb4f1 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x31, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x30, True, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); /* pad */ @@ -40,7 +40,6 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io smb2_push_handle(req->out.body+0x10, &io->in.file.handle); SBVAL(req->out.body, 0x20, io->in.unknown1); SBVAL(req->out.body, 0x28, io->in.unknown2); - SCVAL(req->out.body, 0x30, io->in._bug); smb2_transport_send(req); diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index 760aadcd8e..c9d6ce4b53 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -63,12 +63,11 @@ NTSTATUS smb2_write_recv(struct smb2_request *req, struct smb2_write *io) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x11, False); + SMB2_CHECK_PACKET_RECV(req, 0x10, True); io->out._pad = SVAL(req->in.body, 0x02); io->out.nwritten = IVAL(req->in.body, 0x04); io->out.unknown1 = BVAL(req->in.body, 0x08); - io->out._bug = CVAL(req->in.body, 0x10); return smb2_request_destroy(req); } -- cgit From bd0dcebe36ea926e2ad9a32a6eb103a88325c930 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Jun 2006 23:11:07 +0000 Subject: r16705: fix a bug found by valgrind... as we setup the 1 padding byte for non present dynamic part, we need to overwrite it when we're getting a real dynamic part, so we need to remove the buf->size +=1 when we do the first push to the dynamic part (when buf->dynamic is still but->body + buf->body_fixed) metze (This used to be commit f309209629ad1b63a76fc06163a3eeb07dce4c86) --- source4/libcli/smb2/request.c | 33 +++++++++++++++++++++++++-------- source4/libcli/smb2/smb2.h | 1 + source4/libcli/smb2/transport.c | 5 +++-- 3 files changed, 29 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2f1117cf30..60fd6ca3ae 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -69,6 +69,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.body = req->out.hdr + SMB2_HDR_BODY; + req->out.body_fixed= body_fixed_size; req->out.body_size = body_fixed_size; req->out.dynamic = (body_dynamic_size ? req->out.body + body_fixed_size : NULL); @@ -198,6 +199,14 @@ size_t smb2_padding_size(uint32_t offset, size_t n) return n - (offset & (n-1)); } +static size_t smb2_padding_fix(struct smb2_request_buffer *buf) +{ + if (buf->dynamic == (buf->body + buf->body_fixed)) { + return 1; + } + return 0; +} + /* grow a SMB2 buffer by the specified amount */ @@ -261,6 +270,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -286,6 +296,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SSVAL(ptr, 0, offset); SSVAL(ptr, 2, blob.length); @@ -299,8 +310,8 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } @@ -317,6 +328,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -337,6 +349,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SSVAL(ptr, 0, offset); SIVAL(ptr, 2, blob.length); @@ -350,8 +363,8 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } @@ -368,6 +381,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -388,6 +402,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 8); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SIVAL(ptr, 0, offset); SIVAL(ptr, 4, blob.length); @@ -401,8 +416,8 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } @@ -419,6 +434,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -439,6 +455,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 8); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SIVAL(ptr, 0, blob.length); SIVAL(ptr, 4, offset); @@ -452,8 +469,8 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 33df4daabe..14e6e8d835 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -87,6 +87,7 @@ struct smb2_request_buffer { /* the packet body */ uint8_t *body; + size_t body_fixed; size_t body_size; /* this point to the next dynamic byte that can be used diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 9b6a39171d..6f91699704 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -193,10 +193,11 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) } buffer_code = SVAL(req->in.body, 0); + req->in.body_fixed = (buffer_code & ~1); req->in.dynamic = NULL; - dynamic_size = req->in.body_size - (buffer_code & ~1); + dynamic_size = req->in.body_size - req->in.body_fixed; if (dynamic_size != 0 && (buffer_code & 1)) { - req->in.dynamic = req->in.body + (buffer_code & ~1); + req->in.dynamic = req->in.body + req->in.body_fixed; if (smb2_oob(&req->in, req->in.dynamic, dynamic_size)) { DEBUG(1,("SMB2 request invalid dynamic size 0x%x\n", dynamic_size)); -- cgit From 63d0c5a0570908cee293cca3300a4b50f48f8afd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Jun 2006 11:07:47 +0000 Subject: r16708: the packet format of SMB2 SessionSetup has changed, there're 8 more unknown bytes... Note: - vista-CTP also support this as a server, but uses the old format as client - but vista-beta2 only uses and accept the new format metze (This used to be commit b3bdd4afdefc9ad3550f86a0aa6e6c90bf8ab416) --- source4/libcli/raw/interfaces.h | 13 +++++++++---- source4/libcli/smb2/session.c | 12 +++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 3665af9548..c581978b81 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -372,13 +372,18 @@ union smb_sesssetup { enum smb_sesssetup_level level; struct { - /* static body buffer 16 (0x10) bytes */ - /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ + /* NOTE: this was 0x11 = 0x10 + 1 in vista-CTP + * and changed in vista-beta2, but both server's + * can handle the 0x18 clients + */ + /* static body buffer 24 (0x18) bytes */ + /* uint16_t buffer_code; 0x19 = 0x18 + 1 */ uint16_t _pad; - uint32_t unknown2; /* 0xF */ - uint32_t unknown3; /* 0x00 */ + uint32_t unknown2; /* 0x0000000F(vista-CTP) 0x00000007(vista-beta2) */ + uint32_t unknown3; /* 0x0000000 */ /* uint16_t secblob_ofs */ /* uint16_t secblob_size */ + uint64_t unknown4; /* 0x0000000000000000 only present in vista-beta2 */ /* dynamic body */ DATA_BLOB secblob; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 83e6d1ae00..7518a3d6d3 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -69,11 +69,11 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, NTSTATUS status; req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, - 0x10, True, io->in.secblob.length); + 0x18, True, io->in.secblob.length); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); - SSVAL(req->out.body, 0x02, 0); /* pad */ + SSVAL(req->out.body, 0x02, io->in._pad); /* pad */ SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3); @@ -84,6 +84,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, talloc_free(req); return NULL; } + SBVAL(req->out.body, 0x10, io->in.unknown4); smb2_transport_send(req); @@ -209,9 +210,10 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se c->event_ctx = session->transport->socket->event.ctx; ZERO_STRUCT(state->io); - state->io.in._pad = 0x0; - state->io.in.unknown2 = 0xF; - state->io.in.unknown3 = 0x00; + state->io.in._pad = 0x0000; + state->io.in.unknown2 = 0x0000000F; + state->io.in.unknown3 = 0x00000000; + state->io.in.unknown4 = 0; /* uint64_t */ c->status = gensec_set_credentials(session->gensec, credentials); if (!NT_STATUS_IS_OK(c->status)) { -- cgit From 6acd9aed93b09b74e53a3b854085c6c8fab41819 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Jul 2006 14:14:11 +0000 Subject: r16734: the 2 bytes after the opcode and before the flags, is no padding... the following patch is needed for vista beta2 to connect to samba4 metze (This used to be commit 58baae8fc463cd2c4e4ce532c153ad80313b03eb) --- source4/libcli/smb2/request.c | 4 ++-- source4/libcli/smb2/smb2.h | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 60fd6ca3ae..016c885675 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -78,9 +78,9 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); - SSVAL(req->out.hdr, SMB2_HDR_PAD2, 0); + SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,0); SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN, 0); + SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN2,0); SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 14e6e8d835..2c1892cafc 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -143,19 +143,19 @@ struct smb2_request { #define SMB2_MIN_SIZE 0x42 /* offsets into header elements */ -#define SMB2_HDR_LENGTH 0x04 -#define SMB2_HDR_PAD1 0x06 -#define SMB2_HDR_STATUS 0x08 -#define SMB2_HDR_OPCODE 0x0c -#define SMB2_HDR_PAD2 0x0e -#define SMB2_HDR_FLAGS 0x10 -#define SMB2_HDR_UNKNOWN 0x14 -#define SMB2_HDR_SEQNUM 0x18 -#define SMB2_HDR_PID 0x20 -#define SMB2_HDR_TID 0x24 -#define SMB2_HDR_UID 0x28 /* 64 bit */ -#define SMB2_HDR_SIG 0x30 /* guess ... */ -#define SMB2_HDR_BODY 0x40 +#define SMB2_HDR_LENGTH 0x04 +#define SMB2_HDR_PAD1 0x06 +#define SMB2_HDR_STATUS 0x08 +#define SMB2_HDR_OPCODE 0x0c +#define SMB2_HDR_UNKNOWN1 0x0e +#define SMB2_HDR_FLAGS 0x10 +#define SMB2_HDR_UNKNOWN2 0x14 +#define SMB2_HDR_SEQNUM 0x18 +#define SMB2_HDR_PID 0x20 +#define SMB2_HDR_TID 0x24 +#define SMB2_HDR_UID 0x28 /* 64 bit */ +#define SMB2_HDR_SIG 0x30 /* guess ... */ +#define SMB2_HDR_BODY 0x40 /* SMB2 opcodes */ #define SMB2_OP_NEGPROT 0x00 -- cgit From 464e352380865b44e67b7c5526adb94d15274955 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Mon, 3 Jul 2006 22:35:15 +0000 Subject: r16791: Typo fix in a comment. rafal (This used to be commit 48a9f822442c8b115fd61d9c6781d8100df2bf9e) --- source4/libcli/finddcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index aa755b5749..7df0551b53 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -110,7 +110,7 @@ failed: * can find the target's all-important name. (Kerberos and some * netlogon operations are quite picky about names) * - * The name is a courtasy, if we don't find it, don't compleatly fail. + * The name is a courtesy, if we don't find it, don't completely fail. * * However, if the nbt server is down, fall back to a node status * request -- cgit From 91e4f9f6d85eadf10130b21c8ca341d0ddd5094c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 4 Jul 2006 16:42:09 +0000 Subject: r16801: Adding WERR_DS_DRA_ACCESS_DENIED. Guenther (This used to be commit 075242b97614202ee265577c9e5dd499e56bd768) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 65e9470280..8dd9181f7b 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -89,6 +89,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SINGLE_VALUE_CONSTRAINT", WERR_DS_SINGLE_VALUE_CONSTRAINT }, { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, + { "WERR_DS_DRA_ACCESS_DENIED", WERR_DS_DRA_ACCESS_DENIED }, { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE }, { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 601320f6fe..70442056e3 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -260,6 +260,7 @@ #define WERR_DS_SINGLE_VALUE_CONSTRAINT W_ERROR(0x00002081) #define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) #define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) +#define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105) #define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) #define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) -- cgit From af0a9eb52955cfae570bfdc01821f56385c860cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Jul 2006 08:00:24 +0000 Subject: r16834: split the level's of smb_search_first/smb_search_next and the levels of smb_search_data metze (This used to be commit 78c201db8a47a71908698c4dda2add4cf85694d9) --- source4/libcli/clilist.c | 57 +++++++++++-------- source4/libcli/raw/interfaces.h | 74 +++++++++++++++---------- source4/libcli/raw/rawsearch.c | 120 +++++++++++++++++++++++----------------- source4/libcli/smb2/find.c | 14 ++--- 4 files changed, 156 insertions(+), 109 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index f18ec84db9..16986e9428 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -29,7 +29,7 @@ struct search_private { int dirlist_len; int ff_searchcount; /* total received in 1 server trip */ int total_received; /* total received all together */ - enum smb_search_level info_level; + enum smb_search_data_level data_level; const char *last_name; /* used to continue trans2 search */ struct smb_search_id id; /* used for old-style search */ }; @@ -38,7 +38,7 @@ struct search_private { /**************************************************************************** Interpret a long filename structure. ****************************************************************************/ -static BOOL interpret_long_filename(enum smb_search_level level, +static BOOL interpret_long_filename(enum smb_search_data_level level, union smb_search_data *info, struct clilist_file_info *finfo) { @@ -48,7 +48,7 @@ static BOOL interpret_long_filename(enum smb_search_level level, ZERO_STRUCTP(finfo); switch (level) { - case RAW_SEARCH_STANDARD: + case RAW_SEARCH_DATA_STANDARD: finfo->size = info->standard.size; finfo->mtime = info->standard.write_time; finfo->attrib = info->standard.attrib; @@ -56,7 +56,7 @@ static BOOL interpret_long_filename(enum smb_search_level level, finfo->short_name = info->standard.name.s; break; - case RAW_SEARCH_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: finfo->size = info->both_directory_info.size; finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time); finfo->attrib = info->both_directory_info.attrib; @@ -89,7 +89,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) state->dirlist = tdl; state->dirlist_len++; - interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]); + interpret_long_filename(state->data_level, file, &state->dirlist[state->total_received]); state->last_name = state->dirlist[state->total_received].name; state->total_received++; @@ -99,7 +99,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) } int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, - enum smb_search_level level, + enum smb_search_data_level level, void (*fn)(struct clilist_file_info *, const char *, void *), void *caller_state) { @@ -122,21 +122,22 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.dirlist = talloc_new(state.mem_ctx); mask = talloc_strdup(state.mem_ctx, Mask); - if (level == RAW_SEARCH_GENERIC) { + if (level == RAW_SEARCH_DATA_GENERIC) { if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) { - level = RAW_SEARCH_BOTH_DIRECTORY_INFO; + level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO; } else { - level = RAW_SEARCH_STANDARD; + level = RAW_SEARCH_DATA_STANDARD; } } - state.info_level = level; + state.data_level = level; while (1) { state.ff_searchcount = 0; if (first) { NTSTATUS status; - first_parms.t2ffirst.level = state.info_level; + first_parms.t2ffirst.level = RAW_SEARCH_TRANS2; + first_parms.t2ffirst.data_level = state.data_level; first_parms.t2ffirst.in.max_count = max_matches; first_parms.t2ffirst.in.search_attrib = attribute; first_parms.t2ffirst.in.pattern = mask; @@ -162,7 +163,8 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu } else { NTSTATUS status; - next_parms.t2fnext.level = state.info_level; + next_parms.t2fnext.level = RAW_SEARCH_TRANS2; + next_parms.t2fnext.data_level = state.data_level; next_parms.t2fnext.in.max_count = max_matches; next_parms.t2fnext.in.last_name = state.last_name; next_parms.t2fnext.in.handle = ff_dir_handle; @@ -201,20 +203,29 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu Interpret a short filename structure. The length of the structure is returned. ****************************************************************************/ -static BOOL interpret_short_filename(int level, - union smb_search_data *info, - struct clilist_file_info *finfo) +static BOOL interpret_short_filename(enum smb_search_data_level level, + union smb_search_data *info, + struct clilist_file_info *finfo) { struct clilist_file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); + + switch (level) { + case RAW_SEARCH_DATA_SEARCH: + finfo->mtime = info->search.write_time; + finfo->size = info->search.size; + finfo->attrib = info->search.attrib; + finfo->name = info->search.name; + finfo->short_name = info->search.name; + break; + + default: + DEBUG(0,("Unhandled level %d in interpret_short_filename\n", (int)level)); + return False; + } - finfo->mtime = info->search.write_time; - finfo->size = info->search.size; - finfo->attrib = info->search.attrib; - finfo->name = info->search.name; - finfo->short_name = info->search.name; return True; } @@ -236,7 +247,7 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) state->dirlist = tdl; state->dirlist_len++; - interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]); + interpret_short_filename(state->data_level, file, &state->dirlist[state->total_received]); state->total_received++; state->ff_searchcount++; @@ -273,6 +284,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu NTSTATUS status; first_parms.search_first.level = RAW_SEARCH_SEARCH; + first_parms.search_first.data_level = RAW_SEARCH_DATA_SEARCH; first_parms.search_first.in.max_count = num_asked; first_parms.search_first.in.search_attrib = attribute; first_parms.search_first.in.pattern = mask; @@ -294,6 +306,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu NTSTATUS status; next_parms.search_next.level = RAW_SEARCH_SEARCH; + next_parms.search_next.data_level = RAW_SEARCH_DATA_SEARCH; next_parms.search_next.in.max_count = num_asked; next_parms.search_next.in.search_attrib = attribute; next_parms.search_next.in.id = state.id; @@ -336,5 +349,5 @@ int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) return smbcli_list_old(tree, Mask, attribute, fn, state); - return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_GENERIC, fn, state); + return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_DATA_GENERIC, fn, state); } diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index c581978b81..f77d31a1c7 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2146,33 +2146,41 @@ struct smb_notify { } out; }; -enum smb_search_level {RAW_SEARCH_GENERIC = 0xF000, - RAW_SEARCH_SEARCH, /* SMBsearch */ - RAW_SEARCH_FFIRST, /* SMBffirst */ - RAW_SEARCH_FUNIQUE, /* SMBfunique */ - RAW_SEARCH_SMB2, /* SMB2 Find */ - RAW_SEARCH_STANDARD = SMB_FIND_STANDARD, - RAW_SEARCH_EA_SIZE = SMB_FIND_EA_SIZE, - RAW_SEARCH_EA_LIST = SMB_FIND_EA_LIST, - RAW_SEARCH_DIRECTORY_INFO = SMB_FIND_DIRECTORY_INFO, - RAW_SEARCH_FULL_DIRECTORY_INFO = SMB_FIND_FULL_DIRECTORY_INFO, - RAW_SEARCH_NAME_INFO = SMB_FIND_NAME_INFO, - RAW_SEARCH_BOTH_DIRECTORY_INFO = SMB_FIND_BOTH_DIRECTORY_INFO, - RAW_SEARCH_ID_FULL_DIRECTORY_INFO = SMB_FIND_ID_FULL_DIRECTORY_INFO, - RAW_SEARCH_ID_BOTH_DIRECTORY_INFO = SMB_FIND_ID_BOTH_DIRECTORY_INFO, - RAW_SEARCH_UNIX_INFO = SMB_FIND_UNIX_INFO}; +enum smb_search_level { + RAW_SEARCH_SEARCH, /* SMBsearch */ + RAW_SEARCH_FFIRST, /* SMBffirst */ + RAW_SEARCH_FUNIQUE, /* SMBfunique */ + RAW_SEARCH_TRANS2, /* SMBtrans2 */ + RAW_SEARCH_SMB2 /* SMB2 Find */ +}; +enum smb_search_data_level { + RAW_SEARCH_DATA_GENERIC = 0x10000, /* only used in the smbcli_ code */ + RAW_SEARCH_DATA_SEARCH, + RAW_SEARCH_DATA_STANDARD = SMB_FIND_STANDARD, + RAW_SEARCH_DATA_EA_SIZE = SMB_FIND_EA_SIZE, + RAW_SEARCH_DATA_EA_LIST = SMB_FIND_EA_LIST, + RAW_SEARCH_DATA_DIRECTORY_INFO = SMB_FIND_DIRECTORY_INFO, + RAW_SEARCH_DATA_FULL_DIRECTORY_INFO = SMB_FIND_FULL_DIRECTORY_INFO, + RAW_SEARCH_DATA_NAME_INFO = SMB_FIND_NAME_INFO, + RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO = SMB_FIND_BOTH_DIRECTORY_INFO, + RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO = SMB_FIND_ID_FULL_DIRECTORY_INFO, + RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO = SMB_FIND_ID_BOTH_DIRECTORY_INFO, + RAW_SEARCH_DATA_UNIX_INFO = SMB_FIND_UNIX_INFO +}; /* union for file search */ union smb_search_first { struct { enum smb_search_level level; + enum smb_search_data_level data_level; } generic; /* search (old) findfirst interface. Also used for ffirst and funique. */ struct { enum smb_search_level level; + enum smb_search_data_level data_level; struct { uint16_t max_count; @@ -2187,6 +2195,7 @@ union smb_search_first { /* trans2 findfirst interface */ struct { enum smb_search_level level; + enum smb_search_data_level data_level; struct { uint16_t search_attrib; @@ -2207,7 +2216,7 @@ union smb_search_first { } t2ffirst; /* - SMB2 uses different level numbers for the same old SMB search levels + SMB2 uses different level numbers for the same old SMB trans2 search levels */ #define SMB2_FIND_DIRECTORY_INFO 0x01 #define SMB2_FIND_FULL_DIRECTORY_INFO 0x02 @@ -2218,6 +2227,7 @@ union smb_search_first { /* SMB2 Find */ struct smb2_find { enum smb_search_level level; + enum smb_search_data_level data_level; struct { union smb_handle file; @@ -2228,7 +2238,7 @@ union smb_search_first { uint32_t unknown; /* perhaps a continue token? */ /* struct smb2_handle handle; */ /* uint16_t pattern_ofs; */ - /* uint32_t pattern_size; */ + /* uint16_t pattern_size; */ uint32_t max_response_size; /* dynamic body */ @@ -2250,12 +2260,14 @@ union smb_search_first { union smb_search_next { struct { enum smb_search_level level; + enum smb_search_data_level data_level; } generic; /* search (old) findnext interface. Also used for ffirst when continuing */ struct { enum smb_search_level level; + enum smb_search_data_level data_level; struct { uint16_t max_count; @@ -2276,6 +2288,7 @@ union smb_search_next { /* trans2 findnext interface */ struct { enum smb_search_level level; + enum smb_search_data_level data_level; struct { uint16_t handle; @@ -2297,7 +2310,10 @@ union smb_search_next { /* union for search reply file data */ union smb_search_data { - /* search (old) findfirst */ + /* + * search (old) findfirst + * RAW_SEARCH_DATA_SEARCH + */ struct { uint16_t attrib; time_t write_time; @@ -2305,8 +2321,8 @@ union smb_search_data { struct smb_search_id id; const char *name; } search; - - /* trans2 findfirst RAW_SEARCH_STANDARD level */ + + /* trans2 findfirst RAW_SEARCH_DATA_STANDARD level */ struct { uint32_t resume_key; time_t create_time; @@ -2318,7 +2334,7 @@ union smb_search_data { struct smb_wire_string name; } standard; - /* trans2 findfirst RAW_SEARCH_EA_SIZE level */ + /* trans2 findfirst RAW_SEARCH_DATA_EA_SIZE level */ struct { uint32_t resume_key; time_t create_time; @@ -2331,7 +2347,7 @@ union smb_search_data { struct smb_wire_string name; } ea_size; - /* trans2 findfirst RAW_SEARCH_EA_LIST level */ + /* trans2 findfirst RAW_SEARCH_DATA_EA_LIST level */ struct { uint32_t resume_key; time_t create_time; @@ -2344,7 +2360,7 @@ union smb_search_data { struct smb_wire_string name; } ea_list; - /* RAW_SEARCH_DIRECTORY_INFO interface */ + /* RAW_SEARCH_DATA_DIRECTORY_INFO interface */ struct { uint32_t file_index; NTTIME create_time; @@ -2357,7 +2373,7 @@ union smb_search_data { struct smb_wire_string name; } directory_info; - /* RAW_SEARCH_FULL_DIRECTORY_INFO interface */ + /* RAW_SEARCH_DATA_FULL_DIRECTORY_INFO interface */ struct { uint32_t file_index; NTTIME create_time; @@ -2371,13 +2387,13 @@ union smb_search_data { struct smb_wire_string name; } full_directory_info; - /* RAW_SEARCH_NAME_INFO interface */ + /* RAW_SEARCH_DATA_NAME_INFO interface */ struct { uint32_t file_index; struct smb_wire_string name; } name_info; - /* RAW_SEARCH_BOTH_DIRECTORY_INFO interface */ + /* RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO interface */ struct { uint32_t file_index; NTTIME create_time; @@ -2392,7 +2408,7 @@ union smb_search_data { struct smb_wire_string name; } both_directory_info; - /* RAW_SEARCH_ID_FULL_DIRECTORY_INFO interface */ + /* RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO interface */ struct { uint32_t file_index; NTTIME create_time; @@ -2407,7 +2423,7 @@ union smb_search_data { struct smb_wire_string name; } id_full_directory_info; - /* RAW_SEARCH_ID_BOTH_DIRECTORY_INFO interface */ + /* RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO interface */ struct { uint32_t file_index; NTTIME create_time; @@ -2423,7 +2439,7 @@ union smb_search_data { struct smb_wire_string name; } id_both_directory_info; - /* RAW_SEARCH_UNIX_INFO interface */ + /* RAW_SEARCH_DATA_UNIX_INFO interface */ struct { uint32_t file_index; uint64_t size; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 5e05d7c3c5..4836766a93 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -194,7 +194,6 @@ static NTSTATUS smb_raw_search_close_old(struct smbcli_tree *tree, static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, /* used to allocate output blobs */ union smb_search_first *io, - uint16_t info_level, DATA_BLOB *out_param_blob, DATA_BLOB *out_data_blob) { @@ -211,7 +210,15 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, tp.in.max_data = 0xFFFF; tp.in.setup = &setup; - if (info_level == RAW_SEARCH_EA_LIST) { + if (io->t2ffirst.level != RAW_SEARCH_TRANS2) { + return NT_STATUS_INVALID_LEVEL; + } + + if (io->t2ffirst.data_level >= RAW_SEARCH_DATA_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + + if (io->t2ffirst.data_level == RAW_SEARCH_DATA_EA_LIST) { if (!ea_push_name_list(mem_ctx, &tp.in.data, io->t2ffirst.in.num_names, @@ -219,7 +226,7 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, return NT_STATUS_NO_MEMORY; } } - + tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); if (!tp.in.params.data) { return NT_STATUS_NO_MEMORY; @@ -228,7 +235,7 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, SSVAL(tp.in.params.data, 0, io->t2ffirst.in.search_attrib); SSVAL(tp.in.params.data, 2, io->t2ffirst.in.max_count); SSVAL(tp.in.params.data, 4, io->t2ffirst.in.flags); - SSVAL(tp.in.params.data, 6, info_level); + SSVAL(tp.in.params.data, 6, io->t2ffirst.data_level); SIVAL(tp.in.params.data, 8, io->t2ffirst.in.storage_type); smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, @@ -255,7 +262,6 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, - uint16_t info_level, DATA_BLOB *out_param_blob, DATA_BLOB *out_data_blob) { @@ -272,7 +278,15 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, tp.in.max_data = 0xFFFF; tp.in.setup = &setup; - if (info_level == RAW_SEARCH_EA_LIST) { + if (io->t2fnext.level != RAW_SEARCH_TRANS2) { + return NT_STATUS_INVALID_LEVEL; + } + + if (io->t2fnext.data_level >= RAW_SEARCH_DATA_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + + if (io->t2fnext.data_level == RAW_SEARCH_DATA_EA_LIST) { if (!ea_push_name_list(mem_ctx, &tp.in.data, io->t2fnext.in.num_names, @@ -287,8 +301,8 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, } SSVAL(tp.in.params.data, 0, io->t2fnext.in.handle); - SSVAL(tp.in.params.data, 2, io->t2fnext.in.max_count); - SSVAL(tp.in.params.data, 4, info_level); + SSVAL(tp.in.params.data, 2, io->t2fnext.in.max_count); + SSVAL(tp.in.params.data, 4, io->t2fnext.data_level); SIVAL(tp.in.params.data, 6, io->t2fnext.in.resume_key); SSVAL(tp.in.params.data, 10, io->t2fnext.in.flags); @@ -315,7 +329,7 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, SMB2 */ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, - enum smb_search_level level, + enum smb_search_data_level level, const DATA_BLOB *blob, union smb_search_data *data, uint_t *next_ofs, @@ -335,7 +349,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, } switch (level) { - case RAW_SEARCH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_DIRECTORY_INFO: if (blen < 65) return NT_STATUS_INFO_LENGTH_MISMATCH; data->directory_info.file_index = IVAL(blob->data, 4); data->directory_info.create_time = smbcli_pull_nttime(blob->data, 8); @@ -353,7 +367,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, } return NT_STATUS_OK; - case RAW_SEARCH_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: if (blen < 69) return NT_STATUS_INFO_LENGTH_MISMATCH; data->full_directory_info.file_index = IVAL(blob->data, 4); data->full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); @@ -372,7 +386,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, } return NT_STATUS_OK; - case RAW_SEARCH_NAME_INFO: + case RAW_SEARCH_DATA_NAME_INFO: if (blen < 13) return NT_STATUS_INFO_LENGTH_MISMATCH; data->name_info.file_index = IVAL(blob->data, 4); len = smbcli_blob_pull_string(NULL, mem_ctx, blob, @@ -384,7 +398,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; - case RAW_SEARCH_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: if (blen < 95) return NT_STATUS_INFO_LENGTH_MISMATCH; data->both_directory_info.file_index = IVAL(blob->data, 4); data->both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); @@ -407,7 +421,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; - case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: if (blen < 81) return NT_STATUS_INFO_LENGTH_MISMATCH; data->id_full_directory_info.file_index = IVAL(blob->data, 4); data->id_full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); @@ -427,7 +441,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, } return NT_STATUS_OK; - case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: if (blen < 105) return NT_STATUS_INFO_LENGTH_MISMATCH; data->id_both_directory_info.file_index = IVAL(blob->data, 4); data->id_both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); @@ -467,7 +481,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, */ static int parse_trans2_search(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, - enum smb_search_level level, + enum smb_search_data_level level, uint16_t flags, DATA_BLOB *blob, union smb_search_data *data) @@ -478,15 +492,12 @@ static int parse_trans2_search(struct smbcli_tree *tree, NTSTATUS status; switch (level) { - case RAW_SEARCH_GENERIC: - case RAW_SEARCH_SEARCH: - case RAW_SEARCH_FFIRST: - case RAW_SEARCH_FUNIQUE: - case RAW_SEARCH_SMB2: + case RAW_SEARCH_DATA_GENERIC: + case RAW_SEARCH_DATA_SEARCH: /* handled elsewhere */ return -1; - case RAW_SEARCH_STANDARD: + case RAW_SEARCH_DATA_STANDARD: if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { if (blob->length < 4) return -1; data->standard.resume_key = IVAL(blob->data, 0); @@ -508,7 +519,7 @@ static int parse_trans2_search(struct smbcli_tree *tree, 22, 23, STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM); return len + 23; - case RAW_SEARCH_EA_SIZE: + case RAW_SEARCH_DATA_EA_SIZE: if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { if (blob->length < 4) return -1; data->ea_size.resume_key = IVAL(blob->data, 0); @@ -531,7 +542,7 @@ static int parse_trans2_search(struct smbcli_tree *tree, 26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN); return len + 27 + 1; - case RAW_SEARCH_EA_LIST: + case RAW_SEARCH_DATA_EA_LIST: if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) { if (blob->length < 4) return -1; data->ea_list.resume_key = IVAL(blob->data, 0); @@ -569,7 +580,7 @@ static int parse_trans2_search(struct smbcli_tree *tree, STR_LEN8BIT | STR_NOALIGN); return len + ea_size + 23 + 1; - case RAW_SEARCH_UNIX_INFO: + case RAW_SEARCH_DATA_UNIX_INFO: if (blob->length < 109) return -1; ofs = IVAL(blob->data, 0); data->unix_info.file_index = IVAL(blob->data, 4); @@ -594,12 +605,12 @@ static int parse_trans2_search(struct smbcli_tree *tree, } return ofs; - case RAW_SEARCH_DIRECTORY_INFO: - case RAW_SEARCH_FULL_DIRECTORY_INFO: - case RAW_SEARCH_NAME_INFO: - case RAW_SEARCH_BOTH_DIRECTORY_INFO: - case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: - case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: { + case RAW_SEARCH_DATA_DIRECTORY_INFO: + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_NAME_INFO: + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: { uint_t str_flags = STR_UNICODE; if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) { str_flags = STR_ASCII; @@ -622,7 +633,7 @@ static int parse_trans2_search(struct smbcli_tree *tree, ****************************************************************************/ static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, - enum smb_search_level level, + enum smb_search_data_level level, uint16_t flags, int16_t count, DATA_BLOB *blob, @@ -668,22 +679,24 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { - uint16_t info_level = 0; DATA_BLOB p_blob, d_blob; NTSTATUS status; - - if (io->generic.level == RAW_SEARCH_SEARCH || - io->generic.level == RAW_SEARCH_FFIRST || - io->generic.level == RAW_SEARCH_FUNIQUE) { + + switch (io->generic.level) { + case RAW_SEARCH_SEARCH: + case RAW_SEARCH_FFIRST: + case RAW_SEARCH_FUNIQUE: return smb_raw_search_first_old(tree, mem_ctx, io, private, callback); - } - if (io->generic.level >= RAW_SEARCH_GENERIC) { + + case RAW_SEARCH_TRANS2: + break; + + case RAW_SEARCH_SMB2: return NT_STATUS_INVALID_LEVEL; } - info_level = (uint16_t)io->generic.level; status = smb_raw_search_first_blob(tree, mem_ctx, - io, info_level, &p_blob, &d_blob); + io, &p_blob, &d_blob); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -698,9 +711,9 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, io->t2ffirst.out.handle = SVAL(p_blob.data, 0); io->t2ffirst.out.count = SVAL(p_blob.data, 2); io->t2ffirst.out.end_of_search = SVAL(p_blob.data, 4); - + status = smb_raw_t2search_backend(tree, mem_ctx, - io->generic.level, + io->generic.data_level, io->t2ffirst.in.flags, io->t2ffirst.out.count, &d_blob, private, callback); @@ -714,21 +727,26 @@ NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { - uint16_t info_level = 0; DATA_BLOB p_blob, d_blob; NTSTATUS status; - if (io->generic.level == RAW_SEARCH_SEARCH || - io->generic.level == RAW_SEARCH_FFIRST) { + switch (io->generic.level) { + case RAW_SEARCH_SEARCH: + case RAW_SEARCH_FFIRST: return smb_raw_search_next_old(tree, mem_ctx, io, private, callback); - } - if (io->generic.level >= RAW_SEARCH_GENERIC) { + + case RAW_SEARCH_FUNIQUE: + return NT_STATUS_INVALID_LEVEL; + + case RAW_SEARCH_TRANS2: + break; + + case RAW_SEARCH_SMB2: return NT_STATUS_INVALID_LEVEL; } - info_level = (uint16_t)io->generic.level; status = smb_raw_search_next_blob(tree, mem_ctx, - io, info_level, &p_blob, &d_blob); + io, &p_blob, &d_blob); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -744,7 +762,7 @@ NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, io->t2fnext.out.end_of_search = SVAL(p_blob.data, 2); status = smb_raw_t2search_backend(tree, mem_ctx, - io->generic.level, + io->generic.data_level, io->t2fnext.in.flags, io->t2fnext.out.count, &d_blob, private, callback); diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 8f4d6c8301..794e31bed3 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -101,27 +101,27 @@ NTSTATUS smb2_find_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_find f; NTSTATUS status; DATA_BLOB b; - enum smb_search_level smb_level; + enum smb_search_data_level smb_level; uint_t next_ofs=0; switch (level) { case SMB2_FIND_DIRECTORY_INFO: - smb_level = RAW_SEARCH_DIRECTORY_INFO; + smb_level = RAW_SEARCH_DATA_DIRECTORY_INFO; break; case SMB2_FIND_FULL_DIRECTORY_INFO: - smb_level = RAW_SEARCH_FULL_DIRECTORY_INFO; + smb_level = RAW_SEARCH_DATA_FULL_DIRECTORY_INFO; break; case SMB2_FIND_BOTH_DIRECTORY_INFO: - smb_level = RAW_SEARCH_BOTH_DIRECTORY_INFO; + smb_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO; break; case SMB2_FIND_NAME_INFO: - smb_level = RAW_SEARCH_NAME_INFO; + smb_level = RAW_SEARCH_DATA_NAME_INFO; break; case SMB2_FIND_ID_FULL_DIRECTORY_INFO: - smb_level = RAW_SEARCH_ID_FULL_DIRECTORY_INFO; + smb_level = RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO; break; case SMB2_FIND_ID_BOTH_DIRECTORY_INFO: - smb_level = RAW_SEARCH_ID_BOTH_DIRECTORY_INFO; + smb_level = RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO; break; default: return NT_STATUS_INVALID_INFO_CLASS; -- cgit From bb158b74da65edc5ed8ed9fdbcb77ffae373df2e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Jul 2006 08:18:55 +0000 Subject: r16871: zero padding bytes (found by valgrind) metze (This used to be commit 283bec8295b6302dfe3dc12c82d7870bdfee8b37) --- source4/libcli/raw/rawfileinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 67cad83c6d..38f4d12369 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -234,6 +234,7 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->all_info2.out.nlink = IVAL(blob->data, 0x38); parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C); parms->all_info2.out.directory = CVAL(blob->data, 0x3D); + /* 0x3E-0x3F padding */ parms->all_info2.out.file_id = BVAL(blob->data, 0x40); parms->all_info2.out.ea_size = IVAL(blob->data, 0x48); parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C); -- cgit From 7c810db7da89c992a7886757b7aec68eef0cf3eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Jul 2006 08:34:35 +0000 Subject: r16873: - grow the buffer with the correct size, we maybe had 1 byte preallocated - body_size doesn't contain the preallocated byte so don't remove it metze (This used to be commit 3cf50e26b7dc11d85c46ef81a36c74acf97085c0) --- source4/libcli/smb2/request.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 016c885675..c37325fc34 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -301,7 +301,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, SSVAL(ptr, 0, offset); SSVAL(ptr, 2, blob.length); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -311,7 +311,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } @@ -354,7 +354,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, SSVAL(ptr, 0, offset); SIVAL(ptr, 2, blob.length); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -364,7 +364,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } @@ -407,7 +407,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, SIVAL(ptr, 0, offset); SIVAL(ptr, 4, blob.length); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -417,7 +417,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } @@ -460,7 +460,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, SIVAL(ptr, 0, blob.length); SIVAL(ptr, 4, offset); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -470,7 +470,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } -- cgit From a3797ff66a1b3b19329a622fa38b5a073328e003 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Jul 2006 12:34:31 +0000 Subject: r16875: implement SMB2 Find in the frontend metze (This used to be commit 58bed7322c7e552d0462a11ce5d46a282c31f8f7) --- source4/libcli/raw/interfaces.h | 9 +++++++++ source4/libcli/smb2/smb2_calls.h | 4 ---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index f77d31a1c7..27b3510371 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2224,6 +2224,12 @@ union smb_search_first { #define SMB2_FIND_NAME_INFO 0x0C #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26 + +/* flags for RAW_FILEINFO_SMB2_ALL_EAS */ +#define SMB2_CONTINUE_FLAG_RESTART 0x01 +#define SMB2_CONTINUE_FLAG_SINGLE 0x02 +#define SMB2_CONTINUE_FLAG_NEW 0x10 + /* SMB2 Find */ struct smb2_find { enum smb_search_level level; @@ -2306,6 +2312,9 @@ union smb_search_next { uint16_t end_of_search; } out; } t2fnext; + + /* SMB2 Find */ + struct smb2_find smb2; }; /* union for search reply file data */ diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index f870ddb38a..abb7f88ee2 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -57,10 +57,6 @@ struct smb2_negprot { #define SMB2_GETINFO_FS 0x02 #define SMB2_GETINFO_SECURITY 0x03 -/* flags for RAW_FILEINFO_SMB2_ALL_EAS */ -#define SMB2_CONTINUE_FLAG_RESTART 0x01 -#define SMB2_CONTINUE_FLAG_SINGLE 0x02 - /* NOTE! the getinfo fs and file levels exactly match up with the 'passthru' SMB levels, which are levels >= 1000. The SMB2 client lib uses the names from the libcli/raw/ library */ -- cgit From 5468516f9af10cb3c67bc93c610c22b5383e20db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Jul 2006 14:01:53 +0000 Subject: r16918: the SMB2 Ioctls are sometimes called with a wildcard handle the operation doesn't need a valid file handle in that case metze (This used to be commit d41a83d55945b07020349339888f3a34ac4eff4e) --- source4/libcli/raw/interfaces.h | 3 ++- source4/libcli/raw/rawioctl.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 27b3510371..8ebdd38bee 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1949,7 +1949,8 @@ union smb_lpq { enum smb_ioctl_level { RAW_IOCTL_IOCTL, RAW_IOCTL_NTIOCTL, - RAW_IOCTL_SMB2 + RAW_IOCTL_SMB2, + RAW_IOCTL_SMB2_NO_HANDLE }; /* diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 0bd37785ac..a9812022ea 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -134,6 +134,7 @@ struct smbcli_request *smb_raw_ioctl_send(struct smbcli_tree *tree, union smb_io break; case RAW_IOCTL_SMB2: + case RAW_IOCTL_SMB2_NO_HANDLE: return NULL; } @@ -154,6 +155,7 @@ NTSTATUS smb_raw_ioctl_recv(struct smbcli_request *req, return smb_raw_ntioctl_recv(req, mem_ctx, parms); case RAW_IOCTL_SMB2: + case RAW_IOCTL_SMB2_NO_HANDLE: break; } return NT_STATUS_INVALID_LEVEL; -- cgit From d89b4adf7abdc74f23960dee3f4961006ac12be6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Jul 2006 18:06:53 +0000 Subject: r16949: add and fix some NOTIFY return codes metze (This used to be commit e40d62363c2123fff37b35c1c7004e85a6786c2a) --- source4/libcli/util/nterr.c | 2 ++ source4/libcli/util/nterr.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index ef53e030c7..589d8627e6 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -547,6 +547,8 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, + { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP }, + { "STATUS_NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR }, DOS_CODE(ERRDOS, ERRsuccess), DOS_CODE(ERRDOS, ERRbadfunc), diff --git a/source4/libcli/util/nterr.h b/source4/libcli/util/nterr.h index 29afa511d4..baf15d80ef 100644 --- a/source4/libcli/util/nterr.h +++ b/source4/libcli/util/nterr.h @@ -37,9 +37,10 @@ #define STATUS_PENDING NT_STATUS(0x0103) #define STATUS_MORE_ENTRIES NT_STATUS(0x0105) #define STATUS_SOME_UNMAPPED NT_STATUS(0x0107) +#define STATUS_NOTIFY_CLEANUP NT_STATUS(0x010b) +#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) #define ERROR_INVALID_PARAMETER NT_STATUS(0x0057) #define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a) -#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) #define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) /* Win32 Error codes extracted using a loop in smbclient then printing a -- cgit From 86c3e628e0c912b486b406d47b20b1940fa81449 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Jul 2006 07:33:25 +0000 Subject: r16975: implement SMB2 Notify call in the client lib metze (This used to be commit a455dc7a8392230395c0e444f76a4ca13192f871) --- source4/libcli/smb2/config.mk | 1 + source4/libcli/smb2/notify.c | 83 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2_calls.h | 22 +++++++++++ 3 files changed, 106 insertions(+) create mode 100644 source4/libcli/smb2/notify.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 33ef633e1f..9dba94f506 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -19,5 +19,6 @@ OBJ_FILES = \ tdis.o \ flush.o \ lock.o \ + notify.o \ keepalive.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c new file mode 100644 index 0000000000..0e61293495 --- /dev/null +++ b/source4/libcli/smb2/notify.c @@ -0,0 +1,83 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client notify calls + + Copyright (C) Stefan Metzmacher 2006 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a notify request +*/ +struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_NOTIFY, 0x20, False, 0); + if (req == NULL) return NULL; + + SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0x0030); + + SSVAL(req->out.body, 0x02, io->in.recursive); + SIVAL(req->out.body, 0x04, io->in.buffer_size); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); + SIVAL(req->out.body, 0x18, io->in.completion_filter); + SIVAL(req->out.body, 0x1C, io->in.unknown); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a notify reply +*/ +NTSTATUS smb2_notify_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + struct smb2_notify *io) +{ + NTSTATUS status; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x08, True); + + status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return smb2_request_destroy(req); +} + +/* + sync notify request +*/ +NTSTATUS smb2_notify(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, + struct smb2_notify *io) +{ + struct smb2_request *req = smb2_notify_send(tree, io); + return smb2_notify_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index abb7f88ee2..c3dc629430 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -94,6 +94,28 @@ struct smb2_setinfo { } in; }; +struct smb2_notify { + struct { + /* static body buffer 32 (0x20) bytes */ + /* uint16_t buffer_code; 0x32 */ + uint16_t recursive; + uint32_t buffer_size; + union smb_handle file; + uint32_t completion_filter; + uint32_t unknown; + } in; + + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + /* uint16_t blob_ofs; */ + /* uint16_t blob_size; */ + + /* dynamic body */ + DATA_BLOB blob; + } out; +}; + struct cli_credentials; struct event_context; #include "libcli/smb2/smb2_proto.h" -- cgit From a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Jul 2006 14:25:50 +0000 Subject: r16980: - make struct smb_notify a union and add levels RAW_NOTIFY_NTTRANS,RAW_NOTIFY_SMB2 - parse SMB2 Notify reponse metze (This used to be commit de50e0ccddfad16ad7b254770f4c52c1abe707b9) --- source4/libcli/raw/interfaces.h | 65 +++++++++++++++++++++++++++++++--------- source4/libcli/raw/rawnotify.c | 38 +++++++++++++---------- source4/libcli/smb2/notify.c | 31 +++++++++++++++++-- source4/libcli/smb2/smb2_calls.h | 22 -------------- 4 files changed, 103 insertions(+), 53 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 8ebdd38bee..d3e7611c75 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2128,23 +2128,60 @@ struct smb_nttrans { } out; }; +enum smb_notify_level { + RAW_NOTIFY_NTTRANS, + RAW_NOTIFY_SMB2 +}; -/* struct for nttrans change notify call */ -struct smb_notify { +union smb_notify { + /* struct for nttrans change notify call */ struct { - union smb_handle file; - uint32_t buffer_size; - uint32_t completion_filter; - BOOL recursive; - } in; + enum smb_notify_level level; - struct { - uint32_t num_changes; - struct notify_changes { - uint32_t action; - struct smb_wire_string name; - } *changes; - } out; + struct { + union smb_handle file; + uint32_t buffer_size; + uint32_t completion_filter; + BOOL recursive; + } in; + + struct { + uint32_t num_changes; + struct notify_changes { + uint32_t action; + struct smb_wire_string name; + } *changes; + } out; + } nttrans; + + struct smb2_notify { + enum smb_notify_level level; + + struct { + union smb_handle file; + /* static body buffer 32 (0x20) bytes */ + /* uint16_t buffer_code; 0x32 */ + uint16_t recursive; + uint32_t buffer_size; + /*struct smb2_handle file;*/ + uint32_t completion_filter; + uint32_t unknown; + } in; + + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + /* uint16_t blob_ofs; */ + /* uint16_t blob_size; */ + + /* dynamic body */ + /*DATA_BLOB blob;*/ + + /* DATA_BLOB content */ + uint32_t num_changes; + struct notify_changes *changes; + } out; + } smb2; }; enum smb_search_level { diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index f4d4164016..2b68d96a1b 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -25,19 +25,23 @@ /**************************************************************************** change notify (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struct smb_notify *parms) +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) { struct smb_nttrans nt; uint16_t setup[4]; + if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NULL; + } + nt.in.max_setup = 0; - nt.in.max_param = parms->in.buffer_size; + nt.in.max_param = parms->nttrans.in.buffer_size; nt.in.max_data = 0; nt.in.setup_count = 4; nt.in.setup = setup; - SIVAL(setup, 0, parms->in.completion_filter); - SSVAL(setup, 4, parms->in.file.fnum); - SSVAL(setup, 6, parms->in.recursive); + SIVAL(setup, 0, parms->nttrans.in.completion_filter); + SSVAL(setup, 4, parms->nttrans.in.file.fnum); + SSVAL(setup, 6, parms->nttrans.in.recursive); nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; nt.in.params = data_blob(NULL, 0); nt.in.data = data_blob(NULL, 0); @@ -49,41 +53,45 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struc change notify (async recv) ****************************************************************************/ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, - TALLOC_CTX *mem_ctx, struct smb_notify *parms) + TALLOC_CTX *mem_ctx, union smb_notify *parms) { struct smb_nttrans nt; NTSTATUS status; uint32_t ofs, i; struct smbcli_session *session = req?req->session:NULL; + if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_INVALID_LEVEL; + } + status = smb_raw_nttrans_recv(req, mem_ctx, &nt); if (!NT_STATUS_IS_OK(status)) { return status; } - parms->out.changes = NULL; - parms->out.num_changes = 0; + parms->nttrans.out.changes = NULL; + parms->nttrans.out.num_changes = 0; /* count them */ for (ofs=0; nt.out.params.length - ofs > 12; ) { uint32_t next = IVAL(nt.out.params.data, ofs); - parms->out.num_changes++; + parms->nttrans.out.num_changes++; if (next == 0 || ofs + next >= nt.out.params.length) break; ofs += next; } /* allocate array */ - parms->out.changes = talloc_array(mem_ctx, struct notify_changes, parms->out.num_changes); - if (!parms->out.changes) { + parms->nttrans.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->nttrans.out.num_changes); + if (!parms->nttrans.out.changes) { return NT_STATUS_NO_MEMORY; } - for (i=ofs=0; iout.num_changes; i++) { - parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); + for (i=ofs=0; inttrans.out.num_changes; i++) { + parms->nttrans.out.changes[i].action = IVAL(nt.out.params.data, ofs+4); smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, - &parms->out.changes[i].name, - ofs+8, ofs+12, STR_UNICODE); + &parms->nttrans.out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); ofs += IVAL(nt.out.params.data, ofs); } diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 0e61293495..43792267f2 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -56,19 +56,46 @@ NTSTATUS smb2_notify_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_notify *io) { NTSTATUS status; + DATA_BLOB blob; + uint32_t ofs, i; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } SMB2_CHECK_PACKET_RECV(req, 0x08, True); - status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); + status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &blob); if (!NT_STATUS_IS_OK(status)) { return status; } + io->out.changes = NULL; + io->out.num_changes = 0; + + /* count them */ + for (ofs=0; blob.length - ofs > 12; ) { + uint32_t next = IVAL(blob.data, ofs); + io->out.num_changes++; + if (next == 0 || (ofs + next) >= blob.length) break; + ofs += next; + } + + /* allocate array */ + io->out.changes = talloc_array(mem_ctx, struct notify_changes, io->out.num_changes); + if (!io->out.changes) { + return NT_STATUS_NO_MEMORY; + } + + for (i=ofs=0; iout.num_changes; i++) { + io->out.changes[i].action = IVAL(blob.data, ofs+4); + smbcli_blob_pull_string(NULL, mem_ctx, &blob, + &io->out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); + ofs += IVAL(blob.data, ofs); + } + return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index c3dc629430..abb7f88ee2 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -94,28 +94,6 @@ struct smb2_setinfo { } in; }; -struct smb2_notify { - struct { - /* static body buffer 32 (0x20) bytes */ - /* uint16_t buffer_code; 0x32 */ - uint16_t recursive; - uint32_t buffer_size; - union smb_handle file; - uint32_t completion_filter; - uint32_t unknown; - } in; - - struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ - /* uint16_t blob_ofs; */ - /* uint16_t blob_size; */ - - /* dynamic body */ - DATA_BLOB blob; - } out; -}; - struct cli_credentials; struct event_context; #include "libcli/smb2/smb2_proto.h" -- cgit From 09b9d831c285d04d0159d2ca2f0a82be214bf701 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Jul 2006 17:17:27 +0000 Subject: r17019: don't timeout on notifies metze (This used to be commit 8d4fd35b10b176d31f986bbca5848091dffcd657) --- source4/libcli/smb2/notify.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 43792267f2..800f9ae9d5 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -31,6 +31,7 @@ struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify *io) { struct smb2_request *req; + uint32_t old_timeout; req = smb2_request_init_tree(tree, SMB2_OP_NOTIFY, 0x20, False, 0); if (req == NULL) return NULL; @@ -43,7 +44,10 @@ struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify SIVAL(req->out.body, 0x18, io->in.completion_filter); SIVAL(req->out.body, 0x1C, io->in.unknown); + old_timeout = req->transport->options.timeout; + req->transport->options.timeout = 0; smb2_transport_send(req); + req->transport->options.timeout = old_timeout; return req; } -- cgit From 440d0487a6ad9a39630d7364eb54e46367207d05 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Jul 2006 17:37:45 +0000 Subject: r17020: pass the real error to the failing requests metze (This used to be commit 49b96ac44a883c020c69df7a12df154dc4faa4d5) --- source4/libcli/raw/clitransport.c | 12 ++++++++---- source4/libcli/smb2/transport.c | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index fc257b9098..641ad38031 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -52,7 +52,7 @@ static void smbcli_transport_event_handler(struct event_context *ev, */ static int transport_destructor(struct smbcli_transport *transport) { - smbcli_transport_dead(transport); + smbcli_transport_dead(transport, NT_STATUS_LOCAL_DISCONNECT); return 0; } @@ -63,7 +63,7 @@ static int transport_destructor(struct smbcli_transport *transport) static void smbcli_transport_error(void *private, NTSTATUS status) { struct smbcli_transport *transport = talloc_get_type(private, struct smbcli_transport); - smbcli_transport_dead(transport); + smbcli_transport_dead(transport, status); } static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob); @@ -130,15 +130,19 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, /* mark the transport as dead */ -void smbcli_transport_dead(struct smbcli_transport *transport) +void smbcli_transport_dead(struct smbcli_transport *transport, NTSTATUS status) { smbcli_sock_dead(transport->socket); + if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + /* kill all pending receives */ while (transport->pending_recv) { struct smbcli_request *req = transport->pending_recv; req->state = SMBCLI_REQUEST_ERROR; - req->status = NT_STATUS_NET_WRITE_FAULT; + req->status = status; DLIST_REMOVE(transport->pending_recv, req); if (req->async.fn) { req->async.fn(req); diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 6f91699704..df3bec8720 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -53,7 +53,7 @@ static void smb2_transport_event_handler(struct event_context *ev, */ static int transport_destructor(struct smb2_transport *transport) { - smb2_transport_dead(transport); + smb2_transport_dead(transport, NT_STATUS_LOCAL_DISCONNECT); return 0; } @@ -65,7 +65,7 @@ static void smb2_transport_error(void *private, NTSTATUS status) { struct smb2_transport *transport = talloc_get_type(private, struct smb2_transport); - smb2_transport_dead(transport); + smb2_transport_dead(transport, status); } static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob); @@ -120,15 +120,19 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, /* mark the transport as dead */ -void smb2_transport_dead(struct smb2_transport *transport) +void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status) { smbcli_sock_dead(transport->socket); + if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + /* kill all pending receives */ while (transport->pending_recv) { struct smb2_request *req = transport->pending_recv; req->state = SMB2_REQUEST_ERROR; - req->status = NT_STATUS_NET_WRITE_FAULT; + req->status = status; DLIST_REMOVE(transport->pending_recv, req); if (req->async.fn) { req->async.fn(req); -- cgit From 73b066281e6f80beb46bbfdb9742e26d3550dfce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Jul 2006 07:45:23 +0000 Subject: r17081: add idle handler support to the smb2 client lib too metze (This used to be commit 1f48e7dca6a06078f3655a7f7a8f109bd6c0cb8e) --- source4/libcli/smb2/smb2.h | 9 +++++++++ source4/libcli/smb2/transport.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 2c1892cafc..cee414b6e2 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -48,6 +48,15 @@ struct smb2_transport { /* context of the stream -> packet parser */ struct packet_context *packet; + + /* an idle function - if this is defined then it will be + called once every period microseconds while we are waiting + for a packet */ + struct { + void (*func)(struct smb2_transport *, void *); + void *private; + uint_t period; + } idle; }; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index df3bec8720..c970bf7147 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -307,3 +307,39 @@ void smb2_transport_send(struct smb2_request *req) talloc_set_destructor(req, smb2_request_destructor); } + +static void idle_handler(struct event_context *ev, + struct timed_event *te, struct timeval t, void *private) +{ + struct smb2_transport *transport = talloc_get_type(private, + struct smb2_transport); + struct timeval next = timeval_add(&t, 0, transport->idle.period); + transport->socket->event.te = event_add_timed(transport->socket->event.ctx, + transport, + next, + idle_handler, transport); + transport->idle.func(transport, transport->idle.private); +} + +/* + setup the idle handler for a transport + the period is in microseconds +*/ +void smb2_transport_idle_handler(struct smb2_transport *transport, + void (*idle_func)(struct smb2_transport *, void *), + uint64_t period, + void *private) +{ + transport->idle.func = idle_func; + transport->idle.private = private; + transport->idle.period = period; + + if (transport->socket->event.te != NULL) { + talloc_free(transport->socket->event.te); + } + + transport->socket->event.te = event_add_timed(transport->socket->event.ctx, + transport, + timeval_current_ofs(0, period), + idle_handler, transport); +} -- cgit From 152ea280f1982831c31071eec5c5a17f072073b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Jul 2006 08:05:02 +0000 Subject: r17082: Add a test that walks and tests denying tconX access via the share security descriptor. This is something that W2k3 does _not_ pass and probably is not expected to, it seems the don't check access at tconX time. Thanks to metze for the hint how in the srvsvc_NetShareInfo1501 struct the length of the sd can be encoded in idl. As metze says, there's probably more to the share secdesc, this needs more testing. This one is here to walk the samba3 code. Volker (This used to be commit 67185508229a8d7f144c22cb194f573c932d6de5) --- source4/libcli/security/dom_sid.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 951c0f5956..54242eb515 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -215,6 +215,24 @@ struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, return sid; } +/* + Split up a SID into its domain and RID part +*/ +NTSTATUS dom_sid_split_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, + struct dom_sid **domain, uint32_t *rid) +{ + if (sid->num_auths == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!(*domain = dom_sid_dup(mem_ctx, sid))) { + return NT_STATUS_NO_MEMORY; + } + + (*domain)->num_auths -= 1; + *rid = (*domain)->sub_auths[(*domain)->num_auths]; + return NT_STATUS_OK; +} /* return True if the 2nd sid is in the domain given by the first sid -- cgit From a5bafffd66f511375dda4c974e6a1f152fc7aa16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Jul 2006 09:36:52 +0000 Subject: r17083: - implement SMB2 Cancel in the client - the 0xffffffffffffffff seqnum is reserved for SMB2 Break (oplock breaks) so don't use it in a request. we should someday try to test this... metze (This used to be commit 730cdc4475822e28cb400116641294a7f98ad0b5) --- source4/libcli/smb2/cancel.c | 78 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/config.mk | 1 + source4/libcli/smb2/request.c | 11 ++++-- source4/libcli/smb2/smb2.h | 6 ++++ source4/libcli/smb2/transport.c | 14 ++++++-- 5 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 source4/libcli/smb2/cancel.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/cancel.c b/source4/libcli/smb2/cancel.c new file mode 100644 index 0000000000..bf48af7b00 --- /dev/null +++ b/source4/libcli/smb2/cancel.c @@ -0,0 +1,78 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client notify calls + + Copyright (C) Stefan Metzmacher 2006 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a cancel request +*/ +NTSTATUS smb2_cancel(struct smb2_request *r) +{ + NTSTATUS status; + struct smb2_request *c; + uint32_t old_timeout; + uint64_t old_seqnum; + + /* + * if we don't get a pending id yet, we just + * mark the request for pending, so that we directly + * send the cancel after getting the pending id + */ + if (!r->cancel.can_cancel) { + r->cancel.do_cancel++; + return NT_STATUS_OK; + } + + /* we don't want a seqmun for a SMB2 Cancel */ + old_seqnum = r->transport->seqnum; + c = smb2_request_init(r->transport, SMB2_OP_CANCEL, 0x04, False, 0); + r->transport->seqnum = old_seqnum; + NT_STATUS_HAVE_NO_MEMORY(c); + c->seqnum = 0; + + SIVAL(c->out.hdr, SMB2_HDR_FLAGS, 0x00000002); + SSVAL(c->out.hdr, SMB2_HDR_UNKNOWN1, 0x0030); + SIVAL(c->out.hdr, SMB2_HDR_PID, r->cancel.pending_id); + SBVAL(c->out.hdr, SMB2_HDR_SEQNUM, c->seqnum); + if (r->session) { + SBVAL(c->out.hdr, SMB2_HDR_UID, r->session->uid); + } + + SSVAL(c->out.body, 0x02, 0); + + old_timeout = c->transport->options.timeout; + c->transport->options.timeout = 0; + smb2_transport_send(c); + c->transport->options.timeout = old_timeout; + + if (c->state == SMB2_REQUEST_ERROR) { + status = c->status; + } else { + status = NT_STATUS_OK; + } + + talloc_free(c); + return status; +} diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 9dba94f506..ab079fefde 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -20,5 +20,6 @@ OBJ_FILES = \ flush.o \ lock.o \ notify.o \ + cancel.o \ keepalive.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index c37325fc34..72b9ade3e2 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -35,6 +35,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ uint32_t body_dynamic_size) { struct smb2_request *req; + uint64_t seqnum; if (body_dynamic_present) { if (body_dynamic_size == 0) { @@ -47,17 +48,23 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req = talloc(transport, struct smb2_request); if (req == NULL) return NULL; + seqnum = transport->seqnum++; + if (seqnum == UINT64_MAX) { + seqnum = transport->seqnum++; + } + req->state = SMB2_REQUEST_INIT; req->transport = transport; req->session = NULL; req->tree = NULL; - req->seqnum = transport->seqnum++; + req->seqnum = seqnum; req->status = NT_STATUS_OK; req->async.fn = NULL; req->next = req->prev = NULL; + ZERO_STRUCT(req->cancel); ZERO_STRUCT(req->in); - + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size; req->out.allocated = req->out.size + body_dynamic_size; diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index cee414b6e2..070eaf54ab 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -128,6 +128,12 @@ struct smb2_request { uint64_t seqnum; + struct { + BOOL do_cancel; + BOOL can_cancel; + uint32_t pending_id; + } cancel; + /* the NT status for this request. Set by packet receive code or code detecting error. */ NTSTATUS status; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index c970bf7147..ea8c4804ff 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -152,8 +152,10 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) int len; struct smb2_request *req = NULL; uint64_t seqnum; + uint32_t flags; uint16_t buffer_code; uint32_t dynamic_size; + uint32_t i; buffer = blob.data; len = blob.length; @@ -165,7 +167,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) goto error; } - seqnum = BVAL(hdr, SMB2_HDR_SEQNUM); + flags = IVAL(hdr, SMB2_HDR_FLAGS); + seqnum = BVAL(hdr, SMB2_HDR_SEQNUM); /* match the incoming request against the list of pending requests */ for (req=transport->pending_recv; req; req=req->next) { @@ -190,8 +193,13 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { - /* the server has helpfully told us that this request is still being - processed. how useful :) */ + if (flags & 0x00000002) { + req->cancel.can_cancel = True; + req->cancel.pending_id = IVAL(hdr, SMB2_HDR_PID); + for (i=0; i< req->cancel.do_cancel; i++) { + smb2_cancel(req); + } + } talloc_free(buffer); return NT_STATUS_OK; } -- cgit From ba07fa43d0b0090f5e686d8c1822468049f52416 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 23 Jul 2006 02:50:08 +0000 Subject: r17197: This patch moves the encryption of bulk data on SASL negotiated security contexts from the application layer into the socket layer. This improves a number of correctness aspects, as we now allow LDAP packets to cross multiple SASL packets. It should also make it much easier to write async LDAP tests from windows clients, as they use SASL by default. It is also vital to allowing OpenLDAP clients to use GSSAPI against Samba4, as it negotiates a rather small SASL buffer size. This patch mirrors the earlier work done to move TLS into the socket layer. Unusual in this pstch is the extra read callback argument I take. As SASL is a layer on top of a socket, it is entirely possible for the SASL layer to drain a socket dry, but for the caller not to have read all the decrypted data. This would leave the system without an event to restart the read (as the socket is dry). As such, I re-invoke the read handler from a timed callback, which should trigger on the next running of the event loop. I believe that the TLS code does require a similar callback. In trying to understand why this is required, imagine a SASL-encrypted LDAP packet in the following formation: +-----------------+---------------------+ | SASL Packet #1 | SASL Packet #2 | ----------------------------------------+ | LDAP Packet #1 | LDAP Packet #2 | ----------------------------------------+ In the old code, this was illegal, but it is perfectly standard SASL-encrypted LDAP. Without the callback, we would read and process the first LDAP packet, and the SASL code would have read the second SASL packet (to decrypt enough data for the LDAP packet), and no data would remain on the socket. Without data on the socket, read events stop. That is why I add timed events, until the SASL buffer is drained. Another approach would be to add a hack to the event system, to have it pretend there remained data to read off the network (but that is ugly). In improving the code, to handle more real-world cases, I've been able to remove almost all the special-cases in the testnonblock code. The only special case is that we must use a deterministic partial packet when calling send, rather than a random length. (1 + n/2). This is needed because of the way the SASL and TLS code works, and the 'resend on failure' requirements. Andrew Bartlett (This used to be commit 5d7c9c12cb2b39673172a357092b80cd814850b0) --- source4/libcli/ldap/config.mk | 2 +- source4/libcli/ldap/ldap_bind.c | 22 ++++++--- source4/libcli/ldap/ldap_client.c | 94 ++++----------------------------------- source4/libcli/ldap/ldap_client.h | 3 -- 4 files changed, 26 insertions(+), 95 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 88ebc3256f..e5a7133cfa 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL GENSEC_SOCKET #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 6714d68b0e..2b209c3871 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -27,6 +27,8 @@ #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" #include "auth/auth.h" +#include "auth/gensec/socket.h" +#include "lib/stream/packet.h" struct ldap_simple_creds { const char *dn; @@ -365,15 +367,23 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } } - if (NT_STATUS_IS_OK(status) && - (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL) || - gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { - conn->enable_wrap = True; - } - talloc_free(tmp_ctx); if (NT_STATUS_IS_OK(status)) { + struct socket_context *socket = gensec_socket_init(conn->gensec, + conn->sock, + conn->event.event_ctx, + ldap_read_io_handler, + conn); + if (socket) { + conn->sock = socket; + talloc_steal(conn->sock, socket); + packet_set_socket(conn->packet, socket); + } else { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + conn->bind.type = LDAP_BIND_SASL; conn->bind.creds = creds; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 07b7f2b412..2e834b5244 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -165,25 +165,13 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message /* - check if a blob is a complete ldap packet - handle wrapper or unwrapped connections + decode/process LDAP data */ -NTSTATUS ldap_complete_packet(void *private_data, DATA_BLOB blob, size_t *size) -{ - struct ldap_connection *conn = talloc_get_type(private_data, - struct ldap_connection); - if (conn->enable_wrap) { - return packet_full_request_u32(private_data, blob, size); - } - return ldap_full_packet(private_data, blob, size); -} - -/* - decode/process plain data -*/ -static NTSTATUS ldap_decode_plain(struct ldap_connection *conn, DATA_BLOB blob) +static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { struct asn1_data asn1; + struct ldap_connection *conn = talloc_get_type(private_data, + struct ldap_connection); struct ldap_message *msg = talloc(conn, struct ldap_message); if (msg == NULL) { @@ -205,60 +193,14 @@ static NTSTATUS ldap_decode_plain(struct ldap_connection *conn, DATA_BLOB blob) return NT_STATUS_OK; } -/* - decode/process wrapped data -*/ -static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob) -{ - DATA_BLOB wrapped, unwrapped; - struct asn1_data asn1; - struct ldap_message *msg = talloc(conn, struct ldap_message); - NTSTATUS status; - - if (msg == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - wrapped = data_blob_const(blob.data+4, blob.length-4); - - status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - data_blob_free(&blob); - - if (!asn1_load(&asn1, unwrapped)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - while (ldap_decode(&asn1, msg)) { - ldap_match_message(conn, msg); - msg = talloc(conn, struct ldap_message); - } - - talloc_free(msg); - asn1_free(&asn1); - - return NT_STATUS_OK; -} - - -/* - handle ldap recv events -*/ -static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) +/* Handle read events, from the GENSEC socket callback, or real events */ +void ldap_read_io_handler(void *private_data, uint16_t flags) { struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); - if (conn->enable_wrap) { - return ldap_decode_wrapped(conn, blob); - } - - return ldap_decode_plain(conn, blob); + packet_recv(conn->packet); } - /* handle ldap socket events */ @@ -272,7 +214,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, if (!tls_enabled(conn->sock)) return; } if (flags & EVENT_FD_READ) { - packet_recv(conn->packet); + ldap_read_io_handler(private_data, flags); } } @@ -417,7 +359,7 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) packet_set_private(conn->packet, conn); packet_set_socket(conn->packet, conn->sock); packet_set_callback(conn->packet, ldap_recv_handler); - packet_set_full_request(conn->packet, ldap_complete_packet); + packet_set_full_request(conn->packet, ldap_full_packet); packet_set_error_handler(conn->packet, ldap_error_handler); packet_set_event_context(conn->packet, conn->event.event_ctx); packet_set_fde(conn->packet, conn->event.fde); @@ -561,24 +503,6 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, goto failed; } - /* possibly encrypt/sign the request */ - if (conn->enable_wrap) { - DATA_BLOB wrapped; - - status = gensec_wrap(conn->gensec, req, &req->data, &wrapped); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - data_blob_free(&req->data); - req->data = data_blob_talloc(req, NULL, wrapped.length + 4); - if (req->data.data == NULL) { - goto failed; - } - RSIVAL(req->data.data, 0, wrapped.length); - memcpy(req->data.data+4, wrapped.data, wrapped.length); - data_blob_free(&wrapped); - } - status = packet_send(conn->packet, req->data); if (!NT_STATUS_IS_OK(status)) { goto failed; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 28b9f2763c..849737d8a9 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -80,9 +80,6 @@ struct ldap_connection { /* Let's support SASL */ struct gensec_security *gensec; - /* set if we are wrapping requests */ - BOOL enable_wrap; - /* the default timeout for messages */ int timeout; -- cgit From 9d6f2767179fad2f9a067c67c09afddb6304e4eb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Jul 2006 00:57:27 +0000 Subject: r17222: Change the function prototypes for the GENSEc and TLS socket creation routines to return an NTSTATUS. This should help track down errors. Use a bit of talloc_steal and talloc_unlink to get the real socket to be a child of the GENSEC or TLS socket. Always return a new socket, even for the 'pass-though' case. Andrew Bartlett (This used to be commit 003e2ab93c87267ba28cd67bd85975bad62a8ea2) --- source4/libcli/ldap/ldap_bind.c | 21 ++++++++++++--------- source4/libcli/ldap/ldap_client.c | 11 ++++++----- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2b209c3871..f1f7872455 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -370,15 +370,18 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr talloc_free(tmp_ctx); if (NT_STATUS_IS_OK(status)) { - struct socket_context *socket = gensec_socket_init(conn->gensec, - conn->sock, - conn->event.event_ctx, - ldap_read_io_handler, - conn); - if (socket) { - conn->sock = socket; - talloc_steal(conn->sock, socket); - packet_set_socket(conn->packet, socket); + struct socket_context *sasl_socket; + status = gensec_socket_init(conn->gensec, + conn->sock, + conn->event.event_ctx, + ldap_read_io_handler, + conn, + &sasl_socket); + if (NT_STATUS_IS_OK(status)) { + talloc_steal(conn->sock, sasl_socket); + talloc_unlink(conn, conn->sock); + conn->sock = sasl_socket; + packet_set_socket(conn->packet, conn->sock); } else { status = NT_STATUS_NO_MEMORY; goto failed; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 2e834b5244..eb7b9c6327 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -320,7 +320,6 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, static void ldap_connect_recv_conn(struct composite_context *ctx) { - struct socket_context *initial_socket; struct ldap_connect_state *state = talloc_get_type(ctx->async.private_data, struct ldap_connect_state); @@ -341,13 +340,15 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) } talloc_steal(conn, conn->sock); - initial_socket = conn->sock; if (conn->ldaps) { - conn->sock = tls_init_client(conn->sock, conn->event.fde); - if (conn->sock == NULL) { - talloc_free(initial_socket); + struct socket_context *tls_socket = tls_init_client(conn->sock, conn->event.fde); + if (tls_socket == NULL) { + talloc_free(conn->sock); return; } + talloc_unlink(conn, conn->sock); + conn->sock = tls_socket; + talloc_steal(conn, conn->sock); } conn->packet = packet_init(conn); -- cgit From ec8d486e267b60ebad3eac937580986155b75914 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 Jul 2006 12:48:40 +0000 Subject: r17230: don't overwrite the error with NT_STATUS_NO_MEMORY metze (This used to be commit f2196bf9b662d3f38d59eceb8c54f9d2e3f7b505) --- source4/libcli/ldap/ldap_bind.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index f1f7872455..4fdd87a25b 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -377,16 +377,13 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr ldap_read_io_handler, conn, &sasl_socket); - if (NT_STATUS_IS_OK(status)) { - talloc_steal(conn->sock, sasl_socket); - talloc_unlink(conn, conn->sock); - conn->sock = sasl_socket; - packet_set_socket(conn->packet, conn->sock); - } else { - status = NT_STATUS_NO_MEMORY; - goto failed; - } - + if (!NT_STATUS_IS_OK(status)) goto failed; + + talloc_steal(conn->sock, sasl_socket); + talloc_unlink(conn, conn->sock); + conn->sock = sasl_socket; + packet_set_socket(conn->packet, conn->sock); + conn->bind.type = LDAP_BIND_SASL; conn->bind.creds = creds; } -- cgit From 9c8fa196ba31b63e7632df8216ae11c7ce2ce9de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Jul 2006 16:20:59 +0000 Subject: r17277: we need to trigger an event when we return directly, otherwise the callers callback function will not be called and the caller is hanging forever... metze (This used to be commit e231eba828486e68c9d3a246e1e0c943fdb8301c) --- source4/libcli/smb_composite/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 0bad2ff1ad..022faea1d7 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -462,7 +462,7 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se /* no session setup at all in earliest protocol varients */ if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { ZERO_STRUCT(io->out); - c->state = COMPOSITE_STATE_DONE; + composite_done(c); return c; } -- cgit From 6d35c078114d911784bf7c18fc700ea81cea6f6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Jul 2006 16:44:59 +0000 Subject: r17278: fix un uninitialized value found by valgrind metze (This used to be commit fe463bc568e8ac78ca161bcba3e867d33bb828b3) --- source4/libcli/clilist.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 16986e9428..9b4a1a158f 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -274,6 +274,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.mem_ctx = talloc_init("smbcli_list_old"); state.dirlist_len = 0; state.total_received = 0; + state.data_level = RAW_SEARCH_DATA_SEARCH; state.dirlist = talloc_new(state.mem_ctx); mask = talloc_strdup(state.mem_ctx, Mask); -- cgit From 7e949c9fb12483df11c7e926e2c5ed8e4b9b9d20 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 30 Jul 2006 16:48:41 +0000 Subject: r17317: - add a composite_create() function that allocates and initialize the composite_context structue, we should try to convert all code to use this because there're a lot of places where the we have bugs with this task... - add a composite_continue_smb2() helper We should try to hide the internals of the composite code from the users to avoid errors (and I found a lot of them... and will fix then step by step) metze (This used to be commit a16180f20246844d05996d385fcb71893e08f589) --- source4/libcli/composite/composite.c | 28 ++++++++++++++++++++++++++++ source4/libcli/composite/composite.h | 1 + 2 files changed, 29 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 9a745e3013..aea25f183e 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -24,11 +24,29 @@ #include "includes.h" #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" #include "libcli/composite/composite.h" #include "lib/messaging/irpc.h" #include "librpc/rpc/dcerpc.h" #include "libcli/nbt/libnbt.h" +/* + create a new composite_context structure + and initialize it +*/ +_PUBLIC_ struct composite_context *composite_create(TALLOC_CTX *mem_ctx, + struct event_context *ev) +{ + struct composite_context *c; + + c = talloc_zero(mem_ctx, struct composite_context); + if (!c) return NULL; + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->event_ctx = ev; + + return c; +} + /* block until a composite function has completed, then return the status */ @@ -156,6 +174,16 @@ _PUBLIC_ void composite_continue_smb(struct composite_context *ctx, new_req->async.private = private_data; } +_PUBLIC_ void composite_continue_smb2(struct composite_context *ctx, + struct smb2_request *new_req, + void (*continuation)(struct smb2_request *), + void *private_data) +{ + if (composite_nomem(new_req, ctx)) return; + new_req->async.fn = continuation; + new_req->async.private = private_data; +} + _PUBLIC_ void composite_continue_nbt(struct composite_context *ctx, struct nbt_name_request *new_req, void (*continuation)(struct nbt_name_request *), diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index dc04f5a883..d8873684fc 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -63,6 +63,7 @@ struct composite_context { struct irpc_request; struct smbcli_request; +struct smb2_request; struct rpc_request; struct nbt_name_request; -- cgit From 7c50eec25edd2e70d9127f8cc35588c4bfbb53f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 30 Jul 2006 17:29:02 +0000 Subject: r17318: make better usage of the composite api metze (This used to be commit 683fc25f6524a3821ba70529251aabe97bad9370) --- source4/libcli/smb2/connect.c | 22 ++++------------------ source4/libcli/smb2/session.c | 42 +++++++++--------------------------------- 2 files changed, 13 insertions(+), 51 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index b185ff7a88..0d772bccd8 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -171,38 +171,24 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, struct nbt_name name; struct composite_context *creq; - c = talloc_zero(mem_ctx, struct composite_context); + c = composite_create(mem_ctx, ev); if (c == NULL) return NULL; state = talloc(c, struct smb2_connect_state); - if (state == NULL) { - c->status = NT_STATUS_NO_MEMORY; - goto failed; - } - - c->state = COMPOSITE_STATE_IN_PROGRESS; + if (composite_nomem(state, c)) return c; c->private_data = state; - c->event_ctx = ev; state->credentials = credentials; state->host = talloc_strdup(c, host); + if (composite_nomem(state->host, c)) return c; state->share = talloc_strdup(c, share); - if (state->host == NULL || state->share == NULL) { - c->status = NT_STATUS_NO_MEMORY; - goto failed; - } + if (composite_nomem(state->share, c)) return c; ZERO_STRUCT(name); name.name = host; creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); - composite_continue(c, creq, continue_resolve, c); - - return c; - -failed: - composite_error(c, c->status); return c; } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 7518a3d6d3..8ebdc93bd4 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -196,18 +196,12 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se struct composite_context *c; struct smb2_session_state *state; - c = talloc_zero(session, struct composite_context); + c = composite_create(session, session->transport->socket->event.ctx); if (c == NULL) return NULL; state = talloc(c, struct smb2_session_state); - if (state == NULL) { - c->status = NT_STATUS_NO_MEMORY; - goto failed; - } - - c->state = COMPOSITE_STATE_IN_PROGRESS; + if (composite_nomem(state, c)) return c; c->private_data = state; - c->event_ctx = session->transport->socket->event.ctx; ZERO_STRUCT(state->io); state->io.in._pad = 0x0000; @@ -216,47 +210,29 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se state->io.in.unknown4 = 0; /* uint64_t */ c->status = gensec_set_credentials(session->gensec, credentials); - if (!NT_STATUS_IS_OK(c->status)) { - goto failed; - } + if (!composite_is_ok(c)) return c; c->status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); - if (!NT_STATUS_IS_OK(c->status)) { - goto failed; - } + if (!composite_is_ok(c)) return c; c->status = gensec_set_target_service(session->gensec, "cifs"); - if (!NT_STATUS_IS_OK(c->status)) { - goto failed; - } + if (!composite_is_ok(c)) return c; c->status = gensec_start_mech_by_oid(session->gensec, GENSEC_OID_SPNEGO); - if (!NT_STATUS_IS_OK(c->status)) { - goto failed; - } + if (!composite_is_ok(c)) return c; c->status = gensec_update(session->gensec, c, session->transport->negotiate.secblob, &state->io.in.secblob); if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto failed; + composite_error(c, c->status); + return c; } state->gensec_status = c->status; state->req = smb2_session_setup_send(session, &state->io); - if (state->req == NULL) { - c->status = NT_STATUS_NO_MEMORY; - goto failed; - } - - state->req->async.fn = session_request_handler; - state->req->async.private = c; - - return c; - -failed: - composite_error(c, c->status); + composite_continue_smb2(c, state->req, session_request_handler, c); return c; } -- cgit From 3437c2d92ccf42dbe3737c1c6a8786dfa54515d3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 30 Jul 2006 17:31:12 +0000 Subject: r17319: make better usage of the composite api metze (This used to be commit 8f9e201b9a797c0772672efab0f8e6a7a6312eb0) --- source4/libcli/finddcs.c | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 7df0551b53..417b33f277 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -66,44 +66,36 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct messaging_context *msg_ctx) { - struct composite_context *result, *ctx; + struct composite_context *c, *creq; struct finddcs_state *state; struct nbt_name name; - result = talloc_zero(mem_ctx, struct composite_context); - if (result == NULL) goto failed; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->async.fn = NULL; - result->event_ctx = event_ctx; + c = composite_create(mem_ctx, event_ctx); + if (c == NULL) return NULL; - state = talloc(result, struct finddcs_state); - if (state == NULL) goto failed; - state->ctx = result; - result->private_data = state; + state = talloc(c, struct finddcs_state); + if (composite_nomem(state, c)) return c; + c->private_data = state; + + state->ctx = c; state->domain_name = talloc_strdup(state, domain_name); - if (state->domain_name == NULL) goto failed; - state->domain_sid = domain_sid; - if (domain_sid != NULL) { - if (talloc_reference(state, domain_sid) == NULL) { - goto failed; - } + if (composite_nomem(state->domain_name, c)) return c; + + if (domain_sid) { + state->domain_sid = talloc_reference(state, domain_sid); + if (composite_nomem(state->domain_sid, c)) return c; + } else { + state->domain_sid = NULL; } + state->msg_ctx = msg_ctx; make_nbt_name(&name, state->domain_name, name_type); - ctx = resolve_name_send(&name, result->event_ctx, - methods); - - if (ctx == NULL) goto failed; - ctx->async.fn = finddcs_name_resolved; - ctx->async.private_data = state; - - return result; - -failed: - talloc_free(result); - return NULL; + creq = resolve_name_send(&name, event_ctx, + methods); + composite_continue(c, creq, finddcs_name_resolved, state); + return c; } /* Having got an name query answer, fire off a GetDC request, so we -- cgit From 3455998edc03268b7b73c80cf1630127e5a3f8df Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 06:20:55 +0000 Subject: r17414: add new error code metze (This used to be commit e15a015a1d9aa3872271c0c5542e7d055a6f673a) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 8dd9181f7b..91a47bfbb5 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -86,6 +86,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, { "WERR_DS_DRA_INTERNAL_ERROR", WERR_DS_DRA_INTERNAL_ERROR }, + { "WERR_DS_DRA_OUT_OF_MEM", WERR_DS_DRA_OUT_OF_MEM }, { "WERR_DS_SINGLE_VALUE_CONSTRAINT", WERR_DS_SINGLE_VALUE_CONSTRAINT }, { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 70442056e3..386735617a 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -257,6 +257,7 @@ #define WERR_DS_DRA_BAD_DN W_ERROR(0x000020f7) #define WERR_DS_DRA_BAD_NC W_ERROR(0x000020f8) #define WERR_DS_DRA_INTERNAL_ERROR W_ERROR(0x000020fa) +#define WERR_DS_DRA_OUT_OF_MEM W_ERROR(0x000020fe) #define WERR_DS_SINGLE_VALUE_CONSTRAINT W_ERROR(0x00002081) #define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) #define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) -- cgit From b4028ca1041fc8e0266de2f5c858dd40e660aafb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 10:26:23 +0000 Subject: r17418: add client support for the LDAP_SERVER_SD_FLAGS control metze (This used to be commit 23759a1e9b05c4fde475a9016cb0b7447656d7e7) --- source4/libcli/ldap/ldap_controls.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index ee8f9d4bb1..445b5f8086 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -182,6 +182,37 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + struct asn1_data data; + struct ldb_sd_flags_control *lsdfc; + + if (!asn1_load(&data, in)) { + return False; + } + + lsdfc = talloc(mem_ctx, struct ldb_sd_flags_control); + if (!lsdfc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lsdfc->secinfo_flags))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lsdfc; + + return True; +} + static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; @@ -631,6 +662,33 @@ static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lsdfc->secinfo_flags)) { + return False; + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); @@ -878,6 +936,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, + { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, -- cgit From 817610f38540fb99595f6e3b77b9f6696f9e3b3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 11:18:14 +0000 Subject: r17419: add client support for the LDAP_SERVER_SEARCH_OPTIONS support. with this you can limit a search to a specific partitions or a search over all partitions without getting referrals. (Witch is the default behavior on the Global Catalog Port) metze (This used to be commit 4ccd0f8171f3748ee6efe1abd3f894d2cdf46bf4) --- source4/libcli/ldap/ldap_controls.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 445b5f8086..4c5d214a8f 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -213,6 +213,37 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + struct asn1_data data; + struct ldb_search_options_control *lsoc; + + if (!asn1_load(&data, in)) { + return False; + } + + lsoc = talloc(mem_ctx, struct ldb_search_options_control); + if (!lsoc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lsoc->search_options))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lsoc; + + return True; +} + static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; @@ -689,6 +720,33 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lsoc->search_options)) { + return False; + } + + if (!asn1_pop_tag(&data)) { + return False; + } + + *out = data_blob_talloc(mem_ctx, data.data, data.length); + if (out->data == NULL) { + return False; + } + + return True; +} + static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); @@ -937,6 +995,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, + { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, -- cgit From 8ac0237eba1831c8ba6d01c2b9d8402636a21bb2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 11:38:50 +0000 Subject: r17420: add client support for the LDAP_SERVER_DOMAIN_SCOPE control metze (This used to be commit 84e74a759cfa49ebc8b4ba1b8e729d6d920fc55a) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 4c5d214a8f..395c4eb836 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -401,6 +401,15 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { @@ -850,6 +859,16 @@ static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { @@ -995,6 +1014,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, + { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, -- cgit From 12050962f6dd37819e58e1e0b572c159f0406f7a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 19:35:00 +0000 Subject: r17429: implement the LDAP_SERVER_SHOW_DELETED control in the client metze (This used to be commit 40dc7c1787c16bfc15ac87fee81d2d2d1f3d2fde) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 395c4eb836..75af597c33 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -419,6 +419,15 @@ static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { @@ -879,6 +888,16 @@ static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { @@ -1013,6 +1032,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, + { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, -- cgit From 3a083f8f53b998b6aabf69e845fd0fbdf86b6499 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 19:50:58 +0000 Subject: r17430: implement the LDAP_SERVER_PERMISSIVE_MODIFY control in the client metze (This used to be commit 96259f0f24b114e505241c9d2deb702a8b40f1b6) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 75af597c33..5cd0451136 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -428,6 +428,15 @@ static BOOL decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { @@ -898,6 +907,16 @@ static BOOL encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { @@ -1033,6 +1052,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request }, + { "1.2.840.113556.1.4.1413", decode_permissive_modify_request, encode_permissive_modify_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, -- cgit From b0a264f1ae1457910a66a118104d172d2e73637b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Aug 2006 08:53:25 +0000 Subject: r17567: add error code I got from DsGetNCChanges when I don't use the DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION flag on DsBind metze (This used to be commit 8458ee72c5c1005ab80b9f7ea6efe617e5c76106) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 91a47bfbb5..c7d7053165 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -101,6 +101,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS }, { "WERR_SHUTDOWN_ALREADY_IN_PROGRESS", WERR_SHUTDOWN_ALREADY_IN_PROGRESS }, + { "WERR_SEC_E_ALGORITHM_MISMATCH", WERR_SEC_E_ALGORITHM_MISMATCH }, { NULL, W_ERROR(0) } }; diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 386735617a..32807da47c 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -265,6 +265,9 @@ #define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) #define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) +/* SEC errors */ +#define WERR_SEC_E_ALGORITHM_MISMATCH W_ERROR(0x80090331) + #define WERR_FOOBAR WERR_GENERAL_FAILURE #endif /* _DOSERR_H */ -- cgit From a2eca9174c7803732658a1e6f7e8ed873c4fb6fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Aug 2006 13:37:04 +0000 Subject: r17586: merge lib/netif into lib/socket and use -lnsl -lsocket on the configure check for the interfaces. should fix the build on some old sun boxes metze (This used to be commit f20e251bfd9f1eb7ce5c00739631b1625a2aa467) --- source4/libcli/resolve/bcast.c | 2 +- source4/libcli/resolve/nbtlist.c | 2 +- source4/libcli/wrepl/winsrepl.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 1b58918ea7..8824ad395e 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -23,7 +23,7 @@ #include "includes.h" #include "libcli/resolve/resolve.h" #include "system/network.h" -#include "netif/netif.h" +#include "lib/socket/netif.h" /* broadcast name resolution method - async send diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index a8ca2ced8b..9d7035c26d 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -27,7 +27,7 @@ #include "includes.h" #include "libcli/composite/composite.h" #include "system/network.h" -#include "netif/netif.h" +#include "lib/socket/netif.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "libcli/nbt/libnbt.h" diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index a1735c547c..bf0be9fb9b 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -29,7 +29,7 @@ #include "lib/stream/packet.h" #include "libcli/composite/composite.h" #include "system/network.h" -#include "netif/netif.h" +#include "lib/socket/netif.h" static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status); -- cgit From 9ba16109e50ca9e411c62dbdfd7a0ed44591d2be Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 26 Aug 2006 22:27:29 +0000 Subject: r17846: Ok, this is a patch that needs further discussion. On Solaris, snprintf seems to be broken. The %lu modifies apparently can not cope with the high bit==1. In dom_sid_string I added some printfs and got: auth: 21 auth: 2666793276 auth: 679821296 auth: 2310223117 auth: 1206 sid=S-1-5-21-8446744072081377596-679821296-8446744071724807437-1206 The "auth:" values are direct printfs, the sid= is the resulting code from dom_sid_string. I could not reproduce it with a simple test program, and #ifdef'ing out HAVE_SNPRINTF in config.h manually does not help either, probably because the dynamic linker overwrites the symbol in lib/replace. Checking it in because it fixes the RPC-SAMBA3-SHARESEC test directly on host "sunx", I would like to see whether it also fixes IRIX and AIX. Volker (This used to be commit 1a9401738f652a87d377a32086342f5f98525fc2) --- source4/libcli/security/dom_sid.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 54242eb515..90421104a7 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -285,7 +285,14 @@ char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) (unsigned int)sid->sid_rev_num, (unsigned long)ia); for (i = 0; i < sid->num_auths; i++) { - ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); + char *tmp = talloc_asprintf(mem_ctx, "%lu", + (unsigned long)sid->sub_auths[i]); + if (tmp == NULL) { + talloc_free(ret); + return NULL; + } + ofs += snprintf(ret + ofs, maxlen - ofs, "-%s", tmp); + talloc_free(tmp); } return ret; -- cgit From 7917a26fabb7835017a6c3a2780c8425a4a92ffa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Aug 2006 10:08:18 +0000 Subject: r17848: Ok, this did not do it. Still got the same problem. (This used to be commit bb393603707ada3d4b917f8374b7738f16c78f46) --- source4/libcli/security/dom_sid.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 90421104a7..54242eb515 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -285,14 +285,7 @@ char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) (unsigned int)sid->sid_rev_num, (unsigned long)ia); for (i = 0; i < sid->num_auths; i++) { - char *tmp = talloc_asprintf(mem_ctx, "%lu", - (unsigned long)sid->sub_auths[i]); - if (tmp == NULL) { - talloc_free(ret); - return NULL; - } - ofs += snprintf(ret + ofs, maxlen - ofs, "-%s", tmp); - talloc_free(tmp); + ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]); } return ret; -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/libcli/auth/smbencrypt.c | 1 - source4/libcli/cldap/cldap.c | 2 +- source4/libcli/composite/composite.h | 2 + source4/libcli/dgram/dgramsocket.c | 2 +- source4/libcli/dgram/mailslot.c | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/raw/rawnotify.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/raw/rawtrans.c | 2 +- source4/libcli/raw/smb.h | 593 +++++++++++++++++++++++++++++++ source4/libcli/smb2/request.c | 2 +- source4/libcli/smb2/transport.c | 2 +- source4/libcli/smb_composite/fetchfile.c | 1 - source4/libcli/wrepl/winsrepl.c | 2 +- 16 files changed, 607 insertions(+), 14 deletions(-) create mode 100644 source4/libcli/raw/smb.h (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 98f98a4986..9fce590d43 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -24,7 +24,6 @@ #include "includes.h" #include "system/time.h" -#include "smb.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/msrpc_parse.h" #include "lib/crypto/crypto.h" diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 03e690ef18..1b09272f04 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -34,7 +34,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "libcli/ldap/ldap.h" #include "libcli/cldap/cldap.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index d8873684fc..cb45382c40 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "libcli/raw/interfaces.h" + /* this defines the structures associated with "composite" requests. Composite requests are libcli requests that are internally diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index e7eb01b7e9..2e16014aad 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -22,7 +22,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_nbt.h" diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index c59cab79da..a0021d7a68 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -34,7 +34,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index eb7b9c6327..efc6f7b4e5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -25,7 +25,7 @@ #include "includes.h" #include "libcli/util/asn_1.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 7bdeb834f9..a48f9873c8 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -22,7 +22,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_nbt.h" diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 641ad38031..8c4c7f7c43 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -23,7 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "lib/socket/socket.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/stream/packet.h" #include "librpc/gen_ndr/ndr_nbt.h" diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 2b68d96a1b..5f3fa0f50e 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -20,7 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" /**************************************************************************** change notify (async send) diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index f042c7b581..3eab563a40 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -25,7 +25,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" /* we over allocate the data buffer to prevent too many realloc calls */ diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 53e80d4753..cd309e0736 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "libcli/raw/libcliraw.h" #define TORTURE_TRANS_DATA 0 diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h new file mode 100644 index 0000000000..98e7eca581 --- /dev/null +++ b/source4/libcli/raw/smb.h @@ -0,0 +1,593 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup, plus a whole lot more. + + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) John H Terpstra 1996-2002 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Paul Ashton 1998-2000 + Copyright (C) Simo Sorce 2001-2002 + Copyright (C) Martin Pool 2002 + + 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. +*/ + +#ifndef _SMB_H +#define _SMB_H + +/* deny modes */ +#define DENY_DOS 0 +#define DENY_ALL 1 +#define DENY_WRITE 2 +#define DENY_READ 3 +#define DENY_NONE 4 +#define DENY_FCB 7 + +/* open modes */ +#define DOS_OPEN_RDONLY 0 +#define DOS_OPEN_WRONLY 1 +#define DOS_OPEN_RDWR 2 +#define DOS_OPEN_FCB 0xF + + +/**********************************/ +/* SMBopen field definitions */ +#define OPEN_FLAGS_DENY_MASK 0x70 +#define OPEN_FLAGS_DENY_DOS 0x00 +#define OPEN_FLAGS_DENY_ALL 0x10 +#define OPEN_FLAGS_DENY_WRITE 0x20 +#define OPEN_FLAGS_DENY_READ 0x30 +#define OPEN_FLAGS_DENY_NONE 0x40 + +#define OPEN_FLAGS_MODE_MASK 0x0F +#define OPEN_FLAGS_OPEN_READ 0 +#define OPEN_FLAGS_OPEN_WRITE 1 +#define OPEN_FLAGS_OPEN_RDWR 2 +#define OPEN_FLAGS_FCB 0xFF + + +/**********************************/ +/* SMBopenX field definitions */ + +/* OpenX Flags field. */ +#define OPENX_FLAGS_ADDITIONAL_INFO 0x01 +#define OPENX_FLAGS_REQUEST_OPLOCK 0x02 +#define OPENX_FLAGS_REQUEST_BATCH_OPLOCK 0x04 +#define OPENX_FLAGS_EA_LEN 0x08 +#define OPENX_FLAGS_EXTENDED_RETURN 0x10 + +/* desired access (open_mode), split info 4 4-bit nibbles */ +#define OPENX_MODE_ACCESS_MASK 0x000F +#define OPENX_MODE_ACCESS_READ 0x0000 +#define OPENX_MODE_ACCESS_WRITE 0x0001 +#define OPENX_MODE_ACCESS_RDWR 0x0002 +#define OPENX_MODE_ACCESS_EXEC 0x0003 +#define OPENX_MODE_ACCESS_FCB 0x000F + +#define OPENX_MODE_DENY_SHIFT 4 +#define OPENX_MODE_DENY_MASK (0xF << OPENX_MODE_DENY_SHIFT) +#define OPENX_MODE_DENY_DOS (DENY_DOS << OPENX_MODE_DENY_SHIFT) +#define OPENX_MODE_DENY_ALL (DENY_ALL << OPENX_MODE_DENY_SHIFT) +#define OPENX_MODE_DENY_WRITE (DENY_WRITE << OPENX_MODE_DENY_SHIFT) +#define OPENX_MODE_DENY_READ (DENY_READ << OPENX_MODE_DENY_SHIFT) +#define OPENX_MODE_DENY_NONE (DENY_NONE << OPENX_MODE_DENY_SHIFT) +#define OPENX_MODE_DENY_FCB (0xF << OPENX_MODE_DENY_SHIFT) + +#define OPENX_MODE_LOCALITY_MASK 0x0F00 /* what does this do? */ + +#define OPENX_MODE_NO_CACHE 0x1000 +#define OPENX_MODE_WRITE_THRU 0x4000 + +/* open function values */ +#define OPENX_OPEN_FUNC_MASK 0x3 +#define OPENX_OPEN_FUNC_FAIL 0x0 +#define OPENX_OPEN_FUNC_OPEN 0x1 +#define OPENX_OPEN_FUNC_TRUNC 0x2 + +/* The above can be OR'ed with... */ +#define OPENX_OPEN_FUNC_CREATE 0x10 + +/* openx action in reply */ +#define OPENX_ACTION_EXISTED 1 +#define OPENX_ACTION_CREATED 2 +#define OPENX_ACTION_TRUNCATED 3 + + +/**********************************/ +/* SMBntcreateX field definitions */ + +/* ntcreatex flags field. */ +#define NTCREATEX_FLAGS_REQUEST_OPLOCK 0x02 +#define NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK 0x04 +#define NTCREATEX_FLAGS_OPEN_DIRECTORY 0x08 /* TODO: opens parent? we need + a test suite for this */ +#define NTCREATEX_FLAGS_EXTENDED 0x10 + +/* the ntcreatex access_mask field + this is split into 4 pieces + AAAABBBBCCCCCCCCDDDDDDDDDDDDDDDD + A -> GENERIC_RIGHT_* + B -> SEC_RIGHT_* + C -> STD_RIGHT_* + D -> SA_RIGHT_* + + which set of SA_RIGHT_* bits is applicable depends on the type + of object. +*/ + + + +/* ntcreatex share_access field */ +#define NTCREATEX_SHARE_ACCESS_NONE 0 +#define NTCREATEX_SHARE_ACCESS_READ 1 +#define NTCREATEX_SHARE_ACCESS_WRITE 2 +#define NTCREATEX_SHARE_ACCESS_DELETE 4 + +/* ntcreatex open_disposition field */ +#define NTCREATEX_DISP_SUPERSEDE 0 /* supersede existing file (if it exists) */ +#define NTCREATEX_DISP_OPEN 1 /* if file exists open it, else fail */ +#define NTCREATEX_DISP_CREATE 2 /* if file exists fail, else create it */ +#define NTCREATEX_DISP_OPEN_IF 3 /* if file exists open it, else create it */ +#define NTCREATEX_DISP_OVERWRITE 4 /* if exists overwrite, else fail */ +#define NTCREATEX_DISP_OVERWRITE_IF 5 /* if exists overwrite, else create */ + +/* ntcreatex create_options field */ +#define NTCREATEX_OPTIONS_DIRECTORY 0x0001 +#define NTCREATEX_OPTIONS_WRITE_THROUGH 0x0002 +#define NTCREATEX_OPTIONS_SEQUENTIAL_ONLY 0x0004 +#define NTCREATEX_OPTIONS_SYNC_ALERT 0x0010 +#define NTCREATEX_OPTIONS_ASYNC_ALERT 0x0020 +#define NTCREATEX_OPTIONS_NON_DIRECTORY_FILE 0x0040 +#define NTCREATEX_OPTIONS_NO_EA_KNOWLEDGE 0x0200 +#define NTCREATEX_OPTIONS_EIGHT_DOT_THREE_ONLY 0x0400 +#define NTCREATEX_OPTIONS_RANDOM_ACCESS 0x0800 +#define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000 +#define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000 +#define NTCREATEX_OPTIONS_UNKNOWN_400000 0x400000 + +/* create options these bits are for private use by backends, they are + not valid on the wire */ +#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 + + +/* ntcreatex impersonation field */ +#define NTCREATEX_IMPERSONATION_ANONYMOUS 0 +#define NTCREATEX_IMPERSONATION_IDENTIFICATION 1 +#define NTCREATEX_IMPERSONATION_IMPERSONATION 2 +#define NTCREATEX_IMPERSONATION_DELEGATION 3 + +/* ntcreatex security flags bit field */ +#define NTCREATEX_SECURITY_DYNAMIC 1 +#define NTCREATEX_SECURITY_ALL 2 + +/* ntcreatex create_action in reply */ +#define NTCREATEX_ACTION_EXISTED 1 +#define NTCREATEX_ACTION_CREATED 2 +#define NTCREATEX_ACTION_TRUNCATED 3 +/* the value 5 can also be returned when you try to create a directory with + incorrect parameters - what does it mean? maybe created temporary file? */ +#define NTCREATEX_ACTION_UNKNOWN 5 + +#define SMB_MAGIC 0x424D53FF /* 0xFF 'S' 'M' 'B' */ + +/* the basic packet size, assuming no words or bytes. Does not include the NBT header */ +#define MIN_SMB_SIZE 35 + +/* when using NBT encapsulation every packet has a 4 byte header */ +#define NBT_HDR_SIZE 4 + +/* offsets into message header for common items - NOTE: These have + changed from being offsets from the base of the NBT packet to the base of the SMB packet. + this has reduced all these values by 4 +*/ +#define HDR_COM 4 +#define HDR_RCLS 5 +#define HDR_REH 6 +#define HDR_ERR 7 +#define HDR_FLG 9 +#define HDR_FLG2 10 +#define HDR_PIDHIGH 12 +#define HDR_SS_FIELD 14 +#define HDR_TID 24 +#define HDR_PID 26 +#define HDR_UID 28 +#define HDR_MID 30 +#define HDR_WCT 32 +#define HDR_VWV 33 + + +/* types of buffers in core SMB protocol */ +#define SMB_DATA_BLOCK 0x1 +#define SMB_ASCII4 0x4 + + +/* flag defines. CIFS spec 3.1.1 */ +#define FLAG_SUPPORT_LOCKREAD 0x01 +#define FLAG_CLIENT_BUF_AVAIL 0x02 +#define FLAG_RESERVED 0x04 +#define FLAG_CASELESS_PATHNAMES 0x08 +#define FLAG_CANONICAL_PATHNAMES 0x10 +#define FLAG_REQUEST_OPLOCK 0x20 +#define FLAG_REQUEST_BATCH_OPLOCK 0x40 +#define FLAG_REPLY 0x80 + +/* the complete */ +#define SMBmkdir 0x00 /* create directory */ +#define SMBrmdir 0x01 /* delete directory */ +#define SMBopen 0x02 /* open file */ +#define SMBcreate 0x03 /* create file */ +#define SMBclose 0x04 /* close file */ +#define SMBflush 0x05 /* flush file */ +#define SMBunlink 0x06 /* delete file */ +#define SMBmv 0x07 /* rename file */ +#define SMBgetatr 0x08 /* get file attributes */ +#define SMBsetatr 0x09 /* set file attributes */ +#define SMBread 0x0A /* read from file */ +#define SMBwrite 0x0B /* write to file */ +#define SMBlock 0x0C /* lock byte range */ +#define SMBunlock 0x0D /* unlock byte range */ +#define SMBctemp 0x0E /* create temporary file */ +#define SMBmknew 0x0F /* make new file */ +#define SMBchkpth 0x10 /* check directory path */ +#define SMBexit 0x11 /* process exit */ +#define SMBlseek 0x12 /* seek */ +#define SMBtcon 0x70 /* tree connect */ +#define SMBtconX 0x75 /* tree connect and X*/ +#define SMBtdis 0x71 /* tree disconnect */ +#define SMBnegprot 0x72 /* negotiate protocol */ +#define SMBdskattr 0x80 /* get disk attributes */ +#define SMBsearch 0x81 /* search directory */ +#define SMBsplopen 0xC0 /* open print spool file */ +#define SMBsplwr 0xC1 /* write to print spool file */ +#define SMBsplclose 0xC2 /* close print spool file */ +#define SMBsplretq 0xC3 /* return print queue */ +#define SMBsends 0xD0 /* send single block message */ +#define SMBsendb 0xD1 /* send broadcast message */ +#define SMBfwdname 0xD2 /* forward user name */ +#define SMBcancelf 0xD3 /* cancel forward */ +#define SMBgetmac 0xD4 /* get machine name */ +#define SMBsendstrt 0xD5 /* send start of multi-block message */ +#define SMBsendend 0xD6 /* send end of multi-block message */ +#define SMBsendtxt 0xD7 /* send text of multi-block message */ + +/* Core+ protocol */ +#define SMBlockread 0x13 /* Lock a range and read */ +#define SMBwriteunlock 0x14 /* write then range then unlock it */ +#define SMBreadbraw 0x1a /* read a block of data with no smb header */ +#define SMBwritebraw 0x1d /* write a block of data with no smb header */ +#define SMBwritec 0x20 /* secondary write request */ +#define SMBwriteclose 0x2c /* write a file then close it */ + +/* dos extended protocol */ +#define SMBreadBraw 0x1A /* read block raw */ +#define SMBreadBmpx 0x1B /* read block multiplexed */ +#define SMBreadBs 0x1C /* read block (secondary response) */ +#define SMBwriteBraw 0x1D /* write block raw */ +#define SMBwriteBmpx 0x1E /* write block multiplexed */ +#define SMBwriteBs 0x1F /* write block (secondary request) */ +#define SMBwriteC 0x20 /* write complete response */ +#define SMBsetattrE 0x22 /* set file attributes expanded */ +#define SMBgetattrE 0x23 /* get file attributes expanded */ +#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ +#define SMBtrans 0x25 /* transaction - name, bytes in/out */ +#define SMBtranss 0x26 /* transaction (secondary request/response) */ +#define SMBioctl 0x27 /* IOCTL */ +#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ +#define SMBcopy 0x29 /* copy */ +#define SMBmove 0x2A /* move */ +#define SMBecho 0x2B /* echo */ +#define SMBopenX 0x2D /* open and X */ +#define SMBreadX 0x2E /* read and X */ +#define SMBwriteX 0x2F /* write and X */ +#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ +#define SMBffirst 0x82 /* find first */ +#define SMBfunique 0x83 /* find unique */ +#define SMBfclose 0x84 /* find close */ +#define SMBkeepalive 0x85 /* keepalive */ +#define SMBinvalid 0xFE /* invalid command */ + +/* Extended 2.0 protocol */ +#define SMBtrans2 0x32 /* TRANS2 protocol set */ +#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */ +#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */ +#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */ +#define SMBulogoffX 0x74 /* user logoff */ + +/* NT SMB extensions. */ +#define SMBnttrans 0xA0 /* NT transact */ +#define SMBnttranss 0xA1 /* NT transact secondary */ +#define SMBntcreateX 0xA2 /* NT create and X */ +#define SMBntcancel 0xA4 /* NT cancel */ +#define SMBntrename 0xA5 /* NT rename */ + +/* used to indicate end of chain */ +#define SMB_CHAIN_NONE 0xFF + +/* These are the trans subcommands */ +#define TRANSACT_SETNAMEDPIPEHANDLESTATE 0x01 +#define TRANSACT_DCERPCCMD 0x26 +#define TRANSACT_WAITNAMEDPIPEHANDLESTATE 0x53 + +/* These are the NT transact sub commands. */ +#define NT_TRANSACT_CREATE 1 +#define NT_TRANSACT_IOCTL 2 +#define NT_TRANSACT_SET_SECURITY_DESC 3 +#define NT_TRANSACT_NOTIFY_CHANGE 4 +#define NT_TRANSACT_RENAME 5 +#define NT_TRANSACT_QUERY_SECURITY_DESC 6 + +/* this is used on a TConX. I'm not sure the name is very helpful though */ +#define SMB_SUPPORT_SEARCH_BITS 0x0001 +#define SMB_SHARE_IN_DFS 0x0002 + +/* Named pipe write mode flags. Used in writeX calls. */ +#define PIPE_RAW_MODE 0x4 +#define PIPE_START_MESSAGE 0x8 + +/* the desired access to use when opening a pipe */ +#define DESIRED_ACCESS_PIPE 0x2019f + + +/* Mapping of generic access rights for files to specific rights. */ +#define FILE_GENERIC_ALL (STANDARD_RIGHTS_REQUIRED_ACCESS| NT_ACCESS_SYNCHRONIZE_ACCESS|FILE_ALL_ACCESS) + +#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ_ACCESS|FILE_READ_DATA|FILE_READ_ATTRIBUTES|\ + FILE_READ_EA|NT_ACCESS_SYNCHRONIZE_ACCESS) + +#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE_ACCESS|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|\ + FILE_WRITE_EA|FILE_APPEND_DATA|NT_ACCESS_SYNCHRONIZE_ACCESS) + +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|FILE_READ_ATTRIBUTES|\ + FILE_EXECUTE|NT_ACCESS_SYNCHRONIZE_ACCESS) + + +/* FileAttributes (search attributes) field */ +#define FILE_ATTRIBUTE_READONLY 0x0001 +#define FILE_ATTRIBUTE_HIDDEN 0x0002 +#define FILE_ATTRIBUTE_SYSTEM 0x0004 +#define FILE_ATTRIBUTE_VOLUME 0x0008 +#define FILE_ATTRIBUTE_DIRECTORY 0x0010 +#define FILE_ATTRIBUTE_ARCHIVE 0x0020 +#define FILE_ATTRIBUTE_DEVICE 0x0040 +#define FILE_ATTRIBUTE_NORMAL 0x0080 +#define FILE_ATTRIBUTE_TEMPORARY 0x0100 +#define FILE_ATTRIBUTE_SPARSE 0x0200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400 +#define FILE_ATTRIBUTE_COMPRESSED 0x0800 +#define FILE_ATTRIBUTE_OFFLINE 0x1000 +#define FILE_ATTRIBUTE_NONINDEXED 0x2000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 + +/* Flags - combined with attributes. */ +#define FILE_FLAG_WRITE_THROUGH 0x80000000L +#define FILE_FLAG_NO_BUFFERING 0x20000000L +#define FILE_FLAG_RANDOM_ACCESS 0x10000000L +#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000L +#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000L +#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L /* only if backup/restore privilege? */ +#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L + +/* Responses when opening a file. */ +#define FILE_WAS_SUPERSEDED 0 +#define FILE_WAS_OPENED 1 +#define FILE_WAS_CREATED 2 +#define FILE_WAS_OVERWRITTEN 3 + +/* File type flags */ +#define FILE_TYPE_DISK 0 +#define FILE_TYPE_BYTE_MODE_PIPE 1 +#define FILE_TYPE_MESSAGE_MODE_PIPE 2 +#define FILE_TYPE_PRINTER 3 +#define FILE_TYPE_COMM_DEVICE 4 +#define FILE_TYPE_UNKNOWN 0xFFFF + +/* Flag for NT transact rename call. */ +#define RENAME_REPLACE_IF_EXISTS 1 + +/* flags for SMBntrename call */ +#define RENAME_FLAG_MOVE_CLUSTER_INFORMATION 0x102 /* ???? */ +#define RENAME_FLAG_HARD_LINK 0x103 +#define RENAME_FLAG_RENAME 0x104 +#define RENAME_FLAG_COPY 0x105 + +/* Filesystem Attributes. */ +#define FILE_CASE_SENSITIVE_SEARCH 0x01 +#define FILE_CASE_PRESERVED_NAMES 0x02 +#define FILE_UNICODE_ON_DISK 0x04 +/* According to cifs9f, this is 4, not 8 */ +/* Acconding to testing, this actually sets the security attribute! */ +#define FILE_PERSISTENT_ACLS 0x08 +/* These entries added from cifs9f --tsb */ +#define FILE_FILE_COMPRESSION 0x10 +#define FILE_VOLUME_QUOTAS 0x20 +/* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */ +#define FILE_VOLUME_SPARSE_FILE 0x40 +#define FILE_VOLUME_IS_COMPRESSED 0x8000 + +/* ChangeNotify flags. */ +#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 +#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 +#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 +#define FILE_NOTIFY_CHANGE_SIZE 0x00000008 +#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 +#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020 +#define FILE_NOTIFY_CHANGE_CREATION 0x00000040 +#define FILE_NOTIFY_CHANGE_EA 0x00000080 +#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100 +#define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 +#define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 +#define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 + +#define FILE_NOTIFY_CHANGE_NAME \ + (FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME) + +/* change notify action results */ +#define NOTIFY_ACTION_ADDED 1 +#define NOTIFY_ACTION_REMOVED 2 +#define NOTIFY_ACTION_MODIFIED 3 +#define NOTIFY_ACTION_OLD_NAME 4 +#define NOTIFY_ACTION_NEW_NAME 5 +#define NOTIFY_ACTION_ADDED_STREAM 6 +#define NOTIFY_ACTION_REMOVED_STREAM 7 +#define NOTIFY_ACTION_MODIFIED_STREAM 8 + +/* seek modes for smb_seek */ +#define SEEK_MODE_START 0 +#define SEEK_MODE_CURRENT 1 +#define SEEK_MODE_END 2 + +/* where to find the base of the SMB packet proper */ +/* REWRITE TODO: smb_base needs to be removed */ +#define smb_base(buf) (((char *)(buf))+4) + +/* we don't allow server strings to be longer than 48 characters as + otherwise NT will not honour the announce packets */ +#define MAX_SERVER_STRING_LENGTH 48 + +/* This was set by JHT in liaison with Jeremy Allison early 1997 + * History: + * Version 4.0 - never made public + * Version 4.10 - New to 1.9.16p2, lost in space 1.9.16p3 to 1.9.16p9 + * - Reappeared in 1.9.16p11 with fixed smbd services + * Version 4.20 - To indicate that nmbd and browsing now works better + * Version 4.50 - Set at release of samba-2.2.0 by JHT + * + * Note: In the presence of NT4.X do not set above 4.9 + * Setting this above 4.9 can have undesired side-effects. + * This may change again in Samba-3.0 after further testing. JHT + */ + +#define DEFAULT_MAJOR_VERSION 0x04 +#define DEFAULT_MINOR_VERSION 0x09 + +/* Browser Election Values */ +#define BROWSER_ELECTION_VERSION 0x010f +#define BROWSER_CONSTANT 0xaa55 + +/* Sercurity mode bits. */ +#define NEGOTIATE_SECURITY_USER_LEVEL 0x01 +#define NEGOTIATE_SECURITY_CHALLENGE_RESPONSE 0x02 +#define NEGOTIATE_SECURITY_SIGNATURES_ENABLED 0x04 +#define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED 0x08 + +/* NT Flags2 bits - cifs6.txt section 3.1.2 */ +#define FLAGS2_LONG_PATH_COMPONENTS 0x0001 +#define FLAGS2_EXTENDED_ATTRIBUTES 0x0002 +#define FLAGS2_SMB_SECURITY_SIGNATURES 0x0004 +#define FLAGS2_IS_LONG_NAME 0x0040 +#define FLAGS2_EXTENDED_SECURITY 0x0800 +#define FLAGS2_DFS_PATHNAMES 0x1000 +#define FLAGS2_READ_PERMIT_EXECUTE 0x2000 +#define FLAGS2_32_BIT_ERROR_CODES 0x4000 +#define FLAGS2_UNICODE_STRINGS 0x8000 + + +/* CIFS protocol capabilities */ +#define CAP_RAW_MODE 0x00000001 +#define CAP_MPX_MODE 0x00000002 +#define CAP_UNICODE 0x00000004 +#define CAP_LARGE_FILES 0x00000008 +#define CAP_NT_SMBS 0x00000010 +#define CAP_RPC_REMOTE_APIS 0x00000020 +#define CAP_STATUS32 0x00000040 +#define CAP_LEVEL_II_OPLOCKS 0x00000080 +#define CAP_LOCK_AND_READ 0x00000100 +#define CAP_NT_FIND 0x00000200 +#define CAP_DFS 0x00001000 +#define CAP_W2K_SMBS 0x00002000 +#define CAP_LARGE_READX 0x00004000 +#define CAP_LARGE_WRITEX 0x00008000 +#define CAP_UNIX 0x00800000 /* Capabilities for UNIX extensions. Created by HP. */ +#define CAP_EXTENDED_SECURITY 0x80000000 + +/* + * Global value meaning that the smb_uid field should be + * ingored (in share level security and protocol level == CORE) + */ + +#define UID_FIELD_INVALID 0 + +/* Lock types. */ +#define LOCKING_ANDX_SHARED_LOCK 0x01 +#define LOCKING_ANDX_OPLOCK_RELEASE 0x02 +#define LOCKING_ANDX_CHANGE_LOCKTYPE 0x04 +#define LOCKING_ANDX_CANCEL_LOCK 0x08 +#define LOCKING_ANDX_LARGE_FILES 0x10 + +/* + * Bits we test with. + */ + +#define OPLOCK_NONE 0 +#define OPLOCK_EXCLUSIVE 1 +#define OPLOCK_BATCH 2 +#define OPLOCK_LEVEL_II 4 + +#define CORE_OPLOCK_GRANTED (1<<5) +#define EXTENDED_OPLOCK_GRANTED (1<<15) + +/* + * Return values for oplock types. + */ + +#define NO_OPLOCK_RETURN 0 +#define EXCLUSIVE_OPLOCK_RETURN 1 +#define BATCH_OPLOCK_RETURN 2 +#define LEVEL_II_OPLOCK_RETURN 3 + +/* oplock levels sent in oplock break */ +#define OPLOCK_BREAK_TO_NONE 0 +#define OPLOCK_BREAK_TO_LEVEL_II 1 + + +#define CMD_REPLY 0x8000 + +/* The maximum length of a trust account password. + Used when we randomly create it, 15 char passwords + exceed NT4's max password length */ + +#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14 + + +/* + filesystem attribute bits +*/ +#define FS_ATTR_CASE_SENSITIVE_SEARCH 0x00000001 +#define FS_ATTR_CASE_PRESERVED_NAMES 0x00000002 +#define FS_ATTR_UNICODE_ON_DISK 0x00000004 +#define FS_ATTR_PERSISTANT_ACLS 0x00000008 +#define FS_ATTR_COMPRESSION 0x00000010 +#define FS_ATTR_QUOTAS 0x00000020 +#define FS_ATTR_SPARSE_FILES 0x00000040 +#define FS_ATTR_REPARSE_POINTS 0x00000080 +#define FS_ATTR_REMOTE_STORAGE 0x00000100 +#define FS_ATTR_LFN_SUPPORT 0x00004000 +#define FS_ATTR_IS_COMPRESSED 0x00008000 +#define FS_ATTR_OBJECT_IDS 0x00010000 +#define FS_ATTR_ENCRYPTION 0x00020000 +#define FS_ATTR_NAMED_STREAMS 0x00040000 + +#define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16)) +#define _smb_setlen(buf,len) do {(buf)[0] = 0; (buf)[1] = ((len)&0x10000)>>16; \ + (buf)[2] = ((len)&0xFF00)>>8; (buf)[3] = (len)&0xFF;} while (0) +#define _smb2_setlen(buf,len) do {(buf)[0] = 0; (buf)[1] = ((len)&0xFF0000)>>16; \ + (buf)[2] = ((len)&0xFF00)>>8; (buf)[3] = (len)&0xFF;} while (0) + +#include "libcli/raw/trans2.h" +#include "libcli/raw/interfaces.h" + +#endif /* _SMB_H */ diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 72b9ade3e2..87c4dd78e1 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -24,7 +24,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "include/dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" /* diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index ea8c4804ff..8e27873a88 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -27,7 +27,7 @@ #include "lib/socket/socket.h" #include "lib/events/events.h" #include "lib/stream/packet.h" -#include "include/dlinklist.h" +#include "lib/util/dlinklist.h" /* diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 6ad70a3af7..5783a3258f 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "smb.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index bf0be9fb9b..83cbe2877d 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -22,7 +22,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/socket/socket.h" #include "libcli/wrepl/winsrepl.h" #include "librpc/gen_ndr/ndr_winsrepl.h" -- cgit From 22ced36791da7de99afb799deb30b934ccbd902e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 4 Sep 2006 00:26:10 +0000 Subject: r18021: Add ldapi support to our LDAP client. To be used for testing an OpenLDAP backend. Andrew Bartlett (This used to be commit da66b53e6ac39c5f020781830ee69d460aa0cae5) --- source4/libcli/ldap/ldap_client.c | 127 ++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 34 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index efc6f7b4e5..4fa8cc0146 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -226,19 +226,13 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, { int tmp_port = 0; char protocol[11]; - char tmp_host[255]; - const char *p = url; + char tmp_host[1025]; int ret; - /* skip leading "URL:" (if any) */ - if (strncasecmp(p, "URL:", 4) == 0) { - p += 4; - } - /* Paranoia check */ SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); - ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + ret = sscanf(url, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); if (ret < 2) { return NT_STATUS_INVALID_PARAMETER; } @@ -272,13 +266,16 @@ struct ldap_connect_state { struct ldap_connection *conn; }; -static void ldap_connect_recv_conn(struct composite_context *ctx); +static void ldap_connect_recv_unix_conn(struct composite_context *ctx); +static void ldap_connect_recv_tcp_conn(struct composite_context *ctx); struct composite_context *ldap_connect_send(struct ldap_connection *conn, const char *url) { struct composite_context *result, *ctx; struct ldap_connect_state *state; + char protocol[11]; + int ret; result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; @@ -298,44 +295,73 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, if (conn->reconnect.url == NULL) goto failed; } - state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, - &conn->port, &conn->ldaps); - if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_error(state->ctx, state->ctx->status); - return result; + /* Paranoia check */ + SMB_ASSERT(sizeof(protocol)>10); + + ret = sscanf(url, "%10[^:]://", protocol); + if (ret < 1) { + return NULL; } - ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - conn->event.event_ctx); - if (ctx == NULL) goto failed; + if (strequal(protocol, "ldapi")) { + struct socket_address *unix_addr; + char path[1025]; + + NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &conn->sock, 0); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + SMB_ASSERT(sizeof(protocol)>10); + SMB_ASSERT(sizeof(path)>1024); + + ret = sscanf(url, "%10[^:]://%1025c", protocol, path); + if (ret < 2) { + composite_error(state->ctx, NT_STATUS_INVALID_PARAMETER); + return result; + } - ctx->async.fn = ldap_connect_recv_conn; - ctx->async.private_data = state; - return result; + rfc1738_unescape(path); + + unix_addr = socket_address_from_strings(conn, conn->sock->backend_name, + path, 0); + if (!unix_addr) { + return NULL; + } + + ctx = socket_connect_send(conn->sock, NULL, unix_addr, + 0, conn->event.event_ctx); + ctx->async.fn = ldap_connect_recv_unix_conn; + ctx->async.private_data = state; + return result; + } else { + NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_error(state->ctx, status); + return result; + } + + ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, + conn->event.event_ctx); + if (ctx == NULL) goto failed; + ctx->async.fn = ldap_connect_recv_tcp_conn; + ctx->async.private_data = state; + return result; + } failed: talloc_free(result); return NULL; } -static void ldap_connect_recv_conn(struct composite_context *ctx) +static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_connection *conn) { - struct ldap_connect_state *state = - talloc_get_type(ctx->async.private_data, - struct ldap_connect_state); - struct ldap_connection *conn = state->conn; - uint16_t port; - - state->ctx->status = socket_connect_multi_recv(ctx, state, &conn->sock, - &port); - if (!composite_is_ok(state->ctx)) return; - /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, socket_get_fd(conn->sock), EVENT_FD_READ, ldap_io_handler, conn); if (conn->event.fde == NULL) { - composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); + composite_error(ctx, NT_STATUS_INTERNAL_ERROR); return; } @@ -366,9 +392,42 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) packet_set_fde(conn->packet, conn->event.fde); packet_set_serialise(conn->packet); - composite_done(state->ctx); + composite_done(ctx); +} + +static void ldap_connect_recv_tcp_conn(struct composite_context *ctx) +{ + struct ldap_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct ldap_connect_state); + struct ldap_connection *conn = state->conn; + uint16_t port; + + NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock, + &port); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_error(state->ctx, status); + return; + } + + ldap_connect_got_sock(state->ctx, conn); +} + +static void ldap_connect_recv_unix_conn(struct composite_context *ctx) +{ + struct ldap_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct ldap_connect_state); + struct ldap_connection *conn = state->conn; + + NTSTATUS status = socket_connect_recv(ctx); + + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_error(state->ctx, status); + return; + } - return; + ldap_connect_got_sock(state->ctx, conn); } NTSTATUS ldap_connect_recv(struct composite_context *ctx) -- cgit From e21e8379a2ce9f3ca70227889c5c11a719516980 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 4 Sep 2006 01:59:23 +0000 Subject: r18024: The %c sscanf format I'm using doesn't null terminate. Andrew Bartlett (This used to be commit 1920cb8b3978f745cba7e854410deb9174de2dc0) --- source4/libcli/ldap/ldap_client.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 4fa8cc0146..bc230879fc 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -311,9 +311,12 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, if (!NT_STATUS_IS_OK(status)) { return NULL; } + talloc_steal(conn, conn->sock); SMB_ASSERT(sizeof(protocol)>10); SMB_ASSERT(sizeof(path)>1024); + /* The %c specifier doesn't null terminate :-( */ + ZERO_STRUCT(path); ret = sscanf(url, "%10[^:]://%1025c", protocol, path); if (ret < 2) { composite_error(state->ctx, NT_STATUS_INVALID_PARAMETER); -- cgit From 556aab78a0ff18505f7c8561586abc977adf8e43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 4 Sep 2006 03:59:04 +0000 Subject: r18025: Don't try to set a target host if there isn't one (such as with ldapi://). Andrew Bartlett (This used to be commit 556a21faeed0b6e3cc6efcfa8e0939b151a802de) --- source4/libcli/ldap/ldap_bind.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 4fdd87a25b..f617cbe102 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -236,11 +236,13 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } - status = gensec_set_target_hostname(conn->gensec, conn->host); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto failed; + if (conn->host) { + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto failed; + } } status = gensec_set_target_service(conn->gensec, "ldap"); -- cgit From 014f70008fcfdb631031c48aa9654ad5b42e62f9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Sep 2006 04:58:06 +0000 Subject: r18130: the move to system/ in libreplace broke some things ... should be happier now (This used to be commit 18542f184f75074e56a9793a9e3b6c6d747bb9e6) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 5a0b7e14dc..e43c39cf1b 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -8,6 +8,6 @@ OBJ_FILES = credentials.o \ smbencrypt.o \ smbdes.o PUBLIC_DEPENDENCIES = \ - SCHANNELDB MSRPC_PARSE + SCHANNELDB MSRPC_PARSE LIBREPLACE # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 46f3336fd1..ccc21d07df 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -41,6 +41,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h OBJ_FILES = nbt/nbtname.o +PUBLIC_DEPENDENCIES = LIBREPLACE [SUBSYSTEM::LIBCLI_NBT] #VERSION = 0.0.1 -- cgit From 1b5c28a627fa7d5f185537c85a43c7629273a2d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Sep 2006 09:49:34 +0000 Subject: r18211: wct is not a size, so don't use size_t this should fix a pile of printf format warnings (This used to be commit fe209e360e3857f39355335e4fa6a43b2db23038) --- source4/libcli/raw/request.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h index fedebf4c8d..689a5281ce 100644 --- a/source4/libcli/raw/request.h +++ b/source4/libcli/raw/request.h @@ -45,7 +45,7 @@ struct request_buffer { /* the command words and command word count. vwv points into the raw buffer */ uint8_t *vwv; - size_t wct; + uint_t wct; /* the data buffer and size. data points into the raw buffer */ uint8_t *data; -- cgit From a46e12d0e07e1630f8ef15aff0f97cb2f1f4c273 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Sep 2006 10:02:32 +0000 Subject: r18213: don't list LIBREPLACE depdendecies explicit and always at it as first private dependencies metze (This used to be commit 135d096776b53ae09ffc2b4f767dfbd18139570f) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index e43c39cf1b..5a0b7e14dc 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -8,6 +8,6 @@ OBJ_FILES = credentials.o \ smbencrypt.o \ smbdes.o PUBLIC_DEPENDENCIES = \ - SCHANNELDB MSRPC_PARSE LIBREPLACE + SCHANNELDB MSRPC_PARSE # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index ccc21d07df..46f3336fd1 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -41,7 +41,6 @@ PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h OBJ_FILES = nbt/nbtname.o -PUBLIC_DEPENDENCIES = LIBREPLACE [SUBSYSTEM::LIBCLI_NBT] #VERSION = 0.0.1 -- cgit From ed962c833bd37b05c1fadd1857b22b5566d7f850 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Sep 2006 03:06:47 +0000 Subject: r18243: when setting up a composite continuation, if the context has already finished when we need to trigger the continuation immediately. Via a fairly complex path, this fixes the problem where all hosts in the build farm that do not have ipv6 failed a lot of the RPC tests. This happened because the dcerpc_connect() async code used a composite_continue() on a context which was already in an error state, due to the socket backend saying that ipv6 was unavailable (This used to be commit dbf935d38b6b1fea5ed00e94c9b1a518cb14768b) --- source4/libcli/composite/composite.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index aea25f183e..e690c33f58 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -142,6 +142,13 @@ _PUBLIC_ void composite_continue(struct composite_context *ctx, if (composite_nomem(new_ctx, ctx)) return; new_ctx->async.fn = continuation; new_ctx->async.private_data = private_data; + + /* if we are setting up a continuation, and the context has + already finished, then we should run the callback with an + immediate event, otherwise we can be stuck forever */ + if (new_ctx->state >= COMPOSITE_STATE_DONE && continuation) { + event_add_timed(new_ctx->event_ctx, new_ctx, timeval_zero(), composite_trigger, new_ctx); + } } _PUBLIC_ void composite_continue_rpc(struct composite_context *ctx, -- cgit From d7534e0cc772b9aa0b7cdeb0ed4469e44173348f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Sep 2006 06:04:10 +0000 Subject: r18256: use the right status variable (This used to be commit f4b4bd945f5c3955aab0c3cf89ad6cdda7529dac) --- source4/libcli/ldap/ldap_client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index bc230879fc..da1ffcd317 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -405,10 +405,9 @@ static void ldap_connect_recv_tcp_conn(struct composite_context *ctx) struct ldap_connect_state); struct ldap_connection *conn = state->conn; uint16_t port; - NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock, &port); - if (!NT_STATUS_IS_OK(state->ctx->status)) { + if (!NT_STATUS_IS_OK(status)) { composite_error(state->ctx, status); return; } -- cgit From c2387587cb9c43c5f642554be9f08cc4ab0badc9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 02:12:09 +0000 Subject: r18280: more portability tidyups, ensuring we use libreplace everywhere (This used to be commit 4860d0256547b33709cdc109bdf7bb0310c2a5b6) --- source4/libcli/libcli.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index c104fcf80e..aee22e2693 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -22,7 +22,7 @@ #ifndef __LIBCLI_H__ #define __LIBCLI_H__ -#include +#include "core.h" #include "librpc/gen_ndr/nbt.h" /* -- cgit From 30ee8beb9316a99e8a49993306252591106cb349 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 10:05:58 +0000 Subject: r18301: I discovered how to load the warnings from a build farm build into emacs compile mode (hint, paste to a file, and compile as "cat filename"). This allowed me to fix nearly all the warnings for a IA_64 SuSE build very quickly. (This used to be commit eba6c84efff735bb0ca941ac4b755ce2b0591667) --- source4/libcli/raw/rawfile.c | 2 +- source4/libcli/smb2/smb2.h | 4 ++-- source4/libcli/wrepl/winsrepl.c | 9 ++++++--- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index f8b5e90e4b..3d2d407583 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -860,7 +860,7 @@ NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms) struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms) { struct smbcli_request *req; - uint16_t fnum; + uint16_t fnum=0; switch (parms->generic.level) { case RAW_FLUSH_FLUSH: diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 070eaf54ab..586acaccf6 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -204,12 +204,12 @@ struct smb2_request { uint16_t want_size = ((dynamic)?(size)+1:(size)); \ if (is_size < (size)) { \ DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \ - __location__, is_size, want_size)); \ + __location__, (unsigned)is_size, (unsigned)want_size)); \ return NT_STATUS_BUFFER_TOO_SMALL; \ }\ if (field_size != want_size) { \ DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \ - __location__, field_size, want_size)); \ + __location__, (unsigned)field_size, (unsigned)want_size)); \ return NT_STATUS_INVALID_PARAMETER; \ } \ } while (0) diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 83cbe2877d..78ee2d165e 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -88,7 +88,8 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) DATA_BLOB blob; if (!req) { - DEBUG(1,("Received unexpected WINS packet of length %u!\n", packet_blob_in.length)); + DEBUG(1,("Received unexpected WINS packet of length %u!\n", + (unsigned)packet_blob_in.length)); return NT_STATUS_INVALID_NETWORK_RESPONSE; } @@ -108,7 +109,8 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) } if (DEBUGLVL(10)) { - DEBUG(10,("Received WINS packet of length %u\n", packet_blob_in.length)); + DEBUG(10,("Received WINS packet of length %u\n", + (unsigned)packet_blob_in.length)); NDR_PRINT_DEBUG(wrepl_packet, req->packet); } @@ -489,7 +491,8 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, } if (DEBUGLVL(10)) { - DEBUG(10,("Sending WINS packet of length %u\n", blob.length)); + DEBUG(10,("Sending WINS packet of length %u\n", + (unsigned)blob.length)); NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet); } -- cgit From e91cee468eceb6ff8843bafc7fbb22a21b52a00c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 12:57:45 +0000 Subject: r18309: FreeBSD 6.1 has a symbol ldap_new_connection() in the system ldap library. Even though we don't like to that library, it gets loaded via nss-ldap, which means nss-ldap calls into the samba ldap lib with the wrong parameters, and crashes. We really need to use a completely different namespace in libcli/ldap/ (This used to be commit c440e0eed9afae5fe69995a7416971e7c8560779) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index da1ffcd317..7bb4d0c79a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -40,7 +40,7 @@ /* create a new ldap_connection stucture. The event context is optional */ -struct ldap_connection *ldap_new_connection(TALLOC_CTX *mem_ctx, +struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, struct event_context *ev) { struct ldap_connection *conn; -- cgit From f3fd73ed52349a75890c30a7dfac72fa20618e3a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 18 Sep 2006 20:44:54 +0000 Subject: r18633: Add a couple of new WERR codes encountered with dfs torture testing. Guenther (This used to be commit e2879f6fc21e5ca96b24ed11e4a460a0ebada8c3) --- source4/libcli/util/doserr.c | 7 ++++++- source4/libcli/util/doserr.h | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index c7d7053165..c0a4e2cb96 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -36,9 +36,10 @@ static const struct werror_code_struct dos_errs[] = { "WERR_BADFID", WERR_BADFID }, { "WERR_BADFUNC", WERR_BADFUNC }, { "WERR_BAD_NETPATH", WERR_BAD_NETPATH }, + { "WERR_UNEXP_NET_ERR", WERR_UNEXP_NET_ERR }, { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, - { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, + { "WERR_FILE_EXISTS", WERR_FILE_EXISTS }, { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, { "WERR_NOT_SUPPORTED", WERR_NOT_SUPPORTED }, { "WERR_BAD_PASSWORD", WERR_BAD_PASSWORD }, @@ -46,6 +47,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_NAME", WERR_INVALID_NAME }, { "WERR_UNKNOWN_LEVEL", WERR_UNKNOWN_LEVEL }, { "WERR_OBJECT_PATH_INVALID", WERR_OBJECT_PATH_INVALID }, + { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, { "WERR_NO_MORE_ITEMS", WERR_NO_MORE_ITEMS }, { "WERR_MORE_DATA", WERR_MORE_DATA }, { "WERR_UNKNOWN_PRINTER_DRIVER", WERR_UNKNOWN_PRINTER_DRIVER }, @@ -55,10 +57,12 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_ENVIRONMENT", WERR_INVALID_ENVIRONMENT }, { "WERR_INVALID_FORM_NAME", WERR_INVALID_FORM_NAME }, { "WERR_INVALID_FORM_SIZE", WERR_INVALID_FORM_SIZE }, + { "WERR_ALREADY_SHARED", WERR_ALREADY_SHARED }, { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES", WERR_STATUS_MORE_ENTRIES }, { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, @@ -97,6 +101,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE }, + { "WERR_NOT_FOUND", WERR_NOT_FOUND }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 32807da47c..d80cdd1052 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -174,19 +174,22 @@ #define WERR_GENERAL_FAILURE W_ERROR(31) #define WERR_NOT_SUPPORTED W_ERROR(50) #define WERR_BAD_NETPATH W_ERROR(53) +#define WERR_UNEXP_NET_ERR W_ERROR(59) #define WERR_PRINTQ_FULL W_ERROR(61) #define WERR_NO_SPOOL_SPACE W_ERROR(62) #define WERR_NO_SUCH_SHARE W_ERROR(67) -#define WERR_ALREADY_EXISTS W_ERROR(80) +#define WERR_FILE_EXISTS W_ERROR(80) #define WERR_BAD_PASSWORD W_ERROR(86) #define WERR_INVALID_PARAM W_ERROR(87) #define WERR_INSUFFICIENT_BUFFER W_ERROR(122) #define WERR_INVALID_NAME W_ERROR(123) #define WERR_UNKNOWN_LEVEL W_ERROR(124) #define WERR_OBJECT_PATH_INVALID W_ERROR(161) +#define WERR_ALREADY_EXISTS W_ERROR(183) #define WERR_NO_MORE_ITEMS W_ERROR(259) #define WERR_MORE_DATA W_ERROR(234) #define WERR_CAN_NOT_COMPLETE W_ERROR(1003) +#define WERR_NOT_FOUND W_ERROR(1168) #define WERR_INVALID_COMPUTERNAME W_ERROR(1210) #define WERR_INVALID_DOMAINNAME W_ERROR(1212) #define WERR_UNKNOWN_REVISION W_ERROR(1305) @@ -200,10 +203,12 @@ #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) #define WERR_INVALID_FORM_NAME W_ERROR(1902) #define WERR_INVALID_FORM_SIZE W_ERROR(1903) +#define WERR_ALREADY_SHARED W_ERROR(2118) #define WERR_BUF_TOO_SMALL W_ERROR(2123) #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) +#define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) #define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) #define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled) -- cgit From 19f9b91d288c781e71539804467c9c9726e1060d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Sep 2006 16:33:25 +0000 Subject: r18715: 0x8 style status returns should also fail here (thanks metze) (This used to be commit f55de25ab30f9270bbd139dc1e683101db1069c8) --- source4/libcli/smb2/read.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index eb935fb4f1..272bc82882 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -56,7 +56,7 @@ NTSTATUS smb2_read_recv(struct smb2_request *req, NTSTATUS status; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } -- cgit From 921f73c7e58eac1900eb7ec9f7276cd3afaf0480 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 23 Sep 2006 02:19:15 +0000 Subject: r18835: expand IO limits on SMB2. Samba4 now tops out at 16.7MB IOs. (This used to be commit 1e34e4d5a1fd3d74080424140e4ab276b6042d12) --- source4/libcli/raw/interfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d3e7611c75..c2f0c3530b 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1589,7 +1589,7 @@ union smb_read { uint8_t *data; uint16_t remaining; uint16_t compaction_mode; - uint16_t nread; + uint32_t nread; } out; } readx, generic; -- cgit From 333557e28fc1c1934756b96f08711e050568926f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 23 Sep 2006 19:04:39 +0000 Subject: r18847: Add WERR_NO_SYSTEM_RESOURCES showing up in dfs torture testing. Guenther (This used to be commit 692746ff8d1352a93a19ba9d537ca894a2ea186f) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index c0a4e2cb96..ed1700aeb0 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -82,6 +82,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_PRIVILEGE_NOT_HELD", WERR_PRIVILEGE_NOT_HELD }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, + { "WERR_NO_SYSTEM_RESOURCES", WERR_NO_SYSTEM_RESOURCES }, { "WERR_DS_SERVICE_BUSY", WERR_DS_SERVICE_BUSY }, { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index d80cdd1052..d5a6b2e90d 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -200,6 +200,7 @@ #define WERR_NO_SUCH_USER W_ERROR(1317) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) #define WERR_NO_SUCH_DOMAIN W_ERROR(1355) +#define WERR_NO_SYSTEM_RESOURCES W_ERROR(1450) #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) #define WERR_INVALID_FORM_NAME W_ERROR(1902) #define WERR_INVALID_FORM_SIZE W_ERROR(1903) -- cgit From a0c614ede22e629eea267b54d3b1852fe9cc2aad Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Sep 2006 11:27:09 +0000 Subject: r18916: fixed the messaging layer on *BSD systems. When a socket was full we were getting ENOBUFS, which mapped to NT_STATUS_NO_MEMORY, which in turn caused the messaging code to loop trying until it gave up. Now it correctly falls back to select. Messaging speed goes from 3 messages per second to over 7000 on my test vmware box. Not bad for a one line change :) (This used to be commit 6568f30adf980c572f9ffd6ff884336ebe652f90) --- source4/libcli/util/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index e6a1c0e71c..2ff9803d39 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1278,7 +1278,7 @@ const struct unix_error_map unix_nt_errmap[] = { { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, { EFAULT, NT_STATUS_INVALID_PARAMETER }, { EMSGSIZE, NT_STATUS_INVALID_BUFFER_SIZE }, - { ENOBUFS, NT_STATUS_NO_MEMORY }, + { ENOBUFS, STATUS_MORE_ENTRIES }, { ENOMEM, NT_STATUS_NO_MEMORY }, { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, -- cgit From f3d684a48c1339a8df4fb5b8e79b194a1752bb7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Sep 2006 23:24:36 +0000 Subject: r18965: fixed the bug with RPC-NETLOGON and solaris sparc machines. This bug took a _LONG_ time to find. The problem was that when encoding/decoding password buffers we use the pull/push string functions, which by default align unicode strings. But on solaris sparc the buffer is not aligned always (its a stack variable, an array of uint8_t). That perfectly OK in C, so we just tell the pull/push functions not to auto-align. (This used to be commit bb7835eced00607eb6b1725be6d96a6dcb842049) --- source4/libcli/auth/smbencrypt.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 9fce590d43..67da795a44 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -460,6 +460,9 @@ BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag uint8_t new_pw[512]; size_t new_pw_len; + /* the incoming buffer can be any alignment. */ + string_flags |= STR_NOALIGN; + new_pw_len = push_string(new_pw, password, sizeof(new_pw), string_flags); @@ -489,6 +492,9 @@ BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, { int byte_len=0; + /* the incoming buffer can be any alignment. */ + string_flags |= STR_NOALIGN; + /* Warning !!! : This function is called from some rpc call. The password IN the buffer may be a UNICODE string. -- cgit From bbe3cffb4b86439cccb39471ca386ee9321239ae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Sep 2006 01:17:16 +0000 Subject: r18968: EWOULDBLOCK should also be mapped to STATUS_MORE_ENTRIES (This used to be commit 27114fe1752f20c58948b34264e38db263f7a0ea) --- source4/libcli/util/errormap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 2ff9803d39..1e90969f95 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1262,6 +1262,10 @@ struct unix_error_map { const struct unix_error_map unix_nt_errmap[] = { { EAGAIN, STATUS_MORE_ENTRIES }, { EINTR, STATUS_MORE_ENTRIES }, + { ENOBUFS, STATUS_MORE_ENTRIES }, +#ifdef EWOULDBLOCK + { EWOULDBLOCK, STATUS_MORE_ENTRIES }, +#endif { EINPROGRESS, NT_STATUS_MORE_PROCESSING_REQUIRED }, { EPERM, NT_STATUS_ACCESS_DENIED }, { EACCES, NT_STATUS_ACCESS_DENIED }, @@ -1278,7 +1282,6 @@ const struct unix_error_map unix_nt_errmap[] = { { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, { EFAULT, NT_STATUS_INVALID_PARAMETER }, { EMSGSIZE, NT_STATUS_INVALID_BUFFER_SIZE }, - { ENOBUFS, STATUS_MORE_ENTRIES }, { ENOMEM, NT_STATUS_NO_MEMORY }, { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, -- cgit From 318682b00377605a26d0b7fd4b59713c6c429b81 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Sep 2006 06:44:47 +0000 Subject: r18971: avoid strndup is a few places. Fixes a minor memory leak, and should fix RPC-LSA on AIX. (This used to be commit 6cce709d08579f4e00b44b692332a557b0ea3b86) --- source4/libcli/auth/session.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 280a0d282c..430eecd78f 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -97,7 +97,8 @@ DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key) caller should free the returned string */ -char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) +char *sess_decrypt_string(TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, const DATA_BLOB *session_key) { DATA_BLOB out; int slen; @@ -107,7 +108,7 @@ char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) return NULL; } - out = data_blob(NULL, blob->length); + out = data_blob_talloc(mem_ctx, NULL, blob->length); if (!out.data) { return NULL; } @@ -117,19 +118,23 @@ char *sess_decrypt_string(DATA_BLOB *blob, const DATA_BLOB *session_key) if (IVAL(out.data, 4) != 1) { DEBUG(0,("Unexpected revision number %d in session crypted string\n", IVAL(out.data, 4))); + data_blob_free(&out); return NULL; } slen = IVAL(out.data, 0); if (slen > blob->length - 8) { DEBUG(0,("Invalid crypt length %d\n", slen)); + data_blob_free(&out); return NULL; } - ret = strndup((const char *)(out.data+8), slen); + ret = talloc_strndup(mem_ctx, (const char *)(out.data+8), slen); data_blob_free(&out); + DEBUG(0,("decrypted string '%s' of length %d\n", ret, slen)); + return ret; } -- cgit From 31454d2e8b70f7aca87099dba25abe790781c7a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Sep 2006 04:45:15 +0000 Subject: r18989: Fixes found by these two LDAP testsuites: - http://www.ee.oulu.fi/research/ouspg/protos/testing/c06/ldapv3/ - http://gleg.net/protover_ldap_sample.shtml Also fixes found by a subsequent audit of the code for similar issues. (This used to be commit 441a4f6262459dabfefd9bb12622ada9c007a60c) --- source4/libcli/ldap/ldap.c | 25 +++++++++++++++++++++---- source4/libcli/util/asn1.c | 23 ++++++++++++++++++++++- 2 files changed, 43 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6a0b86f78b..5a7174b41d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -949,8 +949,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->mechanism = LDAP_AUTH_MECH_SIMPLE; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return False; + } if (pwlen != 0) { char *pw = talloc_size(msg, pwlen+1); + if (!pw) { + return False; + } asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -974,6 +980,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->creds.SASL.secblob = NULL; } asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return False; } asn1_end_tag(data); break; @@ -1096,8 +1105,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) ldap_decode_attrib(msg, data, &mod.attrib); asn1_end_tag(data); if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) - break; + &r->mods, &r->num_mods)) { + return False; + } } asn1_end_tag(data); @@ -1146,6 +1156,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); + if (len == -1) { + return False; + } dn = talloc_size(msg, len+1); if (dn == NULL) break; @@ -1179,9 +1192,13 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); + if (len == -1) { + return False; + } newsup = talloc_size(msg, len+1); - if (newsup == NULL) - break; + if (newsup == NULL) { + return False; + } asn1_read(data, newsup, len); newsup[len] = '\0'; r->newsuperior = newsup; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index db3f7823fa..01c869dc17 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -396,6 +396,9 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) nesting->start = data->ofs; nesting->next = data->nesting; data->nesting = nesting; + if (asn1_tag_remaining(data) == -1) { + return False; + } return !data->has_error; } @@ -426,11 +429,21 @@ BOOL asn1_end_tag(struct asn1_data *data) /* work out how many bytes are left in this nested tag */ int asn1_tag_remaining(struct asn1_data *data) { + int remaining; + if (data->has_error) { + return -1; + } + if (!data->nesting) { data->has_error = True; return -1; } - return data->nesting->taglen - (data->ofs - data->nesting->start); + remaining = data->nesting->taglen - (data->ofs - data->nesting->start); + if (remaining > (data->length - data->ofs)) { + data->has_error = True; + return -1; + } + return remaining; } /* read an object ID from a ASN1 buffer */ @@ -518,6 +531,10 @@ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) return False; } *blob = data_blob(NULL, len+1); + if (!blob->data) { + data->has_error = True; + return False; + } asn1_read(data, blob->data, len); asn1_end_tag(data); blob->length--; @@ -542,6 +559,10 @@ BOOL asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blo return False; } *blob = data_blob(NULL, len); + if (!blob->data) { + data->has_error = True; + return False; + } asn1_read(data, blob->data, len); asn1_end_tag(data); return !data->has_error; -- cgit From 7c793e1bb74593357708e92dba6a99d89ac77c59 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 7 Oct 2006 05:28:14 +0000 Subject: r19162: Merge WERR code from Samba 3. Guenther (This used to be commit d9562e0f83d76043da7955e89b1fff8a1d921a36) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index ed1700aeb0..fe2b555ab6 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -78,6 +78,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_INVALID_COMPUTERNAME", WERR_INVALID_COMPUTERNAME }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, + { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_PRIVILEGE", WERR_NO_SUCH_PRIVILEGE }, { "WERR_PRIVILEGE_NOT_HELD", WERR_PRIVILEGE_NOT_HELD }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index d5a6b2e90d..0e1bcd4499 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -195,6 +195,7 @@ #define WERR_UNKNOWN_REVISION W_ERROR(1305) #define WERR_REVISION_MISMATCH W_ERROR(1306) #define WERR_INVALID_OWNER W_ERROR(1307) +#define WERR_NO_LOGON_SERVERS W_ERROR(1311) #define WERR_NO_SUCH_PRIVILEGE W_ERROR(1313) #define WERR_PRIVILEGE_NOT_HELD W_ERROR(1314) #define WERR_NO_SUCH_USER W_ERROR(1317) -- cgit From 5c4626504872ce1d0eb3f48f7162b607119b7e09 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 9 Oct 2006 11:19:30 +0000 Subject: r19200: Implement smbcli_rap_netservergetinfo. To be used in RPC-SAMBA3SPOOLSS and others that might need the server name. Volker (This used to be commit 03eaf0edf9f8a6d70375f9f12810b4fbb860290a) --- source4/libcli/rap/rap.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/rap/rap.h b/source4/libcli/rap/rap.h index c831f6f007..46bce225ff 100644 --- a/source4/libcli/rap/rap.h +++ b/source4/libcli/rap/rap.h @@ -343,3 +343,17 @@ struct rap_NetServerEnum2 { union rap_server_info *info; } out; }; + +struct rap_WserverGetInfo { + struct { + uint16_t level; + uint16_t bufsize; + } in; + + struct { + uint16_t status; + uint16_t convert; + uint16_t available; + union rap_server_info info; + } out; +}; -- cgit From 95424817274295c56da3d3a5dc1ba3b2d75b0f8d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 23 Oct 2006 06:06:35 +0000 Subject: r19464: Reject passwords that cannot be converted into UCS2. Andrew Bartlett (This used to be commit c843fce7a0e9b91c4d2de44e7a9ad9599b33ec5c) --- source4/libcli/auth/smbencrypt.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 67da795a44..296d44f5d4 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -63,18 +63,24 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -void E_md4hash(const char *passwd, uint8_t p16[16]) +BOOL E_md4hash(const char *passwd, uint8_t p16[16]) { int len; void *wpwd; len = push_ucs2_talloc(NULL, &wpwd, passwd); - SMB_ASSERT(len >= 2); + if (len < 2) { + /* We don't want to return fixed data, as most callers + * don't check */ + mdfour(p16, passwd, strlen(passwd)); + return False; + } len -= 2; mdfour(p16, wpwd, len); talloc_free(wpwd); + return True; } /** -- cgit From 9b97c4d02e5391f5e5df10468c3a5f428e49d955 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Oct 2006 16:14:00 +0000 Subject: r19480: - clear the whole session struct (only let the pid untouched) - zero state struct metze (This used to be commit 97fb407a4cfcf71e95663e437cb7f638ac4028fc) --- source4/libcli/smb_composite/connect.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 7d4960d7d5..fc788d5d31 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -179,6 +179,9 @@ static NTSTATUS connect_session_setup(struct composite_context *c, * have been given a uid in the NTLMSSP_CHALLENGE reply. This * would lead to an invalid uid in the anonymous fallback */ state->session->vuid = 0; + data_blob_free(&state->session->user_session_key); + talloc_free(state->session->gensec); + state->session->gensec = NULL; state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); @@ -441,7 +444,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) goto failed; - state = talloc(c, struct connect_state); + state = talloc_zero(c, struct connect_state); if (state == NULL) goto failed; if (event_ctx == NULL) { -- cgit From 827d142e9df24f135d36d3981a1a9eaf679ecc8c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Oct 2006 16:16:31 +0000 Subject: r19481: - reset the vuid before trying a new session setup - only touch session->vuid when needed - it make no sense to set an .spnego.out.vuid metze (This used to be commit 1940fbed154c89d29214ddf293128a70a97bf923) --- source4/libcli/smb_composite/sesssetup.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 022faea1d7..d264f588da 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -80,6 +80,8 @@ static void request_handler(struct smbcli_request *req) /* This doesn't work, as this only happens on old * protocols, where this comparison won't match. */ if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { + /* we neet to reset the vuid for a new try */ + session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_old(c, session, state->io, @@ -97,6 +99,8 @@ static void request_handler(struct smbcli_request *req) case RAW_SESSSETUP_NT1: state->io->out.vuid = state->setup.nt1.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { + /* we neet to reset the vuid for a new try */ + session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_nt1(c, session, state->io, @@ -112,8 +116,10 @@ static void request_handler(struct smbcli_request *req) break; case RAW_SESSSETUP_SPNEGO: - session->vuid = state->io->out.vuid = state->setup.spnego.out.vuid; + state->io->out.vuid = state->setup.spnego.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { + /* we neet to reset the vuid for a new try */ + session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_spnego(c, session, state->io, @@ -160,7 +166,14 @@ static void request_handler(struct smbcli_request *req) } if (state->setup.spnego.in.secblob.length) { + /* + * set the session->vuid value only for calling + * smb_raw_sesssetup_send() + */ + uint16_t vuid = session->vuid; + session->vuid = state->io->out.vuid; state->req = smb_raw_sesssetup_send(session, &state->setup); + session->vuid = vuid; state->req->async.fn = request_handler; state->req->async.private = c; return; @@ -343,8 +356,6 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, state->setup.spnego.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); state->setup.spnego.in.workgroup = io->in.workgroup; - state->setup.spnego.out.vuid = session->vuid; - smbcli_temp_set_signing(session->transport); status = gensec_client_start(session, &session->gensec, c->event_ctx); -- cgit From 4fa24df98ded939c68bdc95e9f09334caeeb84af Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 29 Oct 2006 17:40:19 +0000 Subject: r19507: Merge my DSO fixes branch. Building Samba's libraries as shared libraries works again now, by specifying --enable-dso to configure. (This used to be commit 7a01235067a4800b07b8919a6a475954bfb0b04c) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7bb4d0c79a..2c2cd0dd66 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -432,7 +432,7 @@ static void ldap_connect_recv_unix_conn(struct composite_context *ctx) ldap_connect_got_sock(state->ctx, conn); } -NTSTATUS ldap_connect_recv(struct composite_context *ctx) +_PUBLIC_ NTSTATUS ldap_connect_recv(struct composite_context *ctx) { NTSTATUS status = composite_wait(ctx); talloc_free(ctx); -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/libcli/auth/libcli_auth.h | 2 +- source4/libcli/config.mk | 2 +- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/smb_composite/sesssetup.c | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/libcli_auth.h b/source4/libcli/auth/libcli_auth.h index f8f07e8337..e6e00568ff 100644 --- a/source4/libcli/auth/libcli_auth.h +++ b/source4/libcli/auth/libcli_auth.h @@ -19,7 +19,7 @@ #define __LIBCLI_AUTH_H__ #include "librpc/gen_ndr/netlogon.h" -#include "auth/credentials/credentials.h" +#include "libcli/auth/credentials.h" #include "libcli/auth/proto.h" #endif /* __LIBCLI_AUTH_H__ */ diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 46f3336fd1..a64f41dbf4 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -36,7 +36,7 @@ OBJ_FILES = \ smb_composite/fetchfile.o \ smb_composite/appendacl.o \ smb_composite/fsinfo.o -PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE +PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index f617cbe102..c4c731e4f5 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -26,7 +26,7 @@ #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" -#include "auth/auth.h" +#include "auth/gensec/gensec.h" #include "auth/gensec/socket.h" #include "lib/stream/packet.h" diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index d264f588da..8528ac2ef7 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -27,6 +27,8 @@ #include "libcli/smb_composite/smb_composite.h" #include "libcli/auth/libcli_auth.h" #include "auth/auth.h" +#include "auth/gensec/gensec.h" +#include "auth/credentials/credentials.h" #include "version.h" struct sesssetup_state { -- cgit From d5314b9f3f8b27ea0f9efdf3fad27fd349a1adf3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Nov 2006 21:18:24 +0000 Subject: r19638: convert resolve.c to the new composite api metze (This used to be commit 617f9c70c1b61e0fd4338048bbd94e7a4722ad9d) --- source4/libcli/resolve/resolve.c | 42 ++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 8bacab8cd7..532cf19bb4 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -123,49 +123,45 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ { struct composite_context *c; struct resolve_state *state; - NTSTATUS status; - - c = talloc_zero(NULL, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct resolve_state); - if (state == NULL) goto failed; - - status = nbt_name_dup(state, name, &state->name); - if (!NT_STATUS_IS_OK(status)) goto failed; - if (methods == NULL) goto failed; - state->methods = str_list_copy(state, methods); - if (state->methods == NULL) goto failed; + c = composite_create(event_ctx, event_ctx); + if (c == NULL) return NULL; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->private_data = state; + if (methods == NULL) { + composite_error(c, NT_STATUS_INVALID_PARAMETER); + return c; + } if (event_ctx == NULL) { c->event_ctx = event_context_init(c); - if (c->event_ctx == NULL) goto failed; - } else { c->event_ctx = talloc_reference(c, event_ctx); } + if (composite_nomem(c->event_ctx, c)) return c; + + state = talloc(c, struct resolve_state); + if (composite_nomem(state, c)) return c; + c->private_data = state; + + c->status = nbt_name_dup(state, name, &state->name); + if (!composite_is_ok(c)) return c; + + state->methods = str_list_copy(state, methods); + if (composite_nomem(state->methods, c)) return c; if (is_ipaddress(state->name.name) || strcasecmp(state->name.name, "localhost") == 0) { struct ipv4_addr ip = interpret_addr2(state->name.name); state->reply_addr = talloc_strdup(state, sys_inet_ntoa(ip)); - if (!state->reply_addr) goto failed; + if (composite_nomem(state->reply_addr, c)) return c; composite_done(c); return c; } state->creq = setup_next_method(c); - if (state->creq == NULL) goto failed; + if (composite_nomem(state->creq, c)) return c; return c; - -failed: - talloc_free(c); - return NULL; } /* -- cgit From 3bc459f813f24a96e273be893023a92a3fc2c2d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Nov 2006 21:20:45 +0000 Subject: r19639: convert nbtlist.c to new composite api metze (This used to be commit 800999733eb2f35486a62fb8fa9d179c8ca312fa) --- source4/libcli/resolve/nbtlist.c | 99 ++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 55 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 9d7035c26d..df76ec66a5 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -48,6 +48,7 @@ static void nbtlist_handler(struct nbt_name_request *req) struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state); + struct nbt_name_query *q; int i; for (i=0;inum_queries;i++) { @@ -56,46 +57,39 @@ static void nbtlist_handler(struct nbt_name_request *req) if (i == state->num_queries) { /* not for us?! */ - c->status = NT_STATUS_INTERNAL_ERROR; - c->state = COMPOSITE_STATE_ERROR; - goto done; + composite_error(c, NT_STATUS_INTERNAL_ERROR); + return; } - c->status = nbt_name_query_recv(req, state, &state->io_queries[i]); - if (!NT_STATUS_IS_OK(c->status)) { - c->state = COMPOSITE_STATE_ERROR; - - } else { - if (state->io_queries[i].out.num_addrs < 1) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - - } else { - struct nbt_name_query *q = &state->io_queries[i]; - c->state = COMPOSITE_STATE_DONE; - /* favor a local address if possible */ - state->reply_addr = NULL; - - for (i=0;iout.num_addrs;i++) { - if (iface_is_local(q->out.reply_addrs[i])) { - state->reply_addr = talloc_steal(state, - q->out.reply_addrs[i]); - break; - } - } - - if (state->reply_addr == NULL) { - state->reply_addr = talloc_steal(state, - q->out.reply_addrs[0]); - } + q = &state->io_queries[i]; + + c->status = nbt_name_query_recv(req, state, q); + + /* free the network resource directly */ + talloc_free(state->nbtsock); + if (!composite_is_ok(c)) return; + + if (state->io_queries[i].out.num_addrs < 1) { + composite_error(c, NT_STATUS_UNEXPECTED_NETWORK_ERROR); + return; + } + + /* favor a local address if possible */ + state->reply_addr = NULL; + for (i=0;iout.num_addrs;i++) { + if (iface_is_local(q->out.reply_addrs[i])) { + state->reply_addr = talloc_steal(state, + q->out.reply_addrs[i]); + break; } } -done: - talloc_free(state->nbtsock); - if (c->async.fn) { - c->async.fn(c); + if (state->reply_addr == NULL) { + state->reply_addr = talloc_steal(state, + q->out.reply_addrs[0]); } + + composite_done(c); } /* @@ -110,41 +104,44 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, struct composite_context *c; struct nbtlist_state *state; int i; - NTSTATUS status; - c = talloc_zero(NULL, struct composite_context); - if (c == NULL) goto failed; + c = composite_create(event_ctx, event_ctx); + if (c == NULL) return NULL; + + c->event_ctx = talloc_reference(c, event_ctx); + if (composite_nomem(c->event_ctx, c)) return c; state = talloc(c, struct nbtlist_state); - if (state == NULL) goto failed; + if (composite_nomem(state, c)) return c; + c->private_data = state; - status = nbt_name_dup(state, name, &state->name); - if (!NT_STATUS_IS_OK(status)) goto failed; + c->status = nbt_name_dup(state, name, &state->name); + if (!composite_is_ok(c)) return c; state->name.name = strupper_talloc(state, state->name.name); - if (state->name.name == NULL) goto failed; + if (composite_nomem(state->name.name, c)) return c; if (state->name.scope) { state->name.scope = strupper_talloc(state, state->name.scope); - if (state->name.scope == NULL) goto failed; + if (composite_nomem(state->name.scope, c)) return c; } state->nbtsock = nbt_name_socket_init(state, event_ctx); - if (state->nbtsock == NULL) goto failed; + if (composite_nomem(state->nbtsock, c)) return c; /* count the address_list size */ for (i=0;address_list[i];i++) /* noop */ ; state->num_queries = i; state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries); - if (!state->io_queries) goto failed; + if (composite_nomem(state->io_queries, c)) return c; state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries); - if (!state->queries) goto failed; + if (composite_nomem(state->queries, c)) return c; for (i=0;inum_queries;i++) { state->io_queries[i].in.name = state->name; state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); - if (!state->io_queries[i].in.dest_addr) goto failed; + if (composite_nomem(state->io_queries[i].in.dest_addr, c)) return c; state->io_queries[i].in.broadcast = broadcast; state->io_queries[i].in.wins_lookup = wins_lookup; @@ -152,21 +149,13 @@ struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, state->io_queries[i].in.retries = 2; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); - if (!state->queries[i]) goto failed; + if (composite_nomem(state->queries[i], c)) return c; state->queries[i]->async.fn = nbtlist_handler; state->queries[i]->async.private = c; } - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->private_data = state; - c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx); - return c; - -failed: - talloc_free(c); - return NULL; } /* -- cgit From c71152180c6e65e1492e41e9c2ea61b37f4f8df1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Nov 2006 22:33:22 +0000 Subject: r19642: convert host.c to new composite api metze (This used to be commit a5d36a6ddefb8c24e748b839391241da41e31440) --- source4/libcli/resolve/host.c | 61 ++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 35 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 18188f7c1c..5f99a85268 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -99,31 +99,23 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, relationship, and even if they did then giving an error is the right thing to do */ ret = read(state->child_fd, address, sizeof(address)-1); - if (ret <= 0) goto failed; + if (ret <= 0) { + composite_error(c, NT_STATUS_BAD_NETWORK_NAME); + return; + } /* enusre the address looks good */ address[ret] = 0; if (strcmp(address, "0.0.0.0") == 0 || inet_addr(address) == INADDR_NONE) { - goto failed; + composite_error(c, NT_STATUS_BAD_NETWORK_NAME); + return; } state->reply_addr = talloc_strdup(state, address); - if (state->reply_addr == NULL) goto failed; - - c->status = NT_STATUS_OK; - c->state = COMPOSITE_STATE_DONE; - if (c->async.fn) { - c->async.fn(c); - } - return; + if (composite_nomem(state->reply_addr, c)) return; -failed: - c->status = NT_STATUS_BAD_NETWORK_NAME; - c->state = COMPOSITE_STATE_ERROR; - if (c->async.fn) { - c->async.fn(c); - } + composite_done(c); } /* @@ -134,26 +126,28 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, { struct composite_context *c; struct host_state *state; - NTSTATUS status; int fd[2] = { -1, -1 }; int ret; - c = talloc_zero(NULL, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct host_state); - if (state == NULL) goto failed; + c = composite_create(event_ctx, event_ctx); + if (c == NULL) return NULL; - status = nbt_name_dup(state, name, &state->name); - if (!NT_STATUS_IS_OK(status)) goto failed; + c->event_ctx = talloc_reference(c, event_ctx); + if (composite_nomem(c->event_ctx, c)) return c; - c->state = COMPOSITE_STATE_IN_PROGRESS; + state = talloc(c, struct host_state); + if (composite_nomem(state, c)) return c; c->private_data = state; - c->event_ctx = talloc_reference(c, event_ctx); + + c->status = nbt_name_dup(state, name, &state->name); + if (!composite_is_ok(c)) return c; /* setup a pipe to chat to our child */ ret = pipe(fd); - if (ret == -1) goto failed; + if (ret == -1) { + composite_error(c, map_nt_error_from_unix(errno)); + return c; + } state->child_fd = fd[0]; state->event_ctx = c->event_ctx; @@ -162,10 +156,10 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, we know when the gethostbyname() has finished */ state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ, pipe_handler, c); - if (state->fde == NULL) { + if (composite_nomem(state->fde, c)) { close(fd[0]); close(fd[1]); - goto failed; + return c; } /* signal handling in posix really sucks - doing this in a library @@ -174,7 +168,8 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, state->child = fork(); if (state->child == (pid_t)-1) { - goto failed; + composite_error(c, map_nt_error_from_unix(errno)); + return c; } if (state->child == 0) { @@ -187,11 +182,7 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, /* cleanup wayward children */ talloc_set_destructor(state, host_destructor); - return c; - -failed: - talloc_free(c); - return NULL; + return c; } /* -- cgit From fe2a5a8abf3e1fb916e49700c5293eb91f9524ed Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Nov 2006 01:11:45 +0000 Subject: r19645: don't pass NULL as mem_ctx... metze (This used to be commit 643a38bc30a0df1582035b8d264e0dbbc2d2e152) --- source4/libcli/resolve/bcast.c | 11 ++++++----- source4/libcli/resolve/host.c | 13 ++++++++----- source4/libcli/resolve/nbtlist.c | 15 ++++++++------- source4/libcli/resolve/resolve.c | 4 ++-- source4/libcli/resolve/wins.c | 11 ++++++----- 5 files changed, 30 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 8824ad395e..ba07670ced 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -28,15 +28,16 @@ /* broadcast name resolution method - async send */ -struct composite_context *resolve_name_bcast_send(struct nbt_name *name, - struct event_context *event_ctx) +struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct nbt_name *name) { int num_interfaces = iface_count(); const char **address_list; struct composite_context *c; int i, count=0; - address_list = talloc_array(NULL, const char *, num_interfaces+1); + address_list = talloc_array(mem_ctx, const char *, num_interfaces+1); if (address_list == NULL) return NULL; for (i=0;ievent_ctx = talloc_reference(c, event_ctx); @@ -172,6 +174,7 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, return c; } + if (state->child == 0) { close(fd[0]); run_child(c, fd[1]); @@ -189,7 +192,7 @@ struct composite_context *resolve_name_host_send(struct nbt_name *name, gethostbyname name resolution method - recv side */ NTSTATUS resolve_name_host_recv(struct composite_context *c, - TALLOC_CTX *mem_ctx, const char **reply_addr) + TALLOC_CTX *mem_ctx, const char **reply_addr) { NTSTATUS status; @@ -211,7 +214,7 @@ NTSTATUS resolve_name_host(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct composite_context *c = resolve_name_host_send(name, NULL); + struct composite_context *c = resolve_name_host_send(mem_ctx, NULL, name); return resolve_name_host_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index df76ec66a5..58433d0a70 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -95,11 +95,12 @@ static void nbtlist_handler(struct nbt_name_request *req) /* nbtlist name resolution method - async send */ -struct composite_context *resolve_name_nbtlist_send(struct nbt_name *name, - struct event_context *event_ctx, - const char **address_list, - BOOL broadcast, - BOOL wins_lookup) +struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct nbt_name *name, + const char **address_list, + BOOL broadcast, + BOOL wins_lookup) { struct composite_context *c; struct nbtlist_state *state; @@ -186,8 +187,8 @@ NTSTATUS resolve_name_nbtlist(struct nbt_name *name, BOOL broadcast, BOOL wins_lookup, const char **reply_addr) { - struct composite_context *c = resolve_name_nbtlist_send(name, NULL, address_list, - broadcast, wins_lookup); + struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL, name, address_list, + broadcast, wins_lookup); return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 532cf19bb4..5e37fec42b 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -38,7 +38,7 @@ static struct composite_context *setup_next_method(struct composite_context *c); /* pointers to the resolver backends */ static const struct resolve_method { const char *name; - struct composite_context *(*send_fn)(struct nbt_name *, struct event_context *); + struct composite_context *(*send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, struct nbt_name *); NTSTATUS (*recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); } resolve_methods[] = { @@ -101,7 +101,7 @@ static struct composite_context *setup_next_method(struct composite_context *c) do { const struct resolve_method *method = find_method(state->methods[0]); if (method) { - creq = method->send_fn(&state->name, c->event_ctx); + creq = method->send_fn(c, c->event_ctx, &state->name); } if (creq == NULL && state->methods[0]) state->methods++; diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 6478710682..62a3b81d0a 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -27,19 +27,20 @@ /* wins name resolution method - async send */ -struct composite_context *resolve_name_wins_send(struct nbt_name *name, - struct event_context *event_ctx) +struct composite_context *resolve_name_wins_send(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct nbt_name *name) { const char **address_list = lp_wins_server_list(); if (address_list == NULL) return NULL; - return resolve_name_nbtlist_send(name, event_ctx, address_list, False, True); + return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, False, True); } /* wins name resolution method - recv side */ NTSTATUS resolve_name_wins_recv(struct composite_context *c, - TALLOC_CTX *mem_ctx, const char **reply_addr) + TALLOC_CTX *mem_ctx, const char **reply_addr) { return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } @@ -51,7 +52,7 @@ NTSTATUS resolve_name_wins(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct composite_context *c = resolve_name_wins_send(name, NULL); + struct composite_context *c = resolve_name_wins_send(mem_ctx, NULL, name); return resolve_name_wins_recv(c, mem_ctx, reply_addr); } -- cgit From c81f2930a2df7cbd72a28e167ac522d2638661ea Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 12 Nov 2006 02:49:05 +0000 Subject: r19676: Fix some more dependencies. (This used to be commit 8768bec81f57131a0c9754e8121b345c0be4a5d0) --- source4/libcli/auth/smbencrypt.c | 4 ++-- source4/libcli/config.mk | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 296d44f5d4..461665d670 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -63,7 +63,7 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -BOOL E_md4hash(const char *passwd, uint8_t p16[16]) +_PUBLIC_ BOOL E_md4hash(const char *passwd, uint8_t p16[16]) { int len; void *wpwd; @@ -91,7 +91,7 @@ BOOL E_md4hash(const char *passwd, uint8_t p16[16]) * @note p16 is filled in regardless */ -BOOL E_deshash(const char *passwd, uint8_t p16[16]) +_PUBLIC_ BOOL E_deshash(const char *passwd, uint8_t p16[16]) { BOOL ret = True; fstring dospwd; diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index a64f41dbf4..6aba69c2af 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -54,7 +54,7 @@ OBJ_FILES = \ nbt/namerefresh.o \ nbt/namerelease.o PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ - NDR_SECURITY samba-socket + NDR_SECURITY samba-socket LIBSAMBA-UTIL [LIBRARY::swig_libcli_nbt] LIBRARY_REALNAME = swig/_libcli_nbt.$(SHLIBEXT) @@ -77,6 +77,7 @@ DESCRIPTION = CLDAP client library OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h PUBLIC_DEPENDENCIES = LIBCLI_LDAP +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL ldb [LIBRARY::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h @@ -85,7 +86,7 @@ SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o -PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS +PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS LIBPACKET [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h -- cgit From 146a4ff13a56ac5d72203adbf47c6cd53e892b32 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Nov 2006 17:08:45 +0000 Subject: r19724: add a helper functions to return an CLDAP error metze (This used to be commit 0a1ecb911656f8170708ce13e1183557fe118794) --- source4/libcli/cldap/cldap.c | 28 ++++++++++++++++++++++++++++ source4/libcli/cldap/cldap.h | 14 +++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 1b09272f04..94887ef697 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -636,6 +636,34 @@ NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, return status; } +/* + send an error reply (used on any error, so the client doesn't keep waiting + or send the bad request again) +*/ +NTSTATUS cldap_error_reply(struct cldap_socket *cldap, + uint32_t message_id, + struct socket_address *src, + int resultcode, + const char *errormessage) +{ + NTSTATUS status; + struct cldap_reply reply; + struct ldap_Result result; + + reply.messageid = message_id; + reply.dest = src; + reply.response = NULL; + reply.result = &result; + + ZERO_STRUCT(result); + result.resultcode = resultcode; + result.errormessage = errormessage; + + status = cldap_reply_send(cldap, &reply); + + return status; +} + /* send a netlogon reply diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 98cb54dded..8bae2aa41b 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -135,6 +135,15 @@ struct cldap_reply { NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io); +NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, + uint32_t message_id, + struct socket_address *src); +NTSTATUS cldap_error_reply(struct cldap_socket *cldap, + uint32_t message_id, + struct socket_address *src, + int resultcode, + const char *errormessage); + /* a netlogon cldap request */ @@ -161,11 +170,6 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, struct cldap_netlogon *io); NTSTATUS cldap_netlogon(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, struct cldap_netlogon *io); - - -NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, - uint32_t message_id, - struct socket_address *src); NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, -- cgit From c7367e873e4896566fb2b954aaadeeef0b734b33 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Nov 2006 10:37:21 +0000 Subject: r19734: display LDAP error code nicer metze (This used to be commit a0a45c3326560b9b31d0e17f1439d2638e91aee0) --- source4/libcli/util/nterr.c | 53 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 589d8627e6..5b6e2b2b50 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -22,6 +22,7 @@ #include "includes.h" #include "pstring.h" +#include "libcli/ldap/ldap.h" typedef struct { @@ -30,6 +31,7 @@ typedef struct } nt_err_code_struct; #define DOS_CODE(class, code) { #class ":" #code, NT_STATUS_DOS(class, code) } +#define LDAP_CODE(code) { #code, NT_STATUS_LDAP(code) } static const nt_err_code_struct nt_errs[] = { @@ -671,6 +673,46 @@ static const nt_err_code_struct nt_errs[] = DOS_CODE(ERRHRD, ERRsharebufexc), DOS_CODE(ERRHRD, ERRdiskfull), + LDAP_CODE(LDAP_SUCCESS), + LDAP_CODE(LDAP_OPERATIONS_ERROR), + LDAP_CODE(LDAP_PROTOCOL_ERROR), + LDAP_CODE(LDAP_TIME_LIMIT_EXCEEDED), + LDAP_CODE(LDAP_SIZE_LIMIT_EXCEEDED), + LDAP_CODE(LDAP_COMPARE_FALSE), + LDAP_CODE(LDAP_COMPARE_TRUE), + LDAP_CODE(LDAP_AUTH_METHOD_NOT_SUPPORTED), + LDAP_CODE(LDAP_STRONG_AUTH_REQUIRED), + LDAP_CODE(LDAP_REFERRAL), + LDAP_CODE(LDAP_ADMIN_LIMIT_EXCEEDED), + LDAP_CODE(LDAP_UNAVAILABLE_CRITICAL_EXTENSION), + LDAP_CODE(LDAP_CONFIDENTIALITY_REQUIRED), + LDAP_CODE(LDAP_SASL_BIND_IN_PROGRESS), + LDAP_CODE(LDAP_NO_SUCH_ATTRIBUTE), + LDAP_CODE(LDAP_UNDEFINED_ATTRIBUTE_TYPE), + LDAP_CODE(LDAP_INAPPROPRIATE_MATCHING), + LDAP_CODE(LDAP_CONSTRAINT_VIOLATION), + LDAP_CODE(LDAP_ATTRIBUTE_OR_VALUE_EXISTS), + LDAP_CODE(LDAP_INVALID_ATTRIBUTE_SYNTAX), + LDAP_CODE(LDAP_NO_SUCH_OBJECT), + LDAP_CODE(LDAP_ALIAS_PROBLEM), + LDAP_CODE(LDAP_INVALID_DN_SYNTAX), + LDAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), + LDAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), + LDAP_CODE(LDAP_INVALID_CREDENTIALS), + LDAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTs), + LDAP_CODE(LDAP_BUSY), + LDAP_CODE(LDAP_UNAVAILABLE), + LDAP_CODE(LDAP_UNWILLING_TO_PERFORM), + LDAP_CODE(LDAP_LOOP_DETECT), + LDAP_CODE(LDAP_NAMING_VIOLATION), + LDAP_CODE(LDAP_OBJECT_CLASS_VIOLATION), + LDAP_CODE(LDAP_NOT_ALLOWED_ON_NON_LEAF), + LDAP_CODE(LDAP_NOT_ALLOWED_ON_RDN), + LDAP_CODE(LDAP_ENTRY_ALREADY_EXISTS), + LDAP_CODE(LDAP_OBJECT_CLASS_MODS_PROHIBITED), + LDAP_CODE(LDAP_AFFECTS_MULTIPLE_DSAS), + LDAP_CODE(LDAP_OTHER), + { NULL, NT_STATUS(0) } }; @@ -772,7 +814,6 @@ static const nt_err_code_struct nt_err_desc[] = { NULL, NT_STATUS(0) } }; - /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ @@ -781,11 +822,6 @@ const char *nt_errstr(NTSTATUS nt_code) static char msg[40]; int idx = 0; - if (NT_STATUS_IS_LDAP(nt_code)) { - slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); - return msg; - } - while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) { @@ -794,6 +830,11 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } + if (NT_STATUS_IS_LDAP(nt_code)) { + slprintf(msg, sizeof(msg), "LDAP code %u", NT_STATUS_LDAP_CODE(nt_code)); + return msg; + } + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); return msg; -- cgit From 3826a6027fa3c7247bbb5084942fed1700f73e90 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Nov 2006 10:42:07 +0000 Subject: r19735: report the LDAP error code in the CLDAP replies to the caller metze (This used to be commit f4a6fade3a3113732ef66433c5739657f0bfdbee) --- source4/libcli/cldap/cldap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 94887ef697..9dfa8e81b1 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -450,7 +450,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, if (!ldap_decode(&req->asn1, ldap_msg)) { talloc_free(req); - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } ZERO_STRUCT(io->out); @@ -464,13 +464,13 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, /* decode the 2nd part */ if (!ldap_decode(&req->asn1, ldap_msg)) { talloc_free(req); - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } } if (ldap_msg->type != LDAP_TAG_SearchResultDone) { talloc_free(req); - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } io->out.result = talloc(mem_ctx, struct ldap_Result); @@ -478,6 +478,10 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, *io->out.result = ldap_msg->r.SearchResultDone; talloc_free(req); + + if (io->out.result->resultcode != LDAP_SUCCESS) { + return NT_STATUS_LDAP(io->out.result->resultcode); + } return NT_STATUS_OK; } -- cgit From be69066736c23f40d9131e608ead94874208da05 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Dec 2006 20:12:24 +0000 Subject: r20072: make sure WERR_ACCESS_DENIED gets mapped to NT_STATUS_ACCESS_DENIED metze (This used to be commit 417f64184e734ab4ce5c78dc3d268c5c4a2cd18d) --- source4/libcli/util/errormap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 1e90969f95..ff6acf9dd9 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -617,6 +617,11 @@ static const struct { NTSTATUS ntstatus; WERROR werror; } ntstatus_to_werror_map[] = { + /* + * we add this manualy here, so that W_ERROR(0x5) + * gets mapped to NTSTATUS_ACCESS_DENIED + */ + {NT_STATUS_ACCESS_DENIED, WERR_ACCESS_DENIED}, {NT_STATUS(0x103), W_ERROR(0x3e5)}, {NT_STATUS(0x105), W_ERROR(0xea)}, {NT_STATUS(0x106), W_ERROR(0x514)}, -- cgit From c72c3e983468bdee33e4482e7b7ccb45cb7c9ddb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Dec 2006 03:47:02 +0000 Subject: r20077: support large readx replies, as done by samba3 (and the snia spec), but not done by windows servers (This used to be commit e5dbbe177c13b2788b4b4765b3b37cc918b3405c) --- source4/libcli/raw/rawreadwrite.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 7a47ce66f4..e7a3209d07 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -161,6 +161,20 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) parms->readx.out.remaining = SVAL(req->in.vwv, VWV(2)); parms->readx.out.compaction_mode = SVAL(req->in.vwv, VWV(3)); parms->readx.out.nread = SVAL(req->in.vwv, VWV(5)); + + /* handle oversize replies for non-chained readx replies with + CAP_LARGE_READX. The snia spec has must to answer for. */ + if ((req->tree->session->transport->negotiate.capabilities & CAP_LARGE_READX) + && CVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE && + req->in.size >= 0x10000) { + parms->readx.out.nread += (SVAL(req->in.vwv, VWV(7)) << 16); + if (req->in.hdr + SVAL(req->in.vwv, VWV(6)) + + parms->readx.out.nread <= + req->in.buffer + req->in.size) { + req->in.data_size += (SVAL(req->in.vwv, VWV(7)) << 16); + } + } + if (parms->readx.out.nread > MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt) || !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), parms->readx.out.nread, -- cgit From f9609d779dcbae389386ab594605d188c6933766 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Dec 2006 18:01:30 +0000 Subject: r20080: add error code that maps to NT_STATUS_INVALID_NETWORD_RESPONSE metze (This used to be commit cb5c2e9dc6838145fe9f6f2e727a1df26e688467) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index fe2b555ab6..6f0d27e8ab 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -36,6 +36,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_BADFID", WERR_BADFID }, { "WERR_BADFUNC", WERR_BADFUNC }, { "WERR_BAD_NETPATH", WERR_BAD_NETPATH }, + { "WERR_BAD_NET_RESP", WERR_BAD_NET_RESP }, { "WERR_UNEXP_NET_ERR", WERR_UNEXP_NET_ERR }, { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 0e1bcd4499..18b66065e2 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -174,6 +174,7 @@ #define WERR_GENERAL_FAILURE W_ERROR(31) #define WERR_NOT_SUPPORTED W_ERROR(50) #define WERR_BAD_NETPATH W_ERROR(53) +#define WERR_BAD_NET_RESP W_ERROR(58) #define WERR_UNEXP_NET_ERR W_ERROR(59) #define WERR_PRINTQ_FULL W_ERROR(61) #define WERR_NO_SPOOL_SPACE W_ERROR(62) -- cgit From b236d54c42a01343c4b0ec68d70a47a48531e71d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Dec 2006 22:43:35 +0000 Subject: r20141: use the gensec_features of the cli_credentials for ildap connections, instead of hardcoded GENSEC_FEATURE_SEAL. That means plain LDAP is now the default. metze (This used to be commit b69471866c2a6c61002147938f233f2f63963ba4) --- source4/libcli/ldap/ldap_bind.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c4c731e4f5..addc8cf91e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -28,6 +28,7 @@ #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "auth/gensec/socket.h" +#include "auth/credentials/credentials.h" #include "lib/stream/packet.h" struct ldap_simple_creds { @@ -211,7 +212,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr int count, i; const char **sasl_names; - + uint32_t old_gensec_features; static const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", NULL @@ -225,10 +226,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr /* require Kerberos SIGN/SEAL only if we don't use SSL * Windows seem not to like double encryption */ - if (!tls_enabled(conn->sock)) { - gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + old_gensec_features = cli_credentials_get_gensec_features(creds); + if (tls_enabled(conn->sock)) { + cli_credentials_set_gensec_features(creds, 0); } + /* this call also sets the gensec_want_features */ status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to set GENSEC creds: %s\n", @@ -236,6 +239,9 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } + /* reset the original gensec_features */ + cli_credentials_set_gensec_features(creds, old_gensec_features); + if (conn->host) { status = gensec_set_target_hostname(conn->gensec, conn->host); if (!NT_STATUS_IS_OK(status)) { -- cgit From f37b7b85821c821c358bf900fd621bf9aada5c35 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 16 Dec 2006 17:21:53 +0000 Subject: r20213: add 2 error codes related to the msDs-IntId attribute metze (This used to be commit dd5df84cccd10e9880648eecbff6faf7252d5e73) --- source4/libcli/util/doserr.c | 2 ++ source4/libcli/util/doserr.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 6f0d27e8ab..4b39dace47 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -100,6 +100,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_DRA_ACCESS_DENIED", WERR_DS_DRA_ACCESS_DENIED }, { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE }, { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, + { "WERR_DS_NO_MSDS_INTID", WERR_DS_NO_MSDS_INTID }, + { "WERR_DS_DUP_MSDS_INTID", WERR_DS_DUP_MSDS_INTID }, { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 18b66065e2..0cf53c1cf2 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -272,6 +272,8 @@ #define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105) #define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) #define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) +#define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194) +#define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) /* SEC errors */ #define WERR_SEC_E_ALGORITHM_MISMATCH W_ERROR(0x80090331) -- cgit From b55a68b368d2e14545f374938071a7f09af3c263 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 19 Dec 2006 19:25:49 +0000 Subject: r20258: add functions to read and write asn1 encoded OID strings without leading tag metze (This used to be commit 576d4c54cca844164b90e5d6ec71fe44b59607b7) --- source4/libcli/util/asn1.c | 75 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 01c869dc17..c8e2d6f301 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -185,25 +185,37 @@ BOOL asn1_write_Integer(struct asn1_data *data, int i) return asn1_pop_tag(data); } -/* write an object ID to a ASN1 buffer */ -BOOL asn1_write_OID(struct asn1_data *data, const char *OID) +BOOL asn1_write_OID_String(struct asn1_data *data, const char *OID) { uint_t v, v2; const char *p = (const char *)OID; char *newp; - if (!asn1_push_tag(data, ASN1_OID)) + v = strtoul(p, &newp, 10); + if (newp[0] != '.') { + data->has_error = True; return False; - v = strtol(p, &newp, 10); - p = newp; - v2 = strtol(p, &newp, 10); - p = newp; + } + p = newp + 1; + v2 = strtoul(p, &newp, 10); + if (newp[0] != '.') { + data->has_error = True; + return False; + } + p = newp + 1; if (!asn1_write_uint8(data, 40*v + v2)) return False; while (*p) { - v = strtol(p, &newp, 10); - p = newp; + v = strtoul(p, &newp, 10); + if (newp[0] == '.') { + p = newp + 1; + } else if (newp[0] == '\0') { + p = newp; + } else { + data->has_error = True; + return False; + } if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff)); if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); @@ -211,6 +223,15 @@ BOOL asn1_write_OID(struct asn1_data *data, const char *OID) if (!asn1_write_uint8(data, v&0x7f)) return False; } + + return !data->has_error; +} + +/* write an object ID to a ASN1 buffer */ +BOOL asn1_write_OID(struct asn1_data *data, const char *OID) +{ + if (!asn1_push_tag(data, ASN1_OID)) return False; + if (!asn1_write_OID_String(data, OID)) return False; return asn1_pop_tag(data); } @@ -447,16 +468,17 @@ int asn1_tag_remaining(struct asn1_data *data) } /* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID(struct asn1_data *data, const char **OID) +BOOL asn1_read_OID_String(struct asn1_data *data, const char **OID) { uint8_t b; char *tmp_oid = NULL; - if (!asn1_start_tag(data, ASN1_OID)) return False; - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) return False; tmp_oid = talloc_asprintf(NULL, "%u", b/40); - tmp_oid = talloc_asprintf_append(tmp_oid, " %u", b%40); + if (!tmp_oid) goto nomem; + tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", b%40); + if (!tmp_oid) goto nomem; while (!data->has_error && asn1_tag_remaining(data) > 0) { uint_t v = 0; @@ -464,15 +486,34 @@ BOOL asn1_read_OID(struct asn1_data *data, const char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && (b & 0x80)); - tmp_oid = talloc_asprintf_append(tmp_oid, " %u", v); + tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", v); + if (!tmp_oid) goto nomem; } - asn1_end_tag(data); + if (!data->has_error) { + *OID = talloc_strdup(NULL, tmp_oid); + if (!*OID) goto nomem; + } - *OID = talloc_strdup(NULL, tmp_oid); talloc_free(tmp_oid); + return !data->has_error; +nomem: + talloc_free(tmp_oid); + data->has_error = True; + return False; +} - return (*OID && !data->has_error); +/* read an object ID from a ASN1 buffer */ +BOOL asn1_read_OID(struct asn1_data *data, const char **OID) +{ + if (!asn1_start_tag(data, ASN1_OID)) return False; + if (!asn1_read_OID_String(data, OID)) return False; + if (!asn1_end_tag(data)) { + talloc_free(discard_const(*OID)); + *OID = NULL; + return False; + } + return True; } /* check that the next object ID is correct */ -- cgit From 3853f820e630641d302435933241875a64b5980c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 19 Dec 2006 19:28:49 +0000 Subject: r20259: add function to start a fake tag so that asn1_read_OID_String() can work alone metze (This used to be commit ea70f6ff07930951d98a952b03963d0ba358fec4) --- source4/libcli/util/asn1.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index c8e2d6f301..83044f8e30 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -423,6 +423,25 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) return !data->has_error; } +BOOL asn1_start_fake_tag(struct asn1_data *data) +{ + struct nesting *nesting; + + nesting = talloc(NULL, struct nesting); + if (!nesting) { + data->has_error = True; + return False; + } + + nesting->start = data->ofs; + nesting->taglen = data->length - data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + if (asn1_tag_remaining(data) == -1) { + return False; + } + return !data->has_error; +} /* stop reading a tag */ BOOL asn1_end_tag(struct asn1_data *data) -- cgit From bfa5a5a4412ce810da91c2b3d8e6f1b86f24eb5a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Dec 2006 12:51:29 +0000 Subject: r20276: remove unneeded talloc_strdup() metze (This used to be commit c4733b20c7c113dc1abfb2219a899b80bbcc2875) --- source4/libcli/util/asn1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 83044f8e30..3c669292cb 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -510,11 +510,11 @@ BOOL asn1_read_OID_String(struct asn1_data *data, const char **OID) } if (!data->has_error) { - *OID = talloc_strdup(NULL, tmp_oid); - if (!*OID) goto nomem; + *OID = tmp_oid; + } else { + talloc_free(tmp_oid); } - talloc_free(tmp_oid); return !data->has_error; nomem: talloc_free(tmp_oid); -- cgit From 06c58a3dbbf76a0790627fd13b788a4626fca78e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Dec 2006 12:53:58 +0000 Subject: r20277: make sure the asn1 structure has a welldefined state after a asn1_free() metze (This used to be commit 7e7d1a1da2d64d28915a06c399072de1caf108c4) --- source4/libcli/util/asn1.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 3c669292cb..c82269fd60 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -25,6 +25,8 @@ void asn1_free(struct asn1_data *data) { talloc_free(data->data); + ZERO_STRUCTP(data); + data->has_error = True; } /* write to the ASN1 buffer, advancing the buffer pointer */ -- cgit From 52455cb9224bc7358f6700c8e3a233ff8c9a0f2a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 20 Dec 2006 15:51:02 +0000 Subject: r20284: Simplify OID primitive BER parsing. Do not require an artificial ASN.1 context to be setup. Simo. (This used to be commit 14b3b9861ae47498c74a6643e6979b3d85260a61) --- source4/libcli/util/asn1.c | 146 ++++++++++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 63 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index c82269fd60..d139996bd0 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -187,27 +187,28 @@ BOOL asn1_write_Integer(struct asn1_data *data, int i) return asn1_pop_tag(data); } -BOOL asn1_write_OID_String(struct asn1_data *data, const char *OID) +BOOL ber_write_OID_String(DATA_BLOB *blob, const char *OID) { uint_t v, v2; const char *p = (const char *)OID; char *newp; + int i; v = strtoul(p, &newp, 10); - if (newp[0] != '.') { - data->has_error = True; - return False; - } + if (newp[0] != '.') return False; p = newp + 1; + v2 = strtoul(p, &newp, 10); - if (newp[0] != '.') { - data->has_error = True; - return False; - } + if (newp[0] != '.') return False; p = newp + 1; - if (!asn1_write_uint8(data, 40*v + v2)) - return False; + /*the ber representation can't use more space then the string one */ + *blob = data_blob(NULL, strlen(OID)); + if (!blob->data) return False; + + blob->data[0] = 40*v + v2; + + i = 1; while (*p) { v = strtoul(p, &newp, 10); if (newp[0] == '.') { @@ -215,25 +216,38 @@ BOOL asn1_write_OID_String(struct asn1_data *data, const char *OID) } else if (newp[0] == '\0') { p = newp; } else { - data->has_error = True; + data_blob_free(blob); return False; } - if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff)); - if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); - if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); - if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); - if (!asn1_write_uint8(data, v&0x7f)) - return False; + if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f)); + if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f)); + if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f)); + if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f)); + blob->data[i++] = (v&0x7f); } - return !data->has_error; + blob->length = i; + + return True; } /* write an object ID to a ASN1 buffer */ BOOL asn1_write_OID(struct asn1_data *data, const char *OID) { + DATA_BLOB blob; + if (!asn1_push_tag(data, ASN1_OID)) return False; - if (!asn1_write_OID_String(data, OID)) return False; + + if (!ber_write_OID_String(&blob, OID)) { + data->has_error = True; + return False; + } + + if (!asn1_write(data, blob.data, blob.length)) { + data->has_error = True; + return False; + } + data_blob_free(&blob); return asn1_pop_tag(data); } @@ -425,26 +439,6 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) return !data->has_error; } -BOOL asn1_start_fake_tag(struct asn1_data *data) -{ - struct nesting *nesting; - - nesting = talloc(NULL, struct nesting); - if (!nesting) { - data->has_error = True; - return False; - } - - nesting->start = data->ofs; - nesting->taglen = data->length - data->ofs; - nesting->next = data->nesting; - data->nesting = nesting; - if (asn1_tag_remaining(data) == -1) { - return False; - } - return !data->has_error; -} - /* stop reading a tag */ BOOL asn1_end_tag(struct asn1_data *data) { @@ -488,52 +482,78 @@ int asn1_tag_remaining(struct asn1_data *data) return remaining; } -/* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID_String(struct asn1_data *data, const char **OID) +/* read an object ID from a data blob */ +BOOL ber_read_OID_String(DATA_BLOB blob, const char **OID) { - uint8_t b; + int i; + uint8_t *b; + uint_t v; char *tmp_oid = NULL; - if (!asn1_read_uint8(data, &b)) return False; + if (blob.length < 2) return False; + + b = blob.data; - tmp_oid = talloc_asprintf(NULL, "%u", b/40); + tmp_oid = talloc_asprintf(NULL, "%u", b[0]/40); if (!tmp_oid) goto nomem; - tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", b%40); + tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", b[0]%40); if (!tmp_oid) goto nomem; - while (!data->has_error && asn1_tag_remaining(data) > 0) { - uint_t v = 0; - do { - asn1_read_uint8(data, &b); - v = (v<<7) | (b&0x7f); - } while (!data->has_error && (b & 0x80)); - tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", v); + for(i = 1, v = 0; i < blob.length; i++) { + v = (v<<7) | (b[i]&0x7f); + if ( ! (b[i] & 0x80)) { + tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", v); + v = 0; + } if (!tmp_oid) goto nomem; } - if (!data->has_error) { - *OID = tmp_oid; - } else { + if (v != 0) { talloc_free(tmp_oid); + return False; } - return !data->has_error; + *OID = tmp_oid; + return True; + nomem: - talloc_free(tmp_oid); - data->has_error = True; return False; } /* read an object ID from a ASN1 buffer */ BOOL asn1_read_OID(struct asn1_data *data, const char **OID) { + DATA_BLOB blob; + int len; + if (!asn1_start_tag(data, ASN1_OID)) return False; - if (!asn1_read_OID_String(data, OID)) return False; - if (!asn1_end_tag(data)) { - talloc_free(discard_const(*OID)); - *OID = NULL; + + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } + + blob = data_blob(NULL, len); + if (!blob.data) { + data->has_error = True; + return False; + } + + asn1_read(data, blob.data, len); + asn1_end_tag(data); + if (data->has_error) { + data_blob_free(&blob); return False; } + + if (!ber_read_OID_String(blob, OID)) { + data->has_error = True; + data_blob_free(&blob); + return False; + } + + data_blob_free(&blob); return True; } -- cgit From 84e7faf6cdb4330316bf21a21b0448e074064996 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 21 Dec 2006 21:14:53 +0000 Subject: r20308: ContextSimple can be zero length -- seen in a multi-step gssapi ldap bind. Did not find that in Samba3 code, so there's nothing to port. Volker (This used to be commit 9bdc19b6d5fe3dff57a07f4b760840d0043a53ad) --- source4/libcli/util/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index d139996bd0..b1328344c5 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -641,7 +641,7 @@ BOOL asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blo return False; } *blob = data_blob(NULL, len); - if (!blob->data) { + if ((len != 0) && (!blob->data)) { data->has_error = True; return False; } -- cgit From 11018b0e134bee5bd7f7680114343e9f17f529e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Dec 2006 12:17:01 +0000 Subject: r20378: add new error code that says the schema mismatches between DC's metze (This used to be commit e769029f42f848db8121c7dcfe5be261861776c8) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 4b39dace47..5a4660c095 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -89,6 +89,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_DS_DRA_SCHEMA_MISMATCH", WERR_DS_DRA_SCHEMA_MISMATCH }, { "WERR_DS_DRA_INVALID_PARAMETER", WERR_DS_DRA_INVALID_PARAMETER }, { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 0cf53c1cf2..17a9757d6e 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -261,6 +261,7 @@ #define WERR_DS_SERVICE_UNAVAILABLE W_ERROR(0x0000200f) #define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030) #define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208d) +#define WERR_DS_DRA_SCHEMA_MISMATCH W_ERROR(0x000020e2) #define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020f5) #define WERR_DS_DRA_BAD_DN W_ERROR(0x000020f7) #define WERR_DS_DRA_BAD_NC W_ERROR(0x000020f8) -- cgit From a2f568f0008238bc76f7b8d32f21f75b239a4925 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 29 Dec 2006 10:34:15 +0000 Subject: r20404: add error code for missing attribute syntax metze (This used to be commit 769ce9799b0e9d1ccc5f2155440e5dedf655d40c) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 5a4660c095..c23e62afd8 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -89,6 +89,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_DS_ATT_SCHEMA_REQ_SYNTAX", WERR_DS_ATT_SCHEMA_REQ_SYNTAX }, { "WERR_DS_DRA_SCHEMA_MISMATCH", WERR_DS_DRA_SCHEMA_MISMATCH }, { "WERR_DS_DRA_INVALID_PARAMETER", WERR_DS_DRA_INVALID_PARAMETER }, { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 17a9757d6e..84b84bb6f5 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -261,6 +261,7 @@ #define WERR_DS_SERVICE_UNAVAILABLE W_ERROR(0x0000200f) #define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030) #define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208d) +#define WERR_DS_ATT_SCHEMA_REQ_SYNTAX W_ERROR(0x000020e0) #define WERR_DS_DRA_SCHEMA_MISMATCH W_ERROR(0x000020e2) #define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020f5) #define WERR_DS_DRA_BAD_DN W_ERROR(0x000020f7) -- cgit From 1cd4339b9a2786aa26691ca4f02fa93ab0958b88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 10:52:09 +0000 Subject: r20646: first preparations for cluster enablement. This changes " uint32_t server_id to struct server_id server_id; which allows a server ID to have an node number. The node number will be zero in non-clustered case. This is the most basic hook needed for clustering, and ctdb. (This used to be commit 2365abaa991d57d68c6ebe9be608e01c907102eb) --- source4/libcli/finddcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 417b33f277..d8acf44ba0 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -112,7 +112,7 @@ static void finddcs_name_resolved(struct composite_context *ctx) struct finddcs_state *state = talloc_get_type(ctx->async.private_data, struct finddcs_state); struct irpc_request *ireq; - uint32_t *nbt_servers; + struct server_id *nbt_servers; const char *address; state->ctx->status = resolve_name_recv(ctx, state, &address); @@ -134,7 +134,7 @@ static void finddcs_name_resolved(struct composite_context *ctx) } nbt_servers = irpc_servers_byname(state->msg_ctx, "nbt_server"); - if ((nbt_servers == NULL) || (nbt_servers[0] == 0)) { + if ((nbt_servers == NULL) || (nbt_servers[0].id == 0)) { fallback_node_status(state); return; } -- cgit From f6274959ba381b6b5d025cb0cee78665107a72a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 11:16:11 +0000 Subject: r20647: add cluster code (This used to be commit 5870830b99a8d76bda1ff5af3fcf8dda9aba50ec) --- source4/libcli/raw/trans2.h | 5 +++++ source4/libcli/smb2/create.c | 1 + 2 files changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index a3f6e28a2a..a1a34ea118 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -1,3 +1,8 @@ +/* + NTFS filesystem internals + +*/ + /* Unix SMB/CIFS implementation. SMB transaction2 handling diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index da21d090fd..81c11eebc2 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -72,6 +72,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.impersonation); + /* are these 16 bytes the root_fid (vl) */ SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); SIVAL(req->out.body, 0x10, io->in.unknown3[2]); -- cgit From 1c211a2e43db46c649a963ec883481cc4321870a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 11:50:33 +0000 Subject: r20650: revert a bunch of code I didn't mean to commit yet (This used to be commit b3e2d4908781781a487eaeb683d22eb967e5597d) --- source4/libcli/raw/trans2.h | 5 ----- source4/libcli/smb2/create.c | 1 - 2 files changed, 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index a1a34ea118..a3f6e28a2a 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -1,8 +1,3 @@ -/* - NTFS filesystem internals - -*/ - /* Unix SMB/CIFS implementation. SMB transaction2 handling diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 81c11eebc2..da21d090fd 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -72,7 +72,6 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.impersonation); - /* are these 16 bytes the root_fid (vl) */ SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); SIVAL(req->out.body, 0x10, io->in.unknown3[2]); -- cgit From 15f6cf2449898432112140aea9f3f9445ca2ea68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 14 Jan 2007 15:17:48 +0000 Subject: r20765: add two more schema related error codes metze (This used to be commit 75f5a88f2229fa604726ecb0ebb2b5a4589d5b86) --- source4/libcli/util/doserr.c | 2 ++ source4/libcli/util/doserr.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index c23e62afd8..51a633238f 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -89,6 +89,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_SERVICE_UNAVAILABLE", WERR_DS_SERVICE_UNAVAILABLE }, { "WERR_DS_NO_SUCH_OBJECT", WERR_DS_NO_SUCH_OBJECT }, { "WERR_DS_OBJ_NOT_FOUND", WERR_DS_OBJ_NOT_FOUND }, + { "WERR_DS_SCHEMA_NOT_LOADED", WERR_DS_SCHEMA_NOT_LOADED }, + { "WERR_DS_SCHEMA_ALLOC_FAILED", WERR_DS_SCHEMA_ALLOC_FAILED }, { "WERR_DS_ATT_SCHEMA_REQ_SYNTAX", WERR_DS_ATT_SCHEMA_REQ_SYNTAX }, { "WERR_DS_DRA_SCHEMA_MISMATCH", WERR_DS_DRA_SCHEMA_MISMATCH }, { "WERR_DS_DRA_INVALID_PARAMETER", WERR_DS_DRA_INVALID_PARAMETER }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 84b84bb6f5..79bbb1a4d8 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -261,6 +261,8 @@ #define WERR_DS_SERVICE_UNAVAILABLE W_ERROR(0x0000200f) #define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030) #define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208d) +#define WERR_DS_SCHEMA_NOT_LOADED W_ERROR(0x20de) +#define WERR_DS_SCHEMA_ALLOC_FAILED W_ERROR(0x20df) #define WERR_DS_ATT_SCHEMA_REQ_SYNTAX W_ERROR(0x000020e0) #define WERR_DS_DRA_SCHEMA_MISMATCH W_ERROR(0x000020e2) #define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020f5) -- cgit From 2246d32e70f38ce31d8432eeb436fb522661d1c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2007 09:02:58 +0000 Subject: r20795: dom_sid_parse_talloc() gets an null terminated string as input, the SDDL string has the sid strings embedded, so we need to create a null terminated string... metze (This used to be commit 532395a18db84affa8a743b995e9fae2e3c312f2) --- source4/libcli/security/sddl.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 14dd7e0917..423ccc92e9 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -100,9 +100,17 @@ static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp, /* see if its in the numeric format */ if (strncmp(sddl, "S-", 2) == 0) { + struct dom_sid *sid; + char *sid_str; size_t len = strspn(sddl+2, "-0123456789"); + sid_str = talloc_strndup(mem_ctx, sddl, len+2); + if (!sid_str) { + return NULL; + } (*sddlp) += len+2; - return dom_sid_parse_talloc(mem_ctx, sddl); + sid = dom_sid_parse_talloc(mem_ctx, sid_str); + talloc_free(sid_str); + return sid; } /* now check for one of the special codes */ -- cgit From e754ec1d8a52ac717d0d511b28c8556d43eb2f86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2007 10:10:15 +0000 Subject: r20799: if any ace has the optional sub object, the acl revision needs to be SECURITY_ACL_REVISION_ADS (4) metze (This used to be commit a67bb4365958f4bfadbf47b2231992e2aadd26a1) --- source4/libcli/security/sddl.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 423ccc92e9..2746ed8f81 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -312,6 +312,14 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, talloc_free(acl); return NULL; } + switch (acl->aces[acl->num_aces].type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + acl->revision = SECURITY_ACL_REVISION_ADS; + break; + } talloc_free(astr); sddl += len+2; acl->num_aces++; -- cgit From d6fafdb23714551e844c2ce6006683f9f51e4ff1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2007 10:39:17 +0000 Subject: r20800: fix compiler warnings metze (This used to be commit 6ce994720cdd8b7dd0b789460b5ae7da19261696) --- source4/libcli/security/sddl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 2746ed8f81..7d0e6ee748 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -319,6 +319,8 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: acl->revision = SECURITY_ACL_REVISION_ADS; break; + default: + break; } talloc_free(astr); sddl += len+2; -- cgit From d363192d6466d3b1654284227addc745ca5d0a81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2007 10:47:22 +0000 Subject: r20801: try to always fix up the acl revision when we add or remove an ace metze (This used to be commit 18cc56be6a7c21e5b19d0826aca6ae2416c116b8) --- source4/libcli/security/security_descriptor.c | 41 ++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index f7972f57ac..441f2c6370 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -150,7 +150,7 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, if (sd->dacl == NULL) { return NT_STATUS_NO_MEMORY; } - sd->dacl->revision = NT4_ACL_REVISION; + sd->dacl->revision = SECURITY_ACL_REVISION_NT4; sd->dacl->size = 0; sd->dacl->num_aces = 0; sd->dacl->aces = NULL; @@ -171,7 +171,18 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, if (sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths == NULL) { return NT_STATUS_NO_MEMORY; } - + + switch (sd->dacl->aces[sd->dacl->num_aces].type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + sd->dacl->revision = SECURITY_ACL_REVISION_ADS; + break; + default: + break; + } + sd->dacl->num_aces++; sd->type |= SEC_DESC_DACL_PRESENT; @@ -187,11 +198,13 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, struct dom_sid *trustee) { int i; + bool found = false; if (sd->dacl == NULL) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - + + /* there can be multiple ace's for one trustee */ for (i=0;idacl->num_aces;i++) { if (dom_sid_equal(trustee, &sd->dacl->aces[i].trustee)) { memmove(&sd->dacl->aces[i], &sd->dacl->aces[i+1], @@ -200,10 +213,30 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, if (sd->dacl->num_aces == 0) { sd->dacl->aces = NULL; } + found = true; + } + } + + if (!found) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + sd->dacl->revision = SECURITY_ACL_REVISION_NT4; + + for (i=0;idacl->num_aces;i++) { + switch (sd->dacl->aces[i].type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + sd->dacl->revision = SECURITY_ACL_REVISION_ADS; return NT_STATUS_OK; + default: + break; /* only for the switch statement */ } } - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + + return NT_STATUS_OK; } -- cgit From c471abbcfe21e853f5664320c5b3498cdd4ad186 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 23 Jan 2007 01:29:17 +0000 Subject: r20963: remove unused functions, run LOCAL-TDR by default (This used to be commit 0f34c67fff53d5bd3c1b5a5618190ad7154e8d07) --- source4/libcli/raw/rawacl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 6f35b7f829..1a2d75d274 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -131,12 +131,12 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, nt.in.params.data = params; nt.in.params.length = 8; - ndr = ndr_push_init(); + ndr = ndr_push_init_ctx(NULL); if (!ndr) return NULL; status = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->set_secdesc.in.sd); if (!NT_STATUS_IS_OK(status)) { - ndr_push_free(ndr); + talloc_free(ndr); return NULL; } @@ -144,7 +144,7 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, req = smb_raw_nttrans_send(tree, &nt); - ndr_push_free(ndr); + talloc_free(ndr); return req; } -- cgit From a9a3e4eafc8ae67ebd00a476cf34bd69400413ba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Jan 2007 09:25:37 +0000 Subject: r21072: fix compiler warning metze (This used to be commit e788709835fa13b512fbf38951c9d0ca9bc3df18) --- source4/libcli/auth/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 461665d670..3c55658025 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -72,7 +72,7 @@ _PUBLIC_ BOOL E_md4hash(const char *passwd, uint8_t p16[16]) if (len < 2) { /* We don't want to return fixed data, as most callers * don't check */ - mdfour(p16, passwd, strlen(passwd)); + mdfour(p16, (const uint8_t *)passwd, strlen(passwd)); return False; } -- cgit From 2342219d699eb17d48a2b31c297121a158ba85d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 Feb 2007 18:16:10 +0000 Subject: r21183: Commit the big/little endian fix for nttrans setup[] handling. Please check! For code symmetry reasons, trans2 might also see this fix, but this is left to the interested reader :-) Volker (This used to be commit f2d364ebe69fc5d624e456cc7d941071811a5567) --- source4/libcli/raw/rawtrans.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index cd309e0736..08d7483a87 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -555,7 +555,6 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, { struct smbcli_request *req; uint8_t *outdata, *outparam; - int i; int align = 0; /* only align if there are parameters or data */ @@ -592,9 +591,8 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, SIVAL(req->out.vwv, 31, PTR_DIFF(outdata,req->out.hdr)); SCVAL(req->out.vwv, 35, parms->in.setup_count); SSVAL(req->out.vwv, 36, parms->in.function); - for (i=0;iin.setup_count;i++) { - SSVAL(req->out.vwv,VWV(19+i),parms->in.setup[i]); - } + memcpy(req->out.vwv + VWV(19), parms->in.setup, + sizeof(uint16_t) * parms->in.setup_count); if (parms->in.params.length) { memcpy(outparam, parms->in.params.data, parms->in.params.length); } -- cgit From 21650cf3779f20aad808f8ce4e95daa7a2d0e1e7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Feb 2007 00:21:29 +0000 Subject: r21206: - a couple more nttrans places were a memcpy() should be used - changed the setup array in nttrans to be a uint8 array, instead of a uint16 array. This makes it clearer that it is the job of the caller to do any byte swapping within that data (This used to be commit fa3c9b29ae1c7c6a9bc97484cc386aeec9b5d266) --- source4/libcli/raw/interfaces.h | 6 +++--- source4/libcli/raw/rawioctl.c | 2 +- source4/libcli/raw/rawnotify.c | 2 +- source4/libcli/raw/rawtrans.c | 9 ++++----- 4 files changed, 9 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index c2f0c3530b..60cefe6931 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2115,14 +2115,14 @@ struct smb_nttrans { uint32_t max_data; uint32_t setup_count; uint16_t function; - uint16_t *setup; + uint8_t *setup; DATA_BLOB params; DATA_BLOB data; } in; struct { - uint8_t setup_count; - uint16_t *setup; + uint8_t setup_count; /* in units of 16 bit words */ + uint8_t *setup; DATA_BLOB params; DATA_BLOB data; } out; diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index a9812022ea..9477af4eb2 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -79,7 +79,7 @@ static struct smbcli_request *smb_raw_ntioctl_send(struct smbcli_tree *tree, nt.in.max_param = 0; nt.in.max_data = parms->ntioctl.in.max_data; nt.in.setup_count = 4; - nt.in.setup = (uint16_t *)setup; + nt.in.setup = setup; SIVAL(setup, 0, parms->ntioctl.in.function); SSVAL(setup, 4, parms->ntioctl.in.file.fnum); SCVAL(setup, 6, parms->ntioctl.in.fsctl); diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 5f3fa0f50e..e847368f73 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -28,7 +28,7 @@ change notify (async send) struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) { struct smb_nttrans nt; - uint16_t setup[4]; + uint8_t setup[8]; if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { return NULL; diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 08d7483a87..164354c701 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -449,15 +449,14 @@ NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req, SMBCLI_CHECK_WCT(req, 18 + parms->out.setup_count); if (parms->out.setup_count > 0) { - int i; - parms->out.setup = talloc_array(mem_ctx, uint16_t, parms->out.setup_count); + parms->out.setup = talloc_array(mem_ctx, uint8_t, + parms->out.setup_count*2); if (!parms->out.setup) { req->status = NT_STATUS_NO_MEMORY; return smbcli_request_destroy(req); } - for (i=0;iout.setup_count;i++) { - parms->out.setup[i] = SVAL(req->in.vwv, VWV(18+i)); - } + memcpy(parms->out.setup, VWV(18) + (uint8_t *)req->out.vwv, + sizeof(uint16_t) * parms->out.setup_count); } while (recvd_data < total_data || -- cgit From 10c928a94f6fafd79ae4c9e581c793bbf700a9b5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Feb 2007 09:36:53 +0000 Subject: r21291: add two more error codes metze (This used to be commit dd04c5dec58b18048ca5029f7bfe513242cbe4e9) --- source4/libcli/util/doserr.c | 2 ++ source4/libcli/util/doserr.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 51a633238f..3f646f4be5 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -115,6 +115,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS }, { "WERR_SHUTDOWN_ALREADY_IN_PROGRESS", WERR_SHUTDOWN_ALREADY_IN_PROGRESS }, + { "WERR_SEC_E_ENCRYPT_FAILURE", WERR_SEC_E_ENCRYPT_FAILURE }, + { "WERR_SEC_E_DECRYPT_FAILURE", WERR_SEC_E_DECRYPT_FAILURE }, { "WERR_SEC_E_ALGORITHM_MISMATCH", WERR_SEC_E_ALGORITHM_MISMATCH }, { NULL, W_ERROR(0) } }; diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 79bbb1a4d8..69499c17e9 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -280,7 +280,9 @@ #define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) /* SEC errors */ -#define WERR_SEC_E_ALGORITHM_MISMATCH W_ERROR(0x80090331) +#define WERR_SEC_E_ENCRYPT_FAILURE W_ERROR(0x80090329) +#define WERR_SEC_E_DECRYPT_FAILURE W_ERROR(0x80090330) +#define WERR_SEC_E_ALGORITHM_MISMATCH W_ERROR(0x80090331) #define WERR_FOOBAR WERR_GENERAL_FAILURE -- cgit From 97416e6b011a3c733d07f83073bf12796c7ecc6b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Feb 2007 12:12:12 +0000 Subject: r21297: Remove the GTK+ tools and library from the main repository. They are now maintained separately in bzr at http://people.samba.org/bzr/jelmer/samba-gtk This also adds some more headers to the list that is installed and a couple of extra #include lines so these headers can be used externally without problems. (This used to be commit 07652f65ce7a5b19130f1a27cbf0e1e5fae13454) --- source4/libcli/util/nt_status.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nt_status.h b/source4/libcli/util/nt_status.h index 06aeaa3dac..3e2a126b41 100644 --- a/source4/libcli/util/nt_status.h +++ b/source4/libcli/util/nt_status.h @@ -22,6 +22,8 @@ #ifndef _NT_STATUS_H #define _NT_STATUS_H +#include + /* the following rather strange looking definitions of NTSTATUS and WERROR and there in order to catch common coding errors where different error types are mixed up. This is especially important as we slowly convert Samba -- cgit From 08de05ce5a4da17403fc8feb2a1760ab21a767fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Feb 2007 09:27:56 +0000 Subject: r21307: make it possible to pass in NULL for domain or rid, if someone isn't interessted in one of it metze (This used to be commit 1fdc71918a430c35af91fa7788e191d381f76d56) --- source4/libcli/security/dom_sid.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 54242eb515..a72588dee1 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -225,12 +225,18 @@ NTSTATUS dom_sid_split_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, return NT_STATUS_INVALID_PARAMETER; } - if (!(*domain = dom_sid_dup(mem_ctx, sid))) { - return NT_STATUS_NO_MEMORY; + if (domain) { + if (!(*domain = dom_sid_dup(mem_ctx, sid))) { + return NT_STATUS_NO_MEMORY; + } + + (*domain)->num_auths -= 1; + } + + if (rid) { + *rid = sid->sub_auths[sid->num_auths - 1]; } - (*domain)->num_auths -= 1; - *rid = (*domain)->sub_auths[(*domain)->num_auths]; return NT_STATUS_OK; } -- cgit From aa5677040cd675dbf650f1f8acdfdb687f989978 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Feb 2007 15:17:29 +0000 Subject: r21316: if we got an unexpected nbt packet that most times mean we got a 2nd answer to a broadcast message and have already remove the packet id from out list while getting the first response metze (This used to be commit 8c26e04900da02bdf440f1d48b512e2550e89c34) --- source4/libcli/nbt/nbtsocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index a48f9873c8..c1e30fc245 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -215,7 +215,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) if (nbtsock->unexpected.handler) { nbtsock->unexpected.handler(nbtsock, packet, src); } else { - DEBUG(2,("Failed to match request for incoming name packet id 0x%04x on %p\n", + DEBUG(10,("Failed to match request for incoming name packet id 0x%04x on %p\n", packet->name_trn_id, nbtsock)); } talloc_free(tmp_ctx); -- cgit From 31d6d8c45735bef52a14b922667a036245df8061 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2007 14:29:04 +0000 Subject: r21501: ugly but the windows 2000 mmc deturns decoding error without this metze (This used to be commit f17da75754f8cc79b60e04b54a4bc99191e71ff3) --- source4/libcli/ldap/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5a7174b41d..bdcea0962d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -237,6 +237,10 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct ldap_encode_response(&data, &r->response); if (r->SASL.secblob) { asn1_write_ContextSimple(&data, 7, r->SASL.secblob); + } else { + /* ugly but the windows 2000 mmc deturns decoding error without this */ + DATA_BLOB zero = data_blob(NULL, 0); + asn1_write_ContextSimple(&data, 7, &zero); } asn1_pop_tag(&data); break; -- cgit From 7f9d949bd34cbeaca8452ea08d39c0e4bbd3a669 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Feb 2007 07:32:13 +0000 Subject: r21510: make it possible to push tags with length > 0xFFFFFF metze (This used to be commit 8e604107da4a8a1bf6ccab45e85e147daab29519) --- source4/libcli/util/asn1.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index b1328344c5..e64ffdf86c 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -89,7 +89,18 @@ BOOL asn1_pop_tag(struct asn1_data *data) /* yes, this is ugly. We don't know in advance how many bytes the length of a tag will take, so we assumed 1 byte. If we were wrong then we need to correct our mistake */ - if (len > 0xFFFF) { + if (len > 0xFFFFFF) { + data->data[nesting->start] = 0x84; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+5, data->data+nesting->start+1, len); + data->data[nesting->start+1] = (len>>24) & 0xFF; + data->data[nesting->start+2] = (len>>16) & 0xFF; + data->data[nesting->start+3] = (len>>8) & 0xFF; + data->data[nesting->start+4] = len&0xff; + } else if (len > 0xFFFF) { data->data[nesting->start] = 0x83; if (!asn1_write_uint8(data, 0)) return False; if (!asn1_write_uint8(data, 0)) return False; -- cgit From bf772399bf38b16567b68e7fde102431e5a28135 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Feb 2007 07:46:51 +0000 Subject: r21511: this seems to be the nicer fix for the problem with the windows 2000 LDAP client metze (This used to be commit d40465470fa09827ea529e1f2c80bca9efc152a8) --- source4/libcli/ldap/ldap.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index bdcea0962d..5a7174b41d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -237,10 +237,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct ldap_encode_response(&data, &r->response); if (r->SASL.secblob) { asn1_write_ContextSimple(&data, 7, r->SASL.secblob); - } else { - /* ugly but the windows 2000 mmc deturns decoding error without this */ - DATA_BLOB zero = data_blob(NULL, 0); - asn1_write_ContextSimple(&data, 7, &zero); } asn1_pop_tag(&data); break; -- cgit From 60fd088c480e474c3db8870f1288462a8452cea3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Feb 2007 05:37:19 +0000 Subject: r21535: - fixed a crash in the RAW-ACLS test. When a dcerpc_pipe is created using the pattern in the clilsa code, it didn't fill in the p->binding structure. This affects nearly all users of dcerpc_pipe_open_smb(), so the simplest fix is to ensure that dcerpc_pipe_open_smb() initialises the binding if its not already there. - re-enable the RAW-ACLS test (This used to be commit d8875c286d2be49c01703d8fd58bbc1842054bd9) --- source4/libcli/util/clilsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index e491d1c9ee..cd9a02deb1 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -86,7 +86,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } /* open the LSA pipe */ - status = dcerpc_pipe_open_smb(lsa->pipe->conn, lsa->ipc_tree, DCERPC_LSARPC_NAME); + status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME); if (!NT_STATUS_IS_OK(status)) { talloc_free(lsa); return status; -- cgit From 505fd4eb9901a1ff8ecbd244fe2227eae59ca2d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Feb 2007 17:19:35 +0000 Subject: r21591: add new error code metze (This used to be commit 04da3db29d57ffeab3ba39551b326b8c176a5bcb) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 3f646f4be5..716ca438db 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -73,6 +73,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_UNKNOWN_REVISION", WERR_UNKNOWN_REVISION }, { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 69499c17e9..a45831347f 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -200,6 +200,7 @@ #define WERR_NO_SUCH_PRIVILEGE W_ERROR(1313) #define WERR_PRIVILEGE_NOT_HELD W_ERROR(1314) #define WERR_NO_SUCH_USER W_ERROR(1317) +#define WERR_LOGON_FAILURE W_ERROR(1326) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) #define WERR_NO_SUCH_DOMAIN W_ERROR(1355) #define WERR_NO_SYSTEM_RESOURCES W_ERROR(1450) -- cgit From 7f13043d7eed4ee907bda688b5e10bef233871f5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Feb 2007 17:23:35 +0000 Subject: r21592: compress_name() returns NULL for names longer than 15 chars giving NO_MEMORY back is ugly, so give a useful error metze (This used to be commit fbc1e16331c5957892e4bfc439ea5c4e0387b32e) --- source4/libcli/nbt/nbtname.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 871e29794d..584af96984 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -332,6 +332,12 @@ _PUBLIC_ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const s return NT_STATUS_OK; } + if (strlen(r->name) > 15) { + return ndr_push_error(ndr, NDR_ERR_STRING, + "nbt_name longer as 15 chars: %s", + r->name); + } + cname = compress_name(ndr, (const uint8_t *)r->name, r->type); NT_STATUS_HAVE_NO_MEMORY(cname); -- cgit From e31d922592b3bb037daff487f0b68c719e7584d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Feb 2007 17:25:29 +0000 Subject: r21593: give a more useful error, when we can't resolve a long name via broadcast of wins metze (This used to be commit 49591d699653e48f2e9540359e5b4ae97786511c) --- source4/libcli/resolve/nbtlist.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 58433d0a70..e8ea22a0dc 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -126,6 +126,15 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state->name.scope, c)) return c; } + /* + * we can't push long names on the wire, + * so bail out here to give a useful error message + */ + if (strlen(state->name.name) > 15) { + composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); + return c; + } + state->nbtsock = nbt_name_socket_init(state, event_ctx); if (composite_nomem(state->nbtsock, c)) return c; -- cgit From c6b66db2b23f5a590152b3909da1193dc54d21ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Feb 2007 17:26:25 +0000 Subject: r21594: give the same error in all resolve backends metze (This used to be commit 5534ba591deb362e30e40afff923af4b890ab7a9) --- source4/libcli/resolve/host.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index f84a7dc808..43467cd274 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -101,7 +101,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, the right thing to do */ ret = read(state->child_fd, address, sizeof(address)-1); if (ret <= 0) { - composite_error(c, NT_STATUS_BAD_NETWORK_NAME); + composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } @@ -109,7 +109,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, address[ret] = 0; if (strcmp(address, "0.0.0.0") == 0 || inet_addr(address) == INADDR_NONE) { - composite_error(c, NT_STATUS_BAD_NETWORK_NAME); + composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } -- cgit From fcaeedeff3c7d65f65da19440eb7b1ac01481167 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 2 Mar 2007 23:24:27 +0000 Subject: r21668: Add SMB_QFS_POSIX_WHOAMI to trans2.h so it's easy to find. Add convenience API to create an anonymous credential. Don't clobber cmdline_credentials in the UNIX-WHOAMI test. (This used to be commit 73cea4e0c66f57057ed12b07bbb94b4e783ba6bf) --- source4/libcli/raw/trans2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index a3f6e28a2a..bdc5bb2168 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -74,6 +74,7 @@ Found 4 aliased levels #define SMB_QFS_ATTRIBUTE_INFO 0x105 #define SMB_QFS_UNIX_INFO 0x200 #define SMB_QFS_POSIX_INFO 0x201 +#define SMB_QFS_POSIX_WHOAMI 0x202 #define SMB_QFS_VOLUME_INFORMATION 1001 #define SMB_QFS_SIZE_INFORMATION 1003 #define SMB_QFS_DEVICE_INFORMATION 1004 -- cgit From 754d416ea54e1e520aa035a759ec8e3975ab5354 Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 5 Mar 2007 22:26:38 +0000 Subject: r21710: Add client support for the UNIX_INFO2 info level in the QueryFile, QueryPath and FindFirst calls. Add a new torture test to verify the server side. (This used to be commit 7f56da2d1fa0718e5282bb4aea7d9a63a62f0bc7) --- source4/libcli/raw/interfaces.h | 84 +++++++++++++++++++++++++++++++++++-- source4/libcli/raw/rawfileinfo.c | 21 ++++++++++ source4/libcli/raw/rawsearch.c | 67 ++++++++++++++++++++++------- source4/libcli/raw/rawsetfileinfo.c | 21 ++++++++++ source4/libcli/raw/trans2.h | 46 +++++++++++++++++--- 5 files changed, 214 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 60cefe6931..e4efab3375 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -3,6 +3,7 @@ SMB request interface structures Copyright (C) Andrew Tridgell 2003 Copyright (C) James J Myers 2003 + Copyright (C) James Peach 2007 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 @@ -426,6 +427,7 @@ enum smb_fileinfo_level { RAW_FILEINFO_STREAM_INFO = SMB_QFILEINFO_STREAM_INFO, RAW_FILEINFO_COMPRESSION_INFO = SMB_QFILEINFO_COMPRESSION_INFO, RAW_FILEINFO_UNIX_BASIC = SMB_QFILEINFO_UNIX_BASIC, + RAW_FILEINFO_UNIX_INFO2 = SMB_QFILEINFO_UNIX_INFO2, RAW_FILEINFO_UNIX_LINK = SMB_QFILEINFO_UNIX_LINK, RAW_FILEINFO_BASIC_INFORMATION = SMB_QFILEINFO_BASIC_INFORMATION, RAW_FILEINFO_STANDARD_INFORMATION = SMB_QFILEINFO_STANDARD_INFORMATION, @@ -745,6 +747,32 @@ union smb_fileinfo { } out; } unix_basic_info; + /* RAW_FILEINFO_UNIX_INFO2 interface */ + struct { + enum smb_fileinfo_level level; + struct { + union smb_handle_or_path file; + } in; + struct { + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + NTTIME create_time; + uint32_t file_flags; + uint32_t flags_mask; + } out; + } unix_info2; + /* RAW_FILEINFO_UNIX_LINK interface */ struct { enum smb_fileinfo_level level; @@ -867,6 +895,7 @@ enum smb_setfileinfo_level { RAW_SFILEINFO_ALLOCATION_INFO = SMB_SFILEINFO_ALLOCATION_INFO, RAW_SFILEINFO_END_OF_FILE_INFO = SMB_SFILEINFO_END_OF_FILE_INFO, RAW_SFILEINFO_UNIX_BASIC = SMB_SFILEINFO_UNIX_BASIC, + RAW_SFILEINFO_UNIX_INFO2 = SMB_SFILEINFO_UNIX_INFO2, RAW_SFILEINFO_UNIX_LINK = SMB_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK = SMB_SFILEINFO_UNIX_HLINK, RAW_SFILEINFO_BASIC_INFORMATION = SMB_SFILEINFO_BASIC_INFORMATION, @@ -1003,8 +1032,6 @@ union smb_setfileinfo { } in; } mode_information; - - /* RAW_SFILEINFO_UNIX_BASIC interface */ struct { enum smb_setfileinfo_level level; @@ -1026,7 +1053,31 @@ union smb_setfileinfo { uint64_t nlink; } in; } unix_basic; - + + /* RAW_SFILEINFO_UNIX_INFO2 interface */ + struct { + enum smb_setfileinfo_level level; + struct { + union smb_handle_or_path file; + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + NTTIME create_time; + uint32_t file_flags; + uint32_t flags_mask; + } in; + } unix_info2; + /* RAW_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK interface */ struct { enum smb_setfileinfo_level level; @@ -2204,7 +2255,8 @@ enum smb_search_data_level { RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO = SMB_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO = SMB_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO = SMB_FIND_ID_BOTH_DIRECTORY_INFO, - RAW_SEARCH_DATA_UNIX_INFO = SMB_FIND_UNIX_INFO + RAW_SEARCH_DATA_UNIX_INFO = SMB_FIND_UNIX_INFO, + RAW_SEARCH_DATA_UNIX_INFO2 = SMB_FIND_UNIX_INFO2 }; /* union for file search */ @@ -2504,8 +2556,32 @@ union smb_search_data { uint64_t nlink; const char *name; } unix_info; + + /* RAW_SEARCH_DATA_UNIX_INFO2 interface */ + struct { + uint32_t file_index; + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + NTTIME create_time; + uint32_t file_flags; + uint32_t flags_mask; + const char *name; + } unix_info2; }; +/* Callback function passed to the raw search interface. */ +typedef BOOL (*smbcli_search_callback)(void *private, const union smb_search_data *file); enum smb_search_close_level {RAW_FINDCLOSE_GENERIC, RAW_FINDCLOSE_FCLOSE, RAW_FINDCLOSE_FINDCLOSE}; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 38f4d12369..7b15ce6fd6 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -3,6 +3,7 @@ client trans2 operations Copyright (C) James Myers 2003 Copyright (C) Andrew Tridgell 2003 + Copyright (C) James Peach 2007 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 @@ -403,6 +404,26 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->unix_basic_info.out.nlink = BVAL(blob->data, 92); return NT_STATUS_OK; + case RAW_FILEINFO_UNIX_INFO2: + FINFO_CHECK_SIZE(116); + parms->unix_info2.out.end_of_file = BVAL(blob->data, 0); + parms->unix_info2.out.num_bytes = BVAL(blob->data, 8); + parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16); + parms->unix_info2.out.access_time = smbcli_pull_nttime(blob->data, 24); + parms->unix_info2.out.change_time = smbcli_pull_nttime(blob->data, 32); + parms->unix_info2.out.uid = BVAL(blob->data, 40); + parms->unix_info2.out.gid = BVAL(blob->data, 48); + parms->unix_info2.out.file_type = IVAL(blob->data, 52); + parms->unix_info2.out.dev_major = BVAL(blob->data, 60); + parms->unix_info2.out.dev_minor = BVAL(blob->data, 68); + parms->unix_info2.out.unique_id = BVAL(blob->data, 76); + parms->unix_info2.out.permissions = BVAL(blob->data, 84); + parms->unix_info2.out.nlink = BVAL(blob->data, 92); + parms->unix_info2.out.create_time = smbcli_pull_nttime(blob->data, 100); + parms->unix_info2.out.file_flags = IVAL(blob->data, 108); + parms->unix_info2.out.flags_mask = IVAL(blob->data, 112); + return NT_STATUS_OK; + case RAW_FILEINFO_UNIX_LINK: smbcli_blob_pull_string(session, mem_ctx, blob, &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE); diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 4836766a93..5abe19d50c 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client directory search routines Copyright (C) James Myers 2003 + Copyright (C) James Peach 2007 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 @@ -28,7 +29,7 @@ static void smb_raw_search_backend(struct smbcli_request *req, TALLOC_CTX *mem_ctx, uint16_t count, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { union smb_search_data search_data; @@ -69,7 +70,7 @@ static void smb_raw_search_backend(struct smbcli_request *req, static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { struct smbcli_request *req; @@ -110,7 +111,7 @@ static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { struct smbcli_request *req; @@ -605,17 +606,51 @@ static int parse_trans2_search(struct smbcli_tree *tree, } return ofs; - case RAW_SEARCH_DATA_DIRECTORY_INFO: - case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: - case RAW_SEARCH_DATA_NAME_INFO: - case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: - case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: - case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: { - uint_t str_flags = STR_UNICODE; - if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) { - str_flags = STR_ASCII; + case RAW_SEARCH_DATA_UNIX_INFO2: + if (blob->length < (116 + 8 + 1)) { + return -1; } - + + ofs = IVAL(blob->data, 0); + data->unix_info2.file_index = IVAL(blob->data, 4); + data->unix_info2.end_of_file = BVAL(blob->data, 8); + data->unix_info2.num_bytes = BVAL(blob->data, 16); + data->unix_info2.status_change_time = smbcli_pull_nttime(blob->data, 24); + data->unix_info2.access_time = smbcli_pull_nttime(blob->data, 32); + data->unix_info2.change_time = smbcli_pull_nttime(blob->data, 40); + data->unix_info2.uid = IVAL(blob->data, 48); + data->unix_info2.gid = IVAL(blob->data, 56); + data->unix_info2.file_type = IVAL(blob->data, 64); + data->unix_info2.dev_major = BVAL(blob->data, 68); + data->unix_info2.dev_minor = BVAL(blob->data, 76); + data->unix_info2.unique_id = BVAL(blob->data, 84); + data->unix_info2.permissions = IVAL(blob->data, 92); + data->unix_info2.nlink = IVAL(blob->data, 100); + data->unix_info2.create_time = smbcli_pull_nttime(blob->data, 108); + data->unix_info2.file_flags = IVAL(blob->data, 116); + data->unix_info2.flags_mask = IVAL(blob->data, 120); + + /* There is no length field for this name but we know it's null terminated. */ + len = smbcli_blob_pull_unix_string(tree->session, mem_ctx, blob, + &data->unix_info2.name, 116 + 8, 0); + + if (ofs != 0 && ofs < (116 + 8 + len)) { + return -1; + } + + return ofs; + + case RAW_SEARCH_DATA_DIRECTORY_INFO: + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_NAME_INFO: + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: { + uint_t str_flags = STR_UNICODE; + if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) { + str_flags = STR_ASCII; + } + status = smb_raw_search_common(mem_ctx, level, blob, data, &ofs, str_flags); if (!NT_STATUS_IS_OK(status)) { return -1; @@ -638,7 +673,7 @@ static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, int16_t count, DATA_BLOB *blob, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { int i; @@ -677,7 +712,7 @@ static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { DATA_BLOB p_blob, d_blob; NTSTATUS status; @@ -725,7 +760,7 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { DATA_BLOB p_blob, d_blob; NTSTATUS status; diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 0daf14e0cc..794ba25480 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -3,6 +3,7 @@ RAW_SFILEINFO_* calls Copyright (C) James Myers 2003 Copyright (C) Andrew Tridgell 2003 + Copyright (C) James Peach 2007 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 @@ -166,6 +167,26 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, SBVAL(blob->data, 92, parms->unix_basic.in.nlink); return True; + case RAW_SFILEINFO_UNIX_INFO2: + NEED_BLOB(116); + SBVAL(blob->data, 0, parms->unix_info2.in.end_of_file); + SBVAL(blob->data, 8, parms->unix_info2.in.num_bytes); + smbcli_push_nttime(blob->data, 16, parms->unix_info2.in.status_change_time); + smbcli_push_nttime(blob->data, 24, parms->unix_info2.in.access_time); + smbcli_push_nttime(blob->data, 32, parms->unix_info2.in.change_time); + SBVAL(blob->data, 40,parms->unix_info2.in.uid); + SBVAL(blob->data, 48,parms->unix_info2.in.gid); + SIVAL(blob->data, 52,parms->unix_info2.in.file_type); + SBVAL(blob->data, 60,parms->unix_info2.in.dev_major); + SBVAL(blob->data, 68,parms->unix_info2.in.dev_minor); + SBVAL(blob->data, 76,parms->unix_info2.in.unique_id); + SBVAL(blob->data, 84,parms->unix_info2.in.permissions); + SBVAL(blob->data, 92,parms->unix_info2.in.nlink); + smbcli_push_nttime(blob->data, 100, parms->unix_info2.in.create_time); + SIVAL(blob->data, 108, parms->unix_info2.in.file_flags); + SIVAL(blob->data, 112, parms->unix_info2.in.flags_mask); + return True; + case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_DISPOSITION_INFORMATION, diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index bdc5bb2168..e4e85b58bc 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -3,6 +3,7 @@ SMB transaction2 handling Copyright (C) Jeremy Allison 1994-2002. Copyright (C) Andrew Tridgell 1995-2003. + Copyright (C) James Peach 2007 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 @@ -141,6 +142,7 @@ Found 8 aliased levels #define SMB_QFILEINFO_COMPRESSION_INFO 0x10b #define SMB_QFILEINFO_UNIX_BASIC 0x200 #define SMB_QFILEINFO_UNIX_LINK 0x201 +#define SMB_QFILEINFO_UNIX_INFO2 0x20b #define SMB_QFILEINFO_BASIC_INFORMATION 1004 #define SMB_QFILEINFO_STANDARD_INFORMATION 1005 #define SMB_QFILEINFO_INTERNAL_INFORMATION 1006 @@ -213,6 +215,7 @@ Found 13 valid levels #define SMB_SPATHINFO_POSIX_ACL 0x204 #define SMB_SPATHINFO_XATTR 0x205 #define SMB_SFILEINFO_ATTR_FLAGS 0x206 +#define SMB_SFILEINFO_UNIX_INFO2 0x20b #define SMB_SFILEINFO_BASIC_INFORMATION 1004 #define SMB_SFILEINFO_RENAME_INFORMATION 1010 #define SMB_SFILEINFO_DISPOSITION_INFORMATION 1013 @@ -267,6 +270,7 @@ Found 0 aliased levels #define SMB_FIND_ID_FULL_DIRECTORY_INFO 0x105 #define SMB_FIND_ID_BOTH_DIRECTORY_INFO 0x106 #define SMB_FIND_UNIX_INFO 0x202 +#define SMB_FIND_UNIX_INFO2 0x20b /* flags on trans2 findfirst/findnext that control search */ #define FLAG_TRANS2_FIND_CLOSE 0x1 @@ -321,9 +325,6 @@ Found 0 aliased levels #define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL)) -#define SMB_QFILEINFO_UNIX_BASIC 0x200 /* UNIX File Info*/ -#define SMB_SFILEINFO_UNIX_BASIC 0x200 - #define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */ /* means "don't change it" */ #define SMB_UID_NO_CHANGE 0xFFFFFFFF @@ -336,6 +337,8 @@ Found 0 aliased levels #define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF /* +UNIX_BASIC info level: + Offset Size Name 0 LARGE_INTEGER EndOfFile File size 8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks). @@ -365,6 +368,31 @@ Offset Size Name 100 - end. */ +/* +SMB_QUERY_FILE_UNIX_INFO2 is SMB_QUERY_FILE_UNIX_BASIC with create +time and file flags appended. The corresponding info level for +findfirst/findnext is SMB_FIND_FILE_UNIX_UNIX2. + +Size Offset Value +--------------------- +0 LARGE_INTEGER EndOfFile File size +8 LARGE_INTEGER Blocks Number of blocks used on disk +16 LARGE_INTEGER ChangeTime Attribute change time +24 LARGE_INTEGER LastAccessTime Last access time +32 LARGE_INTEGER LastModificationTime Last modification time +40 LARGE_INTEGER Uid Numeric user id for the owner +48 LARGE_INTEGER Gid Numeric group id of owner +56 ULONG Type Enumeration specifying the file type +60 LARGE_INTEGER devmajor Major device number if type is device +68 LARGE_INTEGER devminor Minor device number if type is device +76 LARGE_INTEGER uniqueid This is a server-assigned unique id +84 LARGE_INTEGER permissions Standard UNIX permissions +92 LARGE_INTEGER nlinks Number of hard link) +100 LARGE_INTEGER CreationTime Create/birth time +108 ULONG FileFlags File flags enumeration +112 ULONG FileFlagsMask Mask of valid flags +*/ + /* UNIX filetype mappings. */ #define UNIX_TYPE_FILE 0 @@ -404,12 +432,20 @@ Offset Size Name #define UNIX_EXTRA_MASK 0007000 #define UNIX_ALL_MASK 0007777 +/* Flags for the file_flags field in UNIX_INFO2: */ +#define EXT_SECURE_DELETE 0x00000001 +#define EXT_ENABLE_UNDELETE 0x00000002 +#define EXT_SYNCHRONOUS 0x00000004 +#define EXT_IMMUTABLE 0x00000008 +#define EXT_OPEN_APPEND_ONLY 0x00000010 +#define EXT_DO_NOT_BACKUP 0x00000020 +#define EXT_NO_UPDATE_ATIME 0x00000040 +#define EXT_HIDDEN 0x00000080 + #define SMB_QFILEINFO_UNIX_LINK 0x201 #define SMB_SFILEINFO_UNIX_LINK 0x201 #define SMB_SFILEINFO_UNIX_HLINK 0x203 -#define SMB_FIND_FILE_UNIX 0x202 - /* Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus 64-bits worth of capability fun :-). -- cgit From 3370f2f2d7e5296e8f54f721003c07fac111d1ad Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Mar 2007 06:23:39 +0000 Subject: r21761: - Give more detail on LDAP client library failures (make it clear where the error is from) - Make default error string more consistant Andrew Bartlett (This used to be commit 7f115579d20a3112efd11444fafcbf78698fc9a1) --- source4/libcli/ldap/ldap_client.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 2c2cd0dd66..82cafd721a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -562,6 +562,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; if (!ldap_encode(msg, &req->data, req)) { + status = NT_STATUS_INTERNAL_ERROR; goto failed; } @@ -704,12 +705,14 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r /* return error string representing the last error */ -const char *ldap_errstr(struct ldap_connection *conn, NTSTATUS status) +const char *ldap_errstr(struct ldap_connection *conn, + TALLOC_CTX *mem_ctx, + NTSTATUS status) { if (NT_STATUS_IS_LDAP(status) && conn->last_error != NULL) { - return conn->last_error; + return talloc_strdup(mem_ctx, conn->last_error); } - return nt_errstr(status); + return talloc_asprintf(mem_ctx, "LDAP client internal error: %s", nt_errstr(status)); } -- cgit From 9b03286b32a916dbef59f1459eefa01f0ebfeed3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Mar 2007 00:59:06 +0000 Subject: r21806: I've been working over the last week to fix up the LDAP backend for Samba4. This only broke on global catalog queries, which turned out to be due to changes in the partitions module that metze needed for his DRSUAPI work. I've reworked partitions.c to always include the 'problematic' control, and therefore demonstrated that this is the issue. This ensures consistency, and should help with finding issues like this in future. As this control (DSDB_CONTROL_CURRENT_PARTITION_OID) is not intended to be linearised, I've added logic to allow it to be skipped when creating network packets. I've likewise make our LDAP server skip unknown controls, when marked 'not critical' on it's input, rather than just dropping the entire request. I need some help to generate a correct error packet when it is marked critical. Further work could perhaps be to have the ldap_encode routine return a textual description of what failed to encode, as that would have saved me a lot of time... Andrew Bartlett (This used to be commit eef710668f91d1bbaa2d834d9e653e11c8aac817) --- source4/libcli/cldap/cldap.c | 18 ++++++--- source4/libcli/ldap/ldap.c | 75 +++++++++++++++++++++++-------------- source4/libcli/ldap/ldap_client.c | 7 +++- source4/libcli/ldap/ldap_controls.c | 71 ++++++++++++++++++++++------------- 4 files changed, 107 insertions(+), 64 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 9dfa8e81b1..96b60da25f 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -107,8 +107,9 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } /* this initial decode is used to find the message id */ - if (!ldap_decode(&asn1, ldap_msg)) { - DEBUG(2,("Failed to decode ldap message\n")); + status = ldap_decode(&asn1, ldap_msg); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); return; } @@ -428,6 +429,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, struct cldap_search *io) { struct ldap_message *ldap_msg; + NTSTATUS status; if (req == NULL) { return NT_STATUS_NO_MEMORY; @@ -448,9 +450,11 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, ldap_msg = talloc(mem_ctx, struct ldap_message); NT_STATUS_HAVE_NO_MEMORY(ldap_msg); - if (!ldap_decode(&req->asn1, ldap_msg)) { + status = ldap_decode(&req->asn1, ldap_msg); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status))); talloc_free(req); - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + return status; } ZERO_STRUCT(io->out); @@ -462,9 +466,11 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, *io->out.response = ldap_msg->r.SearchResultEntry; /* decode the 2nd part */ - if (!ldap_decode(&req->asn1, ldap_msg)) { + status = ldap_decode(&req->asn1, ldap_msg); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status))); talloc_free(req); - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + return status; } } diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5a7174b41d..1e308d5847 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -925,7 +925,9 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); } -BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) +/* This routine returns LDAP status codes */ + +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) { uint8_t tag; @@ -933,7 +935,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_Integer(data, &msg->messageid); if (!asn1_peek_uint8(data, &tag)) - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); switch(tag) { @@ -950,12 +952,12 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen == -1) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } if (pwlen != 0) { char *pw = talloc_size(msg, pwlen+1); if (!pw) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; @@ -971,7 +973,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_OctetString(data, &tmp_blob); r->creds.SASL.secblob = talloc(msg, DATA_BLOB); if (!r->creds.SASL.secblob) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, tmp_blob.data, tmp_blob.length); @@ -982,7 +984,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_end_tag(data); } else { /* Neither Simple nor SASL bind */ - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } asn1_end_tag(data); break; @@ -998,7 +1000,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_ContextSimple(data, 7, &tmp_blob); r->SASL.secblob = talloc(msg, DATA_BLOB); if (!r->SASL.secblob) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, tmp_blob.data, tmp_blob.length); @@ -1030,7 +1032,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->tree = ldap_decode_filter_tree(msg, data); if (r->tree == NULL) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } asn1_start_tag(data, ASN1_SEQUENCE(0)); @@ -1038,15 +1040,16 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->num_attributes = 0; r->attributes = NULL; - while (asn1_tag_remaining(data) > 0) { + while (asn1_tag_remaining(data) > 0) { + const char *attr; if (!asn1_read_OctetString_talloc(msg, data, &attr)) - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); if (!add_string_to_array(msg, attr, &r->attributes, &r->num_attributes)) - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } asn1_end_tag(data); @@ -1106,7 +1109,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_end_tag(data); if (!add_mod_to_array_talloc(msg, &mod, &r->mods, &r->num_mods)) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } } @@ -1157,7 +1160,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); if (len == -1) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } dn = talloc_size(msg, len+1); if (dn == NULL) @@ -1193,11 +1196,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); if (len == -1) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } newsup = talloc_size(msg, len+1); if (newsup == NULL) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } asn1_read(data, newsup, len); newsup[len] = '\0'; @@ -1259,19 +1262,19 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_ExtendedRequest; asn1_start_tag(data,tag); if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } r->oid = blob2string_talloc(msg, tmp_blob); data_blob_free(&tmp_blob); if (!r->oid) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { asn1_read_ContextSimple(data, 1, &tmp_blob); r->value = talloc(msg, DATA_BLOB); if (!r->value) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); @@ -1296,7 +1299,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->oid = blob2string_talloc(msg, tmp_blob); data_blob_free(&tmp_blob); if (!r->oid) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } } else { r->oid = NULL; @@ -1306,7 +1309,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_ContextSimple(data, 1, &tmp_blob); r->value = talloc(msg, DATA_BLOB); if (!r->value) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); @@ -1318,34 +1321,45 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) break; } default: - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } msg->controls = NULL; if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i; + int i = 0; struct ldb_control **ctrl = NULL; asn1_start_tag(data, ASN1_CONTEXT(0)); - for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); if (!ctrl) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } ctrl[i] = talloc(ctrl, struct ldb_control); if (!ctrl[i]) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } - if (!ldap_decode_control(ctrl, data, ctrl[i])) { - return False; + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + return NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + i++; } - } if (ctrl != NULL) { @@ -1358,7 +1372,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } asn1_end_tag(data); - return ((!data->has_error) && (data->nesting == NULL)); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 82cafd721a..8852fd5427 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -169,6 +169,8 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message */ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { + int ret; + NTSTATUS status; struct asn1_data asn1; struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); @@ -182,8 +184,9 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - if (!ldap_decode(&asn1, msg)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + status = ldap_decode(&asn1, msg); + if (!NT_STATUS_IS_OK(status)) { + return status; } ldap_match_message(conn, msg); diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 5cd0451136..bbb0cb1aa5 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -1059,14 +1059,35 @@ struct control_handler ldap_known_controls[] = { { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, +/* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */ + { "1.3.6.1.4.1.7165.4.3.2", NULL, NULL }, +/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */ + { "1.3.6.1.4.1.7165.4.4.1", NULL, NULL }, { NULL, NULL, NULL } }; -BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) +BOOL ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) { int i; + + for (i = 0; ldap_known_controls[i].oid != NULL; i++) { + if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { + if (!ldap_known_controls[i].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { + return False; + } + break; + } + } + if (ldap_known_controls[i].oid == NULL) { + return False; + } + + return True; +} + +BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) +{ DATA_BLOB oid; - DATA_BLOB value; if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; @@ -1096,19 +1117,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr goto end_tag; } - if (!asn1_read_OctetString(data, &value)) { - return False; - } - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { - return False; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { + if (!asn1_read_OctetString(data, value)) { return False; } @@ -1125,6 +1134,26 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr DATA_BLOB value; int i; + for (i = 0; ldap_known_controls[i].oid != NULL; i++) { + if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { + if (!ldap_known_controls[i].encode) { + if (ctrl->critical) { + return False; + } else { + /* not encoding this control */ + return True; + } + } + if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { + return False; + } + break; + } + } + if (ldap_known_controls[i].oid == NULL) { + return False; + } + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -1143,18 +1172,6 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr goto pop_tag; } - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { - return False; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return False; - } - if (!asn1_write_OctetString(data, value.data, value.length)) { return False; } -- cgit From c61db93c7e2d46ac0fd1a0f98199c111fd416a9b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 23 Mar 2007 19:24:21 +0000 Subject: r21949: After discussion with the Apple and Linux client maintainers, changing the FindFirst response for the UNIX_INFO2 level to include a length field before the name. The name is not required to be null terminated. the lenght field does not count any null. (This used to be commit eef672bfff6b112ceceec2a58c78042352e83276) --- source4/libcli/raw/interfaces.h | 2 +- source4/libcli/raw/rawsearch.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index e4efab3375..4620baed78 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2576,7 +2576,7 @@ union smb_search_data { NTTIME create_time; uint32_t file_flags; uint32_t flags_mask; - const char *name; + struct smb_wire_string name; } unix_info2; }; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 5abe19d50c..3c7ca5788e 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -607,7 +607,12 @@ static int parse_trans2_search(struct smbcli_tree *tree, return ofs; case RAW_SEARCH_DATA_UNIX_INFO2: - if (blob->length < (116 + 8 + 1)) { + /* 8 - size of ofs + file_index + * 116 - size of unix_info2 + * 4 - size of name length + * 2 - "." is the shortest name + */ + if (blob->length < (116 + 8 + 4 + 2)) { return -1; } @@ -630,11 +635,16 @@ static int parse_trans2_search(struct smbcli_tree *tree, data->unix_info2.file_flags = IVAL(blob->data, 116); data->unix_info2.flags_mask = IVAL(blob->data, 120); - /* There is no length field for this name but we know it's null terminated. */ - len = smbcli_blob_pull_unix_string(tree->session, mem_ctx, blob, - &data->unix_info2.name, 116 + 8, 0); + /* There is a 4 byte length field for this name. The length + * does not include the NULL terminator. + */ + len = smbcli_blob_pull_string(tree->session, mem_ctx, blob, + &data->unix_info2.name, + 8 + 116, /* offset to length */ + 8 + 116 + 4, /* offset to string */ + 0); - if (ofs != 0 && ofs < (116 + 8 + len)) { + if (ofs != 0 && ofs < (8 + 116 + 4 + len)) { return -1; } -- cgit From 4685a42eaf28e0d4644bfa4cf18ef08abee329d3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 5 Apr 2007 07:37:21 +0000 Subject: r22090: fix error handling in cldap client library to cope with bad host names (This used to be commit 99c51b104d05a8ad32563497216271e2f20d4985) --- source4/libcli/cldap/cldap.c | 16 +++++++++++----- source4/libcli/cldap/cldap.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 96b60da25f..c68a037552 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -165,7 +165,8 @@ static void cldap_request_timeout(struct event_context *event_ctx, return; } - req->state = CLDAP_REQUEST_TIMEOUT; + req->state = CLDAP_REQUEST_ERROR; + req->status = NT_STATUS_IO_TIMEOUT; if (req->async.fn) { req->async.fn(req); } @@ -186,10 +187,14 @@ static void cldap_socket_send(struct cldap_socket *cldap) status = socket_sendto(cldap->sock, &req->encoded, &len, req->dest); if (NT_STATUS_IS_ERR(status)) { - DEBUG(3,("Failed to send cldap request of length %u to %s:%d\n", + DEBUG(0,("Failed to send cldap request of length %u to %s:%d\n", (unsigned)req->encoded.length, req->dest->addr, req->dest->port)); DLIST_REMOVE(cldap->send_queue, req); - talloc_free(req); + req->state = CLDAP_REQUEST_ERROR; + req->status = status; + if (req->async.fn) { + req->async.fn(req); + } continue; } @@ -442,9 +447,10 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, } } - if (req->state == CLDAP_REQUEST_TIMEOUT) { + if (req->state == CLDAP_REQUEST_ERROR) { + status = req->status; talloc_free(req); - return NT_STATUS_IO_TIMEOUT; + return status; } ldap_msg = talloc(mem_ctx, struct ldap_message); diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 8bae2aa41b..928cf1f3e4 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -28,7 +28,7 @@ struct ldap_message; enum cldap_request_state {CLDAP_REQUEST_SEND, CLDAP_REQUEST_WAIT, CLDAP_REQUEST_DONE, - CLDAP_REQUEST_TIMEOUT}; + CLDAP_REQUEST_ERROR}; /* a cldap request packet @@ -39,6 +39,7 @@ struct cldap_request { struct cldap_socket *cldap; enum cldap_request_state state; + NTSTATUS status; /* where to send the request */ struct socket_address *dest; -- cgit From 1c8b46bb7236edac23de83d1d8de7244e4044a81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Apr 2007 11:02:45 +0000 Subject: r22405: fix memory leak in error path metze (This used to be commit d19195bfa5405822613d5236cd76547f0ac77bde) --- source4/libcli/ldap/ldap_client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8852fd5427..39f265015a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -186,6 +186,7 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) status = ldap_decode(&asn1, msg); if (!NT_STATUS_IS_OK(status)) { + asn1_free(&asn1); return status; } -- cgit From b7e20c87e317ae73feb7f393a38d0ab0fa64d5d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 30 Apr 2007 22:38:27 +0000 Subject: r22616: allow the unclist file to not specify a share name, and instead inherit the share name from the command line if it is not specified. This allows you to just specify the servers in the unclist, and connect to the same share on all servers. (This used to be commit 946f5d09ae204348026170173cf2bfd30d49e4f2) --- source4/libcli/cliconnect.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 45f44adba1..27f9736371 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -224,6 +224,9 @@ BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, if (p && *p) { *sharename = talloc_strdup(mem_ctx, p); terminate_path_at_separator(*sharename); + } else { + *sharename = talloc_strdup(mem_ctx, + lp_parm_string(-1, "torture", "share")); } if (*hostname && *sharename) { -- cgit From a475bfdcca0bc84a3a823a3061bbd53d9bad2842 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 May 2007 02:08:11 +0000 Subject: r22620: fix compiler warnings metze (This used to be commit b7adc88e743308742545f3ee6710f8c0bfa197d8) --- source4/libcli/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 9b4a1a158f..341b934aae 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -39,7 +39,7 @@ struct search_private { Interpret a long filename structure. ****************************************************************************/ static BOOL interpret_long_filename(enum smb_search_data_level level, - union smb_search_data *info, + const union smb_search_data *info, struct clilist_file_info *finfo) { struct clilist_file_info finfo2; @@ -73,7 +73,7 @@ static BOOL interpret_long_filename(enum smb_search_data_level level, } /* callback function used for trans2 search */ -static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) +static BOOL smbcli_list_new_callback(void *private, const union smb_search_data *file) { struct search_private *state = (struct search_private*) private; struct clilist_file_info *tdl; @@ -204,7 +204,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu The length of the structure is returned. ****************************************************************************/ static BOOL interpret_short_filename(enum smb_search_data_level level, - union smb_search_data *info, + const union smb_search_data *info, struct clilist_file_info *finfo) { struct clilist_file_info finfo2; @@ -230,7 +230,7 @@ static BOOL interpret_short_filename(enum smb_search_data_level level, } /* callback function used for smb_search */ -static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) +static BOOL smbcli_list_old_callback(void *private, const union smb_search_data *file) { struct search_private *state = (struct search_private*) private; struct clilist_file_info *tdl; -- cgit From 298f178dcacad6c92e6e1901243d1ca753a12d6c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 May 2007 09:06:25 +0000 Subject: r22628: convert to new composite api and free the smbcli_request explicit to fix a crash where the request handler gets called after its private data is already freed metze (This used to be commit 55306c618807f2661090d2189e269cb3e142ee06) --- source4/libcli/smb_composite/sesssetup.c | 57 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 8528ac2ef7..9267d1d38b 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -38,6 +38,16 @@ struct sesssetup_state { struct smbcli_request *req; }; +static int sesssetup_state_destructor(struct sesssetup_state *state) +{ + if (state->req) { + talloc_free(state->req); + state->req = NULL; + } + + return 0; +} + static NTSTATUS session_setup_old(struct composite_context *c, struct smbcli_session *session, struct smb_composite_sesssetup *io, @@ -75,6 +85,7 @@ static void request_handler(struct smbcli_request *req) NTSTATUS session_key_err, nt_status; c->status = smb_raw_sesssetup_recv(req, state, &state->setup); + state->req = NULL; switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: @@ -90,8 +101,7 @@ static void request_handler(struct smbcli_request *req) &state->req); if (NT_STATUS_IS_OK(nt_status)) { c->status = nt_status; - state->req->async.fn = request_handler; - state->req->async.private = c; + composite_continue_smb(c, state->req, request_handler, c); return; } } @@ -109,8 +119,7 @@ static void request_handler(struct smbcli_request *req) &state->req); if (NT_STATUS_IS_OK(nt_status)) { c->status = nt_status; - state->req->async.fn = request_handler; - state->req->async.private = c; + composite_continue_smb(c, state->req, request_handler, c); return; } } @@ -128,8 +137,7 @@ static void request_handler(struct smbcli_request *req) &state->req); if (NT_STATUS_IS_OK(nt_status)) { c->status = nt_status; - state->req->async.fn = request_handler; - state->req->async.private = c; + composite_continue_smb(c, state->req, request_handler, c); return; } } @@ -158,7 +166,7 @@ static void request_handler(struct smbcli_request *req) } else { state->setup.spnego.in.secblob = data_blob(NULL, 0); } - + /* we need to do another round of session setup. We keep going until both sides are happy */ session_key_err = gensec_session_key(session->gensec, &session_key); @@ -176,8 +184,7 @@ static void request_handler(struct smbcli_request *req) session->vuid = state->io->out.vuid; state->req = smb_raw_sesssetup_send(session, &state->setup); session->vuid = vuid; - state->req->async.fn = request_handler; - state->req->async.private = c; + composite_continue_smb(c, state->req, request_handler, c); return; } break; @@ -196,14 +203,12 @@ static void request_handler(struct smbcli_request *req) } } - if (NT_STATUS_IS_OK(c->status)) { - c->state = COMPOSITE_STATE_DONE; - } else { - c->state = COMPOSITE_STATE_ERROR; - } - if (c->async.fn) { - c->async.fn(c); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; } + + composite_done(c); } @@ -457,20 +462,16 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se struct sesssetup_state *state; NTSTATUS status; - c = talloc_zero(session, struct composite_context); + c = composite_create(session, session->transport->socket->event.ctx); if (c == NULL) return NULL; - state = talloc(c, struct sesssetup_state); - if (state == NULL) { - talloc_free(c); - return NULL; - } + state = talloc_zero(c, struct sesssetup_state); + if (composite_nomem(state, c)) return c; + c->private_data = state; state->io = io; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->private_data = state; - c->event_ctx = session->transport->socket->event.ctx; + talloc_set_destructor(state, sesssetup_state_destructor); /* no session setup at all in earliest protocol varients */ if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) { @@ -491,13 +492,11 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) { - state->req->async.fn = request_handler; - state->req->async.private = c; + composite_continue_smb(c, state->req, request_handler, c); return c; } - c->state = COMPOSITE_STATE_ERROR; - c->status = status; + composite_error(c, status); return c; } -- cgit From 68b531e81784d218b598e4ec403443bbc039ca77 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 May 2007 15:19:53 +0000 Subject: r22748: fix memleaks by passing an mem_ctx to irpc_servers_byname() metze (This used to be commit b54584dfabee77ec7743cab431bda9765057a295) --- source4/libcli/finddcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index d8acf44ba0..09967c72b1 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -133,7 +133,7 @@ static void finddcs_name_resolved(struct composite_context *ctx) return; } - nbt_servers = irpc_servers_byname(state->msg_ctx, "nbt_server"); + nbt_servers = irpc_servers_byname(state->msg_ctx, state, "nbt_server"); if ((nbt_servers == NULL) || (nbt_servers[0].id == 0)) { fallback_node_status(state); return; -- cgit From 7fe9a3255ae84ed531d0a3d0a8cbf0812559fc5e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 May 2007 15:27:50 +0000 Subject: r22749: fix memory leak of nbt_name_request structure which are used to send replies and never have an async callback that could free it. we only had the memory leak in the error path the standard path was ok. metze (This used to be commit d2a2fe662db5b773f4bd54498d6b31b773633903) --- source4/libcli/nbt/nbtsocket.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index c1e30fc245..0931de63c8 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -45,6 +45,7 @@ static int nbt_name_request_destructor(struct nbt_name_request *req) req->name_trn_id = 0; } if (req->te) { + talloc_free(req->te); req->te = NULL; } if (req->nbtsock->send_queue == NULL) { @@ -102,6 +103,8 @@ failed: talloc_free(tmp_ctx); if (req->async.fn) { req->async.fn(req); + } else if (req->is_reply) { + talloc_free(req); } return; } @@ -140,6 +143,8 @@ static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event } if (req->async.fn) { req->async.fn(req); + } else if (req->is_reply) { + talloc_free(req); } } @@ -462,9 +467,7 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) if (event_loop_once(req->nbtsock->event_ctx) != 0) { req->state = NBT_REQUEST_ERROR; req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - if (req->async.fn) { - req->async.fn(req); - } + break; } } return req->status; -- cgit From cc26fe9b749d00bc7c002f6a5a24ff67af497c49 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 May 2007 21:17:58 +0000 Subject: r22762: Some ldb_map changes: * Change license to LGPL, so it can be used by non-Samba users of LDB (cleared with Martin as well). * Include ldb_map in standalone build. * Move ldb_map to its own directory (This used to be commit a90202abca26c0da5425a2f3dd8494077c3290fd) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 6aba69c2af..74af8185e6 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -77,7 +77,7 @@ DESCRIPTION = CLDAP client library OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h PUBLIC_DEPENDENCIES = LIBCLI_LDAP -PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL ldb +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB [LIBRARY::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h -- cgit From 7e330c7c0c2aecf2dd2d049b0a58e20309ad4223 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 May 2007 08:59:14 +0000 Subject: r22788: fix typo metze (This used to be commit 635a636e89e462825efaacd5563c40fec2ceefb1) --- source4/libcli/smb2/lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c index c06c10a806..23693a0757 100644 --- a/source4/libcli/smb2/lock.c +++ b/source4/libcli/smb2/lock.c @@ -39,7 +39,7 @@ struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io smb2_push_handle(req->out.body+0x08, &io->in.file.handle); SBVAL(req->out.body, 0x18, io->in.offset); SBVAL(req->out.body, 0x20, io->in.count); - SIVAL(req->out.body, 0x28, io->in.unknown5); + SIVAL(req->out.body, 0x24, io->in.unknown5); SIVAL(req->out.body, 0x28, io->in.flags); smb2_transport_send(req); -- cgit From e1635caaf38b69cc0b237ebbc6c2dff08ac7e285 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 May 2007 10:03:04 +0000 Subject: r22790: fix initialization for chained requests metze (This used to be commit e1cc933c009f98264c0e8c65bfd93a0d1219a0e2) --- source4/libcli/raw/rawrequest.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 3eab563a40..7d1bfdb30d 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -268,6 +268,7 @@ NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req, SSVAL(req->out.vwv, VWV(wct), buflen); req->out.size += new_size; + req->out.data_size += new_size; return NT_STATUS_OK; } -- cgit From 4ef7bab6d0dd64fc426508be164b3d3f24762b22 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 May 2007 10:05:13 +0000 Subject: r22791: make it possible to use smb2_create_blob_add() in the server code too metze (This used to be commit c08eeb62ca001cebcb7af2b655269e4b388e69c1) --- source4/libcli/smb2/create.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index da21d090fd..fe91acbf0a 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -31,9 +31,9 @@ /* add a blob to a smb2_create attribute blob */ -static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - uint32_t tag, - DATA_BLOB add, BOOL last) +NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + uint32_t tag, + DATA_BLOB add, BOOL last) { NTSTATUS status; uint32_t ofs = blob->length; -- cgit From 5151068d5a98a143dd77bddeb3af2a4775cb959d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 17:08:18 +0000 Subject: r22858: - let SMB2-LOCK-VALID-REQUEST pass against longhorn beta3 - add modify the SMB2-LOCK-BLOCK-WRITE test to also test reading and name in SMB2-LOCK-RW-EXCLUSIV - add SMB2-LOCK-NONE and SMB2-LOCK-SHARED metze (This used to be commit 258555975d3877cff3bc3022f3439cdd61f6c8ac) --- source4/libcli/raw/interfaces.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 4620baed78..d0c3ab2d15 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1889,11 +1889,12 @@ union smb_lock { uint64_t offset; uint64_t count; uint32_t unknown5; -#define SMB2_LOCK_FLAG_NONE 0x00000000 -#define SMB2_LOCK_FLAG_EXCLUSIV 0x00000002 -#define SMB2_LOCK_FLAG_UNLOCK 0x00000004 -#define SMB2_LOCK_FLAGS_MASK 0x00000006 - uint32_t flags; +#define SMB2_LOCK_FLAG_NONE 0x00000000 +#define SMB2_LOCK_FLAG_SHARED 0x00000001 +#define SMB2_LOCK_FLAG_EXCLUSIV 0x00000002 +#define SMB2_LOCK_FLAG_UNLOCK 0x00000004 +#define SMB2_LOCK_FLAG_NO_PENDING 0x00000010 + uint32_t flags; } in; struct { /* static body buffer 4 (0x04) bytes */ -- cgit From bf62b6642c77e14142cdb724dc99dd3f8bfd89ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 18:02:49 +0000 Subject: r22866: handle incoming chained smb2 requests in our server code to let the windows explorer in longhorn beta3 work. metze (This used to be commit 2390c9f24daccec917608cac0870890cdc73cb1c) --- source4/libcli/smb2/request.c | 24 ++++++++++++------------ source4/libcli/smb2/smb2.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 87c4dd78e1..ef024d53f8 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -80,18 +80,18 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req->out.body_size = body_fixed_size; req->out.dynamic = (body_dynamic_size ? req->out.body + body_fixed_size : NULL); - SIVAL(req->out.hdr, 0, SMB2_MAGIC); - SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); - SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); - SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,0); - SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN2,0); - SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); - SIVAL(req->out.hdr, SMB2_HDR_PID, 0); - SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SBVAL(req->out.hdr, SMB2_HDR_UID, 0); + SIVAL(req->out.hdr, 0, SMB2_MAGIC); + SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); + SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); + SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); + SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0); + SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); + SIVAL(req->out.hdr, SMB2_HDR_CHAIN_OFFSET, 0); + SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_PID, 0); + SIVAL(req->out.hdr, SMB2_HDR_TID, 0); + SBVAL(req->out.hdr, SMB2_HDR_UID, 0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); /* set the length of the fixed body part and +1 if there's a dynamic part also */ diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 586acaccf6..4db7c126d8 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -164,7 +164,7 @@ struct smb2_request { #define SMB2_HDR_OPCODE 0x0c #define SMB2_HDR_UNKNOWN1 0x0e #define SMB2_HDR_FLAGS 0x10 -#define SMB2_HDR_UNKNOWN2 0x14 +#define SMB2_HDR_CHAIN_OFFSET 0x14 #define SMB2_HDR_SEQNUM 0x18 #define SMB2_HDR_PID 0x20 #define SMB2_HDR_TID 0x24 -- cgit From cb00a33c672ce78dc58a722804013e5b567fdf45 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 May 2007 07:16:04 +0000 Subject: r22884: Be consistant with the case of these constants. Andrew Bartlett (This used to be commit 7b086eebd6af21674ca18c7d9b35cb2c6b57514a) --- source4/libcli/ldap/ldap.h | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/util/nterr.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 30c5acc6fb..faf6815390 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -79,7 +79,7 @@ enum ldap_result_code { LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, LDAP_INAPPROPRIATE_AUTHENTICATION = 48, LDAP_INVALID_CREDENTIALS = 49, - LDAP_INSUFFICIENT_ACCESS_RIGHTs = 50, + LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, LDAP_BUSY = 51, LDAP_UNAVAILABLE = 52, LDAP_UNWILLING_TO_PERFORM = 53, diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 39f265015a..c819122dd2 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -658,7 +658,7 @@ static const struct { _LDAP_MAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), _LDAP_MAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), _LDAP_MAP_CODE(LDAP_INVALID_CREDENTIALS), - _LDAP_MAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTs), + _LDAP_MAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTS), _LDAP_MAP_CODE(LDAP_BUSY), _LDAP_MAP_CODE(LDAP_UNAVAILABLE), _LDAP_MAP_CODE(LDAP_UNWILLING_TO_PERFORM), diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 5b6e2b2b50..59d4bb0c1f 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -699,7 +699,7 @@ static const nt_err_code_struct nt_errs[] = LDAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), LDAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), LDAP_CODE(LDAP_INVALID_CREDENTIALS), - LDAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTs), + LDAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTS), LDAP_CODE(LDAP_BUSY), LDAP_CODE(LDAP_UNAVAILABLE), LDAP_CODE(LDAP_UNWILLING_TO_PERFORM), -- cgit From 40cd2d778093d7799b27b6beb37166d8a53f965c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 May 2007 14:52:54 +0000 Subject: r22944: fix bug #4618: rename private -> private_data metze (This used to be commit 58551f2f28fce8f1fcd04736c47ecd7458f32ea2) --- source4/libcli/composite/composite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index e690c33f58..e929ad70e3 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -158,7 +158,7 @@ _PUBLIC_ void composite_continue_rpc(struct composite_context *ctx, { if (composite_nomem(new_req, ctx)) return; new_req->async.callback = continuation; - new_req->async.private = private_data; + new_req->async.private_data = private_data; } _PUBLIC_ void composite_continue_irpc(struct composite_context *ctx, -- cgit From 402218516a141722cf6cf42c29f15834122acbd7 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 17 May 2007 01:17:43 +0000 Subject: r22958: For SRVSVC/NetFileClose only Administrator is allowed to close open files. If a normal user tries to close a file that exists, even that users own files the server responds with this error on w2k if the file does not exist, the server instead responds with WERR_BADFILE (This used to be commit c17df8bed66d70765b85b6e04f2ad0a57073ffb4) --- source4/libcli/util/doserr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index a45831347f..6df5181654 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -211,6 +211,7 @@ #define WERR_BUF_TOO_SMALL W_ERROR(2123) #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) +#define WERR_FID_NOT_FOUND W_ERROR(2314) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) #define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) #define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) -- cgit From a777eb0cfa5b135acc0bb5fd6396362b72c2315b Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Fri, 18 May 2007 05:21:25 +0000 Subject: r22986: error 2312 is returned when NetSessDel() fails because a matching session (username/clientname) could not be found (This used to be commit e2b46d280db114656e18f023a9efa939b5c893d5) --- source4/libcli/util/doserr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 6df5181654..ddcc060eb6 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -211,6 +211,7 @@ #define WERR_BUF_TOO_SMALL W_ERROR(2123) #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) +#define WERR_SESSION_NOT_FOUND W_ERROR(2312) #define WERR_FID_NOT_FOUND W_ERROR(2314) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) #define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) -- cgit From 7bb939b1cb2b39a8271cf16d9f5fce5312a9af10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 May 2007 06:12:06 +0000 Subject: r23030: finally fixed up our asn1 code to use better memory allocation. This should allow us to fix some long standing memory leaks. (This used to be commit 3db49c2ec9968221c1361785b94061046ecd159d) --- source4/libcli/cldap/cldap.c | 16 +- source4/libcli/cldap/cldap.h | 2 +- source4/libcli/ldap/ldap.c | 297 ++++++++++++++++--------------- source4/libcli/ldap/ldap_client.c | 11 +- source4/libcli/ldap/ldap_controls.c | 344 +++++++++++++++++------------------- source4/libcli/util/asn1.c | 61 ++++--- 6 files changed, 363 insertions(+), 368 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index c68a037552..e92abe4d47 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -66,7 +66,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; - struct asn1_data asn1; + struct asn1_data *asn1 = asn1_init(tmp_ctx); struct ldap_message *ldap_msg; struct cldap_request *req; @@ -93,12 +93,12 @@ static void cldap_socket_recv(struct cldap_socket *cldap) DEBUG(2,("Received cldap packet of length %d from %s:%d\n", (int)blob.length, src->addr, src->port)); - if (!asn1_load(&asn1, blob)) { + if (!asn1_load(asn1, blob)) { DEBUG(2,("Failed to setup for asn.1 decode\n")); talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, asn1.data); + talloc_steal(tmp_ctx, asn1->data); ldap_msg = talloc(tmp_ctx, struct ldap_message); if (ldap_msg == NULL) { @@ -107,7 +107,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } /* this initial decode is used to find the message id */ - status = ldap_decode(&asn1, ldap_msg); + status = ldap_decode(asn1, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); @@ -128,8 +128,8 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } req->asn1 = asn1; - talloc_steal(req, asn1.data); - req->asn1.ofs = 0; + talloc_steal(req, asn1->data); + req->asn1->ofs = 0; req->state = CLDAP_REQUEST_DONE; talloc_free(req->te); @@ -456,7 +456,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, ldap_msg = talloc(mem_ctx, struct ldap_message); NT_STATUS_HAVE_NO_MEMORY(ldap_msg); - status = ldap_decode(&req->asn1, ldap_msg); + status = ldap_decode(req->asn1, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status))); talloc_free(req); @@ -472,7 +472,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, *io->out.response = ldap_msg->r.SearchResultEntry; /* decode the 2nd part */ - status = ldap_decode(&req->asn1, ldap_msg); + status = ldap_decode(req->asn1, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status))); talloc_free(req); diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 928cf1f3e4..4b4be0d316 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -59,7 +59,7 @@ struct cldap_request { DATA_BLOB encoded; /* the reply data */ - struct asn1_data asn1; + struct asn1_data *asn1; /* information on what to do on completion */ struct { diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1e308d5847..70ba9335db 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -190,55 +190,54 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); int i, j; - ZERO_STRUCT(data); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_Integer(&data, msg->messageid); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); switch (msg->type) { case LDAP_TAG_BindRequest: { struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(&data, r->version); - asn1_write_OctetString(&data, r->dn, + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, (r->dn != NULL) ? strlen(r->dn) : 0); switch (r->mechanism) { case LDAP_AUTH_MECH_SIMPLE: /* context, primitive */ - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(&data, r->creds.password, + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, strlen(r->creds.password)); - asn1_pop_tag(&data); + asn1_pop_tag(data); break; case LDAP_AUTH_MECH_SASL: /* context, constructed */ - asn1_push_tag(&data, ASN1_CONTEXT(3)); - asn1_write_OctetString(&data, r->creds.SASL.mechanism, + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); if (r->creds.SASL.secblob) { - asn1_write_OctetString(&data, r->creds.SASL.secblob->data, + asn1_write_OctetString(data, r->creds.SASL.secblob->data, r->creds.SASL.secblob->length); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; default: return False; } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_BindResponse: { struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, &r->response); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); if (r->SASL.secblob) { - asn1_write_ContextSimple(&data, 7, r->SASL.secblob); + asn1_write_ContextSimple(data, 7, r->SASL.secblob); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_UnbindRequest: { @@ -247,223 +246,223 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(&data, r->scope); - asn1_write_enumerated(&data, r->deref); - asn1_write_Integer(&data, r->sizelimit); - asn1_write_Integer(&data, r->timelimit); - asn1_write_BOOLEAN(&data, r->attributesonly); - - if (!ldap_push_filter(&data, r->tree)) { + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { return False; } - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { - asn1_write_OctetString(&data, r->attributes[i], + asn1_write_OctetString(data, r->attributes[i], strlen(r->attributes[i])); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultEntry: { struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, attr->name, + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, strlen(attr->name)); - asn1_push_tag(&data, ASN1_SEQUENCE(1)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); for (j=0; jnum_values; j++) { - asn1_write_OctetString(&data, + asn1_write_OctetString(data, attr->values[j].data, attr->values[j].length); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultDone: { struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyRequest: { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_mods; i++) { struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(&data, r->mods[i].type); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, attrib->name, + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, strlen(attrib->name)); - asn1_push_tag(&data, ASN1_SET); + asn1_push_tag(data, ASN1_SET); for (j=0; jnum_values; j++) { - asn1_write_OctetString(&data, + asn1_write_OctetString(data, attrib->values[j].data, attrib->values[j].length); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyResponse: { struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_AddRequest: { struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, attrib->name, + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, strlen(attrib->name)); - asn1_push_tag(&data, ASN1_SET); + asn1_push_tag(data, ASN1_SET); for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(&data, + asn1_write_OctetString(data, attrib->values[j].data, attrib->values[j].length); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_AddResponse: { struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_DelRequest: { struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(&data, r->dn, strlen(r->dn)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); break; } case LDAP_TAG_DelResponse: { struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyDNRequest: { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(&data, r->deleteolddn); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); if (r->newsuperior) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(&data, r->newsuperior, + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, strlen(r->newsuperior)); - asn1_pop_tag(&data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyDNResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_CompareRequest: { struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, r->attribute, + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, strlen(r->attribute)); - asn1_write_OctetString(&data, r->value.data, + asn1_write_OctetString(data, r->value.data, r->value.length); - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_CompareResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_AbandonRequest: { struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(&data, r->messageid); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultReference: { struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->referral, strlen(r->referral)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); break; } case LDAP_TAG_ExtendedRequest: { struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(&data, r->oid, strlen(r->oid)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); if (r->value) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(&data, r->value->data, r->value->length); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_ExtendedResponse: { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, &r->response); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); if (r->oid) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(&data, r->oid, strlen(r->oid)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); } if (r->value) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(&data, r->value->data, r->value->length); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } default: @@ -471,26 +470,26 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct } if (msg->controls != NULL) { - asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(data, ASN1_CONTEXT(0)); for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, &data, msg->controls[i])) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { return False; } } - asn1_pop_tag(&data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); - if (data.has_error) { - asn1_free(&data); + if (data->has_error) { + asn1_free(data); return False; } - *result = data_blob_talloc(mem_ctx, data.data, data.length); - asn1_free(&data); + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); return True; } @@ -508,7 +507,7 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, const char **result) { DATA_BLOB string; - if (!asn1_read_OctetString(data, &string)) + if (!asn1_read_OctetString(data, mem_ctx, &string)) return False; *result = blob2string_talloc(mem_ctx, string); data_blob_free(&string); @@ -631,7 +630,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -653,7 +652,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - if (!asn1_read_OctetString(data, &attr)) { + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { goto failed; } @@ -673,7 +672,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (subs_tag > 2) goto failed; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, &value); + asn1_read_LDAPString(data, mem_ctx, &value); asn1_end_tag(data); switch (subs_tag) { @@ -743,7 +742,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -762,7 +761,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -781,7 +780,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { goto failed; } - if (!asn1_read_LDAPString(data, &attr)) { + if (!asn1_read_LDAPString(data, ret, &attr)) { goto failed; } @@ -800,7 +799,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -825,16 +824,16 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, /* either oid or type must be defined */ if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, &oid); + asn1_read_LDAPString(data, ret, &oid); asn1_end_tag(data); } if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, &attr); + asn1_read_LDAPString(data, ret, &attr); asn1_end_tag(data); } asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, &value); + asn1_read_LDAPString(data, ret, &value); asn1_end_tag(data); /* dnAttributes is marked as BOOLEAN DEFAULT FALSE it is not marked as OPTIONAL but openldap tools @@ -902,7 +901,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - asn1_read_OctetString(data, &blob); + asn1_read_OctetString(data, mem_ctx, &blob); add_value_to_attrib(mem_ctx, &blob, attrib); } asn1_end_tag(data); @@ -970,7 +969,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, &tmp_blob); + asn1_read_OctetString(data, msg, &tmp_blob); r->creds.SASL.secblob = talloc(msg, DATA_BLOB); if (!r->creds.SASL.secblob) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); @@ -1228,7 +1227,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_OctetString_talloc(msg, data, &r->dn); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, &r->value); + asn1_read_OctetString(data, msg, &r->value); if (r->value.data) { talloc_steal(msg, r->value.data); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c819122dd2..5e4eddee92 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -169,31 +169,30 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message */ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { - int ret; NTSTATUS status; - struct asn1_data asn1; struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); struct ldap_message *msg = talloc(conn, struct ldap_message); + struct asn1_data *asn1 = asn1_init(conn); if (msg == NULL) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - if (!asn1_load(&asn1, blob)) { + if (!asn1_load(asn1, blob)) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - status = ldap_decode(&asn1, msg); + status = ldap_decode(asn1, msg); if (!NT_STATUS_IS_OK(status)) { - asn1_free(&asn1); + asn1_free(asn1); return status; } ldap_match_message(conn, msg); data_blob_free(&blob); - asn1_free(&asn1); + asn1_free(asn1); return NT_STATUS_OK; } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index bbb0cb1aa5..180e6eeb62 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -34,10 +34,10 @@ struct control_handler { static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -46,17 +46,17 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_enumerated(&data, &(lsrc->result))) { + if (!asn1_read_enumerated(data, &(lsrc->result))) { return False; } lsrc->attr_desc = NULL; - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &attr)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { return False; } lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); @@ -65,7 +65,7 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) } } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -78,21 +78,21 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; DATA_BLOB rule; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_server_sort_control **lssc; int num; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } lssc = NULL; - for (num = 0; asn1_peek_tag(&data, ASN1_SEQUENCE(0)); num++) { + for (num = 0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); num++) { lssc = talloc_realloc(mem_ctx, lssc, struct ldb_server_sort_control *, num + 2); if (!lssc) { return False; @@ -102,11 +102,11 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_OctetString(&data, &attr)) { + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { return False; } @@ -115,8 +115,8 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &rule)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &rule)) { return False; } lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); @@ -125,15 +125,15 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } } - if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { + if (asn1_peek_tag(data, ASN1_BOOLEAN)) { BOOL reverse; - if (!asn1_read_BOOLEAN(&data, &reverse)) { + if (!asn1_read_BOOLEAN(data, &reverse)) { return False; } lssc[num]->reverse = reverse; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } } @@ -142,7 +142,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) lssc[num] = NULL; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -153,10 +153,10 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_extended_dn_control *ledc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -165,15 +165,15 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(ledc->type))) { + if (!asn1_read_Integer(data, &(ledc->type))) { return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -184,10 +184,10 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -196,15 +196,15 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lsdfc->secinfo_flags))) { + if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) { return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -215,10 +215,10 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -227,15 +227,15 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lsoc->search_options))) { + if (!asn1_read_Integer(data, &(lsoc->search_options))) { return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -247,10 +247,10 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -259,15 +259,15 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lprc->size))) { + if (!asn1_read_Integer(data, &(lprc->size))) { return False; } - if (!asn1_read_OctetString(&data, &cookie)) { + if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { return False; } lprc->cookie_len = cookie.length; @@ -281,7 +281,7 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out lprc->cookie = NULL; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -293,10 +293,10 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -305,19 +305,19 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(ldc->flags))) { + if (!asn1_read_Integer(data, &(ldc->flags))) { return False; } - if (!asn1_read_Integer(&data, &(ldc->max_attributes))) { + if (!asn1_read_Integer(data, &(ldc->max_attributes))) { return False; } - if (!asn1_read_OctetString(&data, &cookie)) { + if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { return False; } ldc->cookie_len = cookie.length; @@ -331,7 +331,7 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) ldc->cookie = NULL; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -346,10 +346,10 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB source_attribute; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -358,13 +358,13 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &source_attribute)) { + if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) { return False; } lac->src_attr_len = source_attribute.length; @@ -380,9 +380,9 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) lac->request = 1; - } else if (asn1_peek_tag(&data, ASN1_ENUMERATED)) { + } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) { - if (!asn1_read_enumerated(&data, &(lac->result))) { + if (!asn1_read_enumerated(data, &(lac->result))) { return False; } @@ -392,7 +392,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -449,10 +449,10 @@ static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB assertion_value, context_id; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -461,43 +461,43 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->beforeCount))) { + if (!asn1_read_Integer(data, &(lvrc->beforeCount))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->afterCount))) { + if (!asn1_read_Integer(data, &(lvrc->afterCount))) { return False; } - if (asn1_peek_tag(&data, ASN1_CONTEXT(0))) { + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { lvrc->type = 0; - if (!asn1_start_tag(&data, ASN1_CONTEXT(0))) { + if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.offset))) { + if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.contentCount))) { + if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) { return False; } - if (!asn1_end_tag(&data)) { /*SEQUENCE*/ + if (!asn1_end_tag(data)) { /*SEQUENCE*/ return False; } - if (!asn1_end_tag(&data)) { /*CONTEXT*/ + if (!asn1_end_tag(data)) { /*CONTEXT*/ return False; } @@ -505,11 +505,11 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 1; - if (!asn1_start_tag(&data, ASN1_CONTEXT(1))) { + if (!asn1_start_tag(data, ASN1_CONTEXT(1))) { return False; } - if (!asn1_read_OctetString(&data, &assertion_value)) { + if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) { return False; } lvrc->match.gtOrEq.value_len = assertion_value.length; @@ -523,13 +523,13 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->match.gtOrEq.value = NULL; } - if (!asn1_end_tag(&data)) { /*CONTEXT*/ + if (!asn1_end_tag(data)) { /*CONTEXT*/ return False; } } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &context_id)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { return False; } lvrc->ctxid_len = context_id.length; @@ -547,7 +547,7 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->ctxid_len = 0; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -559,10 +559,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB context_id; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -571,24 +571,24 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->targetPosition))) { + if (!asn1_read_Integer(data, &(lvrc->targetPosition))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->contentCount))) { + if (!asn1_read_Integer(data, &(lvrc->contentCount))) { return False; } - if (!asn1_read_enumerated(&data, &(lvrc->vlv_result))) { + if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) { return False; } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &context_id)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { return False; } lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); @@ -601,7 +601,7 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) lvrc->ctxid_len = 0; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -613,32 +613,31 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); - struct asn1_data data; - - ZERO_STRUCT(data); + struct asn1_data *data = asn1_init(mem_ctx); - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_enumerated(&data, lsrc->result)) { + if (!asn1_write_enumerated(data, lsrc->result)) { return False; } if (lsrc->attr_desc) { - if (!asn1_write_OctetString(&data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { + if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -646,49 +645,48 @@ static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); int num; - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } for (num = 0; lssc[num]; num++) { - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_OctetString(&data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { + if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { return False; } if (lssc[num]->orderingRule) { - if (!asn1_write_OctetString(&data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) { + if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) { return False; } } if (lssc[num]->reverse) { - if (!asn1_write_BOOLEAN(&data, lssc[num]->reverse)) { + if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -696,26 +694,25 @@ static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control); - struct asn1_data data; - - ZERO_STRUCT(data); + struct asn1_data *data = asn1_init(mem_ctx); - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, ledc->type)) { + if (!asn1_write_Integer(data, ledc->type)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -723,26 +720,25 @@ static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lsdfc->secinfo_flags)) { + if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -750,26 +746,25 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lsoc->search_options)) { + if (!asn1_write_Integer(data, lsoc->search_options)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -777,30 +772,29 @@ static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lprc->size)) { + if (!asn1_write_Integer(data, lprc->size)) { return False; } - if (!asn1_write_OctetString(&data, lprc->cookie, lprc->cookie_len)) { + if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -811,33 +805,32 @@ static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } if (lac->request) { - if (!asn1_write_OctetString(&data, lac->source_attribute, lac->src_attr_len)) { + if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) { return False; } } else { - if (!asn1_write_enumerated(&data, lac->result)) { + if (!asn1_write_enumerated(data, lac->result)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -845,34 +838,33 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, ldc->flags)) { + if (!asn1_write_Integer(data, ldc->flags)) { return False; } - if (!asn1_write_Integer(&data, ldc->max_attributes)) { + if (!asn1_write_Integer(data, ldc->max_attributes)) { return False; } - if (!asn1_write_OctetString(&data, ldc->cookie, ldc->cookie_len)) { + if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -930,74 +922,73 @@ static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lvrc->beforeCount)) { + if (!asn1_write_Integer(data, lvrc->beforeCount)) { return False; } - if (!asn1_write_Integer(&data, lvrc->afterCount)) { + if (!asn1_write_Integer(data, lvrc->afterCount)) { return False; } if (lvrc->type == 0) { - if (!asn1_push_tag(&data, ASN1_CONTEXT(0))) { + if (!asn1_push_tag(data, ASN1_CONTEXT(0))) { return False; } - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) { + if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) { return False; } - if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) { + if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) { return False; } - if (!asn1_pop_tag(&data)) { /*SEQUENCE*/ + if (!asn1_pop_tag(data)) { /*SEQUENCE*/ return False; } - if (!asn1_pop_tag(&data)) { /*CONTEXT*/ + if (!asn1_pop_tag(data)) { /*CONTEXT*/ return False; } } else { - if (!asn1_push_tag(&data, ASN1_CONTEXT(1))) { + if (!asn1_push_tag(data, ASN1_CONTEXT(1))) { return False; } - if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { + if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { return False; } - if (!asn1_pop_tag(&data)) { /*CONTEXT*/ + if (!asn1_pop_tag(data)) { /*CONTEXT*/ return False; } } if (lvrc->ctxid_len) { - if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) { + if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -1005,40 +996,39 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lvrc->targetPosition)) { + if (!asn1_write_Integer(data, lvrc->targetPosition)) { return False; } - if (!asn1_write_Integer(&data, lvrc->contentCount)) { + if (!asn1_write_Integer(data, lvrc->contentCount)) { return False; } - if (!asn1_write_enumerated(&data, lvrc->vlv_result)) { + if (!asn1_write_enumerated(data, lvrc->vlv_result)) { return False; } if (lvrc->ctxid_len) { - if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) { + if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -1093,7 +1083,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l return False; } - if (!asn1_read_OctetString(data, &oid)) { + if (!asn1_read_OctetString(data, mem_ctx, &oid)) { return False; } ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); @@ -1117,7 +1107,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l goto end_tag; } - if (!asn1_read_OctetString(data, value)) { + if (!asn1_read_OctetString(data, mem_ctx, value)) { return False; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index e64ffdf86c..d02f6be9c7 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -21,12 +21,16 @@ #include "includes.h" #include "libcli/util/asn_1.h" +/* allocate an asn1 structure */ +struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(NULL, struct asn1_data); +} + /* free an asn1 structure */ void asn1_free(struct asn1_data *data) { - talloc_free(data->data); - ZERO_STRUCTP(data); - data->has_error = True; + talloc_free(data); } /* write to the ASN1 buffer, advancing the buffer pointer */ @@ -35,7 +39,7 @@ BOOL asn1_write(struct asn1_data *data, const void *p, int len) if (data->has_error) return False; if (data->length < data->ofs+len) { uint8_t *newp; - newp = talloc_realloc(NULL, data->data, uint8_t, data->ofs+len); + newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); if (!newp) { asn1_free(data); data->has_error = True; @@ -61,7 +65,7 @@ BOOL asn1_push_tag(struct asn1_data *data, uint8_t tag) struct nesting *nesting; asn1_write_uint8(data, tag); - nesting = talloc(NULL, struct nesting); + nesting = talloc(data, struct nesting); if (!nesting) { data->has_error = True; return False; @@ -341,7 +345,7 @@ BOOL asn1_check_BOOLEAN(struct asn1_data *data, BOOL v) BOOL asn1_load(struct asn1_data *data, DATA_BLOB blob) { ZERO_STRUCTP(data); - data->data = talloc_memdup(NULL, blob.data, blob.length); + data->data = talloc_memdup(data, blob.data, blob.length); if (!data->data) { data->has_error = True; return False; @@ -417,7 +421,7 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) data->has_error = True; return False; } - nesting = talloc(NULL, struct nesting); + nesting = talloc(data, struct nesting); if (!nesting) { data->has_error = True; return False; @@ -494,7 +498,7 @@ int asn1_tag_remaining(struct asn1_data *data) } /* read an object ID from a data blob */ -BOOL ber_read_OID_String(DATA_BLOB blob, const char **OID) +BOOL ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) { int i; uint8_t *b; @@ -505,7 +509,7 @@ BOOL ber_read_OID_String(DATA_BLOB blob, const char **OID) b = blob.data; - tmp_oid = talloc_asprintf(NULL, "%u", b[0]/40); + tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40); if (!tmp_oid) goto nomem; tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", b[0]%40); if (!tmp_oid) goto nomem; @@ -532,7 +536,7 @@ nomem: } /* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID(struct asn1_data *data, const char **OID) +BOOL asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID) { DATA_BLOB blob; int len; @@ -558,7 +562,7 @@ BOOL asn1_read_OID(struct asn1_data *data, const char **OID) return False; } - if (!ber_read_OID_String(blob, OID)) { + if (!ber_read_OID_String(mem_ctx, blob, OID)) { data->has_error = True; data_blob_free(&blob); return False; @@ -573,9 +577,10 @@ BOOL asn1_check_OID(struct asn1_data *data, const char *OID) { const char *id; - if (!asn1_read_OID(data, &id)) return False; + if (!asn1_read_OID(data, data, &id)) return False; if (strcmp(id, OID) != 0) { + talloc_free(discard_const(id)); data->has_error = True; return False; } @@ -584,7 +589,7 @@ BOOL asn1_check_OID(struct asn1_data *data, const char *OID) } /* read a LDAPString from a ASN1 buffer */ -BOOL asn1_read_LDAPString(struct asn1_data *data, char **s) +BOOL asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) { int len; len = asn1_tag_remaining(data); @@ -592,7 +597,7 @@ BOOL asn1_read_LDAPString(struct asn1_data *data, char **s) data->has_error = True; return False; } - *s = talloc_size(NULL, len+1); + *s = talloc_size(mem_ctx, len+1); if (! *s) { data->has_error = True; return False; @@ -604,16 +609,16 @@ BOOL asn1_read_LDAPString(struct asn1_data *data, char **s) /* read a GeneralString from a ASN1 buffer */ -BOOL asn1_read_GeneralString(struct asn1_data *data, char **s) +BOOL asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) { if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; - if (!asn1_read_LDAPString(data, s)) return False; + if (!asn1_read_LDAPString(data, mem_ctx, s)) return False; return asn1_end_tag(data); } /* read a octet string blob */ -BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) +BOOL asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); @@ -623,7 +628,7 @@ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) data->has_error = True; return False; } - *blob = data_blob(NULL, len+1); + *blob = data_blob_talloc(mem_ctx, NULL, len+1); if (!blob->data) { data->has_error = True; return False; @@ -727,19 +732,21 @@ BOOL asn1_write_enumerated(struct asn1_data *data, uint8_t v) */ NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) { - struct asn1_data asn1; + struct asn1_data *asn1 = asn1_init(NULL); int size; - ZERO_STRUCT(asn1); - asn1.data = blob.data; - asn1.length = blob.length; - asn1_start_tag(&asn1, tag); - if (asn1.has_error) { - talloc_free(asn1.nesting); + NT_STATUS_HAVE_NO_MEMORY(asn1); + + asn1->data = blob.data; + asn1->length = blob.length; + asn1_start_tag(asn1, tag); + if (asn1->has_error) { + talloc_free(asn1); return STATUS_MORE_ENTRIES; } - size = asn1_tag_remaining(&asn1) + asn1.ofs; - talloc_free(asn1.nesting); + size = asn1_tag_remaining(asn1) + asn1->ofs; + + talloc_free(asn1); if (size > blob.length) { return STATUS_MORE_ENTRIES; -- cgit From 931f594cf16b8c7f9f416d7a8831432b783a0ec8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 May 2007 12:47:18 +0000 Subject: r23036: error checking on asn1_init() failure (This used to be commit 26cf8494084c0106ef0e1c9b6ef40eeadf945ef2) --- source4/libcli/cldap/cldap.c | 2 ++ source4/libcli/ldap/ldap.c | 2 ++ source4/libcli/ldap/ldap_client.c | 4 +++- source4/libcli/ldap/ldap_controls.c | 40 +++++++++++++++++++++++++++++++++++++ source4/libcli/util/asn1.c | 6 +++++- 5 files changed, 52 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index e92abe4d47..bd2ab630db 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -70,6 +70,8 @@ static void cldap_socket_recv(struct cldap_socket *cldap) struct ldap_message *ldap_msg; struct cldap_request *req; + if (!asn1) return; + status = socket_pending(cldap->sock, &dsize); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 70ba9335db..55988b8eb4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -193,6 +193,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct asn1_data *data = asn1_init(mem_ctx); int i, j; + if (!data) return False; + asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_Integer(data, msg->messageid); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 5e4eddee92..ce15b39271 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -175,11 +175,13 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) struct ldap_message *msg = talloc(conn, struct ldap_message); struct asn1_data *asn1 = asn1_init(conn); - if (msg == NULL) { + if (asn1 == NULL || msg == NULL) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } if (!asn1_load(asn1, blob)) { + talloc_free(msg); + talloc_free(asn1); return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 180e6eeb62..79c16afc95 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -37,6 +37,8 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -82,6 +84,8 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) struct ldb_server_sort_control **lssc; int num; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -156,6 +160,8 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_extended_dn_control *ledc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -187,6 +193,8 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -218,6 +226,8 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -250,6 +260,8 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -296,6 +308,8 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -349,6 +363,8 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -452,6 +468,8 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -562,6 +580,8 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -615,6 +635,8 @@ static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -648,6 +670,8 @@ static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) struct asn1_data *data = asn1_init(mem_ctx); int num; + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -696,6 +720,8 @@ static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -722,6 +748,8 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -748,6 +776,8 @@ static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -774,6 +804,8 @@ static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -807,6 +839,8 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -840,6 +874,8 @@ static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -924,6 +960,8 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -998,6 +1036,8 @@ static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index d02f6be9c7..81ce72bed9 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -24,7 +24,11 @@ /* allocate an asn1 structure */ struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) { - return talloc_zero(NULL, struct asn1_data); + struct asn1_data *ret = talloc_zero(NULL, struct asn1_data); + if (ret == NULL) { + DEBUG(0,("asn1_init failed! out of memory\n")); + } + return ret; } /* free an asn1 structure */ -- cgit From 774d66c1e69ab17dc3c3c188dafc6b2b005fd562 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 May 2007 13:33:46 +0000 Subject: r23037: actually fix the asn1 memory leak :-) metze (This used to be commit 13bda1152d3b88c0b93610d4698ce24183334276) --- source4/libcli/util/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 81ce72bed9..477887b96a 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -24,7 +24,7 @@ /* allocate an asn1 structure */ struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) { - struct asn1_data *ret = talloc_zero(NULL, struct asn1_data); + struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data); if (ret == NULL) { DEBUG(0,("asn1_init failed! out of memory\n")); } -- cgit From 31f047f734d763ac6661f33afae8f39cf2fd4bd4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 May 2007 23:35:14 +0000 Subject: r23057: only call the async recv function for the first pending receive, not all pending receives, when the transport dies. This is because the async callback most commonly shuts down the connection (it's the only reasonable thing to do when it's dead), and that frees the whole context. That means that if we loop more than once, we'll end up using freed memory. (This used to be commit 75d537d3a5e3fc5258ce48bfec0c0ce6160978f6) --- source4/libcli/raw/clitransport.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 8c4c7f7c43..ea2aa880b6 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -138,8 +138,11 @@ void smbcli_transport_dead(struct smbcli_transport *transport, NTSTATUS status) status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; } - /* kill all pending receives */ - while (transport->pending_recv) { + /* kill only the first pending receive - this is so that if + that async function frees the connection we don't die trying + to use old memory. The caller has to cope with only one + network error */ + if (transport->pending_recv) { struct smbcli_request *req = transport->pending_recv; req->state = SMBCLI_REQUEST_ERROR; req->status = status; -- cgit From 86b91f50731d5e8a3497027d8ac7b2ca001eeaa7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 22 May 2007 00:43:10 +0000 Subject: r23058: the cldap code was getting too intimate with the internals of struct asn1_context. A hangover from when it wasn't a allocated structure (This used to be commit e4b7968a40e11a96a0b9671f8ef5436f18427818) --- source4/libcli/cldap/cldap.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index bd2ab630db..51bab37e97 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -100,7 +100,6 @@ static void cldap_socket_recv(struct cldap_socket *cldap) talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, asn1->data); ldap_msg = talloc(tmp_ctx, struct ldap_message); if (ldap_msg == NULL) { @@ -129,8 +128,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) return; } - req->asn1 = asn1; - talloc_steal(req, asn1->data); + req->asn1 = talloc_steal(req, asn1); req->asn1->ofs = 0; req->state = CLDAP_REQUEST_DONE; @@ -312,6 +310,10 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->timeout = io->in.timeout; req->num_retries = io->in.retries; req->is_reply = False; + req->asn1 = asn1_init(req); + if (!req->asn1) { + goto failed; + } req->dest = socket_address_from_strings(req, cldap->sock->backend_name, io->in.dest_address, lp_cldap_port()); @@ -376,6 +378,10 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) req->cldap = cldap; req->state = CLDAP_REQUEST_SEND; req->is_reply = True; + req->asn1 = asn1_init(req); + if (!req->asn1) { + goto failed; + } req->dest = io->dest; if (talloc_reference(req, io->dest) == NULL) goto failed; -- cgit From c31e144a2d7cb24b866bf95cb27da80f8728c857 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 May 2007 10:42:29 +0000 Subject: r23138: added a raw interface for SMBecho operations (This used to be commit 590c6c21db5abd436441a9af62ee65436d6f1222) --- source4/libcli/raw/clitransport.c | 68 +++++++++++++++++++++++++++++++++++++++ source4/libcli/raw/interfaces.h | 18 +++++++++++ 2 files changed, 86 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index ea2aa880b6..71c87e631a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -593,3 +593,71 @@ void smbcli_transport_send(struct smbcli_request *req) talloc_set_destructor(req, smbcli_request_destructor); } + + +/**************************************************************************** + Send an SMBecho (async send) +*****************************************************************************/ +struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, + struct smb_echo *p) +{ + struct smbcli_request *req; + + req = smbcli_request_setup_transport(transport, SMBecho, 1, p->in.size); + if (!req) return NULL; + + SSVAL(req->out.vwv, VWV(0), p->in.repeat_count); + + memcpy(req->out.data, p->in.data, p->in.size); + + ZERO_STRUCT(p->out); + + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + raw echo interface (async recv) +****************************************************************************/ +NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, + struct smb_echo *p) +{ + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + goto failed; + } + + SMBCLI_CHECK_WCT(req, 1); + p->out.count++; + p->out.sequence_number = SVAL(req->in.vwv, VWV(0)); + p->out.size = req->in.data_size; + talloc_free(p->out.data); + p->out.data = talloc_size(mem_ctx, p->out.size); + NT_STATUS_HAVE_NO_MEMORY(p->out.data); + + if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + + if (p->out.count == p->in.repeat_count) { + return smbcli_request_destroy(req); + } + + return NT_STATUS_OK; + +failed: + return smbcli_request_destroy(req); +} + +/**************************************************************************** + Send a echo (sync interface) +*****************************************************************************/ +NTSTATUS smb_raw_echo(struct smbcli_transport *transport, struct smb_echo *p) +{ + struct smbcli_request *req = smb_raw_echo_send(transport, p); + return smbcli_request_simple_recv(req); +} diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d0c3ab2d15..93d8dd2c20 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2614,4 +2614,22 @@ union smb_search_close { } findclose; }; + +/* + struct for SMBecho call +*/ +struct smb_echo { + struct { + uint16_t repeat_count; + uint16_t size; + uint8_t *data; + } in; + struct { + uint16_t count; + uint16_t sequence_number; + uint16_t size; + uint8_t *data; + } out; +}; + #endif /* __LIBCLI_RAW_INTERFACES_H__ */ -- cgit From b8b580dbcb0468306b89e0a37589700dee6ca7b8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 May 2007 00:34:31 +0000 Subject: r23176: Note that we only return one DC from this call at the moment. Andrew Bartlett (This used to be commit 4fee8a7b77d01c7cb8b32911016158f2ff2cf8f6) --- source4/libcli/finddcs.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 09967c72b1..0f639b084f 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -118,6 +118,9 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->ctx->status = resolve_name_recv(ctx, state, &address); if (!composite_is_ok(state->ctx)) return; + /* TODO: This should try and find all the DCs, and give the + * caller them in the order they responded */ + state->num_dcs = 1; state->dcs = talloc_array(state, struct nbt_dc_name, state->num_dcs); if (composite_nomem(state->dcs, state->ctx)) return; -- cgit From eb9ae52981d0275d3830fb533a06472aef3508db Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 8 Jun 2007 10:32:29 +0000 Subject: r23381: Merge netr_GetDcName WERROR return and WERROR_DOMAIN_CONTROLLER_NOT_FOUND from SAMBA_3_0. Guenther (This used to be commit 841ad140a34648ff52d5e44a6642f346ef9eee02) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 716ca438db..76c59570a9 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -63,6 +63,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES", WERR_STATUS_MORE_ENTRIES }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index ddcc060eb6..b091a290b9 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -214,6 +214,7 @@ #define WERR_SESSION_NOT_FOUND W_ERROR(2312) #define WERR_FID_NOT_FOUND W_ERROR(2314) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) +#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453) #define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) #define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) -- cgit From 491c63a78de92252148d0d7ac7cb50a2f420b062 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Jun 2007 17:13:42 +0000 Subject: r23519: added libcli code for fetching shadow copy information (This used to be commit a9c23729f253f65825466cfef965d259ec35a54c) --- source4/libcli/config.mk | 3 +- source4/libcli/raw/interfaces.h | 15 ++++++++ source4/libcli/raw/rawrequest.c | 6 ++-- source4/libcli/raw/rawshadow.c | 79 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 source4/libcli/raw/rawshadow.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 74af8185e6..d49fc90ec4 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -147,6 +147,7 @@ OBJ_FILES = raw/rawfile.o \ raw/rawioctl.o \ raw/rawacl.o \ raw/rawdate.o \ - raw/rawlpq.o + raw/rawlpq.o \ + raw/rawshadow.o include smb2/config.mk diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 93d8dd2c20..210fb1cccf 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2632,4 +2632,19 @@ struct smb_echo { } out; }; +/* + struct for shadow copy volumes + */ +struct smb_shadow_copy { + struct { + union smb_handle file; + uint32_t max_data; + } in; + struct { + uint32_t num_volumes; + uint32_t num_names; + const char **names; + } out; +}; + #endif /* __LIBCLI_RAW_INTERFACES_H__ */ diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 7d1bfdb30d..a0dfe75096 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -737,9 +737,9 @@ NTTIME smbcli_pull_nttime(void *base, uint16_t offset) on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the blob is returned */ -static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, - const DATA_BLOB *blob, const char **dest, - const uint8_t *src, int byte_len, uint_t flags) +size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, + const DATA_BLOB *blob, const char **dest, + const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; diff --git a/source4/libcli/raw/rawshadow.c b/source4/libcli/raw/rawshadow.c new file mode 100644 index 0000000000..428ebc9f8d --- /dev/null +++ b/source4/libcli/raw/rawshadow.c @@ -0,0 +1,79 @@ +/* + Unix SMB/CIFS implementation. + + shadow copy file operations + + Copyright (C) Andrew Tridgell 2007 + + 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 "libcli/raw/libcliraw.h" +#include "libcli/raw/ioctl.h" + +/* + get shadow volume data +*/ +_PUBLIC_ NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, struct smb_shadow_copy *info) +{ + union smb_ioctl nt; + NTSTATUS status; + DATA_BLOB blob; + uint32_t dlength; + int i; + uint32_t ofs; + + nt.ntioctl.level = RAW_IOCTL_NTIOCTL; + nt.ntioctl.in.function = FSCTL_GET_SHADOW_COPY_DATA; + nt.ntioctl.in.file.fnum = info->in.file.fnum; + nt.ntioctl.in.fsctl = True; + nt.ntioctl.in.filter = 0; + nt.ntioctl.in.max_data = info->in.max_data; + nt.ntioctl.in.blob = data_blob(NULL, 0); + + status = smb_raw_ioctl(tree, mem_ctx, &nt); + + blob = nt.ntioctl.out.blob; + + if (blob.length < 12) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + info->out.num_volumes = IVAL(blob.data, 0); + info->out.num_names = IVAL(blob.data, 4); + dlength = IVAL(blob.data, 8); + if (dlength > blob.length - 12) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + info->out.names = talloc_array(mem_ctx, const char *, info->out.num_names); + NT_STATUS_HAVE_NO_MEMORY(info->out.names); + + ofs = 12; + for (i=0;iout.num_names;i++) { + size_t len; + len = smbcli_blob_pull_ucs2(info->out.names, + &blob, &info->out.names[i], + blob.data+ofs, -1, STR_TERMINATE); + if (len == 0) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + ofs += len; + } + + return status; +} -- cgit From b7b17c654da08e2abcad0e127ed30bb6991e64ab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 9 Jul 2007 03:08:20 +0000 Subject: r23754: Make sure to check the status return before we de-reference the returned elements. Andrew Bartlett (This used to be commit 3a8192c74288b98bc61af95aa5cd39b1584411c1) --- source4/libcli/raw/rawshadow.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawshadow.c b/source4/libcli/raw/rawshadow.c index 428ebc9f8d..206abf56b4 100644 --- a/source4/libcli/raw/rawshadow.c +++ b/source4/libcli/raw/rawshadow.c @@ -46,6 +46,9 @@ _PUBLIC_ NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, nt.ntioctl.in.blob = data_blob(NULL, 0); status = smb_raw_ioctl(tree, mem_ctx, &nt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } blob = nt.ntioctl.out.blob; -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libcli/auth/credentials.c | 5 ++--- source4/libcli/auth/credentials.h | 5 ++--- source4/libcli/auth/libcli_auth.h | 5 ++--- source4/libcli/auth/session.c | 5 ++--- source4/libcli/auth/smbdes.c | 5 ++--- source4/libcli/auth/smbencrypt.c | 5 ++--- source4/libcli/cldap/cldap.c | 5 ++--- source4/libcli/cldap/cldap.h | 5 ++--- source4/libcli/cliconnect.c | 5 ++--- source4/libcli/clideltree.c | 5 ++--- source4/libcli/clifile.c | 5 ++--- source4/libcli/clilist.c | 5 ++--- source4/libcli/climessage.c | 5 ++--- source4/libcli/clireadwrite.c | 5 ++--- source4/libcli/clitrans2.c | 5 ++--- source4/libcli/composite/composite.c | 5 ++--- source4/libcli/composite/composite.h | 5 ++--- source4/libcli/dgram/browse.c | 5 ++--- source4/libcli/dgram/dgramsocket.c | 5 ++--- source4/libcli/dgram/libdgram.h | 5 ++--- source4/libcli/dgram/mailslot.c | 5 ++--- source4/libcli/dgram/netlogon.c | 5 ++--- source4/libcli/dgram/ntlogon.c | 5 ++--- source4/libcli/finddcs.c | 5 ++--- source4/libcli/ldap/ldap.c | 5 ++--- source4/libcli/ldap/ldap.h | 5 ++--- source4/libcli/ldap/ldap_bind.c | 5 ++--- source4/libcli/ldap/ldap_client.c | 5 ++--- source4/libcli/ldap/ldap_client.h | 5 ++--- source4/libcli/ldap/ldap_controls.c | 5 ++--- source4/libcli/ldap/ldap_ildap.c | 5 ++--- source4/libcli/ldap/ldap_msg.c | 5 ++--- source4/libcli/ldap/ldap_ndr.c | 5 ++--- source4/libcli/libcli.h | 5 ++--- source4/libcli/nbt/libnbt.h | 5 ++--- source4/libcli/nbt/namequery.c | 5 ++--- source4/libcli/nbt/namerefresh.c | 5 ++--- source4/libcli/nbt/nameregister.c | 5 ++--- source4/libcli/nbt/namerelease.c | 5 ++--- source4/libcli/nbt/nbtname.c | 5 ++--- source4/libcli/nbt/nbtsocket.c | 5 ++--- source4/libcli/rap/rap.h | 5 ++--- source4/libcli/raw/clioplock.c | 5 ++--- source4/libcli/raw/clisession.c | 5 ++--- source4/libcli/raw/clisocket.c | 5 ++--- source4/libcli/raw/clitransport.c | 5 ++--- source4/libcli/raw/clitree.c | 5 ++--- source4/libcli/raw/interfaces.h | 5 ++--- source4/libcli/raw/ioctl.h | 5 ++--- source4/libcli/raw/libcliraw.h | 5 ++--- source4/libcli/raw/rawacl.c | 5 ++--- source4/libcli/raw/rawdate.c | 5 ++--- source4/libcli/raw/raweas.c | 5 ++--- source4/libcli/raw/rawfile.c | 5 ++--- source4/libcli/raw/rawfileinfo.c | 5 ++--- source4/libcli/raw/rawfsinfo.c | 5 ++--- source4/libcli/raw/rawioctl.c | 5 ++--- source4/libcli/raw/rawlpq.c | 5 ++--- source4/libcli/raw/rawnegotiate.c | 5 ++--- source4/libcli/raw/rawnotify.c | 5 ++--- source4/libcli/raw/rawreadwrite.c | 5 ++--- source4/libcli/raw/rawrequest.c | 5 ++--- source4/libcli/raw/rawsearch.c | 5 ++--- source4/libcli/raw/rawsetfileinfo.c | 5 ++--- source4/libcli/raw/rawshadow.c | 5 ++--- source4/libcli/raw/rawtrans.c | 5 ++--- source4/libcli/raw/request.h | 5 ++--- source4/libcli/raw/signing.h | 5 ++--- source4/libcli/raw/smb.h | 5 ++--- source4/libcli/raw/smb_signing.c | 5 ++--- source4/libcli/raw/trans2.h | 5 ++--- source4/libcli/resolve/bcast.c | 5 ++--- source4/libcli/resolve/host.c | 5 ++--- source4/libcli/resolve/nbtlist.c | 5 ++--- source4/libcli/resolve/resolve.c | 5 ++--- source4/libcli/resolve/resolve.h | 5 ++--- source4/libcli/resolve/wins.c | 5 ++--- source4/libcli/security/access_check.c | 5 ++--- source4/libcli/security/dom_sid.c | 5 ++--- source4/libcli/security/privilege.c | 5 ++--- source4/libcli/security/sddl.c | 5 ++--- source4/libcli/security/security.h | 5 ++--- source4/libcli/security/security_descriptor.c | 5 ++--- source4/libcli/security/security_token.c | 5 ++--- source4/libcli/smb2/cancel.c | 5 ++--- source4/libcli/smb2/close.c | 5 ++--- source4/libcli/smb2/connect.c | 5 ++--- source4/libcli/smb2/create.c | 5 ++--- source4/libcli/smb2/find.c | 5 ++--- source4/libcli/smb2/flush.c | 5 ++--- source4/libcli/smb2/getinfo.c | 5 ++--- source4/libcli/smb2/ioctl.c | 5 ++--- source4/libcli/smb2/keepalive.c | 5 ++--- source4/libcli/smb2/lock.c | 5 ++--- source4/libcli/smb2/logoff.c | 5 ++--- source4/libcli/smb2/negprot.c | 5 ++--- source4/libcli/smb2/notify.c | 5 ++--- source4/libcli/smb2/read.c | 5 ++--- source4/libcli/smb2/request.c | 5 ++--- source4/libcli/smb2/session.c | 5 ++--- source4/libcli/smb2/setinfo.c | 5 ++--- source4/libcli/smb2/smb2.h | 5 ++--- source4/libcli/smb2/smb2_calls.h | 5 ++--- source4/libcli/smb2/tcon.c | 5 ++--- source4/libcli/smb2/tdis.c | 5 ++--- source4/libcli/smb2/transport.c | 5 ++--- source4/libcli/smb2/write.c | 5 ++--- source4/libcli/smb_composite/connect.c | 5 ++--- source4/libcli/smb_composite/fetchfile.c | 5 ++--- source4/libcli/smb_composite/loadfile.c | 5 ++--- source4/libcli/smb_composite/savefile.c | 5 ++--- source4/libcli/smb_composite/sesssetup.c | 5 ++--- source4/libcli/smb_composite/smb_composite.h | 5 ++--- source4/libcli/util/asn1.c | 5 ++--- source4/libcli/util/asn_1.h | 5 ++--- source4/libcli/util/clierror.c | 5 ++--- source4/libcli/util/clilsa.c | 5 ++--- source4/libcli/util/doserr.h | 5 ++--- source4/libcli/util/error.h | 5 ++--- source4/libcli/util/nt_status.h | 5 ++--- source4/libcli/util/nterr.h | 5 ++--- source4/libcli/wrepl/winsrepl.c | 5 ++--- source4/libcli/wrepl/winsrepl.h | 5 ++--- 123 files changed, 246 insertions(+), 369 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 5bae30f580..feb8c92a0b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index 2e781f701f..4e11cb090f 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/libcli/auth/credentials.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "librpc/gen_ndr/netlogon.h" diff --git a/source4/libcli/auth/libcli_auth.h b/source4/libcli/auth/libcli_auth.h index e6e00568ff..ec1c1e7d98 100644 --- a/source4/libcli/auth/libcli_auth.h +++ b/source4/libcli/auth/libcli_auth.h @@ -3,7 +3,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -12,8 +12,7 @@ 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. + along with this program. If not, see . */ #ifndef __LIBCLI_AUTH_H__ #define __LIBCLI_AUTH_H__ diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 430eecd78f..4a9d79c425 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/auth/smbdes.c b/source4/libcli/auth/smbdes.c index d392109b1e..7f998e512d 100644 --- a/source4/libcli/auth/smbdes.c +++ b/source4/libcli/auth/smbdes.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 3c55658025..1f940fb79d 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -9,7 +9,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 51bab37e97..33d6e88a30 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 4b4be0d316..2e88571ee8 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "libcli/util/asn_1.h" diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 27f9736371..e0f3c598b4 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 51b4e6568d..33c39ea093 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index ce49cdea70..b30b82bd79 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 341b934aae..ba85ec397a 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 010d48c9bb..3d4d9da96c 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index afffeadeff..10a1c75308 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 9418c10538..03deea2e82 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index e929ad70e3..3e21c3823c 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ /* composite API helper functions diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index cb45382c40..36ca0e9293 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "libcli/raw/interfaces.h" diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 18ab398c79..84a2a7e534 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 2e16014aad..1097c30f99 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 26675cb420..8165e445bc 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "librpc/gen_ndr/nbt.h" diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index a0021d7a68..14eb7b931b 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 08b9b0e641..df47a34a0e 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index f480212b79..5881dcf702 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 0f639b084f..0e115b0547 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "include/includes.h" diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 55988b8eb4..64f6f90d31 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -9,7 +9,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index faf6815390..fd622de449 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index addc8cf91e..cbe8772414 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index ce15b39271..8476a4977b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -9,7 +9,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 849737d8a9..0850e8ff64 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 79c16afc95..4f76c7315b 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index f26fb7db78..5366e325cb 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index d74aa500ca..c9643dafda 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 0cccdbe971..a5f90cf82b 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index aee22e2693..98ca9d57eb 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #ifndef __LIBCLI_H__ diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 521c4f52bd..3cbbae3fb2 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #ifndef __LIBNBT_H__ diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index cb3c9e158c..32de9723b9 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 8940fbb95e..a60e54ed6a 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 957f87abfd..7b03667fec 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index e8dc175b36..fd3967d1e6 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 584af96984..af3f62b987 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 0931de63c8..597dc5a354 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/rap/rap.h b/source4/libcli/rap/rap.h index 46bce225ff..6dcaa9bc83 100644 --- a/source4/libcli/rap/rap.h +++ b/source4/libcli/rap/rap.h @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #define RAP_WshareEnum 0 diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index f004532b26..12b586aafa 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 9e114aece8..c6c575b818 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 0631d55a9c..0aa6ec5616 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 71c87e631a..98f5042d99 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 51f2e12457..a5217d74b2 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 210fb1cccf..6b3ca94506 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #ifndef __LIBCLI_RAW_INTERFACES_H__ diff --git a/source4/libcli/raw/ioctl.h b/source4/libcli/raw/ioctl.h index 2f0886e43e..a9d3d1b7a6 100644 --- a/source4/libcli/raw/ioctl.h +++ b/source4/libcli/raw/ioctl.h @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 2b856aa52b..645ac46356 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #ifndef __LIBCLI_RAW_H__ diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 1a2d75d274..168f9c0309 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawdate.c b/source4/libcli/raw/rawdate.c index 894eb53528..9a86c88697 100644 --- a/source4/libcli/raw/rawdate.c +++ b/source4/libcli/raw/rawdate.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 26b04838d6..f79de88fa6 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 3d2d407583..60a9bf2656 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 7b15ce6fd6..faae3a52b1 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 9b218586a2..ced977333d 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 9477af4eb2..9205f84e86 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawlpq.c b/source4/libcli/raw/rawlpq.c index 882ed3c302..03f7a82f1c 100644 --- a/source4/libcli/raw/rawlpq.c +++ b/source4/libcli/raw/rawlpq.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 07b9dd572a..c2dc393481 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index e847368f73..91a12a8618 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index e7a3209d07..a288b7ec54 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index a0dfe75096..6bf2bb58cc 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 3c7ca5788e..33fa90d68d 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 794ba25480..7738e849e8 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawshadow.c b/source4/libcli/raw/rawshadow.c index 206abf56b4..8fc81dab4c 100644 --- a/source4/libcli/raw/rawshadow.c +++ b/source4/libcli/raw/rawshadow.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 164354c701..fe26a71310 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h index 689a5281ce..803a450e3c 100644 --- a/source4/libcli/raw/request.h +++ b/source4/libcli/raw/request.h @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "libcli/raw/signing.h" diff --git a/source4/libcli/raw/signing.h b/source4/libcli/raw/signing.h index cea8556c2c..62b06579d5 100644 --- a/source4/libcli/raw/signing.h +++ b/source4/libcli/raw/signing.h @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ enum smb_signing_engine_state { diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 98e7eca581..e054ed6522 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -11,7 +11,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -20,8 +20,7 @@ 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. + along with this program. If not, see . */ #ifndef _SMB_H diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 541fd1fb8c..99044d23ae 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index e4e85b58bc..5b7987aa8c 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #ifndef _TRANS2_H_ diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index ba07670ced..f356dafdaa 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 43467cd274..ec394309ef 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index e8ea22a0dc..ad331c872d 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 5e37fec42b..4df4de020c 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index ad479bab4b..72db3839a2 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #ifndef __RESOLVE_H__ diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 62a3b81d0a..7af12075a1 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index ea63369303..e2ede05545 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index a72588dee1..64e418677a 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index b4855b59e2..635f470bf6 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 7d0e6ee748..4342a7b87a 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h index eca6878031..d9485c825f 100644 --- a/source4/libcli/security/security.h +++ b/source4/libcli/security/security.h @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "librpc/gen_ndr/security.h" diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 441f2c6370..06c3c2eca7 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 28339c969d..684c3de7e6 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/cancel.c b/source4/libcli/smb2/cancel.c index bf48af7b00..f0a0b01817 100644 --- a/source4/libcli/smb2/cancel.c +++ b/source4/libcli/smb2/cancel.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 1e2ef3afb1..e83f81b630 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 0d772bccd8..a365f25d49 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index fe91acbf0a..58e7a905d9 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 794e31bed3..e8643f1868 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index 531322ec4f..2f1b7bd749 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 2af8032938..a9a681ea53 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index a3ac2d9f47..c13ec7943c 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index 75161d8fb5..e2b7c83b8a 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c index 23693a0757..470648a34c 100644 --- a/source4/libcli/smb2/lock.c +++ b/source4/libcli/smb2/lock.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index 67129319fb..00d5e19e82 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index c3b72186a9..07d06ca2ff 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 800f9ae9d5..58e2876745 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index 272bc82882..f78a1a8b0e 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index ef024d53f8..d857fc8c5b 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 8ebdc93bd4..3f9b3ed55c 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index 4b1d4ab608..67d433a48a 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 4db7c126d8..cad9ebd38e 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ struct smb2_options { diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index abb7f88ee2..318a634ac4 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "libcli/raw/interfaces.h" diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 8b94936c42..4f341d1206 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c index 1c6b3e978e..6ad3120740 100644 --- a/source4/libcli/smb2/tdis.c +++ b/source4/libcli/smb2/tdis.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 8e27873a88..de08201c8b 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index c9d6ce4b53..3d501dc915 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index fc788d5d31..026fe0b029 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ /* a composite API for making a full SMB connection diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 5783a3258f..63a10a667d 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ /* a composite API for loading a whole file into memory diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index 8582b71ef4..9b65d04ef3 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ /* a composite API for loading a whole file into memory diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c index d355cf1e26..32fcdbcd87 100644 --- a/source4/libcli/smb_composite/savefile.c +++ b/source4/libcli/smb_composite/savefile.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ /* a composite API for saving a whole file from memory diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 9267d1d38b..25cf8b3f12 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ /* a composite API for making handling a generic async session setup diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index a7a82965e6..e560c790f7 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 477887b96a..e7a2e163aa 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/util/asn_1.h b/source4/libcli/util/asn_1.h index 7033f92a7f..6c70423e96 100644 --- a/source4/libcli/util/asn_1.h +++ b/source4/libcli/util/asn_1.h @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #ifndef _ASN_1_H diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c index 52607b1a47..89bba21ed6 100644 --- a/source4/libcli/util/clierror.c +++ b/source4/libcli/util/clierror.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index cd9a02deb1..a82f687053 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ /* diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index b091a290b9..7dc938b2e7 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #ifndef _DOSERR_H diff --git a/source4/libcli/util/error.h b/source4/libcli/util/error.h index 4aa1ff6a40..8a641c8eb9 100644 --- a/source4/libcli/util/error.h +++ b/source4/libcli/util/error.h @@ -4,7 +4,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -13,8 +13,7 @@ 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. + along with this program. If not, see . */ #ifndef _SAMBA_ERROR_H_ diff --git a/source4/libcli/util/nt_status.h b/source4/libcli/util/nt_status.h index 3e2a126b41..8d81aab175 100644 --- a/source4/libcli/util/nt_status.h +++ b/source4/libcli/util/nt_status.h @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #ifndef _NT_STATUS_H diff --git a/source4/libcli/util/nterr.h b/source4/libcli/util/nterr.h index baf15d80ef..1ee867a0aa 100644 --- a/source4/libcli/util/nterr.h +++ b/source4/libcli/util/nterr.h @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ #ifndef _NTERR_H diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 78ee2d165e..5b2a9e1e4a 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 3ea672327b..b8473d1021 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "librpc/gen_ndr/nbt.h" -- cgit From b8d69a7ea2505b706ff7c74d7c97bc89d82dfa07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:46:15 +0000 Subject: r23795: more v2->v3 conversion (This used to be commit 84b468b2f8f2dffda89593f816e8bc6a8b6d42ac) --- source4/libcli/swig/libcli_nbt.i | 2 +- source4/libcli/util/doserr.c | 2 +- source4/libcli/util/errormap.c | 2 +- source4/libcli/util/nterr.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index 54fbf56839..b2d9397c28 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -12,7 +12,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 76c59570a9..a81d98a8e9 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -5,7 +5,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index ff6acf9dd9..20e7a464e5 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -7,7 +7,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 59d4bb0c1f..8205e45d21 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -5,7 +5,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, -- cgit From 6c973f4e8ccbcb6c9275f8a54e26abb19df7e15a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:42:26 +0000 Subject: r23798: updated old Temple Place FSF addresses to new URL (This used to be commit 40c0919aaa9c1b14bbaebb95ecce53eb0380fdbb) --- source4/libcli/swig/libcli_nbt.i | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index b2d9397c28..b887e7df97 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -20,8 +20,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ %module libcli_nbt -- cgit From cd1217ff5ff18e53c6c9fa3d4f4fd56193fe2a17 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 05:23:25 +0000 Subject: r23801: The FSF has moved around a lot. This fixes their Mass Ave address. (This used to be commit 5c9b19271e0e3ad897499707003ce4703ffa4870) --- source4/libcli/util/doserr.c | 3 +-- source4/libcli/util/errormap.c | 3 +-- source4/libcli/util/nterr.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index a81d98a8e9..3b1c2d264a 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -14,8 +14,7 @@ * 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. + * along with this program; if not, see . */ /* DOS error codes. please read doserr.h */ diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 20e7a464e5..711f02a626 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -16,8 +16,7 @@ * 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. + * along with this program; if not, see . */ #include "includes.h" diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 8205e45d21..3aea0b51bc 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -14,8 +14,7 @@ * 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. + * along with this program; if not, see . */ /* NT error codes. please read nterr.h */ -- cgit From a87dea2a0894015cf4a3140995791f5468c40038 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 Jul 2007 11:37:30 +0000 Subject: r23810: Make things static, and remove unsued code. This includes some of the original ildap ldap client API. ldb provides a much easier abstraction on this to use, and doesn't use these functions. Andrew Bartlett (This used to be commit dc27a7e41c297472675e8c251bb14327a1af3902) --- source4/libcli/ldap/ldap_ildap.c | 114 --------------------------------------- 1 file changed, 114 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 5366e325cb..62019b8cc1 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -24,120 +24,6 @@ #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" -/* - delete a record - */ -NTSTATUS ildap_delete(struct ldap_connection *conn, const char *dn) -{ - struct ldap_message *msg; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - -/* - add a record - */ -NTSTATUS ildap_add(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) -{ - struct ldap_message *msg; - int n, i; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - for (n=0;mods[n];n++) /* noop */ ; - - msg->type = LDAP_TAG_AddRequest; - msg->r.AddRequest.dn = dn; - msg->r.AddRequest.num_attributes = n; - msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); - if (msg->r.AddRequest.attributes == NULL) { - talloc_free(msg); - return NT_STATUS_NO_MEMORY; - } - for (i=0;ir.AddRequest.attributes[i] = mods[i]->attrib; - } - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - - -/* - modify a record - */ -NTSTATUS ildap_modify(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) -{ - struct ldap_message *msg; - int n, i; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - for (n=0;mods[n];n++) /* noop */ ; - - msg->type = LDAP_TAG_ModifyRequest; - msg->r.ModifyRequest.dn = dn; - msg->r.ModifyRequest.num_mods = n; - msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); - if (msg->r.ModifyRequest.mods == NULL) { - talloc_free(msg); - return NT_STATUS_NO_MEMORY; - } - for (i=0;ir.ModifyRequest.mods[i] = *mods[i]; - } - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - - -/* - rename a record - */ -NTSTATUS ildap_rename(struct ldap_connection *conn, const char *dn, const char *newrdn, - const char *parentdn, BOOL deleteolddn) -{ - struct ldap_message *msg; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - msg->type = LDAP_TAG_ModifyDNRequest; - msg->r.ModifyDNRequest.dn = dn; - msg->r.ModifyDNRequest.newrdn = newrdn; - msg->r.ModifyDNRequest.deleteolddn = deleteolddn; - msg->r.ModifyDNRequest.newsuperior = parentdn; - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - /* count the returned search entries -- cgit From a0fa5051bdb30d2d5e6d106f7c67c00211c93341 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 Jul 2007 13:41:00 +0000 Subject: r23816: A little more static, but leave the dead code testjoin.c as documentation. Andrew Bartlett (This used to be commit 6679003c0553804333f0090a91e1fe53837ceb47) --- source4/libcli/auth/session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 4a9d79c425..7f44b6b5a9 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -29,7 +29,7 @@ before calling, the out blob must be initialised to be the same size as the in blob */ -void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, +static void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, BOOL forward) { int i, k; -- cgit From 5f6b501f217bf95522e2d1fe63ee1298feb1abd7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Aug 2007 08:25:15 +0000 Subject: r24146: It is not an error for a Win2k3-only server not to support the NT4 replication call. Andrew Bartlett (This used to be commit 59cba32c09f5b014788e4fb0479ed31f26a3d7e2) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/doserr.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 3b1c2d264a..d62a31c1fa 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -75,6 +75,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, { "WERR_UNKNOWN_REVISION", WERR_UNKNOWN_REVISION }, { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 7dc938b2e7..0478eff947 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -201,6 +201,7 @@ #define WERR_NO_SUCH_USER W_ERROR(1317) #define WERR_LOGON_FAILURE W_ERROR(1326) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) +#define WERR_INVALID_DOMAIN_ROLE W_ERROR(1354) #define WERR_NO_SUCH_DOMAIN W_ERROR(1355) #define WERR_NO_SYSTEM_RESOURCES W_ERROR(1450) #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) -- cgit From 210971d092e908e1ec482646b3ceb2f579d89440 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 6 Aug 2007 04:07:05 +0000 Subject: r24248: Attempt to fix bug #4830 by . If there is no payload to the control, we still need to inialise *value, as otherwise we read uninitialised data later. Andrew Bartlett (This used to be commit f6566480b7f1b4036b38284aa539f3a69f5c4573) --- source4/libcli/ldap/ldap_controls.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 4f76c7315b..3a5d14c0c9 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -1143,6 +1143,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l ctrl->data = NULL; if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { + *value = data_blob(NULL, 0); goto end_tag; } -- cgit From f14bd1a90ab47a418c0ec2492990a417a0bb3bf6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 19 Aug 2007 21:23:03 +0000 Subject: r24557: rename 'dcerpc_table_' -> 'ndr_table_' metze (This used to be commit 84651aee81aaabbebf52ffc3fbcbabb2eec6eed5) --- source4/libcli/finddcs.c | 2 +- source4/libcli/util/clilsa.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 0e115b0547..5371879895 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -151,7 +151,7 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->r.in.domain_sid = state->domain_sid; ireq = irpc_call_send(state->msg_ctx, nbt_servers[0], - &dcerpc_table_irpc, DCERPC_NBTD_GETDCNAME, + &ndr_table_irpc, DCERPC_NBTD_GETDCNAME, &state->r, state); if (!ireq) { fallback_node_status(state); diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index a82f687053..d51ad5e12d 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -92,7 +92,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } /* bind to the LSA pipe */ - status = dcerpc_bind_auth_none(lsa->pipe, &dcerpc_table_lsarpc); + status = dcerpc_bind_auth_none(lsa->pipe, &ndr_table_lsarpc); if (!NT_STATUS_IS_OK(status)) { talloc_free(lsa); return status; -- cgit From 0d7d5a6d492253f184ac58fe45ca22af5a3731de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 19 Aug 2007 22:09:21 +0000 Subject: r24560: rename some DCERPC_ prefixes into NDR_ metze (This used to be commit f874eca5dab74e930d0ec52abeb06295d2d90476) --- source4/libcli/finddcs.c | 2 +- source4/libcli/util/clilsa.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 5371879895..a159ab6dfc 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -151,7 +151,7 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->r.in.domain_sid = state->domain_sid; ireq = irpc_call_send(state->msg_ctx, nbt_servers[0], - &ndr_table_irpc, DCERPC_NBTD_GETDCNAME, + &ndr_table_irpc, NDR_NBTD_GETDCNAME, &state->r, state); if (!ireq) { fallback_node_status(state); diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index d51ad5e12d..6fd84bbe74 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -85,7 +85,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } /* open the LSA pipe */ - status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME); + status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, NDR_LSARPC_NAME); if (!NT_STATUS_IS_OK(status)) { talloc_free(lsa); return status; -- cgit From 61ffa08f4c95e29d301de9fbabd6e71c2dbc1056 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 18:10:19 +0000 Subject: r24712: No longer expose the 'BOOL' data type in any interfaces. (This used to be commit 1ce32673d960c8b05b6c1b1b99e1976a402417ae) --- source4/libcli/cldap/cldap.h | 2 +- source4/libcli/composite/composite.h | 2 +- source4/libcli/ldap/ldap.h | 4 ++-- source4/libcli/ldap/ldap_client.h | 2 +- source4/libcli/nbt/libnbt.h | 20 ++++++++++---------- source4/libcli/raw/interfaces.h | 14 +++++++------- source4/libcli/raw/libcliraw.h | 2 +- source4/libcli/raw/signing.h | 8 ++++---- source4/libcli/smb2/smb2.h | 4 ++-- source4/libcli/smb_composite/smb_composite.h | 4 ++-- source4/libcli/util/asn_1.h | 2 +- source4/libcli/wrepl/winsrepl.h | 12 ++++++------ 12 files changed, 38 insertions(+), 38 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 2e88571ee8..e957ccea19 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -47,7 +47,7 @@ struct cldap_request { int timeout; int num_retries; - BOOL is_reply; + bool is_reply; /* the ldap message_id */ int message_id; diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index 36ca0e9293..db0ecf9af6 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -59,7 +59,7 @@ struct composite_context { void *private_data; } async; - BOOL used_wait; + bool used_wait; }; struct irpc_request; diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index fd622de449..022c70e36a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -143,7 +143,7 @@ struct ldap_SearchRequest { enum ldap_deref deref; uint32_t timelimit; uint32_t sizelimit; - BOOL attributesonly; + bool attributesonly; struct ldb_parse_tree *tree; int num_attributes; const char **attributes; @@ -190,7 +190,7 @@ struct ldap_DelRequest { struct ldap_ModifyDNRequest { const char *dn; const char *newrdn; - BOOL deleteolddn; + bool deleteolddn; const char *newsuperior;/* optional */ }; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 0850e8ff64..d2a12ee8b5 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -53,7 +53,7 @@ struct ldap_connection { struct socket_context *sock; char *host; uint16_t port; - BOOL ldaps; + bool ldaps; const char *auth_dn; const char *simple_pw; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 3cbbae3fb2..e383591089 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -56,7 +56,7 @@ struct nbt_name_request { int num_retries; /* whether we have received a WACK */ - BOOL received_wack; + bool received_wack; /* the timeout event */ struct timed_event *te; @@ -65,13 +65,13 @@ struct nbt_name_request { uint16_t name_trn_id; /* is it a reply? */ - BOOL is_reply; + bool is_reply; /* the encoded request */ DATA_BLOB encoded; /* shall we allow multiple replies? */ - BOOL allow_multiple_replies; + bool allow_multiple_replies; unsigned int num_replies; struct nbt_name_reply { @@ -128,8 +128,8 @@ struct nbt_name_query { struct { struct nbt_name name; const char *dest_addr; - BOOL broadcast; - BOOL wins_lookup; + bool broadcast; + bool wins_lookup; int timeout; /* in seconds */ int retries; } in; @@ -163,9 +163,9 @@ struct nbt_name_register { const char *dest_addr; const char *address; uint16_t nb_flags; - BOOL register_demand; - BOOL broadcast; - BOOL multi_homed; + bool register_demand; + bool broadcast; + bool multi_homed; uint32_t ttl; int timeout; /* in seconds */ int retries; @@ -215,7 +215,7 @@ struct nbt_name_refresh { const char *dest_addr; const char *address; uint16_t nb_flags; - BOOL broadcast; + bool broadcast; uint32_t ttl; int timeout; /* in seconds */ int retries; @@ -252,7 +252,7 @@ struct nbt_name_release { const char *dest_addr; const char *address; uint16_t nb_flags; - BOOL broadcast; + bool broadcast; int timeout; /* in seconds */ int retries; } in; diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 6b3ca94506..23de6c3838 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -608,8 +608,8 @@ union smb_fileinfo { uint64_t alloc_size; uint64_t size; uint32_t nlink; - BOOL delete_pending; - BOOL directory; + bool delete_pending; + bool directory; } out; } standard_info; @@ -976,7 +976,7 @@ union smb_setfileinfo { enum smb_setfileinfo_level level; struct { union smb_handle_or_path file; - BOOL delete_on_close; + bool delete_on_close; } in; } disposition_info; @@ -1633,7 +1633,7 @@ union smb_read { uint16_t mincnt; uint32_t maxcnt; uint16_t remaining; - BOOL read_for_execute; + bool read_for_execute; } in; struct { uint8_t *data; @@ -2035,7 +2035,7 @@ union smb_ioctl { struct { union smb_handle file; uint32_t function; - BOOL fsctl; + bool fsctl; uint8_t filter; uint32_t max_data; DATA_BLOB blob; @@ -2193,7 +2193,7 @@ union smb_notify { union smb_handle file; uint32_t buffer_size; uint32_t completion_filter; - BOOL recursive; + bool recursive; } in; struct { @@ -2581,7 +2581,7 @@ union smb_search_data { }; /* Callback function passed to the raw search interface. */ -typedef BOOL (*smbcli_search_callback)(void *private, const union smb_search_data *file); +typedef bool (*smbcli_search_callback)(void *private, const union smb_search_data *file); enum smb_search_close_level {RAW_FINDCLOSE_GENERIC, RAW_FINDCLOSE_FCLOSE, RAW_FINDCLOSE_FINDCLOSE}; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 645ac46356..a11a9c9e58 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -142,7 +142,7 @@ struct smbcli_transport { struct { /* a oplock break request handler */ - BOOL (*handler)(struct smbcli_transport *transport, + bool (*handler)(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *private); /* private data passed to the oplock handler */ void *private; diff --git a/source4/libcli/raw/signing.h b/source4/libcli/raw/signing.h index 62b06579d5..56e977ed7c 100644 --- a/source4/libcli/raw/signing.h +++ b/source4/libcli/raw/signing.h @@ -34,10 +34,10 @@ struct smb_signing_context { enum smb_signing_engine_state signing_state; DATA_BLOB mac_key; uint32_t next_seq_num; - BOOL allow_smb_signing; - BOOL doing_signing; - BOOL mandatory_signing; - BOOL seen_valid; /* Have I ever seen a validly signed packet? */ + bool allow_smb_signing; + bool doing_signing; + bool mandatory_signing; + bool seen_valid; /* Have I ever seen a validly signed packet? */ }; #endif diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index cad9ebd38e..33876c6f7c 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -128,8 +128,8 @@ struct smb2_request { uint64_t seqnum; struct { - BOOL do_cancel; - BOOL can_cancel; + bool do_cancel; + bool can_cancel; uint32_t pending_id; } cancel; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index e560c790f7..617daaf442 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -89,12 +89,12 @@ struct smb_composite_connect { const char *service; const char *service_type; struct cli_credentials *credentials; - BOOL fallback_to_anonymous; + bool fallback_to_anonymous; const char *workgroup; } in; struct { struct smbcli_tree *tree; - BOOL anonymous_fallback_done; + bool anonymous_fallback_done; } out; }; diff --git a/source4/libcli/util/asn_1.h b/source4/libcli/util/asn_1.h index 6c70423e96..612a8a932f 100644 --- a/source4/libcli/util/asn_1.h +++ b/source4/libcli/util/asn_1.h @@ -31,7 +31,7 @@ struct asn1_data { size_t length; off_t ofs; struct nesting *nesting; - BOOL has_error; + bool has_error; }; #define ASN1_APPLICATION(x) ((x)+0x60) diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index b8473d1021..3265024407 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -45,15 +45,15 @@ struct wrepl_socket { uint32_t timeout_count; /* remember is the socket is dead */ - BOOL dead; + bool dead; /* remember if we need to free the wrepl_socket at the end of wrepl_socket_dead() */ - BOOL free_skipped; + bool free_skipped; }; struct wrepl_send_ctrl { - BOOL send_only; - BOOL disconnect_after_send; + bool send_only; + bool disconnect_after_send; }; enum wrepl_request_state { @@ -71,7 +71,7 @@ struct wrepl_request { struct wrepl_socket *wrepl_socket; enum wrepl_request_state state; - BOOL trigger; + bool trigger; NTSTATUS status; struct timed_event *te; @@ -141,7 +141,7 @@ struct wrepl_pull_names { enum wrepl_name_type type; enum wrepl_name_state state; enum wrepl_name_node node; - BOOL is_static; + bool is_static; uint32_t raw_flags; uint64_t version_id; const char *owner; -- cgit From 0b91f3916430d0271eab867675d44c5439de40c2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 29 Aug 2007 13:07:03 +0000 Subject: r24780: More work allowing libutil to be used by external users. (This used to be commit 31993cf67b816a184a4a4e92ef8ca2532c797190) --- source4/libcli/smb2/create.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 58e7a905d9..c8ac271f44 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -34,11 +34,10 @@ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint32_t tag, DATA_BLOB add, BOOL last) { - NTSTATUS status; uint32_t ofs = blob->length; uint8_t pad = smb2_padding_size(add.length, 8); - status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad); - NT_STATUS_NOT_OK_RETURN(status); + if (!data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad)) + return NT_STATUS_NO_MEMORY; if (last) { SIVAL(blob->data, ofs+0x00, 0); -- cgit From 82037a75eae9deaf6ec80b5ecc3bb89aab6e6dd8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 30 Aug 2007 23:15:12 +0000 Subject: r24814: Fix headers, trim core.h even more. (This used to be commit 9647f860bdd5c0a74583e886182bd041a45e7655) --- source4/libcli/libcli.h | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index 98ca9d57eb..568f2f3b3e 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -21,7 +21,6 @@ #ifndef __LIBCLI_H__ #define __LIBCLI_H__ -#include "core.h" #include "librpc/gen_ndr/nbt.h" /* -- cgit From 8d182d881d189e9855165b3a423f2d545a97fae8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 31 Aug 2007 00:31:32 +0000 Subject: r24816: Move the rest of the contents of core.h to more appropriate places. include/ now only contains build system related headers, all other headers are now near the source code they're related to. (This used to be commit 6890a01dbfc6d8041a88ef5c6be52dfcd046fe80) --- source4/libcli/libcli.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index 568f2f3b3e..1d573cadde 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -50,6 +50,17 @@ struct nbt_dc_name { struct cli_credentials; struct event_context; + +/* passed to br lock code. */ +enum brl_type { + READ_LOCK, + WRITE_LOCK, + PENDING_READ_LOCK, + PENDING_WRITE_LOCK +}; + + + #include "libcli/raw/libcliraw.h" #include "libcli/libcli_proto.h" -- cgit From 8e2d624a588552f5d06f21fe37281615f3ec6296 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Sep 2007 13:13:25 +0000 Subject: r24937: Merge tests spoolss RPC callbacks. (This used to be commit 9b256a0ca232ea6e89771bf73a1adf877273a752) --- source4/libcli/nbt/nbtname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index af3f62b987..911eb0cb5f 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -401,7 +401,7 @@ _PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, n->scope = NULL; n->type = type; - if (is_ipaddress(name)) { + if (is_ipaddress(name) || name == NULL) { n->name = "*SMBSERVER"; return; } -- cgit From bd5a802a26f427779663a3de5f6d49f352b7c473 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 11:47:03 +0000 Subject: r24992: Remove some uses of lp_*(). (This used to be commit a5a1a5540510cdb1bfbb3e89b84f4ba5b2812c55) --- source4/libcli/cldap/cldap.c | 3 ++- source4/libcli/cliconnect.c | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 33d6e88a30..a5c4cc66a1 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -315,7 +315,8 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, } req->dest = socket_address_from_strings(req, cldap->sock->backend_name, - io->in.dest_address, lp_cldap_port()); + io->in.dest_address, + lp_cldap_port()); if (!req->dest) goto failed; req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index e0f3c598b4..50fe41c2bc 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -205,7 +205,7 @@ terminate_path_at_separator(char * path) /* parse a //server/share type UNC name */ -BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, +bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, char **hostname, char **sharename) { char *p; @@ -220,12 +220,9 @@ BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, *hostname = talloc_strdup(mem_ctx, &unc_name[2]); p = terminate_path_at_separator(*hostname); - if (p && *p) { + if (p != NULL && *p) { *sharename = talloc_strdup(mem_ctx, p); terminate_path_at_separator(*sharename); - } else { - *sharename = talloc_strdup(mem_ctx, - lp_parm_string(-1, "torture", "share")); } if (*hostname && *sharename) { -- cgit From 6cf69fee189857ae6f85cd3f81a6a58364839942 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 13:31:15 +0000 Subject: r24994: Fix some C++ warnings. (This used to be commit 925abf74fa1ed5ae726bae8781ec549302786b39) --- source4/libcli/clideltree.c | 2 +- source4/libcli/clireadwrite.c | 6 +++--- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/raw/rawfileinfo.c | 2 +- source4/libcli/raw/rawrequest.c | 2 +- source4/libcli/raw/rawtrans.c | 4 ++-- source4/libcli/smb2/request.c | 2 +- source4/libcli/smb_composite/appendacl.c | 2 +- source4/libcli/smb_composite/loadfile.c | 2 +- source4/libcli/smb_composite/savefile.c | 2 +- source4/libcli/smb_composite/sesssetup.c | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 33c39ea093..d191bd277a 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -33,7 +33,7 @@ struct delete_state { */ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *state) { - struct delete_state *dstate = state; + struct delete_state *dstate = (struct delete_state *)state; char *s, *n; if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { return; diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 10a1c75308..e6e66ef36e 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -27,7 +27,7 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset, size_t size) { - uint8_t *buf = _buf; + uint8_t *buf = (uint8_t *)_buf; union smb_read parms; int readsize; ssize_t total = 0; @@ -87,7 +87,7 @@ ssize_t smbcli_write(struct smbcli_tree *tree, int fnum, uint16_t write_mode, const void *_buf, off_t offset, size_t size) { - const uint8_t *buf = _buf; + const uint8_t *buf = (const uint8_t *)_buf; union smb_write parms; int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32)); ssize_t total = 0; @@ -133,7 +133,7 @@ ssize_t smbcli_write(struct smbcli_tree *tree, ssize_t smbcli_smbwrite(struct smbcli_tree *tree, int fnum, const void *_buf, off_t offset, size_t size1) { - const uint8_t *buf = _buf; + const uint8_t *buf = (const uint8_t *)_buf; union smb_write parms; ssize_t total = 0; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 98f5042d99..0482b04f24 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -635,7 +635,7 @@ NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, p->out.sequence_number = SVAL(req->in.vwv, VWV(0)); p->out.size = req->in.data_size; talloc_free(p->out.data); - p->out.data = talloc_size(mem_ctx, p->out.size); + p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size); NT_STATUS_HAVE_NO_MEMORY(p->out.data); if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) { diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index faae3a52b1..8481995c1a 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -66,7 +66,7 @@ NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx, if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } - io->streams[n].stream_name.s = vstr; + io->streams[n].stream_name.s = (const char *)vstr; io->streams[n].stream_name.private_length = nlen; io->num_streams++; len = IVAL(blob.data, ofs); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 6bf2bb58cc..778b896abd 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -83,7 +83,7 @@ struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *tran /* over allocate by a small amount */ req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; - req->out.buffer = talloc_size(req, req->out.allocated); + req->out.buffer = talloc_array(req, uint8_t, req->out.allocated); if (!req->out.buffer) { return NULL; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index fe26a71310..40a30bd067 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -86,7 +86,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, /* allocate it */ if (total_data != 0) { - tdata = talloc_size(mem_ctx, total_data); + tdata = talloc_array(mem_ctx, uint8_t, total_data); if (!tdata) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); req->status = NT_STATUS_NO_MEMORY; @@ -96,7 +96,7 @@ NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, } if (total_param != 0) { - tparam = talloc_size(mem_ctx, total_param); + tparam = talloc_array(mem_ctx, uint8_t, total_param); if (!tparam) { DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); req->status = NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index d857fc8c5b..392fec1cb9 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -229,7 +229,7 @@ static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t increas dynamic_ofs = buf->dynamic - buf->buffer; - buffer_ptr = talloc_realloc_size(buf, buf->buffer, newsize); + buffer_ptr = talloc_realloc(buf, buf->buffer, uint8_t, newsize); NT_STATUS_HAVE_NO_MEMORY(buffer_ptr); buf->buffer = buffer_ptr; diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index f82714de5b..0fda8c4d65 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -187,7 +187,7 @@ static NTSTATUS appendacl_close(struct composite_context *c, */ static void appendacl_handler(struct smbcli_request *req) { - struct composite_context *c = req->async.private; + struct composite_context *c = (struct composite_context *)req->async.private; struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state); /* when this handler is called, the stage indicates what diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index 9b65d04ef3..d42d3329b6 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -180,7 +180,7 @@ static NTSTATUS loadfile_close(struct composite_context *c, */ static void loadfile_handler(struct smbcli_request *req) { - struct composite_context *c = req->async.private; + struct composite_context *c = (struct composite_context *)req->async.private; struct loadfile_state *state = talloc_get_type(c->private_data, struct loadfile_state); /* when this handler is called, the stage indicates what diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c index 32fcdbcd87..b94be9e9b1 100644 --- a/source4/libcli/smb_composite/savefile.c +++ b/source4/libcli/smb_composite/savefile.c @@ -180,7 +180,7 @@ static NTSTATUS savefile_close(struct composite_context *c, */ static void savefile_handler(struct smbcli_request *req) { - struct composite_context *c = req->async.private; + struct composite_context *c = (struct composite_context *)req->async.private; struct savefile_state *state = talloc_get_type(c->private_data, struct savefile_state); /* when this handler is called, the stage indicates what diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 25cf8b3f12..579706261a 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -76,7 +76,7 @@ static void set_user_session_key(struct smbcli_session *session, */ static void request_handler(struct smbcli_request *req) { - struct composite_context *c = req->async.private; + struct composite_context *c = (struct composite_context *)req->async.private; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); -- cgit From cd962355abad90a2161765a7be7d26e63572cab7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:08:14 +0000 Subject: r25000: Fix some more C++ compatibility warnings. (This used to be commit 08bb1ef643ab906f1645cf6f32763dc73b1884e4) --- source4/libcli/ldap/ldap.c | 8 ++++---- source4/libcli/nbt/nbtsocket.c | 3 ++- source4/libcli/resolve/resolve.c | 2 +- source4/libcli/security/dom_sid.c | 2 +- source4/libcli/smb2/request.c | 2 +- source4/libcli/util/asn1.c | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 64f6f90d31..06ff000acf 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -497,7 +497,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob) { - char *result = talloc_size(mem_ctx, blob.length+1); + char *result = talloc_array(mem_ctx, char, blob.length+1); memcpy(result, blob.data, blob.length); result[blob.length] = '\0'; return result; @@ -955,7 +955,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } if (pwlen != 0) { - char *pw = talloc_size(msg, pwlen+1); + char *pw = talloc_array(msg, char, pwlen+1); if (!pw) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } @@ -1162,7 +1162,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (len == -1) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - dn = talloc_size(msg, len+1); + dn = talloc_array(msg, char, len+1); if (dn == NULL) break; asn1_read(data, dn, len); @@ -1198,7 +1198,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (len == -1) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - newsup = talloc_size(msg, len+1); + newsup = talloc_array(msg, char, len+1); if (newsup == NULL) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 597dc5a354..bb3e15d5de 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -214,7 +214,8 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } /* find the matching request */ - req = idr_find(nbtsock->idr, packet->name_trn_id); + req = (struct nbt_name_request *)idr_find(nbtsock->idr, + packet->name_trn_id); if (req == NULL) { if (nbtsock->unexpected.handler) { nbtsock->unexpected.handler(nbtsock, packet, src); diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 4df4de020c..63598fdd00 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -67,7 +67,7 @@ static const struct resolve_method *find_method(const char *name) */ static void resolve_handler(struct composite_context *creq) { - struct composite_context *c = creq->async.private_data; + struct composite_context *c = (struct composite_context *)creq->async.private_data; struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state); const struct resolve_method *method = find_method(state->methods[0]); diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 64e418677a..8d6bb79714 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -278,7 +278,7 @@ char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) } maxlen = sid->num_auths * 11 + 25; - ret = talloc_size(mem_ctx, maxlen); + ret = talloc_array(mem_ctx, char, maxlen); if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); ia = (sid->id_auth[5]) + diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 392fec1cb9..545f3c8353 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -67,7 +67,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size; req->out.allocated = req->out.size + body_dynamic_size; - req->out.buffer = talloc_size(req, req->out.allocated); + req->out.buffer = talloc_array(req, uint8_t, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); return NULL; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index e7a2e163aa..8bd091a319 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -600,7 +600,7 @@ BOOL asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) data->has_error = True; return False; } - *s = talloc_size(mem_ctx, len+1); + *s = talloc_array(mem_ctx, char, len+1); if (! *s) { data->has_error = True; return False; -- cgit From 959915a8cbea0c598ef1f29ce666329a521ef2f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:35:18 +0000 Subject: r25001: Fix more C++ and other warnings, fix some of the indentation with ts=4 lines that I accidently added earlier. (This used to be commit 0bcb21ed740fcec0f48ad36bbc2deee2948e8fc7) --- source4/libcli/nbt/namerefresh.c | 3 ++- source4/libcli/raw/raweas.c | 1 + source4/libcli/raw/rawlpq.c | 1 + source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/resolve/resolve.c | 3 ++- source4/libcli/resolve/wins.c | 7 ++++--- 6 files changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index a60e54ed6a..afa80d68f8 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -66,7 +66,8 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - dest = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, + dest = socket_address_from_strings(nbtsock, + nbtsock->sock->backend_name, io->in.dest_addr, lp_nbt_port()); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index f79de88fa6..06b5b4fc4d 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -19,6 +19,7 @@ #include "includes.h" #include "smb.h" +#include "libcli/raw/libcliraw.h" /* work out how many bytes on the wire a ea list will consume. diff --git a/source4/libcli/raw/rawlpq.c b/source4/libcli/raw/rawlpq.c index 03f7a82f1c..46e0efaaf5 100644 --- a/source4/libcli/raw/rawlpq.c +++ b/source4/libcli/raw/rawlpq.c @@ -19,6 +19,7 @@ #include "includes.h" #include "smb.h" +#include "libcli/raw/libcliraw.h" /**************************************************************************** lpq - async send diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 99044d23ae..a37c9a7836 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -375,7 +375,7 @@ BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, } -BOOL smbcli_init_signing(struct smbcli_transport *transport) +bool smbcli_init_signing(struct smbcli_transport *transport) { transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) { diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 63598fdd00..ee9b8df148 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -188,7 +188,8 @@ NTSTATUS resolve_name_recv(struct composite_context *c, NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr, struct event_context *ev) { - struct composite_context *c = resolve_name_send(name, ev, lp_name_resolve_order()); + struct composite_context *c = resolve_name_send(name, ev, + lp_name_resolve_order()); return resolve_name_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 7af12075a1..f7bfdc3405 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -26,9 +26,10 @@ /* wins name resolution method - async send */ -struct composite_context *resolve_name_wins_send(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct nbt_name *name) +struct composite_context *resolve_name_wins_send( + TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct nbt_name *name) { const char **address_list = lp_wins_server_list(); if (address_list == NULL) return NULL; -- cgit From 922101afbd64b42c01e1093b9d58fff24b1f852e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 22:01:15 +0000 Subject: r25010: Avoid uses of pstring (This used to be commit cce7785474fc536dd44b39403c785b524b128144) --- source4/libcli/util/doserr.c | 3 +-- source4/libcli/util/nterr.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index d62a31c1fa..49818e573a 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -20,7 +20,6 @@ /* DOS error codes. please read doserr.h */ #include "includes.h" -#include "pstring.h" struct werror_code_struct { const char *dos_errstr; @@ -133,7 +132,7 @@ static const struct werror_code_struct dos_errs[] = *****************************************************************************/ const char *win_errstr(WERROR werror) { - static pstring msg; + static char msg[40]; int idx = 0; while (dos_errs[idx].dos_errstr != NULL) { diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 3aea0b51bc..b1f345016d 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -20,7 +20,6 @@ /* NT error codes. please read nterr.h */ #include "includes.h" -#include "pstring.h" #include "libcli/ldap/ldap.h" typedef struct @@ -862,7 +861,7 @@ const char *get_friendly_nt_error_msg(NTSTATUS nt_code) *****************************************************************************/ const char *get_nt_error_c_code(NTSTATUS nt_code) { - static pstring out; + static char out[40]; int idx = 0; while (nt_errs[idx].nt_errstr != NULL) { -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/libcli/cldap/cldap.c | 1 + source4/libcli/cliconnect.c | 1 + source4/libcli/dgram/browse.c | 1 + source4/libcli/dgram/mailslot.c | 1 + source4/libcli/dgram/netlogon.c | 1 + source4/libcli/dgram/ntlogon.c | 1 + source4/libcli/finddcs.c | 1 + source4/libcli/nbt/namequery.c | 1 + source4/libcli/nbt/namerefresh.c | 1 + source4/libcli/nbt/nameregister.c | 1 + source4/libcli/nbt/namerelease.c | 1 + source4/libcli/nbt/nbtsocket.c | 1 + source4/libcli/raw/clisocket.c | 1 + source4/libcli/raw/clitransport.c | 1 + source4/libcli/raw/clitree.c | 1 + source4/libcli/raw/rawnegotiate.c | 1 + source4/libcli/raw/smb_signing.c | 1 + source4/libcli/resolve/nbtlist.c | 1 + source4/libcli/resolve/resolve.c | 1 + source4/libcli/resolve/wins.c | 1 + source4/libcli/smb2/connect.c | 1 + source4/libcli/smb_composite/connect.c | 1 + source4/libcli/smb_composite/sesssetup.c | 1 + source4/libcli/util/errormap.c | 1 + 24 files changed, 24 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index a5c4cc66a1..4c41e13014 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -39,6 +39,7 @@ #include "lib/socket/socket.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* destroy a pending request diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 50fe41c2bc..a91157cf5d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -25,6 +25,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/auth/libcli_auth.h" #include "libcli/smb_composite/smb_composite.h" +#include "param/param.h" /* wrapper around smbcli_sock_connect() diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 84a2a7e534..78bd4319ee 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -25,6 +25,7 @@ #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 14eb7b931b..7a325ebe38 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -36,6 +36,7 @@ #include "lib/util/dlinklist.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" +#include "param/param.h" /* destroy a mailslot handler diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index df47a34a0e..79acf609f6 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -24,6 +24,7 @@ #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* send a netlogon mailslot request diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 5881dcf702..6b9b17485d 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -24,6 +24,7 @@ #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* send a ntlogon mailslot request diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index a159ab6dfc..46cca36009 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -27,6 +27,7 @@ #include "libcli/composite/composite.h" #include "libcli/libcli.h" #include "libcli/resolve/resolve.h" +#include "param/param.h" struct finddcs_state { struct composite_context *ctx; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 32de9723b9..ab26a7b2d2 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" +#include "param/param.h" /** send a nbt name query diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index afa80d68f8..d68cdb5365 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -23,6 +23,7 @@ #include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" #include "lib/socket/socket.h" +#include "param/param.h" /* send a nbt name refresh request diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 7b03667fec..62c4a19b29 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -24,6 +24,7 @@ #include "libcli/composite/composite.h" #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* send a nbt name registration request diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index fd3967d1e6..efc31b1501 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" +#include "param/param.h" /* send a nbt name release request diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index bb3e15d5de..b44b50efd8 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -25,6 +25,7 @@ #include "libcli/nbt/libnbt.h" #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" #define NBT_MAX_REPLIES 1000 diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 0aa6ec5616..51f631eb67 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -26,6 +26,7 @@ #include "libcli/composite/composite.h" #include "lib/socket/socket.h" #include "libcli/resolve/resolve.h" +#include "param/param.h" struct sock_connect_state { struct composite_context *ctx; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 0482b04f24..90f51b2969 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -26,6 +26,7 @@ #include "lib/events/events.h" #include "lib/stream/packet.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index a5217d74b2..6a15c25eb9 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb_composite/smb_composite.h" +#include "param/param.h" #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index c2dc393481..eff22ee8bc 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "system/time.h" +#include "param/param.h" static const struct { enum protocol_types prot; diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index a37c9a7836..1a82ea0536 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -23,6 +23,7 @@ #include "smb.h" #include "libcli/raw/libcliraw.h" #include "lib/crypto/crypto.h" +#include "param/param.h" /*********************************************************** SMB signing - Common code before we set a new signing implementation diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index ad331c872d..faa2962d5a 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -29,6 +29,7 @@ #include "lib/socket/netif.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "libcli/nbt/libnbt.h" +#include "param/param.h" struct nbtlist_state { struct nbt_name name; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index ee9b8df148..9315c0f354 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -24,6 +24,7 @@ #include "libcli/composite/composite.h" #include "libcli/resolve/resolve.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" struct resolve_state { struct nbt_name name; diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index f7bfdc3405..8c88950f53 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "libcli/resolve/resolve.h" +#include "param/param.h" /* wins name resolution method - async send diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index a365f25d49..0edf64c5df 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -25,6 +25,7 @@ #include "libcli/smb2/smb2_calls.h" #include "libcli/composite/composite.h" #include "libcli/resolve/resolve.h" +#include "param/param.h" struct smb2_connect_state { struct cli_credentials *credentials; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 026fe0b029..27b16ecc41 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -28,6 +28,7 @@ #include "libcli/resolve/resolve.h" #include "auth/credentials/credentials.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 579706261a..6a14e57ad0 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -29,6 +29,7 @@ #include "auth/gensec/gensec.h" #include "auth/credentials/credentials.h" #include "version.h" +#include "param/param.h" struct sesssetup_state { union smb_sesssetup setup; diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 711f02a626..347d513e9c 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "param/param.h" /* This map was extracted by the ERRMAPEXTRACT smbtorture command. The setup was a Samba HEAD (2002-01-03) PDC and an Win2k member -- cgit From dccf3f99e45137b6cd18c1de1c79808ad67130d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 13:27:14 +0000 Subject: r25027: Fix more warnings. (This used to be commit 5085c53fcfade614e83d21fc2c1a5bc43bb2a729) --- source4/libcli/clilist.c | 6 ++++-- source4/libcli/climessage.c | 1 + source4/libcli/clireadwrite.c | 1 + source4/libcli/clitrans2.c | 1 + source4/libcli/finddcs.c | 1 + source4/libcli/security/dom_sid.c | 3 ++- source4/libcli/security/privilege.c | 1 + source4/libcli/security/security_descriptor.c | 6 +++--- source4/libcli/smb2/request.c | 1 + source4/libcli/util/clilsa.c | 1 + 10 files changed, 16 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index ba85ec397a..14fd3ee4f7 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -118,7 +118,8 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.dirlist_len = 0; state.total_received = 0; - state.dirlist = talloc_new(state.mem_ctx); + state.dirlist = talloc_array(state.mem_ctx, + struct clilist_file_info, 0); mask = talloc_strdup(state.mem_ctx, Mask); if (level == RAW_SEARCH_DATA_GENERIC) { @@ -275,7 +276,8 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu state.total_received = 0; state.data_level = RAW_SEARCH_DATA_SEARCH; - state.dirlist = talloc_new(state.mem_ctx); + state.dirlist = talloc_array(state.mem_ctx, struct clilist_file_info, + 0); mask = talloc_strdup(state.mem_ctx, Mask); while (1) { diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 3d4d9da96c..35607ba45b 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" /**************************************************************************** diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index e6e66ef36e..89ae157042 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" /**************************************************************************** Read size bytes at offset offset using SMBreadX. diff --git a/source4/libcli/clitrans2.c b/source4/libcli/clitrans2.c index 03deea2e82..5c5ba6585f 100644 --- a/source4/libcli/clitrans2.c +++ b/source4/libcli/clitrans2.c @@ -19,6 +19,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" /**************************************************************************** send a qpathinfo call diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 46cca36009..edd9a92693 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -27,6 +27,7 @@ #include "libcli/composite/composite.h" #include "libcli/libcli.h" #include "libcli/resolve/resolve.h" +#include "libcli/finddcs.h" #include "param/param.h" struct finddcs_state { diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 8d6bb79714..1ba3edd9bf 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -22,6 +22,7 @@ #include "includes.h" #include "librpc/gen_ndr/security.h" +#include "libcli/security/security.h" /***************************************************************** Compare the auth portion of two sids. @@ -78,7 +79,7 @@ static int dom_sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid Compare two sids. *****************************************************************/ -BOOL dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) +bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) { return dom_sid_compare(sid1, sid2) == 0; } diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 635f470bf6..103e2e3c14 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -21,6 +21,7 @@ #include "includes.h" #include "librpc/gen_ndr/security.h" +#include "libcli/security/security.h" static const struct { diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 06c3c2eca7..1e33e1950b 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -60,7 +60,7 @@ static struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx, return NULL; } - nacl->aces = talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces); + nacl->aces = (struct security_ace *)talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces); if ((nacl->aces == NULL) && (oacl->num_aces > 0)) { goto failed; } @@ -69,7 +69,7 @@ static struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx, for (i = 0; i < oacl->num_aces; i++) { nacl->aces[i].trustee.sub_auths = - talloc_memdup(nacl->aces, nacl->aces[i].trustee.sub_auths, + (uint32_t *)talloc_memdup(nacl->aces, nacl->aces[i].trustee.sub_auths, sizeof(uint32_t) * nacl->aces[i].trustee.num_auths); if ((nacl->aces[i].trustee.sub_auths == NULL) && (nacl->aces[i].trustee.num_auths > 0)) { @@ -163,7 +163,7 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, sd->dacl->aces[sd->dacl->num_aces] = *ace; sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths = - talloc_memdup(sd->dacl->aces, + (uint32_t *)talloc_memdup(sd->dacl->aces, sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths, sizeof(uint32_t) * sd->dacl->aces[sd->dacl->num_aces].trustee.num_auths); diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 545f3c8353..cca4f861de 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -25,6 +25,7 @@ #include "libcli/smb2/smb2.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" +#include "libcli/smb2/smb2_calls.h" /* initialise a smb2 request diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 6fd84bbe74..0fdf8a8e3a 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -31,6 +31,7 @@ #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_lsa_c.h" +#include "libcli/util/clilsa.h" struct smblsa_state { struct dcerpc_pipe *pipe; -- cgit From 98b57d5eb61094a9c88e2f7d90d3e21b7e74e9d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 16:46:30 +0000 Subject: r25035: Fix some more warnings, use service pointer rather than service number in more places. (This used to be commit df9cebcb97e20564359097148665bd519f31bc6f) --- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/resolve/nbtlist.c | 2 +- source4/libcli/smb2/request.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index b44b50efd8..453f0afcff 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -244,7 +244,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req->received_wack = True; /* although there can be a timeout in the packet, w2k3 screws it up, so better to set it ourselves */ - req->timeout = lp_parm_int(-1, "nbt", "wack_timeout", 30); + req->timeout = lp_parm_int(NULL, "nbt", "wack_timeout", 30); req->te = event_add_timed(req->nbtsock->event_ctx, req, timeval_current_ofs(req->timeout, 0), nbt_name_socket_timeout, req); diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index faa2962d5a..be4d01b79a 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -155,7 +155,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, state->io_queries[i].in.broadcast = broadcast; state->io_queries[i].in.wins_lookup = wins_lookup; - state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 1); + state->io_queries[i].in.timeout = lp_parm_int(NULL, "nbt", "timeout", 1); state->io_queries[i].in.retries = 2; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index cca4f861de..2d2c8252a1 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -582,7 +582,7 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); - (*str) = vstr; + (*str) = (char *)vstr; if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } -- cgit From 7e297ecfa4db2c7ab720a63c7764bc0e20f8058c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 9 Sep 2007 19:34:30 +0000 Subject: r25047: Fix more warnings. (This used to be commit 69de86d2d2e49439760fbc61901eb87fb7fc5d55) --- source4/libcli/libcli.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index 1d573cadde..163852d90a 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -23,6 +23,8 @@ #include "librpc/gen_ndr/nbt.h" +struct substitute_context; + /* smbcli_state: internal state used in libcli library for single-threaded callers, i.e. a single session on a single socket. -- cgit From 9a012df08ee829c1d40fc88ba12a0ea479f60be0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Sep 2007 23:21:00 +0000 Subject: r25175: Change to talloc_asprintf_append_buffer(). Jeremy. (This used to be commit 0844dbf597191b3e4d35a696695b229e986daec4) --- source4/libcli/cldap/cldap.c | 14 +++++++------- source4/libcli/nbt/nbtname.c | 2 +- source4/libcli/security/sddl.c | 12 ++++++------ source4/libcli/util/asn1.c | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 4c41e13014..9381e80934 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -536,26 +536,26 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, ldap_encode_ndr_uint32(tmp_ctx, io->in.version)); if (filter == NULL) goto failed; if (io->in.user) { - filter = talloc_asprintf_append(filter, "(User=%s)", io->in.user); + filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user); if (filter == NULL) goto failed; } if (io->in.host) { - filter = talloc_asprintf_append(filter, "(Host=%s)", io->in.host); + filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host); if (filter == NULL) goto failed; } if (io->in.realm) { - filter = talloc_asprintf_append(filter, "(DnsDomain=%s)", io->in.realm); + filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm); if (filter == NULL) goto failed; } if (io->in.acct_control != -1) { - filter = talloc_asprintf_append(filter, "(AAC=%s)", + filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)", ldap_encode_ndr_uint32(tmp_ctx, io->in.acct_control)); if (filter == NULL) goto failed; } if (io->in.domain_sid) { struct dom_sid *sid = dom_sid_parse_talloc(tmp_ctx, io->in.domain_sid); if (sid == NULL) goto failed; - filter = talloc_asprintf_append(filter, "(domainSid=%s)", + filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); if (filter == NULL) goto failed; } @@ -564,11 +564,11 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, NTSTATUS status; status = GUID_from_string(io->in.domain_guid, &guid); if (!NT_STATUS_IS_OK(status)) goto failed; - filter = talloc_asprintf_append(filter, "(DomainGuid=%s)", + filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)", ldap_encode_ndr_GUID(tmp_ctx, &guid)); if (filter == NULL) goto failed; } - filter = talloc_asprintf_append(filter, ")"); + filter = talloc_asprintf_append_buffer(filter, ")"); if (filter == NULL) goto failed; search.in.dest_address = io->in.dest_address; diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 911eb0cb5f..416814220b 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -111,7 +111,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const NT_STATUS_NOT_OK_RETURN(status); if (component == NULL) break; if (name) { - name = talloc_asprintf_append(name, ".%s", component); + name = talloc_asprintf_append_buffer(name, ".%s", component); NT_STATUS_HAVE_NO_MEMORY(name); } else { name = (char *)component; diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index 4342a7b87a..d4efab9b64 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -405,7 +405,7 @@ static char *sddl_flags_to_string(TALLOC_CTX *mem_ctx, const struct flag_map *ma /* now by bits */ for (i=0;map[i].name;i++) { if ((flags & map[i].flag) != 0) { - s = talloc_asprintf_append(s, "%s", map[i].name); + s = talloc_asprintf_append_buffer(s, "%s", map[i].name); if (s == NULL) goto failed; flags &= ~map[i].flag; } @@ -532,7 +532,7 @@ static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl for (i=0;inum_aces;i++) { char *ace = sddl_encode_ace(sddl, &acl->aces[i], domain_sid); if (ace == NULL) goto failed; - sddl = talloc_asprintf_append(sddl, "(%s)", ace); + sddl = talloc_asprintf_append_buffer(sddl, "(%s)", ace); if (sddl == NULL) goto failed; talloc_free(ace); } @@ -563,28 +563,28 @@ char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd, if (sd->owner_sid != NULL) { char *sid = sddl_encode_sid(tmp_ctx, sd->owner_sid, domain_sid); if (sid == NULL) goto failed; - sddl = talloc_asprintf_append(sddl, "O:%s", sid); + sddl = talloc_asprintf_append_buffer(sddl, "O:%s", sid); if (sddl == NULL) goto failed; } if (sd->group_sid != NULL) { char *sid = sddl_encode_sid(tmp_ctx, sd->group_sid, domain_sid); if (sid == NULL) goto failed; - sddl = talloc_asprintf_append(sddl, "G:%s", sid); + sddl = talloc_asprintf_append_buffer(sddl, "G:%s", sid); if (sddl == NULL) goto failed; } if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl != NULL) { char *acl = sddl_encode_acl(tmp_ctx, sd->dacl, sd->type, domain_sid); if (acl == NULL) goto failed; - sddl = talloc_asprintf_append(sddl, "D:%s", acl); + sddl = talloc_asprintf_append_buffer(sddl, "D:%s", acl); if (sddl == NULL) goto failed; } if ((sd->type & SEC_DESC_SACL_PRESENT) && sd->sacl != NULL) { char *acl = sddl_encode_acl(tmp_ctx, sd->sacl, sd->type>>1, domain_sid); if (acl == NULL) goto failed; - sddl = talloc_asprintf_append(sddl, "S:%s", acl); + sddl = talloc_asprintf_append_buffer(sddl, "S:%s", acl); if (sddl == NULL) goto failed; } diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 8bd091a319..7e2d54fcbd 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -514,13 +514,13 @@ BOOL ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40); if (!tmp_oid) goto nomem; - tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", b[0]%40); + tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40); if (!tmp_oid) goto nomem; for(i = 1, v = 0; i < blob.length; i++) { v = (v<<7) | (b[i]&0x7f); if ( ! (b[i] & 0x80)) { - tmp_oid = talloc_asprintf_append(tmp_oid, ".%u", v); + tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v); v = 0; } if (!tmp_oid) goto nomem; -- cgit From f35373709444780c4bf338c17b26ce9cc3ebab50 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 18 Sep 2007 13:31:05 +0000 Subject: r25212: merge some stuff from samba3 metze (This used to be commit 502251451aa78b82131283d0590b382943b1d156) --- source4/libcli/util/asn1.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 7e2d54fcbd..f2098de5c5 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -360,6 +360,9 @@ BOOL asn1_load(struct asn1_data *data, DATA_BLOB blob) /* Peek into an ASN1 buffer, not advancing the pointer */ BOOL asn1_peek(struct asn1_data *data, void *p, int len) { + if (data->has_error) + return False; + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) return False; @@ -405,7 +408,7 @@ BOOL asn1_peek_tag(struct asn1_data *data, uint8_t tag) return False; } - if (!asn1_peek(data, &b, sizeof(b))) + if (!asn1_peek_uint8(data, &b)) return False; return (b == tag); -- cgit From 3eb2b3085db47cfa25f9d46b64d60fdc6b0186e3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 19 Sep 2007 01:59:06 +0000 Subject: r25221: Experiment with Jelmer's new generic loadparm code. (This used to be commit 9fbbd1b5c9c19a0f5d49bafc6d25967e133e38b4) --- source4/libcli/swig/libcli_nbt.i | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index b887e7df97..6bcbd7a65b 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -31,11 +31,16 @@ #include "lib/talloc/talloc.h" #include "lib/events/events.h" #include "libcli/nbt/libnbt.h" +#include "param/param.h" /* Undo strcpy safety macro as it's used by swig )-: */ #undef strcpy +/* Loadparm parameters */ + +static struct loadparm_context lp_ctx; + %} %apply bool { BOOL }; @@ -132,4 +137,6 @@ struct nbt_name_query { NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -void lp_load(void); +%init %{ + loadparm_init(&lp_ctx); +%} -- cgit From 9b009c900987517359485799be8be4167494b376 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Sep 2007 21:35:03 +0000 Subject: r25301: Merge my includes.h cleanups. (This used to be commit 37425495f392a2d0122a93aa2c42758eab7dab5a) --- source4/libcli/config.mk | 3 +- source4/libcli/ldap/ldap.h | 1 + source4/libcli/raw/clierror.c | 72 +++++ source4/libcli/raw/interfaces.h | 1 + source4/libcli/util/clierror.c | 72 ----- source4/libcli/util/doserr.h | 125 -------- source4/libcli/util/error.h | 29 +- source4/libcli/util/nt_status.h | 122 -------- source4/libcli/util/nterr.h | 588 ---------------------------------- source4/libcli/util/ntstatus.h | 675 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/util/werror.h | 193 ++++++++++++ 11 files changed, 970 insertions(+), 911 deletions(-) create mode 100644 source4/libcli/raw/clierror.c delete mode 100644 source4/libcli/util/clierror.c delete mode 100644 source4/libcli/util/nt_status.h delete mode 100644 source4/libcli/util/nterr.h create mode 100644 source4/libcli/util/ntstatus.h create mode 100644 source4/libcli/util/werror.h (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index d49fc90ec4..89e6f3ce1c 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,11 +3,9 @@ include ldap/config.mk include security/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] -PUBLIC_PROTO_HEADER = util/proto.h PUBLIC_HEADERS = util/error.h util/nterr.h util/doserr.h util/nt_status.h OBJ_FILES = util/doserr.o \ util/errormap.o \ - util/clierror.o \ util/nterr.o \ [SUBSYSTEM::ASN1_UTIL] @@ -133,6 +131,7 @@ OBJ_FILES = raw/rawfile.o \ raw/clitransport.o \ raw/clisession.o \ raw/clitree.o \ + raw/clierror.o \ raw/rawrequest.o \ raw/rawreadwrite.o \ raw/rawsearch.o \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 022c70e36a..e89322213a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -22,6 +22,7 @@ #define _SMB_LDAP_H #include "lib/ldb/include/ldb.h" +#include "librpc/gen_ndr/misc.h" enum ldap_request_tag { LDAP_TAG_BindRequest = 0, diff --git a/source4/libcli/raw/clierror.c b/source4/libcli/raw/clierror.c new file mode 100644 index 0000000000..c515259ee7 --- /dev/null +++ b/source4/libcli/raw/clierror.c @@ -0,0 +1,72 @@ +/* + Unix SMB/CIFS implementation. + client error handling routines + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) James Myers 2003 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" + + +/*************************************************************************** + Return an error message from the last response +****************************************************************************/ +const char *smbcli_errstr(struct smbcli_tree *tree) +{ + switch (tree->session->transport->error.etype) { + case ETYPE_SMB: + return nt_errstr(tree->session->transport->error.e.nt_status); + + case ETYPE_SOCKET: + return "socket_error"; + + case ETYPE_NBT: + return "nbt_error"; + + case ETYPE_NONE: + return "no_error"; + } + return NULL; +} + + +/* Return the 32-bit NT status code from the last packet */ +NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) +{ + switch (tree->session->transport->error.etype) { + case ETYPE_SMB: + return tree->session->transport->error.e.nt_status; + + case ETYPE_SOCKET: + return NT_STATUS_UNSUCCESSFUL; + + case ETYPE_NBT: + return NT_STATUS_UNSUCCESSFUL; + + case ETYPE_NONE: + return NT_STATUS_OK; + } + + return NT_STATUS_UNSUCCESSFUL; +} + + +/* Return true if the last packet was an error */ +bool smbcli_is_error(struct smbcli_tree *tree) +{ + return NT_STATUS_IS_ERR(smbcli_nt_error(tree)); +} diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 23de6c3838..00ab788184 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -23,6 +23,7 @@ #define __LIBCLI_RAW_INTERFACES_H__ #include "smb.h" +#include "librpc/gen_ndr/misc.h" /* for struct GUID */ /* this structure is just a wrapper for a string, the only reason we bother with this is that it allows us to check the length provided diff --git a/source4/libcli/util/clierror.c b/source4/libcli/util/clierror.c deleted file mode 100644 index 89bba21ed6..0000000000 --- a/source4/libcli/util/clierror.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - Unix SMB/CIFS implementation. - client error handling routines - Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) James Myers 2003 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" - - -/*************************************************************************** - Return an error message from the last response -****************************************************************************/ -const char *smbcli_errstr(struct smbcli_tree *tree) -{ - switch (tree->session->transport->error.etype) { - case ETYPE_SMB: - return nt_errstr(tree->session->transport->error.e.nt_status); - - case ETYPE_SOCKET: - return "socket_error"; - - case ETYPE_NBT: - return "nbt_error"; - - case ETYPE_NONE: - return "no_error"; - } - return NULL; -} - - -/* Return the 32-bit NT status code from the last packet */ -NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) -{ - switch (tree->session->transport->error.etype) { - case ETYPE_SMB: - return tree->session->transport->error.e.nt_status; - - case ETYPE_SOCKET: - return NT_STATUS_UNSUCCESSFUL; - - case ETYPE_NBT: - return NT_STATUS_UNSUCCESSFUL; - - case ETYPE_NONE: - return NT_STATUS_OK; - } - - return NT_STATUS_UNSUCCESSFUL; -} - - -/* Return true if the last packet was an error */ -BOOL smbcli_is_error(struct smbcli_tree *tree) -{ - return NT_STATUS_IS_ERR(smbcli_nt_error(tree)); -} diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index 0478eff947..bec268a565 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -161,133 +161,8 @@ #define ERRsharebufexc 36 /* share buffer exceeded */ #define ERRdiskfull 39 - -/* these are win32 error codes. There are only a few places where - these matter for Samba, primarily in the NT printing code */ -#define WERR_OK W_ERROR(0) -#define WERR_BADFUNC W_ERROR(1) -#define WERR_BADFILE W_ERROR(2) -#define WERR_ACCESS_DENIED W_ERROR(5) -#define WERR_BADFID W_ERROR(6) -#define WERR_NOMEM W_ERROR(8) -#define WERR_GENERAL_FAILURE W_ERROR(31) -#define WERR_NOT_SUPPORTED W_ERROR(50) -#define WERR_BAD_NETPATH W_ERROR(53) -#define WERR_BAD_NET_RESP W_ERROR(58) -#define WERR_UNEXP_NET_ERR W_ERROR(59) -#define WERR_PRINTQ_FULL W_ERROR(61) -#define WERR_NO_SPOOL_SPACE W_ERROR(62) -#define WERR_NO_SUCH_SHARE W_ERROR(67) -#define WERR_FILE_EXISTS W_ERROR(80) -#define WERR_BAD_PASSWORD W_ERROR(86) -#define WERR_INVALID_PARAM W_ERROR(87) -#define WERR_INSUFFICIENT_BUFFER W_ERROR(122) -#define WERR_INVALID_NAME W_ERROR(123) -#define WERR_UNKNOWN_LEVEL W_ERROR(124) -#define WERR_OBJECT_PATH_INVALID W_ERROR(161) -#define WERR_ALREADY_EXISTS W_ERROR(183) -#define WERR_NO_MORE_ITEMS W_ERROR(259) -#define WERR_MORE_DATA W_ERROR(234) -#define WERR_CAN_NOT_COMPLETE W_ERROR(1003) -#define WERR_NOT_FOUND W_ERROR(1168) -#define WERR_INVALID_COMPUTERNAME W_ERROR(1210) -#define WERR_INVALID_DOMAINNAME W_ERROR(1212) -#define WERR_UNKNOWN_REVISION W_ERROR(1305) -#define WERR_REVISION_MISMATCH W_ERROR(1306) -#define WERR_INVALID_OWNER W_ERROR(1307) -#define WERR_NO_LOGON_SERVERS W_ERROR(1311) -#define WERR_NO_SUCH_PRIVILEGE W_ERROR(1313) -#define WERR_PRIVILEGE_NOT_HELD W_ERROR(1314) -#define WERR_NO_SUCH_USER W_ERROR(1317) -#define WERR_LOGON_FAILURE W_ERROR(1326) -#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) -#define WERR_INVALID_DOMAIN_ROLE W_ERROR(1354) -#define WERR_NO_SUCH_DOMAIN W_ERROR(1355) -#define WERR_NO_SYSTEM_RESOURCES W_ERROR(1450) -#define WERR_SERVER_UNAVAILABLE W_ERROR(1722) -#define WERR_INVALID_FORM_NAME W_ERROR(1902) -#define WERR_INVALID_FORM_SIZE W_ERROR(1903) -#define WERR_ALREADY_SHARED W_ERROR(2118) -#define WERR_BUF_TOO_SMALL W_ERROR(2123) -#define WERR_JOB_NOT_FOUND W_ERROR(2151) -#define WERR_DEST_NOT_FOUND W_ERROR(2152) -#define WERR_SESSION_NOT_FOUND W_ERROR(2312) -#define WERR_FID_NOT_FOUND W_ERROR(2314) -#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) -#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453) -#define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) -#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) - -#define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled) -#define WERR_UNKNOWN_PORT W_ERROR(ERRunknownprinterport) -#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(ERRunknownprinterdriver) -#define WERR_UNKNOWN_PRINTPROCESSOR W_ERROR(ERRunknownprintprocessor) -#define WERR_INVALID_SEPARATOR_FILE W_ERROR(ERRinvalidseparatorfile) -#define WERR_INVALID_PRIORITY W_ERROR(ERRinvalidjobpriority) -#define WERR_INVALID_PRINTER_NAME W_ERROR(ERRinvalidprintername) -#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(ERRprinteralreadyexists) -#define WERR_INVALID_PRINTER_COMMAND W_ERROR(ERRinvalidprintercommand) -#define WERR_INVALID_DATATYPE W_ERROR(ERRinvaliddatatype) -#define WERR_INVALID_ENVIRONMENT W_ERROR(ERRinvalidenvironment) - -#define WERR_UNKNOWN_PRINT_MONITOR W_ERROR(ERRunknownprintmonitor) -#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(ERRprinterdriverinuse) -#define WERR_SPOOL_FILE_NOT_FOUND W_ERROR(ERRspoolfilenotfound) -#define WERR_SPL_NO_STARTDOC W_ERROR(ERRnostartdoc) -#define WERR_SPL_NO_ADDJOB W_ERROR(ERRnoaddjob) -#define WERR_PRINT_PROCESSOR_ALREADY_INSTALLED W_ERROR(ERRprintprocessoralreadyinstalled) -#define WERR_PRINT_MONITOR_ALREADY_INSTALLED W_ERROR(ERRprintmonitoralreadyinstalled) -#define WERR_INVALID_PRINT_MONITOR W_ERROR(ERRinvalidprintmonitor) -#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse) -#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued) - -#define WERR_CLASS_NOT_REGISTERED W_ERROR(0x40154) -#define WERR_NO_SHUTDOWN_IN_PROGRESS W_ERROR(0x45c) -#define WERR_SHUTDOWN_ALREADY_IN_PROGRESS W_ERROR(0x45b) - - #ifndef NERR_BASE #define NERR_BASE (2100) #endif -#define WERR_NET_NAME_NOT_FOUND W_ERROR(NERR_BASE+210) -#define WERR_DEVICE_NOT_SHARED W_ERROR(NERR_BASE+211) - -/* DFS errors */ -#define WERR_DFS_NO_SUCH_VOL W_ERROR(NERR_BASE+562) -#define WERR_DFS_NO_SUCH_SHARE W_ERROR(NERR_BASE+565) -#define WERR_DFS_NO_SUCH_SERVER W_ERROR(NERR_BASE+573) -#define WERR_DFS_INTERNAL_ERROR W_ERROR(NERR_BASE+590) -#define WERR_DFS_CANT_CREATE_JUNCT W_ERROR(NERR_BASE+569) - -/* DS errors */ -#define WERR_DS_SERVICE_BUSY W_ERROR(0x0000200e) -#define WERR_DS_SERVICE_UNAVAILABLE W_ERROR(0x0000200f) -#define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030) -#define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208d) -#define WERR_DS_SCHEMA_NOT_LOADED W_ERROR(0x20de) -#define WERR_DS_SCHEMA_ALLOC_FAILED W_ERROR(0x20df) -#define WERR_DS_ATT_SCHEMA_REQ_SYNTAX W_ERROR(0x000020e0) -#define WERR_DS_DRA_SCHEMA_MISMATCH W_ERROR(0x000020e2) -#define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020f5) -#define WERR_DS_DRA_BAD_DN W_ERROR(0x000020f7) -#define WERR_DS_DRA_BAD_NC W_ERROR(0x000020f8) -#define WERR_DS_DRA_INTERNAL_ERROR W_ERROR(0x000020fa) -#define WERR_DS_DRA_OUT_OF_MEM W_ERROR(0x000020fe) -#define WERR_DS_SINGLE_VALUE_CONSTRAINT W_ERROR(0x00002081) -#define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) -#define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) -#define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105) -#define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) -#define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) -#define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194) -#define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) - -/* SEC errors */ -#define WERR_SEC_E_ENCRYPT_FAILURE W_ERROR(0x80090329) -#define WERR_SEC_E_DECRYPT_FAILURE W_ERROR(0x80090330) -#define WERR_SEC_E_ALGORITHM_MISMATCH W_ERROR(0x80090331) - -#define WERR_FOOBAR WERR_GENERAL_FAILURE - #endif /* _DOSERR_H */ diff --git a/source4/libcli/util/error.h b/source4/libcli/util/error.h index 8a641c8eb9..dd2de3da75 100644 --- a/source4/libcli/util/error.h +++ b/source4/libcli/util/error.h @@ -19,8 +19,33 @@ #ifndef _SAMBA_ERROR_H_ #define _SAMBA_ERROR_H_ -#include "libcli/util/nterr.h" +#include "libcli/util/werror.h" #include "libcli/util/doserr.h" -#include "libcli/util/proto.h" +#include "libcli/util/ntstatus.h" + +/** NT error on DOS connection! (NT_STATUS_OK) */ +bool ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2); + +/***************************************************************************** +convert a NT status code to a dos class/code + *****************************************************************************/ +void ntstatus_to_dos(NTSTATUS ntstatus, uint8_t *eclass, uint32_t *ecode); + +/***************************************************************************** +convert a WERROR to a NT status32 code + *****************************************************************************/ +NTSTATUS werror_to_ntstatus(WERROR error); + +/***************************************************************************** +convert a NTSTATUS to a WERROR + *****************************************************************************/ +WERROR ntstatus_to_werror(NTSTATUS error); + +/********************************************************************* + Map an NT error code from a Unix error code. +*********************************************************************/ +NTSTATUS map_nt_error_from_unix(int unix_error); + + #endif /* _SAMBA_ERROR_H */ diff --git a/source4/libcli/util/nt_status.h b/source4/libcli/util/nt_status.h deleted file mode 100644 index 8d81aab175..0000000000 --- a/source4/libcli/util/nt_status.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup, plus a whole lot more. - - Copyright (C) Andrew Tridgell 2001 - - 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 3 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, see . -*/ - -#ifndef _NT_STATUS_H -#define _NT_STATUS_H - -#include - -/* the following rather strange looking definitions of NTSTATUS and WERROR - and there in order to catch common coding errors where different error types - are mixed up. This is especially important as we slowly convert Samba - from using BOOL for internal functions -*/ - -#if defined(HAVE_IMMEDIATE_STRUCTURES) -typedef struct {uint32_t v;} NTSTATUS; -#define NT_STATUS(x) ((NTSTATUS) { x }) -#define NT_STATUS_V(x) ((x).v) -#else -typedef uint32_t NTSTATUS; -#define NT_STATUS(x) (x) -#define NT_STATUS_V(x) (x) -#endif - -#if defined(HAVE_IMMEDIATE_STRUCTURES) -typedef struct {uint32_t v;} WERROR; -#define W_ERROR(x) ((WERROR) { x }) -#define W_ERROR_V(x) ((x).v) -#else -typedef uint32_t WERROR; -#define W_ERROR(x) (x) -#define W_ERROR_V(x) (x) -#endif - -#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) -#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) -/* checking for DOS error mapping here is ugly, but unfortunately the - alternative is a very intrusive rewrite of the torture code */ -#define NT_STATUS_EQUAL(x,y) (NT_STATUS_IS_DOS(x)||NT_STATUS_IS_DOS(y)?ntstatus_dos_equal(x,y):NT_STATUS_V(x) == NT_STATUS_V(y)) - -#define NT_STATUS_HAVE_NO_MEMORY(x) do { \ - if (!(x)) {\ - return NT_STATUS_NO_MEMORY;\ - }\ -} while (0) - -#define NT_STATUS_IS_OK_RETURN(x) do { \ - if (NT_STATUS_IS_OK(x)) {\ - return x;\ - }\ -} while (0) - -#define NT_STATUS_NOT_OK_RETURN(x) do { \ - if (!NT_STATUS_IS_OK(x)) {\ - return x;\ - }\ -} while (0) - -#define NT_STATUS_IS_ERR_RETURN(x) do { \ - if (NT_STATUS_IS_ERR(x)) {\ - return x;\ - }\ -} while (0) - -#define NT_STATUS_NOT_ERR_RETURN(x) do { \ - if (!NT_STATUS_IS_ERR(x)) {\ - return x;\ - }\ -} while (0) - -#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) -#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) - -#define W_ERROR_HAVE_NO_MEMORY(x) do { \ - if (!(x)) {\ - return WERR_NOMEM;\ - }\ -} while (0) - -#define W_ERROR_IS_OK_RETURN(x) do { \ - if (W_ERROR_IS_OK(x)) {\ - return x;\ - }\ -} while (0) - -#define W_ERROR_NOT_OK_RETURN(x) do { \ - if (!W_ERROR_IS_OK(x)) {\ - return x;\ - }\ -} while (0) - -/* this defines special NTSTATUS codes to represent DOS errors. I - have chosen this macro to produce status codes in the invalid - NTSTATUS range */ -#define NT_STATUS_DOS(class, code) NT_STATUS(0xF1000000 | ((class)<<16) | code) -#define NT_STATUS_IS_DOS(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF1000000) -#define NT_STATUS_DOS_CLASS(status) ((NT_STATUS_V(status) >> 16) & 0xFF) -#define NT_STATUS_DOS_CODE(status) (NT_STATUS_V(status) & 0xFFFF) - -/* define ldap error codes as NTSTATUS codes */ -#define NT_STATUS_LDAP(code) NT_STATUS(0xF2000000 | code) -#define NT_STATUS_IS_LDAP(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF2000000) -#define NT_STATUS_LDAP_CODE(status) (NT_STATUS_V(status) & ~0xFF000000) - -#endif diff --git a/source4/libcli/util/nterr.h b/source4/libcli/util/nterr.h deleted file mode 100644 index 1ee867a0aa..0000000000 --- a/source4/libcli/util/nterr.h +++ /dev/null @@ -1,588 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT error code constants - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) John H Terpstra 1996-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Paul Ashton 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 3 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, see . -*/ - -#ifndef _NTERR_H -#define _NTERR_H - -/* Win32 Status codes. */ - -#define STATUS_BUFFER_OVERFLOW NT_STATUS(0x80000005) -#define STATUS_NO_MORE_FILES NT_STATUS(0x80000006) -#define STATUS_NO_MORE_EAS NT_STATUS(0x80000012) -#define STATUS_INVALID_EA_NAME NT_STATUS(0x80000013) -#define STATUS_EA_LIST_INCONSISTENT NT_STATUS(0x80000014) -#define STATUS_INVALID_EA_FLAG NT_STATUS(0x80000015) -#define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a) - -#define STATUS_PENDING NT_STATUS(0x0103) -#define STATUS_MORE_ENTRIES NT_STATUS(0x0105) -#define STATUS_SOME_UNMAPPED NT_STATUS(0x0107) -#define STATUS_NOTIFY_CLEANUP NT_STATUS(0x010b) -#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) -#define ERROR_INVALID_PARAMETER NT_STATUS(0x0057) -#define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a) -#define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) - -/* Win32 Error codes extracted using a loop in smbclient then printing a - netmon sniff to a file. */ - -/* - -------------- - / \ - / REST \ - / IN \ - / PEACE \ - / \ - | NT_STATUS_NOPROBLEMO | - | | - | | - | 4 September | - | | - | 2001 | - *| * * * | * - _________)/\\_//(\/(/\)/\//\/\///|_)_______ -*/ - -#define NT_STATUS_OK NT_STATUS(0x0000) -#define NT_STATUS_UNSUCCESSFUL NT_STATUS(0xC0000000 | 0x0001) -#define NT_STATUS_NOT_IMPLEMENTED NT_STATUS(0xC0000000 | 0x0002) -#define NT_STATUS_INVALID_INFO_CLASS NT_STATUS(0xC0000000 | 0x0003) -#define NT_STATUS_INFO_LENGTH_MISMATCH NT_STATUS(0xC0000000 | 0x0004) -#define NT_STATUS_ACCESS_VIOLATION NT_STATUS(0xC0000000 | 0x0005) -#define NT_STATUS_IN_PAGE_ERROR NT_STATUS(0xC0000000 | 0x0006) -#define NT_STATUS_PAGEFILE_QUOTA NT_STATUS(0xC0000000 | 0x0007) -#define NT_STATUS_INVALID_HANDLE NT_STATUS(0xC0000000 | 0x0008) -#define NT_STATUS_BAD_INITIAL_STACK NT_STATUS(0xC0000000 | 0x0009) -#define NT_STATUS_BAD_INITIAL_PC NT_STATUS(0xC0000000 | 0x000a) -#define NT_STATUS_INVALID_CID NT_STATUS(0xC0000000 | 0x000b) -#define NT_STATUS_TIMER_NOT_CANCELED NT_STATUS(0xC0000000 | 0x000c) -#define NT_STATUS_INVALID_PARAMETER NT_STATUS(0xC0000000 | 0x000d) -#define NT_STATUS_NO_SUCH_DEVICE NT_STATUS(0xC0000000 | 0x000e) -#define NT_STATUS_NO_SUCH_FILE NT_STATUS(0xC0000000 | 0x000f) -#define NT_STATUS_INVALID_DEVICE_REQUEST NT_STATUS(0xC0000000 | 0x0010) -#define NT_STATUS_END_OF_FILE NT_STATUS(0xC0000000 | 0x0011) -#define NT_STATUS_WRONG_VOLUME NT_STATUS(0xC0000000 | 0x0012) -#define NT_STATUS_NO_MEDIA_IN_DEVICE NT_STATUS(0xC0000000 | 0x0013) -#define NT_STATUS_UNRECOGNIZED_MEDIA NT_STATUS(0xC0000000 | 0x0014) -#define NT_STATUS_NONEXISTENT_SECTOR NT_STATUS(0xC0000000 | 0x0015) -#define NT_STATUS_MORE_PROCESSING_REQUIRED NT_STATUS(0xC0000000 | 0x0016) -#if 0 -/* this demonstrates a little trick when tracking down error codes */ -#define NT_STATUS_NO_MEMORY (printf("no memory at %s\n", __location__), NT_STATUS(0xC0000000 | 0x0017)) -#else -#define NT_STATUS_NO_MEMORY NT_STATUS(0xC0000000 | 0x0017) -#endif -#define NT_STATUS_CONFLICTING_ADDRESSES NT_STATUS(0xC0000000 | 0x0018) -#define NT_STATUS_NOT_MAPPED_VIEW NT_STATUS(0xC0000000 | 0x0019) -#define NT_STATUS_UNABLE_TO_FREE_VM NT_STATUS(0xC0000000 | 0x001a) -#define NT_STATUS_UNABLE_TO_DELETE_SECTION NT_STATUS(0xC0000000 | 0x001b) -#define NT_STATUS_INVALID_SYSTEM_SERVICE NT_STATUS(0xC0000000 | 0x001c) -#define NT_STATUS_ILLEGAL_INSTRUCTION NT_STATUS(0xC0000000 | 0x001d) -#define NT_STATUS_INVALID_LOCK_SEQUENCE NT_STATUS(0xC0000000 | 0x001e) -#define NT_STATUS_INVALID_VIEW_SIZE NT_STATUS(0xC0000000 | 0x001f) -#define NT_STATUS_INVALID_FILE_FOR_SECTION NT_STATUS(0xC0000000 | 0x0020) -#define NT_STATUS_ALREADY_COMMITTED NT_STATUS(0xC0000000 | 0x0021) -#if 0 -/* this demonstrates a little trick when tracking down error codes */ -#define NT_STATUS_ACCESS_DENIED (printf("access denied at %s\n", __location__), NT_STATUS(0xC0000000 | 0x0022)) -#else -#define NT_STATUS_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x0022) -#endif -#define NT_STATUS_BUFFER_TOO_SMALL NT_STATUS(0xC0000000 | 0x0023) -#define NT_STATUS_OBJECT_TYPE_MISMATCH NT_STATUS(0xC0000000 | 0x0024) -#define NT_STATUS_NONCONTINUABLE_EXCEPTION NT_STATUS(0xC0000000 | 0x0025) -#define NT_STATUS_INVALID_DISPOSITION NT_STATUS(0xC0000000 | 0x0026) -#define NT_STATUS_UNWIND NT_STATUS(0xC0000000 | 0x0027) -#define NT_STATUS_BAD_STACK NT_STATUS(0xC0000000 | 0x0028) -#define NT_STATUS_INVALID_UNWIND_TARGET NT_STATUS(0xC0000000 | 0x0029) -#define NT_STATUS_NOT_LOCKED NT_STATUS(0xC0000000 | 0x002a) -#define NT_STATUS_PARITY_ERROR NT_STATUS(0xC0000000 | 0x002b) -#define NT_STATUS_UNABLE_TO_DECOMMIT_VM NT_STATUS(0xC0000000 | 0x002c) -#define NT_STATUS_NOT_COMMITTED NT_STATUS(0xC0000000 | 0x002d) -#define NT_STATUS_INVALID_PORT_ATTRIBUTES NT_STATUS(0xC0000000 | 0x002e) -#define NT_STATUS_PORT_MESSAGE_TOO_LONG NT_STATUS(0xC0000000 | 0x002f) -#define NT_STATUS_INVALID_PARAMETER_MIX NT_STATUS(0xC0000000 | 0x0030) -#define NT_STATUS_INVALID_QUOTA_LOWER NT_STATUS(0xC0000000 | 0x0031) -#define NT_STATUS_DISK_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0032) -#define NT_STATUS_OBJECT_NAME_INVALID NT_STATUS(0xC0000000 | 0x0033) -#define NT_STATUS_OBJECT_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x0034) -#define NT_STATUS_OBJECT_NAME_COLLISION NT_STATUS(0xC0000000 | 0x0035) -#define NT_STATUS_HANDLE_NOT_WAITABLE NT_STATUS(0xC0000000 | 0x0036) -#define NT_STATUS_PORT_DISCONNECTED NT_STATUS(0xC0000000 | 0x0037) -#define NT_STATUS_DEVICE_ALREADY_ATTACHED NT_STATUS(0xC0000000 | 0x0038) -#define NT_STATUS_OBJECT_PATH_INVALID NT_STATUS(0xC0000000 | 0x0039) -#define NT_STATUS_OBJECT_PATH_NOT_FOUND NT_STATUS(0xC0000000 | 0x003a) -#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD NT_STATUS(0xC0000000 | 0x003b) -#define NT_STATUS_DATA_OVERRUN NT_STATUS(0xC0000000 | 0x003c) -#define NT_STATUS_DATA_LATE_ERROR NT_STATUS(0xC0000000 | 0x003d) -#define NT_STATUS_DATA_ERROR NT_STATUS(0xC0000000 | 0x003e) -#define NT_STATUS_CRC_ERROR NT_STATUS(0xC0000000 | 0x003f) -#define NT_STATUS_SECTION_TOO_BIG NT_STATUS(0xC0000000 | 0x0040) -#define NT_STATUS_PORT_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0041) -#define NT_STATUS_INVALID_PORT_HANDLE NT_STATUS(0xC0000000 | 0x0042) -#define NT_STATUS_SHARING_VIOLATION NT_STATUS(0xC0000000 | 0x0043) -#define NT_STATUS_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0044) -#define NT_STATUS_INVALID_PAGE_PROTECTION NT_STATUS(0xC0000000 | 0x0045) -#define NT_STATUS_MUTANT_NOT_OWNED NT_STATUS(0xC0000000 | 0x0046) -#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0047) -#define NT_STATUS_PORT_ALREADY_SET NT_STATUS(0xC0000000 | 0x0048) -#define NT_STATUS_SECTION_NOT_IMAGE NT_STATUS(0xC0000000 | 0x0049) -#define NT_STATUS_SUSPEND_COUNT_EXCEEDED NT_STATUS(0xC0000000 | 0x004a) -#define NT_STATUS_THREAD_IS_TERMINATING NT_STATUS(0xC0000000 | 0x004b) -#define NT_STATUS_BAD_WORKING_SET_LIMIT NT_STATUS(0xC0000000 | 0x004c) -#define NT_STATUS_INCOMPATIBLE_FILE_MAP NT_STATUS(0xC0000000 | 0x004d) -#define NT_STATUS_SECTION_PROTECTION NT_STATUS(0xC0000000 | 0x004e) -#define NT_STATUS_EAS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x004f) -#define NT_STATUS_EA_TOO_LARGE NT_STATUS(0xC0000000 | 0x0050) -#define NT_STATUS_NONEXISTENT_EA_ENTRY NT_STATUS(0xC0000000 | 0x0051) -#define NT_STATUS_NO_EAS_ON_FILE NT_STATUS(0xC0000000 | 0x0052) -#define NT_STATUS_EA_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0053) -#define NT_STATUS_FILE_LOCK_CONFLICT NT_STATUS(0xC0000000 | 0x0054) -#define NT_STATUS_LOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0055) -#define NT_STATUS_DELETE_PENDING NT_STATUS(0xC0000000 | 0x0056) -#define NT_STATUS_CTL_FILE_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x0057) -#define NT_STATUS_UNKNOWN_REVISION NT_STATUS(0xC0000000 | 0x0058) -#define NT_STATUS_REVISION_MISMATCH NT_STATUS(0xC0000000 | 0x0059) -#define NT_STATUS_INVALID_OWNER NT_STATUS(0xC0000000 | 0x005a) -#define NT_STATUS_INVALID_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x005b) -#define NT_STATUS_NO_IMPERSONATION_TOKEN NT_STATUS(0xC0000000 | 0x005c) -#define NT_STATUS_CANT_DISABLE_MANDATORY NT_STATUS(0xC0000000 | 0x005d) -#define NT_STATUS_NO_LOGON_SERVERS NT_STATUS(0xC0000000 | 0x005e) -#define NT_STATUS_NO_SUCH_LOGON_SESSION NT_STATUS(0xC0000000 | 0x005f) -#define NT_STATUS_NO_SUCH_PRIVILEGE NT_STATUS(0xC0000000 | 0x0060) -#define NT_STATUS_PRIVILEGE_NOT_HELD NT_STATUS(0xC0000000 | 0x0061) -#define NT_STATUS_INVALID_ACCOUNT_NAME NT_STATUS(0xC0000000 | 0x0062) -#define NT_STATUS_USER_EXISTS NT_STATUS(0xC0000000 | 0x0063) -#define NT_STATUS_NO_SUCH_USER NT_STATUS(0xC0000000 | 0x0064) -#define NT_STATUS_GROUP_EXISTS NT_STATUS(0xC0000000 | 0x0065) -#define NT_STATUS_NO_SUCH_GROUP NT_STATUS(0xC0000000 | 0x0066) -#define NT_STATUS_MEMBER_IN_GROUP NT_STATUS(0xC0000000 | 0x0067) -#define NT_STATUS_MEMBER_NOT_IN_GROUP NT_STATUS(0xC0000000 | 0x0068) -#define NT_STATUS_LAST_ADMIN NT_STATUS(0xC0000000 | 0x0069) -#define NT_STATUS_WRONG_PASSWORD NT_STATUS(0xC0000000 | 0x006a) -#define NT_STATUS_ILL_FORMED_PASSWORD NT_STATUS(0xC0000000 | 0x006b) -#define NT_STATUS_PASSWORD_RESTRICTION NT_STATUS(0xC0000000 | 0x006c) -#define NT_STATUS_LOGON_FAILURE NT_STATUS(0xC0000000 | 0x006d) -#define NT_STATUS_ACCOUNT_RESTRICTION NT_STATUS(0xC0000000 | 0x006e) -#define NT_STATUS_INVALID_LOGON_HOURS NT_STATUS(0xC0000000 | 0x006f) -#define NT_STATUS_INVALID_WORKSTATION NT_STATUS(0xC0000000 | 0x0070) -#define NT_STATUS_PASSWORD_EXPIRED NT_STATUS(0xC0000000 | 0x0071) -#define NT_STATUS_ACCOUNT_DISABLED NT_STATUS(0xC0000000 | 0x0072) -#define NT_STATUS_NONE_MAPPED NT_STATUS(0xC0000000 | 0x0073) -#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0074) -#define NT_STATUS_LUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0075) -#define NT_STATUS_INVALID_SUB_AUTHORITY NT_STATUS(0xC0000000 | 0x0076) -#define NT_STATUS_INVALID_ACL NT_STATUS(0xC0000000 | 0x0077) -#define NT_STATUS_INVALID_SID NT_STATUS(0xC0000000 | 0x0078) -#define NT_STATUS_INVALID_SECURITY_DESCR NT_STATUS(0xC0000000 | 0x0079) -#define NT_STATUS_PROCEDURE_NOT_FOUND NT_STATUS(0xC0000000 | 0x007a) -#define NT_STATUS_INVALID_IMAGE_FORMAT NT_STATUS(0xC0000000 | 0x007b) -#define NT_STATUS_NO_TOKEN NT_STATUS(0xC0000000 | 0x007c) -#define NT_STATUS_BAD_INHERITANCE_ACL NT_STATUS(0xC0000000 | 0x007d) -#define NT_STATUS_RANGE_NOT_LOCKED NT_STATUS(0xC0000000 | 0x007e) -#define NT_STATUS_DISK_FULL NT_STATUS(0xC0000000 | 0x007f) -#define NT_STATUS_SERVER_DISABLED NT_STATUS(0xC0000000 | 0x0080) -#define NT_STATUS_SERVER_NOT_DISABLED NT_STATUS(0xC0000000 | 0x0081) -#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0082) -#define NT_STATUS_GUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0083) -#define NT_STATUS_INVALID_ID_AUTHORITY NT_STATUS(0xC0000000 | 0x0084) -#define NT_STATUS_AGENTS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0085) -#define NT_STATUS_INVALID_VOLUME_LABEL NT_STATUS(0xC0000000 | 0x0086) -#define NT_STATUS_SECTION_NOT_EXTENDED NT_STATUS(0xC0000000 | 0x0087) -#define NT_STATUS_NOT_MAPPED_DATA NT_STATUS(0xC0000000 | 0x0088) -#define NT_STATUS_RESOURCE_DATA_NOT_FOUND NT_STATUS(0xC0000000 | 0x0089) -#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND NT_STATUS(0xC0000000 | 0x008a) -#define NT_STATUS_RESOURCE_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x008b) -#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED NT_STATUS(0xC0000000 | 0x008c) -#define NT_STATUS_FLOAT_DENORMAL_OPERAND NT_STATUS(0xC0000000 | 0x008d) -#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x008e) -#define NT_STATUS_FLOAT_INEXACT_RESULT NT_STATUS(0xC0000000 | 0x008f) -#define NT_STATUS_FLOAT_INVALID_OPERATION NT_STATUS(0xC0000000 | 0x0090) -#define NT_STATUS_FLOAT_OVERFLOW NT_STATUS(0xC0000000 | 0x0091) -#define NT_STATUS_FLOAT_STACK_CHECK NT_STATUS(0xC0000000 | 0x0092) -#define NT_STATUS_FLOAT_UNDERFLOW NT_STATUS(0xC0000000 | 0x0093) -#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x0094) -#define NT_STATUS_INTEGER_OVERFLOW NT_STATUS(0xC0000000 | 0x0095) -#define NT_STATUS_PRIVILEGED_INSTRUCTION NT_STATUS(0xC0000000 | 0x0096) -#define NT_STATUS_TOO_MANY_PAGING_FILES NT_STATUS(0xC0000000 | 0x0097) -#define NT_STATUS_FILE_INVALID NT_STATUS(0xC0000000 | 0x0098) -#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED NT_STATUS(0xC0000000 | 0x0099) -#define NT_STATUS_INSUFFICIENT_RESOURCES NT_STATUS(0xC0000000 | 0x009a) -#define NT_STATUS_DFS_EXIT_PATH_FOUND NT_STATUS(0xC0000000 | 0x009b) -#define NT_STATUS_DEVICE_DATA_ERROR NT_STATUS(0xC0000000 | 0x009c) -#define NT_STATUS_DEVICE_NOT_CONNECTED NT_STATUS(0xC0000000 | 0x009d) -#define NT_STATUS_DEVICE_POWER_FAILURE NT_STATUS(0xC0000000 | 0x009e) -#define NT_STATUS_FREE_VM_NOT_AT_BASE NT_STATUS(0xC0000000 | 0x009f) -#define NT_STATUS_MEMORY_NOT_ALLOCATED NT_STATUS(0xC0000000 | 0x00a0) -#define NT_STATUS_WORKING_SET_QUOTA NT_STATUS(0xC0000000 | 0x00a1) -#define NT_STATUS_MEDIA_WRITE_PROTECTED NT_STATUS(0xC0000000 | 0x00a2) -#define NT_STATUS_DEVICE_NOT_READY NT_STATUS(0xC0000000 | 0x00a3) -#define NT_STATUS_INVALID_GROUP_ATTRIBUTES NT_STATUS(0xC0000000 | 0x00a4) -#define NT_STATUS_BAD_IMPERSONATION_LEVEL NT_STATUS(0xC0000000 | 0x00a5) -#define NT_STATUS_CANT_OPEN_ANONYMOUS NT_STATUS(0xC0000000 | 0x00a6) -#define NT_STATUS_BAD_VALIDATION_CLASS NT_STATUS(0xC0000000 | 0x00a7) -#define NT_STATUS_BAD_TOKEN_TYPE NT_STATUS(0xC0000000 | 0x00a8) -#define NT_STATUS_BAD_MASTER_BOOT_RECORD NT_STATUS(0xC0000000 | 0x00a9) -#define NT_STATUS_INSTRUCTION_MISALIGNMENT NT_STATUS(0xC0000000 | 0x00aa) -#define NT_STATUS_INSTANCE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ab) -#define NT_STATUS_PIPE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ac) -#define NT_STATUS_INVALID_PIPE_STATE NT_STATUS(0xC0000000 | 0x00ad) -#define NT_STATUS_PIPE_BUSY NT_STATUS(0xC0000000 | 0x00ae) -#define NT_STATUS_ILLEGAL_FUNCTION NT_STATUS(0xC0000000 | 0x00af) -#define NT_STATUS_PIPE_DISCONNECTED NT_STATUS(0xC0000000 | 0x00b0) -#define NT_STATUS_PIPE_CLOSING NT_STATUS(0xC0000000 | 0x00b1) -#define NT_STATUS_PIPE_CONNECTED NT_STATUS(0xC0000000 | 0x00b2) -#define NT_STATUS_PIPE_LISTENING NT_STATUS(0xC0000000 | 0x00b3) -#define NT_STATUS_INVALID_READ_MODE NT_STATUS(0xC0000000 | 0x00b4) -#define NT_STATUS_IO_TIMEOUT NT_STATUS(0xC0000000 | 0x00b5) -#define NT_STATUS_FILE_FORCED_CLOSED NT_STATUS(0xC0000000 | 0x00b6) -#define NT_STATUS_PROFILING_NOT_STARTED NT_STATUS(0xC0000000 | 0x00b7) -#define NT_STATUS_PROFILING_NOT_STOPPED NT_STATUS(0xC0000000 | 0x00b8) -#define NT_STATUS_COULD_NOT_INTERPRET NT_STATUS(0xC0000000 | 0x00b9) -#define NT_STATUS_FILE_IS_A_DIRECTORY NT_STATUS(0xC0000000 | 0x00ba) -#define NT_STATUS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x00bb) -#define NT_STATUS_REMOTE_NOT_LISTENING NT_STATUS(0xC0000000 | 0x00bc) -#define NT_STATUS_DUPLICATE_NAME NT_STATUS(0xC0000000 | 0x00bd) -#define NT_STATUS_BAD_NETWORK_PATH NT_STATUS(0xC0000000 | 0x00be) -#define NT_STATUS_NETWORK_BUSY NT_STATUS(0xC0000000 | 0x00bf) -#define NT_STATUS_DEVICE_DOES_NOT_EXIST NT_STATUS(0xC0000000 | 0x00c0) -#define NT_STATUS_TOO_MANY_COMMANDS NT_STATUS(0xC0000000 | 0x00c1) -#define NT_STATUS_ADAPTER_HARDWARE_ERROR NT_STATUS(0xC0000000 | 0x00c2) -#define NT_STATUS_INVALID_NETWORK_RESPONSE NT_STATUS(0xC0000000 | 0x00c3) -#define NT_STATUS_UNEXPECTED_NETWORK_ERROR NT_STATUS(0xC0000000 | 0x00c4) -#define NT_STATUS_BAD_REMOTE_ADAPTER NT_STATUS(0xC0000000 | 0x00c5) -#define NT_STATUS_PRINT_QUEUE_FULL NT_STATUS(0xC0000000 | 0x00c6) -#define NT_STATUS_NO_SPOOL_SPACE NT_STATUS(0xC0000000 | 0x00c7) -#define NT_STATUS_PRINT_CANCELLED NT_STATUS(0xC0000000 | 0x00c8) -#define NT_STATUS_NETWORK_NAME_DELETED NT_STATUS(0xC0000000 | 0x00c9) -#define NT_STATUS_NETWORK_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x00ca) -#define NT_STATUS_BAD_DEVICE_TYPE NT_STATUS(0xC0000000 | 0x00cb) -#define NT_STATUS_BAD_NETWORK_NAME NT_STATUS(0xC0000000 | 0x00cc) -#define NT_STATUS_TOO_MANY_NAMES NT_STATUS(0xC0000000 | 0x00cd) -#define NT_STATUS_TOO_MANY_SESSIONS NT_STATUS(0xC0000000 | 0x00ce) -#define NT_STATUS_SHARING_PAUSED NT_STATUS(0xC0000000 | 0x00cf) -#define NT_STATUS_REQUEST_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x00d0) -#define NT_STATUS_REDIRECTOR_PAUSED NT_STATUS(0xC0000000 | 0x00d1) -#define NT_STATUS_NET_WRITE_FAULT NT_STATUS(0xC0000000 | 0x00d2) -#define NT_STATUS_PROFILING_AT_LIMIT NT_STATUS(0xC0000000 | 0x00d3) -#define NT_STATUS_NOT_SAME_DEVICE NT_STATUS(0xC0000000 | 0x00d4) -#define NT_STATUS_FILE_RENAMED NT_STATUS(0xC0000000 | 0x00d5) -#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED NT_STATUS(0xC0000000 | 0x00d6) -#define NT_STATUS_NO_SECURITY_ON_OBJECT NT_STATUS(0xC0000000 | 0x00d7) -#define NT_STATUS_CANT_WAIT NT_STATUS(0xC0000000 | 0x00d8) -#define NT_STATUS_PIPE_EMPTY NT_STATUS(0xC0000000 | 0x00d9) -#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO NT_STATUS(0xC0000000 | 0x00da) -#define NT_STATUS_CANT_TERMINATE_SELF NT_STATUS(0xC0000000 | 0x00db) -#define NT_STATUS_INVALID_SERVER_STATE NT_STATUS(0xC0000000 | 0x00dc) -#define NT_STATUS_INVALID_DOMAIN_STATE NT_STATUS(0xC0000000 | 0x00dd) -#define NT_STATUS_INVALID_DOMAIN_ROLE NT_STATUS(0xC0000000 | 0x00de) -#define NT_STATUS_NO_SUCH_DOMAIN NT_STATUS(0xC0000000 | 0x00df) -#define NT_STATUS_DOMAIN_EXISTS NT_STATUS(0xC0000000 | 0x00e0) -#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x00e1) -#define NT_STATUS_OPLOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x00e2) -#define NT_STATUS_INVALID_OPLOCK_PROTOCOL NT_STATUS(0xC0000000 | 0x00e3) -#define NT_STATUS_INTERNAL_DB_CORRUPTION NT_STATUS(0xC0000000 | 0x00e4) -#define NT_STATUS_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x00e5) -#define NT_STATUS_GENERIC_NOT_MAPPED NT_STATUS(0xC0000000 | 0x00e6) -#define NT_STATUS_BAD_DESCRIPTOR_FORMAT NT_STATUS(0xC0000000 | 0x00e7) -#define NT_STATUS_INVALID_USER_BUFFER NT_STATUS(0xC0000000 | 0x00e8) -#define NT_STATUS_UNEXPECTED_IO_ERROR NT_STATUS(0xC0000000 | 0x00e9) -#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR NT_STATUS(0xC0000000 | 0x00ea) -#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR NT_STATUS(0xC0000000 | 0x00eb) -#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR NT_STATUS(0xC0000000 | 0x00ec) -#define NT_STATUS_NOT_LOGON_PROCESS NT_STATUS(0xC0000000 | 0x00ed) -#define NT_STATUS_LOGON_SESSION_EXISTS NT_STATUS(0xC0000000 | 0x00ee) -#define NT_STATUS_INVALID_PARAMETER_1 NT_STATUS(0xC0000000 | 0x00ef) -#define NT_STATUS_INVALID_PARAMETER_2 NT_STATUS(0xC0000000 | 0x00f0) -#define NT_STATUS_INVALID_PARAMETER_3 NT_STATUS(0xC0000000 | 0x00f1) -#define NT_STATUS_INVALID_PARAMETER_4 NT_STATUS(0xC0000000 | 0x00f2) -#define NT_STATUS_INVALID_PARAMETER_5 NT_STATUS(0xC0000000 | 0x00f3) -#define NT_STATUS_INVALID_PARAMETER_6 NT_STATUS(0xC0000000 | 0x00f4) -#define NT_STATUS_INVALID_PARAMETER_7 NT_STATUS(0xC0000000 | 0x00f5) -#define NT_STATUS_INVALID_PARAMETER_8 NT_STATUS(0xC0000000 | 0x00f6) -#define NT_STATUS_INVALID_PARAMETER_9 NT_STATUS(0xC0000000 | 0x00f7) -#define NT_STATUS_INVALID_PARAMETER_10 NT_STATUS(0xC0000000 | 0x00f8) -#define NT_STATUS_INVALID_PARAMETER_11 NT_STATUS(0xC0000000 | 0x00f9) -#define NT_STATUS_INVALID_PARAMETER_12 NT_STATUS(0xC0000000 | 0x00fa) -#define NT_STATUS_REDIRECTOR_NOT_STARTED NT_STATUS(0xC0000000 | 0x00fb) -#define NT_STATUS_REDIRECTOR_STARTED NT_STATUS(0xC0000000 | 0x00fc) -#define NT_STATUS_STACK_OVERFLOW NT_STATUS(0xC0000000 | 0x00fd) -#define NT_STATUS_NO_SUCH_PACKAGE NT_STATUS(0xC0000000 | 0x00fe) -#define NT_STATUS_BAD_FUNCTION_TABLE NT_STATUS(0xC0000000 | 0x00ff) -#define NT_STATUS_DIRECTORY_NOT_EMPTY NT_STATUS(0xC0000000 | 0x0101) -#define NT_STATUS_FILE_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0102) -#define NT_STATUS_NOT_A_DIRECTORY NT_STATUS(0xC0000000 | 0x0103) -#define NT_STATUS_BAD_LOGON_SESSION_STATE NT_STATUS(0xC0000000 | 0x0104) -#define NT_STATUS_LOGON_SESSION_COLLISION NT_STATUS(0xC0000000 | 0x0105) -#define NT_STATUS_NAME_TOO_LONG NT_STATUS(0xC0000000 | 0x0106) -#define NT_STATUS_FILES_OPEN NT_STATUS(0xC0000000 | 0x0107) -#define NT_STATUS_CONNECTION_IN_USE NT_STATUS(0xC0000000 | 0x0108) -#define NT_STATUS_MESSAGE_NOT_FOUND NT_STATUS(0xC0000000 | 0x0109) -#define NT_STATUS_PROCESS_IS_TERMINATING NT_STATUS(0xC0000000 | 0x010a) -#define NT_STATUS_INVALID_LOGON_TYPE NT_STATUS(0xC0000000 | 0x010b) -#define NT_STATUS_NO_GUID_TRANSLATION NT_STATUS(0xC0000000 | 0x010c) -#define NT_STATUS_CANNOT_IMPERSONATE NT_STATUS(0xC0000000 | 0x010d) -#define NT_STATUS_IMAGE_ALREADY_LOADED NT_STATUS(0xC0000000 | 0x010e) -#define NT_STATUS_ABIOS_NOT_PRESENT NT_STATUS(0xC0000000 | 0x010f) -#define NT_STATUS_ABIOS_LID_NOT_EXIST NT_STATUS(0xC0000000 | 0x0110) -#define NT_STATUS_ABIOS_LID_ALREADY_OWNED NT_STATUS(0xC0000000 | 0x0111) -#define NT_STATUS_ABIOS_NOT_LID_OWNER NT_STATUS(0xC0000000 | 0x0112) -#define NT_STATUS_ABIOS_INVALID_COMMAND NT_STATUS(0xC0000000 | 0x0113) -#define NT_STATUS_ABIOS_INVALID_LID NT_STATUS(0xC0000000 | 0x0114) -#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x0115) -#define NT_STATUS_ABIOS_INVALID_SELECTOR NT_STATUS(0xC0000000 | 0x0116) -#define NT_STATUS_NO_LDT NT_STATUS(0xC0000000 | 0x0117) -#define NT_STATUS_INVALID_LDT_SIZE NT_STATUS(0xC0000000 | 0x0118) -#define NT_STATUS_INVALID_LDT_OFFSET NT_STATUS(0xC0000000 | 0x0119) -#define NT_STATUS_INVALID_LDT_DESCRIPTOR NT_STATUS(0xC0000000 | 0x011a) -#define NT_STATUS_INVALID_IMAGE_NE_FORMAT NT_STATUS(0xC0000000 | 0x011b) -#define NT_STATUS_RXACT_INVALID_STATE NT_STATUS(0xC0000000 | 0x011c) -#define NT_STATUS_RXACT_COMMIT_FAILURE NT_STATUS(0xC0000000 | 0x011d) -#define NT_STATUS_MAPPED_FILE_SIZE_ZERO NT_STATUS(0xC0000000 | 0x011e) -#define NT_STATUS_TOO_MANY_OPENED_FILES NT_STATUS(0xC0000000 | 0x011f) -#define NT_STATUS_CANCELLED NT_STATUS(0xC0000000 | 0x0120) -#define NT_STATUS_CANNOT_DELETE NT_STATUS(0xC0000000 | 0x0121) -#define NT_STATUS_INVALID_COMPUTER_NAME NT_STATUS(0xC0000000 | 0x0122) -#define NT_STATUS_FILE_DELETED NT_STATUS(0xC0000000 | 0x0123) -#define NT_STATUS_SPECIAL_ACCOUNT NT_STATUS(0xC0000000 | 0x0124) -#define NT_STATUS_SPECIAL_GROUP NT_STATUS(0xC0000000 | 0x0125) -#define NT_STATUS_SPECIAL_USER NT_STATUS(0xC0000000 | 0x0126) -#define NT_STATUS_MEMBERS_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x0127) -#define NT_STATUS_FILE_CLOSED NT_STATUS(0xC0000000 | 0x0128) -#define NT_STATUS_TOO_MANY_THREADS NT_STATUS(0xC0000000 | 0x0129) -#define NT_STATUS_THREAD_NOT_IN_PROCESS NT_STATUS(0xC0000000 | 0x012a) -#define NT_STATUS_TOKEN_ALREADY_IN_USE NT_STATUS(0xC0000000 | 0x012b) -#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x012c) -#define NT_STATUS_COMMITMENT_LIMIT NT_STATUS(0xC0000000 | 0x012d) -#define NT_STATUS_INVALID_IMAGE_LE_FORMAT NT_STATUS(0xC0000000 | 0x012e) -#define NT_STATUS_INVALID_IMAGE_NOT_MZ NT_STATUS(0xC0000000 | 0x012f) -#define NT_STATUS_INVALID_IMAGE_PROTECT NT_STATUS(0xC0000000 | 0x0130) -#define NT_STATUS_INVALID_IMAGE_WIN_16 NT_STATUS(0xC0000000 | 0x0131) -#define NT_STATUS_LOGON_SERVER_CONFLICT NT_STATUS(0xC0000000 | 0x0132) -#define NT_STATUS_TIME_DIFFERENCE_AT_DC NT_STATUS(0xC0000000 | 0x0133) -#define NT_STATUS_SYNCHRONIZATION_REQUIRED NT_STATUS(0xC0000000 | 0x0134) -#define NT_STATUS_DLL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0135) -#define NT_STATUS_OPEN_FAILED NT_STATUS(0xC0000000 | 0x0136) -#define NT_STATUS_IO_PRIVILEGE_FAILED NT_STATUS(0xC0000000 | 0x0137) -#define NT_STATUS_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0138) -#define NT_STATUS_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0139) -#define NT_STATUS_CONTROL_C_EXIT NT_STATUS(0xC0000000 | 0x013a) -#define NT_STATUS_LOCAL_DISCONNECT NT_STATUS(0xC0000000 | 0x013b) -#define NT_STATUS_REMOTE_DISCONNECT NT_STATUS(0xC0000000 | 0x013c) -#define NT_STATUS_REMOTE_RESOURCES NT_STATUS(0xC0000000 | 0x013d) -#define NT_STATUS_LINK_FAILED NT_STATUS(0xC0000000 | 0x013e) -#define NT_STATUS_LINK_TIMEOUT NT_STATUS(0xC0000000 | 0x013f) -#define NT_STATUS_INVALID_CONNECTION NT_STATUS(0xC0000000 | 0x0140) -#define NT_STATUS_INVALID_ADDRESS NT_STATUS(0xC0000000 | 0x0141) -#define NT_STATUS_DLL_INIT_FAILED NT_STATUS(0xC0000000 | 0x0142) -#define NT_STATUS_MISSING_SYSTEMFILE NT_STATUS(0xC0000000 | 0x0143) -#define NT_STATUS_UNHANDLED_EXCEPTION NT_STATUS(0xC0000000 | 0x0144) -#define NT_STATUS_APP_INIT_FAILURE NT_STATUS(0xC0000000 | 0x0145) -#define NT_STATUS_PAGEFILE_CREATE_FAILED NT_STATUS(0xC0000000 | 0x0146) -#define NT_STATUS_NO_PAGEFILE NT_STATUS(0xC0000000 | 0x0147) -#define NT_STATUS_INVALID_LEVEL NT_STATUS(0xC0000000 | 0x0148) -#define NT_STATUS_WRONG_PASSWORD_CORE NT_STATUS(0xC0000000 | 0x0149) -#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT NT_STATUS(0xC0000000 | 0x014a) -#define NT_STATUS_PIPE_BROKEN NT_STATUS(0xC0000000 | 0x014b) -#define NT_STATUS_REGISTRY_CORRUPT NT_STATUS(0xC0000000 | 0x014c) -#define NT_STATUS_REGISTRY_IO_FAILED NT_STATUS(0xC0000000 | 0x014d) -#define NT_STATUS_NO_EVENT_PAIR NT_STATUS(0xC0000000 | 0x014e) -#define NT_STATUS_UNRECOGNIZED_VOLUME NT_STATUS(0xC0000000 | 0x014f) -#define NT_STATUS_SERIAL_NO_DEVICE_INITED NT_STATUS(0xC0000000 | 0x0150) -#define NT_STATUS_NO_SUCH_ALIAS NT_STATUS(0xC0000000 | 0x0151) -#define NT_STATUS_MEMBER_NOT_IN_ALIAS NT_STATUS(0xC0000000 | 0x0152) -#define NT_STATUS_MEMBER_IN_ALIAS NT_STATUS(0xC0000000 | 0x0153) -#define NT_STATUS_ALIAS_EXISTS NT_STATUS(0xC0000000 | 0x0154) -#define NT_STATUS_LOGON_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0155) -#define NT_STATUS_TOO_MANY_SECRETS NT_STATUS(0xC0000000 | 0x0156) -#define NT_STATUS_SECRET_TOO_LONG NT_STATUS(0xC0000000 | 0x0157) -#define NT_STATUS_INTERNAL_DB_ERROR NT_STATUS(0xC0000000 | 0x0158) -#define NT_STATUS_FULLSCREEN_MODE NT_STATUS(0xC0000000 | 0x0159) -#define NT_STATUS_TOO_MANY_CONTEXT_IDS NT_STATUS(0xC0000000 | 0x015a) -#define NT_STATUS_LOGON_TYPE_NOT_GRANTED NT_STATUS(0xC0000000 | 0x015b) -#define NT_STATUS_NOT_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x015c) -#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x015d) -#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR NT_STATUS(0xC0000000 | 0x015e) -#define NT_STATUS_FT_MISSING_MEMBER NT_STATUS(0xC0000000 | 0x015f) -#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY NT_STATUS(0xC0000000 | 0x0160) -#define NT_STATUS_ILLEGAL_CHARACTER NT_STATUS(0xC0000000 | 0x0161) -#define NT_STATUS_UNMAPPABLE_CHARACTER NT_STATUS(0xC0000000 | 0x0162) -#define NT_STATUS_UNDEFINED_CHARACTER NT_STATUS(0xC0000000 | 0x0163) -#define NT_STATUS_FLOPPY_VOLUME NT_STATUS(0xC0000000 | 0x0164) -#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND NT_STATUS(0xC0000000 | 0x0165) -#define NT_STATUS_FLOPPY_WRONG_CYLINDER NT_STATUS(0xC0000000 | 0x0166) -#define NT_STATUS_FLOPPY_UNKNOWN_ERROR NT_STATUS(0xC0000000 | 0x0167) -#define NT_STATUS_FLOPPY_BAD_REGISTERS NT_STATUS(0xC0000000 | 0x0168) -#define NT_STATUS_DISK_RECALIBRATE_FAILED NT_STATUS(0xC0000000 | 0x0169) -#define NT_STATUS_DISK_OPERATION_FAILED NT_STATUS(0xC0000000 | 0x016a) -#define NT_STATUS_DISK_RESET_FAILED NT_STATUS(0xC0000000 | 0x016b) -#define NT_STATUS_SHARED_IRQ_BUSY NT_STATUS(0xC0000000 | 0x016c) -#define NT_STATUS_FT_ORPHANING NT_STATUS(0xC0000000 | 0x016d) -#define NT_STATUS_PARTITION_FAILURE NT_STATUS(0xC0000000 | 0x0172) -#define NT_STATUS_INVALID_BLOCK_LENGTH NT_STATUS(0xC0000000 | 0x0173) -#define NT_STATUS_DEVICE_NOT_PARTITIONED NT_STATUS(0xC0000000 | 0x0174) -#define NT_STATUS_UNABLE_TO_LOCK_MEDIA NT_STATUS(0xC0000000 | 0x0175) -#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA NT_STATUS(0xC0000000 | 0x0176) -#define NT_STATUS_EOM_OVERFLOW NT_STATUS(0xC0000000 | 0x0177) -#define NT_STATUS_NO_MEDIA NT_STATUS(0xC0000000 | 0x0178) -#define NT_STATUS_NO_SUCH_MEMBER NT_STATUS(0xC0000000 | 0x017a) -#define NT_STATUS_INVALID_MEMBER NT_STATUS(0xC0000000 | 0x017b) -#define NT_STATUS_KEY_DELETED NT_STATUS(0xC0000000 | 0x017c) -#define NT_STATUS_NO_LOG_SPACE NT_STATUS(0xC0000000 | 0x017d) -#define NT_STATUS_TOO_MANY_SIDS NT_STATUS(0xC0000000 | 0x017e) -#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x017f) -#define NT_STATUS_KEY_HAS_CHILDREN NT_STATUS(0xC0000000 | 0x0180) -#define NT_STATUS_CHILD_MUST_BE_VOLATILE NT_STATUS(0xC0000000 | 0x0181) -#define NT_STATUS_DEVICE_CONFIGURATION_ERROR NT_STATUS(0xC0000000 | 0x0182) -#define NT_STATUS_DRIVER_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x0183) -#define NT_STATUS_INVALID_DEVICE_STATE NT_STATUS(0xC0000000 | 0x0184) -#define NT_STATUS_IO_DEVICE_ERROR NT_STATUS(0xC0000000 | 0x0185) -#define NT_STATUS_DEVICE_PROTOCOL_ERROR NT_STATUS(0xC0000000 | 0x0186) -#define NT_STATUS_BACKUP_CONTROLLER NT_STATUS(0xC0000000 | 0x0187) -#define NT_STATUS_LOG_FILE_FULL NT_STATUS(0xC0000000 | 0x0188) -#define NT_STATUS_TOO_LATE NT_STATUS(0xC0000000 | 0x0189) -#define NT_STATUS_NO_TRUST_LSA_SECRET NT_STATUS(0xC0000000 | 0x018a) -#define NT_STATUS_NO_TRUST_SAM_ACCOUNT NT_STATUS(0xC0000000 | 0x018b) -#define NT_STATUS_TRUSTED_DOMAIN_FAILURE NT_STATUS(0xC0000000 | 0x018c) -#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE NT_STATUS(0xC0000000 | 0x018d) -#define NT_STATUS_EVENTLOG_FILE_CORRUPT NT_STATUS(0xC0000000 | 0x018e) -#define NT_STATUS_EVENTLOG_CANT_START NT_STATUS(0xC0000000 | 0x018f) -#define NT_STATUS_TRUST_FAILURE NT_STATUS(0xC0000000 | 0x0190) -#define NT_STATUS_MUTANT_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0191) -#define NT_STATUS_NETLOGON_NOT_STARTED NT_STATUS(0xC0000000 | 0x0192) -#define NT_STATUS_ACCOUNT_EXPIRED NT_STATUS(0xC0000000 | 0x0193) -#define NT_STATUS_POSSIBLE_DEADLOCK NT_STATUS(0xC0000000 | 0x0194) -#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT NT_STATUS(0xC0000000 | 0x0195) -#define NT_STATUS_REMOTE_SESSION_LIMIT NT_STATUS(0xC0000000 | 0x0196) -#define NT_STATUS_EVENTLOG_FILE_CHANGED NT_STATUS(0xC0000000 | 0x0197) -#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0198) -#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0199) -#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x019a) -#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT NT_STATUS(0xC0000000 | 0x019b) -#define NT_STATUS_FS_DRIVER_REQUIRED NT_STATUS(0xC0000000 | 0x019c) -#define NT_STATUS_NO_USER_SESSION_KEY NT_STATUS(0xC0000000 | 0x0202) -#define NT_STATUS_USER_SESSION_DELETED NT_STATUS(0xC0000000 | 0x0203) -#define NT_STATUS_RESOURCE_LANG_NOT_FOUND NT_STATUS(0xC0000000 | 0x0204) -#define NT_STATUS_INSUFF_SERVER_RESOURCES NT_STATUS(0xC0000000 | 0x0205) -#define NT_STATUS_INVALID_BUFFER_SIZE NT_STATUS(0xC0000000 | 0x0206) -#define NT_STATUS_INVALID_ADDRESS_COMPONENT NT_STATUS(0xC0000000 | 0x0207) -#define NT_STATUS_INVALID_ADDRESS_WILDCARD NT_STATUS(0xC0000000 | 0x0208) -#define NT_STATUS_TOO_MANY_ADDRESSES NT_STATUS(0xC0000000 | 0x0209) -#define NT_STATUS_ADDRESS_ALREADY_EXISTS NT_STATUS(0xC0000000 | 0x020a) -#define NT_STATUS_ADDRESS_CLOSED NT_STATUS(0xC0000000 | 0x020b) -#define NT_STATUS_CONNECTION_DISCONNECTED NT_STATUS(0xC0000000 | 0x020c) -#define NT_STATUS_CONNECTION_RESET NT_STATUS(0xC0000000 | 0x020d) -#define NT_STATUS_TOO_MANY_NODES NT_STATUS(0xC0000000 | 0x020e) -#define NT_STATUS_TRANSACTION_ABORTED NT_STATUS(0xC0000000 | 0x020f) -#define NT_STATUS_TRANSACTION_TIMED_OUT NT_STATUS(0xC0000000 | 0x0210) -#define NT_STATUS_TRANSACTION_NO_RELEASE NT_STATUS(0xC0000000 | 0x0211) -#define NT_STATUS_TRANSACTION_NO_MATCH NT_STATUS(0xC0000000 | 0x0212) -#define NT_STATUS_TRANSACTION_RESPONDED NT_STATUS(0xC0000000 | 0x0213) -#define NT_STATUS_TRANSACTION_INVALID_ID NT_STATUS(0xC0000000 | 0x0214) -#define NT_STATUS_TRANSACTION_INVALID_TYPE NT_STATUS(0xC0000000 | 0x0215) -#define NT_STATUS_NOT_SERVER_SESSION NT_STATUS(0xC0000000 | 0x0216) -#define NT_STATUS_NOT_CLIENT_SESSION NT_STATUS(0xC0000000 | 0x0217) -#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x0218) -#define NT_STATUS_DEBUG_ATTACH_FAILED NT_STATUS(0xC0000000 | 0x0219) -#define NT_STATUS_SYSTEM_PROCESS_TERMINATED NT_STATUS(0xC0000000 | 0x021a) -#define NT_STATUS_DATA_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x021b) -#define NT_STATUS_NO_BROWSER_SERVERS_FOUND NT_STATUS(0xC0000000 | 0x021c) -#define NT_STATUS_VDM_HARD_ERROR NT_STATUS(0xC0000000 | 0x021d) -#define NT_STATUS_DRIVER_CANCEL_TIMEOUT NT_STATUS(0xC0000000 | 0x021e) -#define NT_STATUS_REPLY_MESSAGE_MISMATCH NT_STATUS(0xC0000000 | 0x021f) -#define NT_STATUS_MAPPED_ALIGNMENT NT_STATUS(0xC0000000 | 0x0220) -#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH NT_STATUS(0xC0000000 | 0x0221) -#define NT_STATUS_LOST_WRITEBEHIND_DATA NT_STATUS(0xC0000000 | 0x0222) -#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID NT_STATUS(0xC0000000 | 0x0223) -#define NT_STATUS_PASSWORD_MUST_CHANGE NT_STATUS(0xC0000000 | 0x0224) -#define NT_STATUS_NOT_FOUND NT_STATUS(0xC0000000 | 0x0225) -#define NT_STATUS_NOT_TINY_STREAM NT_STATUS(0xC0000000 | 0x0226) -#define NT_STATUS_RECOVERY_FAILURE NT_STATUS(0xC0000000 | 0x0227) -#define NT_STATUS_STACK_OVERFLOW_READ NT_STATUS(0xC0000000 | 0x0228) -#define NT_STATUS_FAIL_CHECK NT_STATUS(0xC0000000 | 0x0229) -#define NT_STATUS_DUPLICATE_OBJECTID NT_STATUS(0xC0000000 | 0x022a) -#define NT_STATUS_OBJECTID_EXISTS NT_STATUS(0xC0000000 | 0x022b) -#define NT_STATUS_CONVERT_TO_LARGE NT_STATUS(0xC0000000 | 0x022c) -#define NT_STATUS_RETRY NT_STATUS(0xC0000000 | 0x022d) -#define NT_STATUS_FOUND_OUT_OF_SCOPE NT_STATUS(0xC0000000 | 0x022e) -#define NT_STATUS_ALLOCATE_BUCKET NT_STATUS(0xC0000000 | 0x022f) -#define NT_STATUS_PROPSET_NOT_FOUND NT_STATUS(0xC0000000 | 0x0230) -#define NT_STATUS_MARSHALL_OVERFLOW NT_STATUS(0xC0000000 | 0x0231) -#define NT_STATUS_INVALID_VARIANT NT_STATUS(0xC0000000 | 0x0232) -#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND NT_STATUS(0xC0000000 | 0x0233) -#define NT_STATUS_ACCOUNT_LOCKED_OUT NT_STATUS(0xC0000000 | 0x0234) -#define NT_STATUS_HANDLE_NOT_CLOSABLE NT_STATUS(0xC0000000 | 0x0235) -#define NT_STATUS_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0236) -#define NT_STATUS_GRACEFUL_DISCONNECT NT_STATUS(0xC0000000 | 0x0237) -#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED NT_STATUS(0xC0000000 | 0x0238) -#define NT_STATUS_ADDRESS_NOT_ASSOCIATED NT_STATUS(0xC0000000 | 0x0239) -#define NT_STATUS_CONNECTION_INVALID NT_STATUS(0xC0000000 | 0x023a) -#define NT_STATUS_CONNECTION_ACTIVE NT_STATUS(0xC0000000 | 0x023b) -#define NT_STATUS_NETWORK_UNREACHABLE NT_STATUS(0xC0000000 | 0x023c) -#define NT_STATUS_HOST_UNREACHABLE NT_STATUS(0xC0000000 | 0x023d) -#define NT_STATUS_PROTOCOL_UNREACHABLE NT_STATUS(0xC0000000 | 0x023e) -#define NT_STATUS_PORT_UNREACHABLE NT_STATUS(0xC0000000 | 0x023f) -#define NT_STATUS_REQUEST_ABORTED NT_STATUS(0xC0000000 | 0x0240) -#define NT_STATUS_CONNECTION_ABORTED NT_STATUS(0xC0000000 | 0x0241) -#define NT_STATUS_BAD_COMPRESSION_BUFFER NT_STATUS(0xC0000000 | 0x0242) -#define NT_STATUS_USER_MAPPED_FILE NT_STATUS(0xC0000000 | 0x0243) -#define NT_STATUS_AUDIT_FAILED NT_STATUS(0xC0000000 | 0x0244) -#define NT_STATUS_TIMER_RESOLUTION_NOT_SET NT_STATUS(0xC0000000 | 0x0245) -#define NT_STATUS_CONNECTION_COUNT_LIMIT NT_STATUS(0xC0000000 | 0x0246) -#define NT_STATUS_LOGIN_TIME_RESTRICTION NT_STATUS(0xC0000000 | 0x0247) -#define NT_STATUS_LOGIN_WKSTA_RESTRICTION NT_STATUS(0xC0000000 | 0x0248) -#define NT_STATUS_IMAGE_MP_UP_MISMATCH NT_STATUS(0xC0000000 | 0x0249) -#define NT_STATUS_INSUFFICIENT_LOGON_INFO NT_STATUS(0xC0000000 | 0x0250) -#define NT_STATUS_BAD_DLL_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0251) -#define NT_STATUS_BAD_SERVICE_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0252) -#define NT_STATUS_LPC_REPLY_LOST NT_STATUS(0xC0000000 | 0x0253) -#define NT_STATUS_IP_ADDRESS_CONFLICT1 NT_STATUS(0xC0000000 | 0x0254) -#define NT_STATUS_IP_ADDRESS_CONFLICT2 NT_STATUS(0xC0000000 | 0x0255) -#define NT_STATUS_REGISTRY_QUOTA_LIMIT NT_STATUS(0xC0000000 | 0x0256) -#define NT_STATUS_PATH_NOT_COVERED NT_STATUS(0xC0000000 | 0x0257) -#define NT_STATUS_NO_CALLBACK_ACTIVE NT_STATUS(0xC0000000 | 0x0258) -#define NT_STATUS_LICENSE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0259) -#define NT_STATUS_PWD_TOO_SHORT NT_STATUS(0xC0000000 | 0x025a) -#define NT_STATUS_PWD_TOO_RECENT NT_STATUS(0xC0000000 | 0x025b) -#define NT_STATUS_PWD_HISTORY_CONFLICT NT_STATUS(0xC0000000 | 0x025c) -#define NT_STATUS_PLUGPLAY_NO_DEVICE NT_STATUS(0xC0000000 | 0x025e) -#define NT_STATUS_UNSUPPORTED_COMPRESSION NT_STATUS(0xC0000000 | 0x025f) -#define NT_STATUS_INVALID_HW_PROFILE NT_STATUS(0xC0000000 | 0x0260) -#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH NT_STATUS(0xC0000000 | 0x0261) -#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0262) -#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0263) -#define NT_STATUS_RESOURCE_NOT_OWNED NT_STATUS(0xC0000000 | 0x0264) -#define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265) -#define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266) -#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) -#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) -#define NT_STATUS_OBJECTID_NOT_FOUND NT_STATUS(0xC0000000 | 0x02F0) -#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ -#define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) -#define NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX NT_STATUS(0xC0000000 | 0x20026) - - -/* I use NT_STATUS_FOOBAR when I have no idea what error code to use - - * this means we need a torture test */ -#define NT_STATUS_FOOBAR NT_STATUS_UNSUCCESSFUL - -#endif /* _NTERR_H */ diff --git a/source4/libcli/util/ntstatus.h b/source4/libcli/util/ntstatus.h new file mode 100644 index 0000000000..026b5162db --- /dev/null +++ b/source4/libcli/util/ntstatus.h @@ -0,0 +1,675 @@ +/* + Unix SMB/CIFS implementation. + NT error code constants + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) John H Terpstra 1996-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Paul Ashton 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 3 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, see . +*/ + +#ifndef _NTSTATUS_H +#define _NTSTATUS_H + +/* the following rather strange looking definitions of NTSTATUS + are there in order to catch common coding errors where different error types + are mixed up. This is especially important as we slowly convert Samba + from using bool for internal functions +*/ + +#if defined(HAVE_IMMEDIATE_STRUCTURES) +typedef struct {uint32_t v;} NTSTATUS; +#define NT_STATUS(x) ((NTSTATUS) { x }) +#define NT_STATUS_V(x) ((x).v) +#else +typedef uint32_t NTSTATUS; +#define NT_STATUS(x) (x) +#define NT_STATUS_V(x) (x) +#endif + +/* Win32 Status codes. */ + +#define STATUS_BUFFER_OVERFLOW NT_STATUS(0x80000005) +#define STATUS_NO_MORE_FILES NT_STATUS(0x80000006) +#define STATUS_NO_MORE_EAS NT_STATUS(0x80000012) +#define STATUS_INVALID_EA_NAME NT_STATUS(0x80000013) +#define STATUS_EA_LIST_INCONSISTENT NT_STATUS(0x80000014) +#define STATUS_INVALID_EA_FLAG NT_STATUS(0x80000015) +#define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a) + +#define STATUS_PENDING NT_STATUS(0x0103) +#define STATUS_MORE_ENTRIES NT_STATUS(0x0105) +#define STATUS_SOME_UNMAPPED NT_STATUS(0x0107) +#define STATUS_NOTIFY_CLEANUP NT_STATUS(0x010b) +#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) +#define ERROR_INVALID_PARAMETER NT_STATUS(0x0057) +#define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a) +#define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) + +/* Win32 Error codes extracted using a loop in smbclient then printing a + netmon sniff to a file. */ + +/* + -------------- + / \ + / REST \ + / IN \ + / PEACE \ + / \ + | NT_STATUS_NOPROBLEMO | + | | + | | + | 4 September | + | | + | 2001 | + *| * * * | * + _________)/\\_//(\/(/\)/\//\/\///|_)_______ +*/ + +#define NT_STATUS_OK NT_STATUS(0x0000) +#define NT_STATUS_UNSUCCESSFUL NT_STATUS(0xC0000000 | 0x0001) +#define NT_STATUS_NOT_IMPLEMENTED NT_STATUS(0xC0000000 | 0x0002) +#define NT_STATUS_INVALID_INFO_CLASS NT_STATUS(0xC0000000 | 0x0003) +#define NT_STATUS_INFO_LENGTH_MISMATCH NT_STATUS(0xC0000000 | 0x0004) +#define NT_STATUS_ACCESS_VIOLATION NT_STATUS(0xC0000000 | 0x0005) +#define NT_STATUS_IN_PAGE_ERROR NT_STATUS(0xC0000000 | 0x0006) +#define NT_STATUS_PAGEFILE_QUOTA NT_STATUS(0xC0000000 | 0x0007) +#define NT_STATUS_INVALID_HANDLE NT_STATUS(0xC0000000 | 0x0008) +#define NT_STATUS_BAD_INITIAL_STACK NT_STATUS(0xC0000000 | 0x0009) +#define NT_STATUS_BAD_INITIAL_PC NT_STATUS(0xC0000000 | 0x000a) +#define NT_STATUS_INVALID_CID NT_STATUS(0xC0000000 | 0x000b) +#define NT_STATUS_TIMER_NOT_CANCELED NT_STATUS(0xC0000000 | 0x000c) +#define NT_STATUS_INVALID_PARAMETER NT_STATUS(0xC0000000 | 0x000d) +#define NT_STATUS_NO_SUCH_DEVICE NT_STATUS(0xC0000000 | 0x000e) +#define NT_STATUS_NO_SUCH_FILE NT_STATUS(0xC0000000 | 0x000f) +#define NT_STATUS_INVALID_DEVICE_REQUEST NT_STATUS(0xC0000000 | 0x0010) +#define NT_STATUS_END_OF_FILE NT_STATUS(0xC0000000 | 0x0011) +#define NT_STATUS_WRONG_VOLUME NT_STATUS(0xC0000000 | 0x0012) +#define NT_STATUS_NO_MEDIA_IN_DEVICE NT_STATUS(0xC0000000 | 0x0013) +#define NT_STATUS_UNRECOGNIZED_MEDIA NT_STATUS(0xC0000000 | 0x0014) +#define NT_STATUS_NONEXISTENT_SECTOR NT_STATUS(0xC0000000 | 0x0015) +#define NT_STATUS_MORE_PROCESSING_REQUIRED NT_STATUS(0xC0000000 | 0x0016) +#if 0 +/* this demonstrates a little trick when tracking down error codes */ +#define NT_STATUS_NO_MEMORY (printf("no memory at %s\n", __location__), NT_STATUS(0xC0000000 | 0x0017)) +#else +#define NT_STATUS_NO_MEMORY NT_STATUS(0xC0000000 | 0x0017) +#endif +#define NT_STATUS_CONFLICTING_ADDRESSES NT_STATUS(0xC0000000 | 0x0018) +#define NT_STATUS_NOT_MAPPED_VIEW NT_STATUS(0xC0000000 | 0x0019) +#define NT_STATUS_UNABLE_TO_FREE_VM NT_STATUS(0xC0000000 | 0x001a) +#define NT_STATUS_UNABLE_TO_DELETE_SECTION NT_STATUS(0xC0000000 | 0x001b) +#define NT_STATUS_INVALID_SYSTEM_SERVICE NT_STATUS(0xC0000000 | 0x001c) +#define NT_STATUS_ILLEGAL_INSTRUCTION NT_STATUS(0xC0000000 | 0x001d) +#define NT_STATUS_INVALID_LOCK_SEQUENCE NT_STATUS(0xC0000000 | 0x001e) +#define NT_STATUS_INVALID_VIEW_SIZE NT_STATUS(0xC0000000 | 0x001f) +#define NT_STATUS_INVALID_FILE_FOR_SECTION NT_STATUS(0xC0000000 | 0x0020) +#define NT_STATUS_ALREADY_COMMITTED NT_STATUS(0xC0000000 | 0x0021) +#if 0 +/* this demonstrates a little trick when tracking down error codes */ +#define NT_STATUS_ACCESS_DENIED (printf("access denied at %s\n", __location__), NT_STATUS(0xC0000000 | 0x0022)) +#else +#define NT_STATUS_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x0022) +#endif +#define NT_STATUS_BUFFER_TOO_SMALL NT_STATUS(0xC0000000 | 0x0023) +#define NT_STATUS_OBJECT_TYPE_MISMATCH NT_STATUS(0xC0000000 | 0x0024) +#define NT_STATUS_NONCONTINUABLE_EXCEPTION NT_STATUS(0xC0000000 | 0x0025) +#define NT_STATUS_INVALID_DISPOSITION NT_STATUS(0xC0000000 | 0x0026) +#define NT_STATUS_UNWIND NT_STATUS(0xC0000000 | 0x0027) +#define NT_STATUS_BAD_STACK NT_STATUS(0xC0000000 | 0x0028) +#define NT_STATUS_INVALID_UNWIND_TARGET NT_STATUS(0xC0000000 | 0x0029) +#define NT_STATUS_NOT_LOCKED NT_STATUS(0xC0000000 | 0x002a) +#define NT_STATUS_PARITY_ERROR NT_STATUS(0xC0000000 | 0x002b) +#define NT_STATUS_UNABLE_TO_DECOMMIT_VM NT_STATUS(0xC0000000 | 0x002c) +#define NT_STATUS_NOT_COMMITTED NT_STATUS(0xC0000000 | 0x002d) +#define NT_STATUS_INVALID_PORT_ATTRIBUTES NT_STATUS(0xC0000000 | 0x002e) +#define NT_STATUS_PORT_MESSAGE_TOO_LONG NT_STATUS(0xC0000000 | 0x002f) +#define NT_STATUS_INVALID_PARAMETER_MIX NT_STATUS(0xC0000000 | 0x0030) +#define NT_STATUS_INVALID_QUOTA_LOWER NT_STATUS(0xC0000000 | 0x0031) +#define NT_STATUS_DISK_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0032) +#define NT_STATUS_OBJECT_NAME_INVALID NT_STATUS(0xC0000000 | 0x0033) +#define NT_STATUS_OBJECT_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x0034) +#define NT_STATUS_OBJECT_NAME_COLLISION NT_STATUS(0xC0000000 | 0x0035) +#define NT_STATUS_HANDLE_NOT_WAITABLE NT_STATUS(0xC0000000 | 0x0036) +#define NT_STATUS_PORT_DISCONNECTED NT_STATUS(0xC0000000 | 0x0037) +#define NT_STATUS_DEVICE_ALREADY_ATTACHED NT_STATUS(0xC0000000 | 0x0038) +#define NT_STATUS_OBJECT_PATH_INVALID NT_STATUS(0xC0000000 | 0x0039) +#define NT_STATUS_OBJECT_PATH_NOT_FOUND NT_STATUS(0xC0000000 | 0x003a) +#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD NT_STATUS(0xC0000000 | 0x003b) +#define NT_STATUS_DATA_OVERRUN NT_STATUS(0xC0000000 | 0x003c) +#define NT_STATUS_DATA_LATE_ERROR NT_STATUS(0xC0000000 | 0x003d) +#define NT_STATUS_DATA_ERROR NT_STATUS(0xC0000000 | 0x003e) +#define NT_STATUS_CRC_ERROR NT_STATUS(0xC0000000 | 0x003f) +#define NT_STATUS_SECTION_TOO_BIG NT_STATUS(0xC0000000 | 0x0040) +#define NT_STATUS_PORT_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0041) +#define NT_STATUS_INVALID_PORT_HANDLE NT_STATUS(0xC0000000 | 0x0042) +#define NT_STATUS_SHARING_VIOLATION NT_STATUS(0xC0000000 | 0x0043) +#define NT_STATUS_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0044) +#define NT_STATUS_INVALID_PAGE_PROTECTION NT_STATUS(0xC0000000 | 0x0045) +#define NT_STATUS_MUTANT_NOT_OWNED NT_STATUS(0xC0000000 | 0x0046) +#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0047) +#define NT_STATUS_PORT_ALREADY_SET NT_STATUS(0xC0000000 | 0x0048) +#define NT_STATUS_SECTION_NOT_IMAGE NT_STATUS(0xC0000000 | 0x0049) +#define NT_STATUS_SUSPEND_COUNT_EXCEEDED NT_STATUS(0xC0000000 | 0x004a) +#define NT_STATUS_THREAD_IS_TERMINATING NT_STATUS(0xC0000000 | 0x004b) +#define NT_STATUS_BAD_WORKING_SET_LIMIT NT_STATUS(0xC0000000 | 0x004c) +#define NT_STATUS_INCOMPATIBLE_FILE_MAP NT_STATUS(0xC0000000 | 0x004d) +#define NT_STATUS_SECTION_PROTECTION NT_STATUS(0xC0000000 | 0x004e) +#define NT_STATUS_EAS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x004f) +#define NT_STATUS_EA_TOO_LARGE NT_STATUS(0xC0000000 | 0x0050) +#define NT_STATUS_NONEXISTENT_EA_ENTRY NT_STATUS(0xC0000000 | 0x0051) +#define NT_STATUS_NO_EAS_ON_FILE NT_STATUS(0xC0000000 | 0x0052) +#define NT_STATUS_EA_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0053) +#define NT_STATUS_FILE_LOCK_CONFLICT NT_STATUS(0xC0000000 | 0x0054) +#define NT_STATUS_LOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0055) +#define NT_STATUS_DELETE_PENDING NT_STATUS(0xC0000000 | 0x0056) +#define NT_STATUS_CTL_FILE_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x0057) +#define NT_STATUS_UNKNOWN_REVISION NT_STATUS(0xC0000000 | 0x0058) +#define NT_STATUS_REVISION_MISMATCH NT_STATUS(0xC0000000 | 0x0059) +#define NT_STATUS_INVALID_OWNER NT_STATUS(0xC0000000 | 0x005a) +#define NT_STATUS_INVALID_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x005b) +#define NT_STATUS_NO_IMPERSONATION_TOKEN NT_STATUS(0xC0000000 | 0x005c) +#define NT_STATUS_CANT_DISABLE_MANDATORY NT_STATUS(0xC0000000 | 0x005d) +#define NT_STATUS_NO_LOGON_SERVERS NT_STATUS(0xC0000000 | 0x005e) +#define NT_STATUS_NO_SUCH_LOGON_SESSION NT_STATUS(0xC0000000 | 0x005f) +#define NT_STATUS_NO_SUCH_PRIVILEGE NT_STATUS(0xC0000000 | 0x0060) +#define NT_STATUS_PRIVILEGE_NOT_HELD NT_STATUS(0xC0000000 | 0x0061) +#define NT_STATUS_INVALID_ACCOUNT_NAME NT_STATUS(0xC0000000 | 0x0062) +#define NT_STATUS_USER_EXISTS NT_STATUS(0xC0000000 | 0x0063) +#define NT_STATUS_NO_SUCH_USER NT_STATUS(0xC0000000 | 0x0064) +#define NT_STATUS_GROUP_EXISTS NT_STATUS(0xC0000000 | 0x0065) +#define NT_STATUS_NO_SUCH_GROUP NT_STATUS(0xC0000000 | 0x0066) +#define NT_STATUS_MEMBER_IN_GROUP NT_STATUS(0xC0000000 | 0x0067) +#define NT_STATUS_MEMBER_NOT_IN_GROUP NT_STATUS(0xC0000000 | 0x0068) +#define NT_STATUS_LAST_ADMIN NT_STATUS(0xC0000000 | 0x0069) +#define NT_STATUS_WRONG_PASSWORD NT_STATUS(0xC0000000 | 0x006a) +#define NT_STATUS_ILL_FORMED_PASSWORD NT_STATUS(0xC0000000 | 0x006b) +#define NT_STATUS_PASSWORD_RESTRICTION NT_STATUS(0xC0000000 | 0x006c) +#define NT_STATUS_LOGON_FAILURE NT_STATUS(0xC0000000 | 0x006d) +#define NT_STATUS_ACCOUNT_RESTRICTION NT_STATUS(0xC0000000 | 0x006e) +#define NT_STATUS_INVALID_LOGON_HOURS NT_STATUS(0xC0000000 | 0x006f) +#define NT_STATUS_INVALID_WORKSTATION NT_STATUS(0xC0000000 | 0x0070) +#define NT_STATUS_PASSWORD_EXPIRED NT_STATUS(0xC0000000 | 0x0071) +#define NT_STATUS_ACCOUNT_DISABLED NT_STATUS(0xC0000000 | 0x0072) +#define NT_STATUS_NONE_MAPPED NT_STATUS(0xC0000000 | 0x0073) +#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0074) +#define NT_STATUS_LUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0075) +#define NT_STATUS_INVALID_SUB_AUTHORITY NT_STATUS(0xC0000000 | 0x0076) +#define NT_STATUS_INVALID_ACL NT_STATUS(0xC0000000 | 0x0077) +#define NT_STATUS_INVALID_SID NT_STATUS(0xC0000000 | 0x0078) +#define NT_STATUS_INVALID_SECURITY_DESCR NT_STATUS(0xC0000000 | 0x0079) +#define NT_STATUS_PROCEDURE_NOT_FOUND NT_STATUS(0xC0000000 | 0x007a) +#define NT_STATUS_INVALID_IMAGE_FORMAT NT_STATUS(0xC0000000 | 0x007b) +#define NT_STATUS_NO_TOKEN NT_STATUS(0xC0000000 | 0x007c) +#define NT_STATUS_BAD_INHERITANCE_ACL NT_STATUS(0xC0000000 | 0x007d) +#define NT_STATUS_RANGE_NOT_LOCKED NT_STATUS(0xC0000000 | 0x007e) +#define NT_STATUS_DISK_FULL NT_STATUS(0xC0000000 | 0x007f) +#define NT_STATUS_SERVER_DISABLED NT_STATUS(0xC0000000 | 0x0080) +#define NT_STATUS_SERVER_NOT_DISABLED NT_STATUS(0xC0000000 | 0x0081) +#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0082) +#define NT_STATUS_GUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0083) +#define NT_STATUS_INVALID_ID_AUTHORITY NT_STATUS(0xC0000000 | 0x0084) +#define NT_STATUS_AGENTS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0085) +#define NT_STATUS_INVALID_VOLUME_LABEL NT_STATUS(0xC0000000 | 0x0086) +#define NT_STATUS_SECTION_NOT_EXTENDED NT_STATUS(0xC0000000 | 0x0087) +#define NT_STATUS_NOT_MAPPED_DATA NT_STATUS(0xC0000000 | 0x0088) +#define NT_STATUS_RESOURCE_DATA_NOT_FOUND NT_STATUS(0xC0000000 | 0x0089) +#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND NT_STATUS(0xC0000000 | 0x008a) +#define NT_STATUS_RESOURCE_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x008b) +#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED NT_STATUS(0xC0000000 | 0x008c) +#define NT_STATUS_FLOAT_DENORMAL_OPERAND NT_STATUS(0xC0000000 | 0x008d) +#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x008e) +#define NT_STATUS_FLOAT_INEXACT_RESULT NT_STATUS(0xC0000000 | 0x008f) +#define NT_STATUS_FLOAT_INVALID_OPERATION NT_STATUS(0xC0000000 | 0x0090) +#define NT_STATUS_FLOAT_OVERFLOW NT_STATUS(0xC0000000 | 0x0091) +#define NT_STATUS_FLOAT_STACK_CHECK NT_STATUS(0xC0000000 | 0x0092) +#define NT_STATUS_FLOAT_UNDERFLOW NT_STATUS(0xC0000000 | 0x0093) +#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x0094) +#define NT_STATUS_INTEGER_OVERFLOW NT_STATUS(0xC0000000 | 0x0095) +#define NT_STATUS_PRIVILEGED_INSTRUCTION NT_STATUS(0xC0000000 | 0x0096) +#define NT_STATUS_TOO_MANY_PAGING_FILES NT_STATUS(0xC0000000 | 0x0097) +#define NT_STATUS_FILE_INVALID NT_STATUS(0xC0000000 | 0x0098) +#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED NT_STATUS(0xC0000000 | 0x0099) +#define NT_STATUS_INSUFFICIENT_RESOURCES NT_STATUS(0xC0000000 | 0x009a) +#define NT_STATUS_DFS_EXIT_PATH_FOUND NT_STATUS(0xC0000000 | 0x009b) +#define NT_STATUS_DEVICE_DATA_ERROR NT_STATUS(0xC0000000 | 0x009c) +#define NT_STATUS_DEVICE_NOT_CONNECTED NT_STATUS(0xC0000000 | 0x009d) +#define NT_STATUS_DEVICE_POWER_FAILURE NT_STATUS(0xC0000000 | 0x009e) +#define NT_STATUS_FREE_VM_NOT_AT_BASE NT_STATUS(0xC0000000 | 0x009f) +#define NT_STATUS_MEMORY_NOT_ALLOCATED NT_STATUS(0xC0000000 | 0x00a0) +#define NT_STATUS_WORKING_SET_QUOTA NT_STATUS(0xC0000000 | 0x00a1) +#define NT_STATUS_MEDIA_WRITE_PROTECTED NT_STATUS(0xC0000000 | 0x00a2) +#define NT_STATUS_DEVICE_NOT_READY NT_STATUS(0xC0000000 | 0x00a3) +#define NT_STATUS_INVALID_GROUP_ATTRIBUTES NT_STATUS(0xC0000000 | 0x00a4) +#define NT_STATUS_BAD_IMPERSONATION_LEVEL NT_STATUS(0xC0000000 | 0x00a5) +#define NT_STATUS_CANT_OPEN_ANONYMOUS NT_STATUS(0xC0000000 | 0x00a6) +#define NT_STATUS_BAD_VALIDATION_CLASS NT_STATUS(0xC0000000 | 0x00a7) +#define NT_STATUS_BAD_TOKEN_TYPE NT_STATUS(0xC0000000 | 0x00a8) +#define NT_STATUS_BAD_MASTER_BOOT_RECORD NT_STATUS(0xC0000000 | 0x00a9) +#define NT_STATUS_INSTRUCTION_MISALIGNMENT NT_STATUS(0xC0000000 | 0x00aa) +#define NT_STATUS_INSTANCE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ab) +#define NT_STATUS_PIPE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ac) +#define NT_STATUS_INVALID_PIPE_STATE NT_STATUS(0xC0000000 | 0x00ad) +#define NT_STATUS_PIPE_BUSY NT_STATUS(0xC0000000 | 0x00ae) +#define NT_STATUS_ILLEGAL_FUNCTION NT_STATUS(0xC0000000 | 0x00af) +#define NT_STATUS_PIPE_DISCONNECTED NT_STATUS(0xC0000000 | 0x00b0) +#define NT_STATUS_PIPE_CLOSING NT_STATUS(0xC0000000 | 0x00b1) +#define NT_STATUS_PIPE_CONNECTED NT_STATUS(0xC0000000 | 0x00b2) +#define NT_STATUS_PIPE_LISTENING NT_STATUS(0xC0000000 | 0x00b3) +#define NT_STATUS_INVALID_READ_MODE NT_STATUS(0xC0000000 | 0x00b4) +#define NT_STATUS_IO_TIMEOUT NT_STATUS(0xC0000000 | 0x00b5) +#define NT_STATUS_FILE_FORCED_CLOSED NT_STATUS(0xC0000000 | 0x00b6) +#define NT_STATUS_PROFILING_NOT_STARTED NT_STATUS(0xC0000000 | 0x00b7) +#define NT_STATUS_PROFILING_NOT_STOPPED NT_STATUS(0xC0000000 | 0x00b8) +#define NT_STATUS_COULD_NOT_INTERPRET NT_STATUS(0xC0000000 | 0x00b9) +#define NT_STATUS_FILE_IS_A_DIRECTORY NT_STATUS(0xC0000000 | 0x00ba) +#define NT_STATUS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x00bb) +#define NT_STATUS_REMOTE_NOT_LISTENING NT_STATUS(0xC0000000 | 0x00bc) +#define NT_STATUS_DUPLICATE_NAME NT_STATUS(0xC0000000 | 0x00bd) +#define NT_STATUS_BAD_NETWORK_PATH NT_STATUS(0xC0000000 | 0x00be) +#define NT_STATUS_NETWORK_BUSY NT_STATUS(0xC0000000 | 0x00bf) +#define NT_STATUS_DEVICE_DOES_NOT_EXIST NT_STATUS(0xC0000000 | 0x00c0) +#define NT_STATUS_TOO_MANY_COMMANDS NT_STATUS(0xC0000000 | 0x00c1) +#define NT_STATUS_ADAPTER_HARDWARE_ERROR NT_STATUS(0xC0000000 | 0x00c2) +#define NT_STATUS_INVALID_NETWORK_RESPONSE NT_STATUS(0xC0000000 | 0x00c3) +#define NT_STATUS_UNEXPECTED_NETWORK_ERROR NT_STATUS(0xC0000000 | 0x00c4) +#define NT_STATUS_BAD_REMOTE_ADAPTER NT_STATUS(0xC0000000 | 0x00c5) +#define NT_STATUS_PRINT_QUEUE_FULL NT_STATUS(0xC0000000 | 0x00c6) +#define NT_STATUS_NO_SPOOL_SPACE NT_STATUS(0xC0000000 | 0x00c7) +#define NT_STATUS_PRINT_CANCELLED NT_STATUS(0xC0000000 | 0x00c8) +#define NT_STATUS_NETWORK_NAME_DELETED NT_STATUS(0xC0000000 | 0x00c9) +#define NT_STATUS_NETWORK_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x00ca) +#define NT_STATUS_BAD_DEVICE_TYPE NT_STATUS(0xC0000000 | 0x00cb) +#define NT_STATUS_BAD_NETWORK_NAME NT_STATUS(0xC0000000 | 0x00cc) +#define NT_STATUS_TOO_MANY_NAMES NT_STATUS(0xC0000000 | 0x00cd) +#define NT_STATUS_TOO_MANY_SESSIONS NT_STATUS(0xC0000000 | 0x00ce) +#define NT_STATUS_SHARING_PAUSED NT_STATUS(0xC0000000 | 0x00cf) +#define NT_STATUS_REQUEST_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x00d0) +#define NT_STATUS_REDIRECTOR_PAUSED NT_STATUS(0xC0000000 | 0x00d1) +#define NT_STATUS_NET_WRITE_FAULT NT_STATUS(0xC0000000 | 0x00d2) +#define NT_STATUS_PROFILING_AT_LIMIT NT_STATUS(0xC0000000 | 0x00d3) +#define NT_STATUS_NOT_SAME_DEVICE NT_STATUS(0xC0000000 | 0x00d4) +#define NT_STATUS_FILE_RENAMED NT_STATUS(0xC0000000 | 0x00d5) +#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED NT_STATUS(0xC0000000 | 0x00d6) +#define NT_STATUS_NO_SECURITY_ON_OBJECT NT_STATUS(0xC0000000 | 0x00d7) +#define NT_STATUS_CANT_WAIT NT_STATUS(0xC0000000 | 0x00d8) +#define NT_STATUS_PIPE_EMPTY NT_STATUS(0xC0000000 | 0x00d9) +#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO NT_STATUS(0xC0000000 | 0x00da) +#define NT_STATUS_CANT_TERMINATE_SELF NT_STATUS(0xC0000000 | 0x00db) +#define NT_STATUS_INVALID_SERVER_STATE NT_STATUS(0xC0000000 | 0x00dc) +#define NT_STATUS_INVALID_DOMAIN_STATE NT_STATUS(0xC0000000 | 0x00dd) +#define NT_STATUS_INVALID_DOMAIN_ROLE NT_STATUS(0xC0000000 | 0x00de) +#define NT_STATUS_NO_SUCH_DOMAIN NT_STATUS(0xC0000000 | 0x00df) +#define NT_STATUS_DOMAIN_EXISTS NT_STATUS(0xC0000000 | 0x00e0) +#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x00e1) +#define NT_STATUS_OPLOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x00e2) +#define NT_STATUS_INVALID_OPLOCK_PROTOCOL NT_STATUS(0xC0000000 | 0x00e3) +#define NT_STATUS_INTERNAL_DB_CORRUPTION NT_STATUS(0xC0000000 | 0x00e4) +#define NT_STATUS_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x00e5) +#define NT_STATUS_GENERIC_NOT_MAPPED NT_STATUS(0xC0000000 | 0x00e6) +#define NT_STATUS_BAD_DESCRIPTOR_FORMAT NT_STATUS(0xC0000000 | 0x00e7) +#define NT_STATUS_INVALID_USER_BUFFER NT_STATUS(0xC0000000 | 0x00e8) +#define NT_STATUS_UNEXPECTED_IO_ERROR NT_STATUS(0xC0000000 | 0x00e9) +#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR NT_STATUS(0xC0000000 | 0x00ea) +#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR NT_STATUS(0xC0000000 | 0x00eb) +#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR NT_STATUS(0xC0000000 | 0x00ec) +#define NT_STATUS_NOT_LOGON_PROCESS NT_STATUS(0xC0000000 | 0x00ed) +#define NT_STATUS_LOGON_SESSION_EXISTS NT_STATUS(0xC0000000 | 0x00ee) +#define NT_STATUS_INVALID_PARAMETER_1 NT_STATUS(0xC0000000 | 0x00ef) +#define NT_STATUS_INVALID_PARAMETER_2 NT_STATUS(0xC0000000 | 0x00f0) +#define NT_STATUS_INVALID_PARAMETER_3 NT_STATUS(0xC0000000 | 0x00f1) +#define NT_STATUS_INVALID_PARAMETER_4 NT_STATUS(0xC0000000 | 0x00f2) +#define NT_STATUS_INVALID_PARAMETER_5 NT_STATUS(0xC0000000 | 0x00f3) +#define NT_STATUS_INVALID_PARAMETER_6 NT_STATUS(0xC0000000 | 0x00f4) +#define NT_STATUS_INVALID_PARAMETER_7 NT_STATUS(0xC0000000 | 0x00f5) +#define NT_STATUS_INVALID_PARAMETER_8 NT_STATUS(0xC0000000 | 0x00f6) +#define NT_STATUS_INVALID_PARAMETER_9 NT_STATUS(0xC0000000 | 0x00f7) +#define NT_STATUS_INVALID_PARAMETER_10 NT_STATUS(0xC0000000 | 0x00f8) +#define NT_STATUS_INVALID_PARAMETER_11 NT_STATUS(0xC0000000 | 0x00f9) +#define NT_STATUS_INVALID_PARAMETER_12 NT_STATUS(0xC0000000 | 0x00fa) +#define NT_STATUS_REDIRECTOR_NOT_STARTED NT_STATUS(0xC0000000 | 0x00fb) +#define NT_STATUS_REDIRECTOR_STARTED NT_STATUS(0xC0000000 | 0x00fc) +#define NT_STATUS_STACK_OVERFLOW NT_STATUS(0xC0000000 | 0x00fd) +#define NT_STATUS_NO_SUCH_PACKAGE NT_STATUS(0xC0000000 | 0x00fe) +#define NT_STATUS_BAD_FUNCTION_TABLE NT_STATUS(0xC0000000 | 0x00ff) +#define NT_STATUS_DIRECTORY_NOT_EMPTY NT_STATUS(0xC0000000 | 0x0101) +#define NT_STATUS_FILE_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0102) +#define NT_STATUS_NOT_A_DIRECTORY NT_STATUS(0xC0000000 | 0x0103) +#define NT_STATUS_BAD_LOGON_SESSION_STATE NT_STATUS(0xC0000000 | 0x0104) +#define NT_STATUS_LOGON_SESSION_COLLISION NT_STATUS(0xC0000000 | 0x0105) +#define NT_STATUS_NAME_TOO_LONG NT_STATUS(0xC0000000 | 0x0106) +#define NT_STATUS_FILES_OPEN NT_STATUS(0xC0000000 | 0x0107) +#define NT_STATUS_CONNECTION_IN_USE NT_STATUS(0xC0000000 | 0x0108) +#define NT_STATUS_MESSAGE_NOT_FOUND NT_STATUS(0xC0000000 | 0x0109) +#define NT_STATUS_PROCESS_IS_TERMINATING NT_STATUS(0xC0000000 | 0x010a) +#define NT_STATUS_INVALID_LOGON_TYPE NT_STATUS(0xC0000000 | 0x010b) +#define NT_STATUS_NO_GUID_TRANSLATION NT_STATUS(0xC0000000 | 0x010c) +#define NT_STATUS_CANNOT_IMPERSONATE NT_STATUS(0xC0000000 | 0x010d) +#define NT_STATUS_IMAGE_ALREADY_LOADED NT_STATUS(0xC0000000 | 0x010e) +#define NT_STATUS_ABIOS_NOT_PRESENT NT_STATUS(0xC0000000 | 0x010f) +#define NT_STATUS_ABIOS_LID_NOT_EXIST NT_STATUS(0xC0000000 | 0x0110) +#define NT_STATUS_ABIOS_LID_ALREADY_OWNED NT_STATUS(0xC0000000 | 0x0111) +#define NT_STATUS_ABIOS_NOT_LID_OWNER NT_STATUS(0xC0000000 | 0x0112) +#define NT_STATUS_ABIOS_INVALID_COMMAND NT_STATUS(0xC0000000 | 0x0113) +#define NT_STATUS_ABIOS_INVALID_LID NT_STATUS(0xC0000000 | 0x0114) +#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x0115) +#define NT_STATUS_ABIOS_INVALID_SELECTOR NT_STATUS(0xC0000000 | 0x0116) +#define NT_STATUS_NO_LDT NT_STATUS(0xC0000000 | 0x0117) +#define NT_STATUS_INVALID_LDT_SIZE NT_STATUS(0xC0000000 | 0x0118) +#define NT_STATUS_INVALID_LDT_OFFSET NT_STATUS(0xC0000000 | 0x0119) +#define NT_STATUS_INVALID_LDT_DESCRIPTOR NT_STATUS(0xC0000000 | 0x011a) +#define NT_STATUS_INVALID_IMAGE_NE_FORMAT NT_STATUS(0xC0000000 | 0x011b) +#define NT_STATUS_RXACT_INVALID_STATE NT_STATUS(0xC0000000 | 0x011c) +#define NT_STATUS_RXACT_COMMIT_FAILURE NT_STATUS(0xC0000000 | 0x011d) +#define NT_STATUS_MAPPED_FILE_SIZE_ZERO NT_STATUS(0xC0000000 | 0x011e) +#define NT_STATUS_TOO_MANY_OPENED_FILES NT_STATUS(0xC0000000 | 0x011f) +#define NT_STATUS_CANCELLED NT_STATUS(0xC0000000 | 0x0120) +#define NT_STATUS_CANNOT_DELETE NT_STATUS(0xC0000000 | 0x0121) +#define NT_STATUS_INVALID_COMPUTER_NAME NT_STATUS(0xC0000000 | 0x0122) +#define NT_STATUS_FILE_DELETED NT_STATUS(0xC0000000 | 0x0123) +#define NT_STATUS_SPECIAL_ACCOUNT NT_STATUS(0xC0000000 | 0x0124) +#define NT_STATUS_SPECIAL_GROUP NT_STATUS(0xC0000000 | 0x0125) +#define NT_STATUS_SPECIAL_USER NT_STATUS(0xC0000000 | 0x0126) +#define NT_STATUS_MEMBERS_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x0127) +#define NT_STATUS_FILE_CLOSED NT_STATUS(0xC0000000 | 0x0128) +#define NT_STATUS_TOO_MANY_THREADS NT_STATUS(0xC0000000 | 0x0129) +#define NT_STATUS_THREAD_NOT_IN_PROCESS NT_STATUS(0xC0000000 | 0x012a) +#define NT_STATUS_TOKEN_ALREADY_IN_USE NT_STATUS(0xC0000000 | 0x012b) +#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x012c) +#define NT_STATUS_COMMITMENT_LIMIT NT_STATUS(0xC0000000 | 0x012d) +#define NT_STATUS_INVALID_IMAGE_LE_FORMAT NT_STATUS(0xC0000000 | 0x012e) +#define NT_STATUS_INVALID_IMAGE_NOT_MZ NT_STATUS(0xC0000000 | 0x012f) +#define NT_STATUS_INVALID_IMAGE_PROTECT NT_STATUS(0xC0000000 | 0x0130) +#define NT_STATUS_INVALID_IMAGE_WIN_16 NT_STATUS(0xC0000000 | 0x0131) +#define NT_STATUS_LOGON_SERVER_CONFLICT NT_STATUS(0xC0000000 | 0x0132) +#define NT_STATUS_TIME_DIFFERENCE_AT_DC NT_STATUS(0xC0000000 | 0x0133) +#define NT_STATUS_SYNCHRONIZATION_REQUIRED NT_STATUS(0xC0000000 | 0x0134) +#define NT_STATUS_DLL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0135) +#define NT_STATUS_OPEN_FAILED NT_STATUS(0xC0000000 | 0x0136) +#define NT_STATUS_IO_PRIVILEGE_FAILED NT_STATUS(0xC0000000 | 0x0137) +#define NT_STATUS_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0138) +#define NT_STATUS_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0139) +#define NT_STATUS_CONTROL_C_EXIT NT_STATUS(0xC0000000 | 0x013a) +#define NT_STATUS_LOCAL_DISCONNECT NT_STATUS(0xC0000000 | 0x013b) +#define NT_STATUS_REMOTE_DISCONNECT NT_STATUS(0xC0000000 | 0x013c) +#define NT_STATUS_REMOTE_RESOURCES NT_STATUS(0xC0000000 | 0x013d) +#define NT_STATUS_LINK_FAILED NT_STATUS(0xC0000000 | 0x013e) +#define NT_STATUS_LINK_TIMEOUT NT_STATUS(0xC0000000 | 0x013f) +#define NT_STATUS_INVALID_CONNECTION NT_STATUS(0xC0000000 | 0x0140) +#define NT_STATUS_INVALID_ADDRESS NT_STATUS(0xC0000000 | 0x0141) +#define NT_STATUS_DLL_INIT_FAILED NT_STATUS(0xC0000000 | 0x0142) +#define NT_STATUS_MISSING_SYSTEMFILE NT_STATUS(0xC0000000 | 0x0143) +#define NT_STATUS_UNHANDLED_EXCEPTION NT_STATUS(0xC0000000 | 0x0144) +#define NT_STATUS_APP_INIT_FAILURE NT_STATUS(0xC0000000 | 0x0145) +#define NT_STATUS_PAGEFILE_CREATE_FAILED NT_STATUS(0xC0000000 | 0x0146) +#define NT_STATUS_NO_PAGEFILE NT_STATUS(0xC0000000 | 0x0147) +#define NT_STATUS_INVALID_LEVEL NT_STATUS(0xC0000000 | 0x0148) +#define NT_STATUS_WRONG_PASSWORD_CORE NT_STATUS(0xC0000000 | 0x0149) +#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT NT_STATUS(0xC0000000 | 0x014a) +#define NT_STATUS_PIPE_BROKEN NT_STATUS(0xC0000000 | 0x014b) +#define NT_STATUS_REGISTRY_CORRUPT NT_STATUS(0xC0000000 | 0x014c) +#define NT_STATUS_REGISTRY_IO_FAILED NT_STATUS(0xC0000000 | 0x014d) +#define NT_STATUS_NO_EVENT_PAIR NT_STATUS(0xC0000000 | 0x014e) +#define NT_STATUS_UNRECOGNIZED_VOLUME NT_STATUS(0xC0000000 | 0x014f) +#define NT_STATUS_SERIAL_NO_DEVICE_INITED NT_STATUS(0xC0000000 | 0x0150) +#define NT_STATUS_NO_SUCH_ALIAS NT_STATUS(0xC0000000 | 0x0151) +#define NT_STATUS_MEMBER_NOT_IN_ALIAS NT_STATUS(0xC0000000 | 0x0152) +#define NT_STATUS_MEMBER_IN_ALIAS NT_STATUS(0xC0000000 | 0x0153) +#define NT_STATUS_ALIAS_EXISTS NT_STATUS(0xC0000000 | 0x0154) +#define NT_STATUS_LOGON_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0155) +#define NT_STATUS_TOO_MANY_SECRETS NT_STATUS(0xC0000000 | 0x0156) +#define NT_STATUS_SECRET_TOO_LONG NT_STATUS(0xC0000000 | 0x0157) +#define NT_STATUS_INTERNAL_DB_ERROR NT_STATUS(0xC0000000 | 0x0158) +#define NT_STATUS_FULLSCREEN_MODE NT_STATUS(0xC0000000 | 0x0159) +#define NT_STATUS_TOO_MANY_CONTEXT_IDS NT_STATUS(0xC0000000 | 0x015a) +#define NT_STATUS_LOGON_TYPE_NOT_GRANTED NT_STATUS(0xC0000000 | 0x015b) +#define NT_STATUS_NOT_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x015c) +#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x015d) +#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR NT_STATUS(0xC0000000 | 0x015e) +#define NT_STATUS_FT_MISSING_MEMBER NT_STATUS(0xC0000000 | 0x015f) +#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY NT_STATUS(0xC0000000 | 0x0160) +#define NT_STATUS_ILLEGAL_CHARACTER NT_STATUS(0xC0000000 | 0x0161) +#define NT_STATUS_UNMAPPABLE_CHARACTER NT_STATUS(0xC0000000 | 0x0162) +#define NT_STATUS_UNDEFINED_CHARACTER NT_STATUS(0xC0000000 | 0x0163) +#define NT_STATUS_FLOPPY_VOLUME NT_STATUS(0xC0000000 | 0x0164) +#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND NT_STATUS(0xC0000000 | 0x0165) +#define NT_STATUS_FLOPPY_WRONG_CYLINDER NT_STATUS(0xC0000000 | 0x0166) +#define NT_STATUS_FLOPPY_UNKNOWN_ERROR NT_STATUS(0xC0000000 | 0x0167) +#define NT_STATUS_FLOPPY_BAD_REGISTERS NT_STATUS(0xC0000000 | 0x0168) +#define NT_STATUS_DISK_RECALIBRATE_FAILED NT_STATUS(0xC0000000 | 0x0169) +#define NT_STATUS_DISK_OPERATION_FAILED NT_STATUS(0xC0000000 | 0x016a) +#define NT_STATUS_DISK_RESET_FAILED NT_STATUS(0xC0000000 | 0x016b) +#define NT_STATUS_SHARED_IRQ_BUSY NT_STATUS(0xC0000000 | 0x016c) +#define NT_STATUS_FT_ORPHANING NT_STATUS(0xC0000000 | 0x016d) +#define NT_STATUS_PARTITION_FAILURE NT_STATUS(0xC0000000 | 0x0172) +#define NT_STATUS_INVALID_BLOCK_LENGTH NT_STATUS(0xC0000000 | 0x0173) +#define NT_STATUS_DEVICE_NOT_PARTITIONED NT_STATUS(0xC0000000 | 0x0174) +#define NT_STATUS_UNABLE_TO_LOCK_MEDIA NT_STATUS(0xC0000000 | 0x0175) +#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA NT_STATUS(0xC0000000 | 0x0176) +#define NT_STATUS_EOM_OVERFLOW NT_STATUS(0xC0000000 | 0x0177) +#define NT_STATUS_NO_MEDIA NT_STATUS(0xC0000000 | 0x0178) +#define NT_STATUS_NO_SUCH_MEMBER NT_STATUS(0xC0000000 | 0x017a) +#define NT_STATUS_INVALID_MEMBER NT_STATUS(0xC0000000 | 0x017b) +#define NT_STATUS_KEY_DELETED NT_STATUS(0xC0000000 | 0x017c) +#define NT_STATUS_NO_LOG_SPACE NT_STATUS(0xC0000000 | 0x017d) +#define NT_STATUS_TOO_MANY_SIDS NT_STATUS(0xC0000000 | 0x017e) +#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x017f) +#define NT_STATUS_KEY_HAS_CHILDREN NT_STATUS(0xC0000000 | 0x0180) +#define NT_STATUS_CHILD_MUST_BE_VOLATILE NT_STATUS(0xC0000000 | 0x0181) +#define NT_STATUS_DEVICE_CONFIGURATION_ERROR NT_STATUS(0xC0000000 | 0x0182) +#define NT_STATUS_DRIVER_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x0183) +#define NT_STATUS_INVALID_DEVICE_STATE NT_STATUS(0xC0000000 | 0x0184) +#define NT_STATUS_IO_DEVICE_ERROR NT_STATUS(0xC0000000 | 0x0185) +#define NT_STATUS_DEVICE_PROTOCOL_ERROR NT_STATUS(0xC0000000 | 0x0186) +#define NT_STATUS_BACKUP_CONTROLLER NT_STATUS(0xC0000000 | 0x0187) +#define NT_STATUS_LOG_FILE_FULL NT_STATUS(0xC0000000 | 0x0188) +#define NT_STATUS_TOO_LATE NT_STATUS(0xC0000000 | 0x0189) +#define NT_STATUS_NO_TRUST_LSA_SECRET NT_STATUS(0xC0000000 | 0x018a) +#define NT_STATUS_NO_TRUST_SAM_ACCOUNT NT_STATUS(0xC0000000 | 0x018b) +#define NT_STATUS_TRUSTED_DOMAIN_FAILURE NT_STATUS(0xC0000000 | 0x018c) +#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE NT_STATUS(0xC0000000 | 0x018d) +#define NT_STATUS_EVENTLOG_FILE_CORRUPT NT_STATUS(0xC0000000 | 0x018e) +#define NT_STATUS_EVENTLOG_CANT_START NT_STATUS(0xC0000000 | 0x018f) +#define NT_STATUS_TRUST_FAILURE NT_STATUS(0xC0000000 | 0x0190) +#define NT_STATUS_MUTANT_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0191) +#define NT_STATUS_NETLOGON_NOT_STARTED NT_STATUS(0xC0000000 | 0x0192) +#define NT_STATUS_ACCOUNT_EXPIRED NT_STATUS(0xC0000000 | 0x0193) +#define NT_STATUS_POSSIBLE_DEADLOCK NT_STATUS(0xC0000000 | 0x0194) +#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT NT_STATUS(0xC0000000 | 0x0195) +#define NT_STATUS_REMOTE_SESSION_LIMIT NT_STATUS(0xC0000000 | 0x0196) +#define NT_STATUS_EVENTLOG_FILE_CHANGED NT_STATUS(0xC0000000 | 0x0197) +#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0198) +#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0199) +#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x019a) +#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT NT_STATUS(0xC0000000 | 0x019b) +#define NT_STATUS_FS_DRIVER_REQUIRED NT_STATUS(0xC0000000 | 0x019c) +#define NT_STATUS_NO_USER_SESSION_KEY NT_STATUS(0xC0000000 | 0x0202) +#define NT_STATUS_USER_SESSION_DELETED NT_STATUS(0xC0000000 | 0x0203) +#define NT_STATUS_RESOURCE_LANG_NOT_FOUND NT_STATUS(0xC0000000 | 0x0204) +#define NT_STATUS_INSUFF_SERVER_RESOURCES NT_STATUS(0xC0000000 | 0x0205) +#define NT_STATUS_INVALID_BUFFER_SIZE NT_STATUS(0xC0000000 | 0x0206) +#define NT_STATUS_INVALID_ADDRESS_COMPONENT NT_STATUS(0xC0000000 | 0x0207) +#define NT_STATUS_INVALID_ADDRESS_WILDCARD NT_STATUS(0xC0000000 | 0x0208) +#define NT_STATUS_TOO_MANY_ADDRESSES NT_STATUS(0xC0000000 | 0x0209) +#define NT_STATUS_ADDRESS_ALREADY_EXISTS NT_STATUS(0xC0000000 | 0x020a) +#define NT_STATUS_ADDRESS_CLOSED NT_STATUS(0xC0000000 | 0x020b) +#define NT_STATUS_CONNECTION_DISCONNECTED NT_STATUS(0xC0000000 | 0x020c) +#define NT_STATUS_CONNECTION_RESET NT_STATUS(0xC0000000 | 0x020d) +#define NT_STATUS_TOO_MANY_NODES NT_STATUS(0xC0000000 | 0x020e) +#define NT_STATUS_TRANSACTION_ABORTED NT_STATUS(0xC0000000 | 0x020f) +#define NT_STATUS_TRANSACTION_TIMED_OUT NT_STATUS(0xC0000000 | 0x0210) +#define NT_STATUS_TRANSACTION_NO_RELEASE NT_STATUS(0xC0000000 | 0x0211) +#define NT_STATUS_TRANSACTION_NO_MATCH NT_STATUS(0xC0000000 | 0x0212) +#define NT_STATUS_TRANSACTION_RESPONDED NT_STATUS(0xC0000000 | 0x0213) +#define NT_STATUS_TRANSACTION_INVALID_ID NT_STATUS(0xC0000000 | 0x0214) +#define NT_STATUS_TRANSACTION_INVALID_TYPE NT_STATUS(0xC0000000 | 0x0215) +#define NT_STATUS_NOT_SERVER_SESSION NT_STATUS(0xC0000000 | 0x0216) +#define NT_STATUS_NOT_CLIENT_SESSION NT_STATUS(0xC0000000 | 0x0217) +#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x0218) +#define NT_STATUS_DEBUG_ATTACH_FAILED NT_STATUS(0xC0000000 | 0x0219) +#define NT_STATUS_SYSTEM_PROCESS_TERMINATED NT_STATUS(0xC0000000 | 0x021a) +#define NT_STATUS_DATA_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x021b) +#define NT_STATUS_NO_BROWSER_SERVERS_FOUND NT_STATUS(0xC0000000 | 0x021c) +#define NT_STATUS_VDM_HARD_ERROR NT_STATUS(0xC0000000 | 0x021d) +#define NT_STATUS_DRIVER_CANCEL_TIMEOUT NT_STATUS(0xC0000000 | 0x021e) +#define NT_STATUS_REPLY_MESSAGE_MISMATCH NT_STATUS(0xC0000000 | 0x021f) +#define NT_STATUS_MAPPED_ALIGNMENT NT_STATUS(0xC0000000 | 0x0220) +#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH NT_STATUS(0xC0000000 | 0x0221) +#define NT_STATUS_LOST_WRITEBEHIND_DATA NT_STATUS(0xC0000000 | 0x0222) +#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID NT_STATUS(0xC0000000 | 0x0223) +#define NT_STATUS_PASSWORD_MUST_CHANGE NT_STATUS(0xC0000000 | 0x0224) +#define NT_STATUS_NOT_FOUND NT_STATUS(0xC0000000 | 0x0225) +#define NT_STATUS_NOT_TINY_STREAM NT_STATUS(0xC0000000 | 0x0226) +#define NT_STATUS_RECOVERY_FAILURE NT_STATUS(0xC0000000 | 0x0227) +#define NT_STATUS_STACK_OVERFLOW_READ NT_STATUS(0xC0000000 | 0x0228) +#define NT_STATUS_FAIL_CHECK NT_STATUS(0xC0000000 | 0x0229) +#define NT_STATUS_DUPLICATE_OBJECTID NT_STATUS(0xC0000000 | 0x022a) +#define NT_STATUS_OBJECTID_EXISTS NT_STATUS(0xC0000000 | 0x022b) +#define NT_STATUS_CONVERT_TO_LARGE NT_STATUS(0xC0000000 | 0x022c) +#define NT_STATUS_RETRY NT_STATUS(0xC0000000 | 0x022d) +#define NT_STATUS_FOUND_OUT_OF_SCOPE NT_STATUS(0xC0000000 | 0x022e) +#define NT_STATUS_ALLOCATE_BUCKET NT_STATUS(0xC0000000 | 0x022f) +#define NT_STATUS_PROPSET_NOT_FOUND NT_STATUS(0xC0000000 | 0x0230) +#define NT_STATUS_MARSHALL_OVERFLOW NT_STATUS(0xC0000000 | 0x0231) +#define NT_STATUS_INVALID_VARIANT NT_STATUS(0xC0000000 | 0x0232) +#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND NT_STATUS(0xC0000000 | 0x0233) +#define NT_STATUS_ACCOUNT_LOCKED_OUT NT_STATUS(0xC0000000 | 0x0234) +#define NT_STATUS_HANDLE_NOT_CLOSABLE NT_STATUS(0xC0000000 | 0x0235) +#define NT_STATUS_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0236) +#define NT_STATUS_GRACEFUL_DISCONNECT NT_STATUS(0xC0000000 | 0x0237) +#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED NT_STATUS(0xC0000000 | 0x0238) +#define NT_STATUS_ADDRESS_NOT_ASSOCIATED NT_STATUS(0xC0000000 | 0x0239) +#define NT_STATUS_CONNECTION_INVALID NT_STATUS(0xC0000000 | 0x023a) +#define NT_STATUS_CONNECTION_ACTIVE NT_STATUS(0xC0000000 | 0x023b) +#define NT_STATUS_NETWORK_UNREACHABLE NT_STATUS(0xC0000000 | 0x023c) +#define NT_STATUS_HOST_UNREACHABLE NT_STATUS(0xC0000000 | 0x023d) +#define NT_STATUS_PROTOCOL_UNREACHABLE NT_STATUS(0xC0000000 | 0x023e) +#define NT_STATUS_PORT_UNREACHABLE NT_STATUS(0xC0000000 | 0x023f) +#define NT_STATUS_REQUEST_ABORTED NT_STATUS(0xC0000000 | 0x0240) +#define NT_STATUS_CONNECTION_ABORTED NT_STATUS(0xC0000000 | 0x0241) +#define NT_STATUS_BAD_COMPRESSION_BUFFER NT_STATUS(0xC0000000 | 0x0242) +#define NT_STATUS_USER_MAPPED_FILE NT_STATUS(0xC0000000 | 0x0243) +#define NT_STATUS_AUDIT_FAILED NT_STATUS(0xC0000000 | 0x0244) +#define NT_STATUS_TIMER_RESOLUTION_NOT_SET NT_STATUS(0xC0000000 | 0x0245) +#define NT_STATUS_CONNECTION_COUNT_LIMIT NT_STATUS(0xC0000000 | 0x0246) +#define NT_STATUS_LOGIN_TIME_RESTRICTION NT_STATUS(0xC0000000 | 0x0247) +#define NT_STATUS_LOGIN_WKSTA_RESTRICTION NT_STATUS(0xC0000000 | 0x0248) +#define NT_STATUS_IMAGE_MP_UP_MISMATCH NT_STATUS(0xC0000000 | 0x0249) +#define NT_STATUS_INSUFFICIENT_LOGON_INFO NT_STATUS(0xC0000000 | 0x0250) +#define NT_STATUS_BAD_DLL_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0251) +#define NT_STATUS_BAD_SERVICE_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0252) +#define NT_STATUS_LPC_REPLY_LOST NT_STATUS(0xC0000000 | 0x0253) +#define NT_STATUS_IP_ADDRESS_CONFLICT1 NT_STATUS(0xC0000000 | 0x0254) +#define NT_STATUS_IP_ADDRESS_CONFLICT2 NT_STATUS(0xC0000000 | 0x0255) +#define NT_STATUS_REGISTRY_QUOTA_LIMIT NT_STATUS(0xC0000000 | 0x0256) +#define NT_STATUS_PATH_NOT_COVERED NT_STATUS(0xC0000000 | 0x0257) +#define NT_STATUS_NO_CALLBACK_ACTIVE NT_STATUS(0xC0000000 | 0x0258) +#define NT_STATUS_LICENSE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0259) +#define NT_STATUS_PWD_TOO_SHORT NT_STATUS(0xC0000000 | 0x025a) +#define NT_STATUS_PWD_TOO_RECENT NT_STATUS(0xC0000000 | 0x025b) +#define NT_STATUS_PWD_HISTORY_CONFLICT NT_STATUS(0xC0000000 | 0x025c) +#define NT_STATUS_PLUGPLAY_NO_DEVICE NT_STATUS(0xC0000000 | 0x025e) +#define NT_STATUS_UNSUPPORTED_COMPRESSION NT_STATUS(0xC0000000 | 0x025f) +#define NT_STATUS_INVALID_HW_PROFILE NT_STATUS(0xC0000000 | 0x0260) +#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH NT_STATUS(0xC0000000 | 0x0261) +#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0262) +#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0263) +#define NT_STATUS_RESOURCE_NOT_OWNED NT_STATUS(0xC0000000 | 0x0264) +#define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265) +#define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266) +#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) +#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) +#define NT_STATUS_OBJECTID_NOT_FOUND NT_STATUS(0xC0000000 | 0x02F0) +#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ +#define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) +#define NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX NT_STATUS(0xC0000000 | 0x20026) + + +/* I use NT_STATUS_FOOBAR when I have no idea what error code to use - + * this means we need a torture test */ +#define NT_STATUS_FOOBAR NT_STATUS_UNSUCCESSFUL + +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +const char *nt_errstr(NTSTATUS nt_code); + +/************************************************************************ + Print friendler version fo NT error code + ***********************************************************************/ +const char *get_friendly_nt_error_msg(NTSTATUS nt_code); + +/***************************************************************************** + returns an NT_STATUS constant as a string for inclusion in autogen C code + *****************************************************************************/ +const char *get_nt_error_c_code(NTSTATUS nt_code); + +/***************************************************************************** + returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) + *****************************************************************************/ +NTSTATUS nt_status_string_to_code(const char *nt_status_str); + +#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) +#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) +/* checking for DOS error mapping here is ugly, but unfortunately the + alternative is a very intrusive rewrite of the torture code */ +#define NT_STATUS_EQUAL(x,y) (NT_STATUS_IS_DOS(x)||NT_STATUS_IS_DOS(y)?ntstatus_dos_equal(x,y):NT_STATUS_V(x) == NT_STATUS_V(y)) + +#define NT_STATUS_HAVE_NO_MEMORY(x) do { \ + if (!(x)) {\ + return NT_STATUS_NO_MEMORY;\ + }\ +} while (0) + +#define NT_STATUS_IS_OK_RETURN(x) do { \ + if (NT_STATUS_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +#define NT_STATUS_NOT_OK_RETURN(x) do { \ + if (!NT_STATUS_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +#define NT_STATUS_IS_ERR_RETURN(x) do { \ + if (NT_STATUS_IS_ERR(x)) {\ + return x;\ + }\ +} while (0) + +#define NT_STATUS_NOT_ERR_RETURN(x) do { \ + if (!NT_STATUS_IS_ERR(x)) {\ + return x;\ + }\ +} while (0) + +/* this defines special NTSTATUS codes to represent DOS errors. I + have chosen this macro to produce status codes in the invalid + NTSTATUS range */ +#define NT_STATUS_DOS(class, code) NT_STATUS(0xF1000000 | ((class)<<16) | code) +#define NT_STATUS_IS_DOS(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF1000000) +#define NT_STATUS_DOS_CLASS(status) ((NT_STATUS_V(status) >> 16) & 0xFF) +#define NT_STATUS_DOS_CODE(status) (NT_STATUS_V(status) & 0xFFFF) + +/* define ldap error codes as NTSTATUS codes */ +#define NT_STATUS_LDAP(code) NT_STATUS(0xF2000000 | code) +#define NT_STATUS_IS_LDAP(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF2000000) +#define NT_STATUS_LDAP_CODE(status) (NT_STATUS_V(status) & ~0xFF000000) + + + +#endif /* _NTSTATUS_H */ diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h new file mode 100644 index 0000000000..0f49514b9f --- /dev/null +++ b/source4/libcli/util/werror.h @@ -0,0 +1,193 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup, plus a whole lot more. + + Copyright (C) Andrew Tridgell 2001 + + 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 3 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, see . +*/ + +#ifndef _WERROR_H_ +#define _WERROR_H + +#include + +/* the following rather strange looking definitions of NTSTATUS and WERROR + and there in order to catch common coding errors where different error types + are mixed up. This is especially important as we slowly convert Samba + from using bool for internal functions +*/ + +#if defined(HAVE_IMMEDIATE_STRUCTURES) +typedef struct {uint32_t v;} WERROR; +#define W_ERROR(x) ((WERROR) { x }) +#define W_ERROR_V(x) ((x).v) +#else +typedef uint32_t WERROR; +#define W_ERROR(x) (x) +#define W_ERROR_V(x) (x) +#endif + +#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) +#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) + +#define W_ERROR_HAVE_NO_MEMORY(x) do { \ + if (!(x)) {\ + return WERR_NOMEM;\ + }\ +} while (0) + +#define W_ERROR_IS_OK_RETURN(x) do { \ + if (W_ERROR_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +#define W_ERROR_NOT_OK_RETURN(x) do { \ + if (!W_ERROR_IS_OK(x)) {\ + return x;\ + }\ +} while (0) + +/* these are win32 error codes. There are only a few places where + these matter for Samba, primarily in the NT printing code */ +#define WERR_OK W_ERROR(0) +#define WERR_BADFUNC W_ERROR(1) +#define WERR_BADFILE W_ERROR(2) +#define WERR_ACCESS_DENIED W_ERROR(5) +#define WERR_BADFID W_ERROR(6) +#define WERR_NOMEM W_ERROR(8) +#define WERR_GENERAL_FAILURE W_ERROR(31) +#define WERR_NOT_SUPPORTED W_ERROR(50) +#define WERR_BAD_NETPATH W_ERROR(53) +#define WERR_BAD_NET_RESP W_ERROR(58) +#define WERR_UNEXP_NET_ERR W_ERROR(59) +#define WERR_PRINTQ_FULL W_ERROR(61) +#define WERR_NO_SPOOL_SPACE W_ERROR(62) +#define WERR_NO_SUCH_SHARE W_ERROR(67) +#define WERR_FILE_EXISTS W_ERROR(80) +#define WERR_BAD_PASSWORD W_ERROR(86) +#define WERR_INVALID_PARAM W_ERROR(87) +#define WERR_INSUFFICIENT_BUFFER W_ERROR(122) +#define WERR_INVALID_NAME W_ERROR(123) +#define WERR_UNKNOWN_LEVEL W_ERROR(124) +#define WERR_OBJECT_PATH_INVALID W_ERROR(161) +#define WERR_ALREADY_EXISTS W_ERROR(183) +#define WERR_NO_MORE_ITEMS W_ERROR(259) +#define WERR_MORE_DATA W_ERROR(234) +#define WERR_CAN_NOT_COMPLETE W_ERROR(1003) +#define WERR_NOT_FOUND W_ERROR(1168) +#define WERR_INVALID_COMPUTERNAME W_ERROR(1210) +#define WERR_INVALID_DOMAINNAME W_ERROR(1212) +#define WERR_UNKNOWN_REVISION W_ERROR(1305) +#define WERR_REVISION_MISMATCH W_ERROR(1306) +#define WERR_INVALID_OWNER W_ERROR(1307) +#define WERR_NO_LOGON_SERVERS W_ERROR(1311) +#define WERR_NO_SUCH_PRIVILEGE W_ERROR(1313) +#define WERR_PRIVILEGE_NOT_HELD W_ERROR(1314) +#define WERR_NO_SUCH_USER W_ERROR(1317) +#define WERR_LOGON_FAILURE W_ERROR(1326) +#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) +#define WERR_INVALID_DOMAIN_ROLE W_ERROR(1354) +#define WERR_NO_SUCH_DOMAIN W_ERROR(1355) +#define WERR_NO_SYSTEM_RESOURCES W_ERROR(1450) +#define WERR_SERVER_UNAVAILABLE W_ERROR(1722) +#define WERR_INVALID_FORM_NAME W_ERROR(1902) +#define WERR_INVALID_FORM_SIZE W_ERROR(1903) +#define WERR_ALREADY_SHARED W_ERROR(2118) +#define WERR_BUF_TOO_SMALL W_ERROR(2123) +#define WERR_JOB_NOT_FOUND W_ERROR(2151) +#define WERR_DEST_NOT_FOUND W_ERROR(2152) +#define WERR_SESSION_NOT_FOUND W_ERROR(2312) +#define WERR_FID_NOT_FOUND W_ERROR(2314) +#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) +#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453) +#define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) +#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) + +#define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled) +#define WERR_UNKNOWN_PORT W_ERROR(ERRunknownprinterport) +#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(ERRunknownprinterdriver) +#define WERR_UNKNOWN_PRINTPROCESSOR W_ERROR(ERRunknownprintprocessor) +#define WERR_INVALID_SEPARATOR_FILE W_ERROR(ERRinvalidseparatorfile) +#define WERR_INVALID_PRIORITY W_ERROR(ERRinvalidjobpriority) +#define WERR_INVALID_PRINTER_NAME W_ERROR(ERRinvalidprintername) +#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(ERRprinteralreadyexists) +#define WERR_INVALID_PRINTER_COMMAND W_ERROR(ERRinvalidprintercommand) +#define WERR_INVALID_DATATYPE W_ERROR(ERRinvaliddatatype) +#define WERR_INVALID_ENVIRONMENT W_ERROR(ERRinvalidenvironment) + +#define WERR_UNKNOWN_PRINT_MONITOR W_ERROR(ERRunknownprintmonitor) +#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(ERRprinterdriverinuse) +#define WERR_SPOOL_FILE_NOT_FOUND W_ERROR(ERRspoolfilenotfound) +#define WERR_SPL_NO_STARTDOC W_ERROR(ERRnostartdoc) +#define WERR_SPL_NO_ADDJOB W_ERROR(ERRnoaddjob) +#define WERR_PRINT_PROCESSOR_ALREADY_INSTALLED W_ERROR(ERRprintprocessoralreadyinstalled) +#define WERR_PRINT_MONITOR_ALREADY_INSTALLED W_ERROR(ERRprintmonitoralreadyinstalled) +#define WERR_INVALID_PRINT_MONITOR W_ERROR(ERRinvalidprintmonitor) +#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse) +#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued) + +#define WERR_CLASS_NOT_REGISTERED W_ERROR(0x40154) +#define WERR_NO_SHUTDOWN_IN_PROGRESS W_ERROR(0x45c) +#define WERR_SHUTDOWN_ALREADY_IN_PROGRESS W_ERROR(0x45b) + +#define WERR_NET_NAME_NOT_FOUND W_ERROR(NERR_BASE+210) +#define WERR_DEVICE_NOT_SHARED W_ERROR(NERR_BASE+211) + +/* DFS errors */ +#define WERR_DFS_NO_SUCH_VOL W_ERROR(NERR_BASE+562) +#define WERR_DFS_NO_SUCH_SHARE W_ERROR(NERR_BASE+565) +#define WERR_DFS_NO_SUCH_SERVER W_ERROR(NERR_BASE+573) +#define WERR_DFS_INTERNAL_ERROR W_ERROR(NERR_BASE+590) +#define WERR_DFS_CANT_CREATE_JUNCT W_ERROR(NERR_BASE+569) + +/* DS errors */ +#define WERR_DS_SERVICE_BUSY W_ERROR(0x0000200e) +#define WERR_DS_SERVICE_UNAVAILABLE W_ERROR(0x0000200f) +#define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030) +#define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208d) +#define WERR_DS_SCHEMA_NOT_LOADED W_ERROR(0x20de) +#define WERR_DS_SCHEMA_ALLOC_FAILED W_ERROR(0x20df) +#define WERR_DS_ATT_SCHEMA_REQ_SYNTAX W_ERROR(0x000020e0) +#define WERR_DS_DRA_SCHEMA_MISMATCH W_ERROR(0x000020e2) +#define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020f5) +#define WERR_DS_DRA_BAD_DN W_ERROR(0x000020f7) +#define WERR_DS_DRA_BAD_NC W_ERROR(0x000020f8) +#define WERR_DS_DRA_INTERNAL_ERROR W_ERROR(0x000020fa) +#define WERR_DS_DRA_OUT_OF_MEM W_ERROR(0x000020fe) +#define WERR_DS_SINGLE_VALUE_CONSTRAINT W_ERROR(0x00002081) +#define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) +#define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) +#define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105) +#define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) +#define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) +#define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194) +#define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) + +/* SEC errors */ +#define WERR_SEC_E_ENCRYPT_FAILURE W_ERROR(0x80090329) +#define WERR_SEC_E_DECRYPT_FAILURE W_ERROR(0x80090330) +#define WERR_SEC_E_ALGORITHM_MISMATCH W_ERROR(0x80090331) + +#define WERR_FOOBAR WERR_GENERAL_FAILURE + +/***************************************************************************** + returns a windows error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +const char *win_errstr(WERROR werror); + + + +#endif -- cgit From 385622396d4bf30b3775d24a7da7ee0c08f07ddd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Sep 2007 13:22:30 +0000 Subject: r25305: Fix installation of missing headers. (This used to be commit 83f1721453c253bff77f9d7ececd462331dd846b) --- source4/libcli/config.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 89e6f3ce1c..3ed35ae627 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,10 +3,10 @@ include ldap/config.mk include security/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] -PUBLIC_HEADERS = util/error.h util/nterr.h util/doserr.h util/nt_status.h +PUBLIC_HEADERS = util/error.h util/ntstatus.h util/doserr.h util/werror.h OBJ_FILES = util/doserr.o \ - util/errormap.o \ - util/nterr.o \ + util/errormap.o \ + util/nterr.o \ [SUBSYSTEM::ASN1_UTIL] PUBLIC_PROTO_HEADER = util/asn1_proto.h -- cgit From 8dc845d42581e6dabc00abdf8f82025a5f44fdcd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 26 Sep 2007 01:26:36 +0000 Subject: r25329: A solution to SWIG not being able to handle a structure and a function having the same name. Hey we can now query nbt names from Python. (This used to be commit 30c34d7a4b12c626bc98e29aa6691ad975845777) --- source4/libcli/swig/libcli_nbt.i | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index 6bcbd7a65b..9aa81acd1f 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -37,10 +37,6 @@ #undef strcpy -/* Loadparm parameters */ - -static struct loadparm_context lp_ctx; - %} %apply bool { BOOL }; @@ -132,11 +128,17 @@ struct nbt_name_query { %include "carrays.i" %array_functions(char *, char_ptr_array); -%rename(do_nbt_name_query) nbt_name_query; +NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); +%{ +NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io) +{ + return nbt_name_query(nbtsock, mem_ctx, io); +} +%} %init %{ - loadparm_init(&lp_ctx); + lp_load(); %} -- cgit From 708729be9f837b95a8e35811282893c428abb450 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 26 Sep 2007 03:08:40 +0000 Subject: r25348: Start working on another Python wrapper. (This used to be commit 441a0404346ce2ff72e8262c5bf6ef94d3b9f331) --- source4/libcli/config.mk | 5 +++++ source4/libcli/swig/libcli_smb.i | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 source4/libcli/swig/libcli_smb.i (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 3ed35ae627..9f052a0065 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -59,6 +59,11 @@ LIBRARY_REALNAME = swig/_libcli_nbt.$(SHLIBEXT) OBJ_FILES = swig/libcli_nbt_wrap.o PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-CONFIG +[LIBRARY::swig_libcli_smb] +LIBRARY_REALNAME = swig/_libcli_smb.$(SHLIBEXT) +OBJ_FILES = swig/libcli_smb_wrap.o +PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-CONFIG + [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ dgram/dgramsocket.o \ diff --git a/source4/libcli/swig/libcli_smb.i b/source4/libcli/swig/libcli_smb.i new file mode 100644 index 0000000000..8eb055c2f0 --- /dev/null +++ b/source4/libcli/swig/libcli_smb.i @@ -0,0 +1,18 @@ +%module libcli_smb + +%{ +#include "includes.h" +#include "lib/talloc/talloc.h" +#include "lib/events/events.h" +#include "libcli/raw/libcliraw.h" +%} + +TALLOC_CTX *talloc_init(char *name); +int talloc_free(TALLOC_CTX *ptr); +struct event_context *event_context_init(TALLOC_CTX *mem_ctx); + +struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, + TALLOC_CTX *mem_ctx, + struct event_context *event_ctx); + +void smbcli_sock_dead(struct smbcli_socket *sock); -- cgit From ca49e5aabfc606aaf70bca30c9a4a965ff248b22 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Sep 2007 16:52:50 +0000 Subject: r25351: disable swig for now to get the build working (This used to be commit 846184f15ca0dbe51e6a73941a0f32e1ec1d1f0b) --- source4/libcli/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 9f052a0065..d6be5d3af8 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -58,6 +58,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ LIBRARY_REALNAME = swig/_libcli_nbt.$(SHLIBEXT) OBJ_FILES = swig/libcli_nbt_wrap.o PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-CONFIG +ENABLE = NO [LIBRARY::swig_libcli_smb] LIBRARY_REALNAME = swig/_libcli_smb.$(SHLIBEXT) -- cgit From 7db71eac7a7b5a46b181130ea6a35fde3e7b9ef5 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 26 Sep 2007 17:39:39 +0000 Subject: r25353: Disable one more swig link to for 'make install' to work. rafal (This used to be commit bcf4e605773d4c1f204a5b678e1ec14ced4be3a4) --- source4/libcli/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index d6be5d3af8..d7aaac0447 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -64,6 +64,7 @@ ENABLE = NO LIBRARY_REALNAME = swig/_libcli_smb.$(SHLIBEXT) OBJ_FILES = swig/libcli_smb_wrap.o PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-CONFIG +ENABLE = NO [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/libcli/cldap/cldap.c | 2 +- source4/libcli/cliconnect.c | 4 ++-- source4/libcli/dgram/browse.c | 2 +- source4/libcli/dgram/mailslot.c | 2 +- source4/libcli/dgram/netlogon.c | 2 +- source4/libcli/dgram/ntlogon.c | 2 +- source4/libcli/finddcs.c | 4 ++-- source4/libcli/nbt/namequery.c | 4 ++-- source4/libcli/nbt/namerefresh.c | 2 +- source4/libcli/nbt/nameregister.c | 2 +- source4/libcli/nbt/namerelease.c | 2 +- source4/libcli/raw/clisocket.c | 4 ++-- source4/libcli/raw/clitransport.c | 7 ++++--- source4/libcli/raw/clitree.c | 2 +- source4/libcli/raw/rawnegotiate.c | 6 +++--- source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/resolve/resolve.c | 2 +- source4/libcli/resolve/wins.c | 2 +- source4/libcli/smb2/connect.c | 2 +- source4/libcli/smb_composite/connect.c | 6 +++--- source4/libcli/smb_composite/sesssetup.c | 16 ++++++++-------- source4/libcli/util/errormap.c | 2 +- 22 files changed, 40 insertions(+), 39 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 9381e80934..8ef511ed79 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -317,7 +317,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->dest = socket_address_from_strings(req, cldap->sock->backend_name, io->in.dest_address, - lp_cldap_port()); + lp_cldap_port(global_loadparm)); if (!req->dest) goto failed; req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index a91157cf5d..715eb875fe 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -57,7 +57,7 @@ BOOL smbcli_transport_establish(struct smbcli_state *cli, /* wrapper around smb_raw_negotiate() */ NTSTATUS smbcli_negprot(struct smbcli_state *cli) { - return smb_raw_negotiate(cli->transport, lp_cli_maxprotocol()); + return smb_raw_negotiate(cli->transport, lp_cli_maxprotocol(global_loadparm)); } /* wrapper around smb_raw_sesssetup() */ @@ -73,7 +73,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.credentials = credentials; - setup.in.workgroup = lp_workgroup(); + setup.in.workgroup = lp_workgroup(global_loadparm); status = smb_composite_sesssetup(cli->session, &setup); diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 78bd4319ee..fc1162e644 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -70,7 +70,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, return status; } - make_nbt_name_client(&myname, lp_netbios_name()); + make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, request->src_addr, request->src_port); diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 7a325ebe38..4e94e5ee5b 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -165,7 +165,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, if (_dest->port == 0) { dest = socket_address_from_strings(tmp_ctx, _dest->family, - _dest->addr, lp_dgram_port()); + _dest->addr, lp_dgram_port(global_loadparm)); } else { dest = _dest; } diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 79acf609f6..46f6e50e7b 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -77,7 +77,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, return status; } - make_nbt_name_client(&myname, lp_netbios_name()); + make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, request->src_addr, request->src_port); diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 6b9b17485d..25f767688a 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -78,7 +78,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, return status; } - make_nbt_name_client(&myname, lp_netbios_name()); + make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index edd9a92693..2ac1358197 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -145,9 +145,9 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->r.in.domainname = state->domain_name; state->r.in.ip_address = state->dcs[0].address; - state->r.in.my_computername = lp_netbios_name(); + state->r.in.my_computername = lp_netbios_name(global_loadparm); state->r.in.my_accountname = talloc_asprintf(state, "%s$", - lp_netbios_name()); + lp_netbios_name(global_loadparm)); if (composite_nomem(state->r.in.my_accountname, state->ctx)) return; state->r.in.account_control = ACB_WSTRUST; state->r.in.domain_sid = state->domain_sid; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index ab26a7b2d2..a55d743efb 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -54,7 +54,7 @@ _PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nb packet->questions[0].question_class = NBT_QCLASS_IP; dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port()); + io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); @@ -158,7 +158,7 @@ _PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *n packet->questions[0].question_class = NBT_QCLASS_IP; dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port()); + io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index d68cdb5365..3114cb2b10 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -69,7 +69,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, dest = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port()); + io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 62c4a19b29..b8fe362694 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -77,7 +77,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port()); + io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index efc31b1501..a72a5c706f 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -67,7 +67,7 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, talloc_strdup(packet->additional, io->in.address); dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port()); + io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 51f631eb67..a748b40a32 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -73,7 +73,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, if (state->host_name == NULL) goto failed; if (port == 0) { - const char **ports = lp_smb_ports(); + const char **ports = lp_smb_ports(global_loadparm); int i; for (i=0;ports[i];i++) /* noop */ ; @@ -120,7 +120,7 @@ static void smbcli_sock_connect_recv_conn(struct composite_context *ctx) if (!composite_is_ok(state->ctx)) return; state->ctx->status = - socket_set_option(sock, lp_socket_options(), NULL); + socket_set_option(sock, lp_socket_options(global_loadparm), NULL); if (!composite_is_ok(state->ctx)) return; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 90f51b2969..6b2c4c37fe 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -85,9 +85,10 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->socket = talloc_reference(transport, sock); } transport->negotiate.protocol = PROTOCOL_NT1; - transport->options.use_spnego = lp_use_spnego() && lp_nt_status_support(); - transport->options.max_xmit = lp_max_xmit(); - transport->options.max_mux = lp_maxmux(); + transport->options.use_spnego = lp_use_spnego(global_loadparm) && + lp_nt_status_support(global_loadparm); + transport->options.max_xmit = lp_max_xmit(global_loadparm); + transport->options.max_mux = lp_maxmux(global_loadparm); transport->options.request_timeout = SMB_REQUEST_TIMEOUT; transport->negotiate.max_xmit = transport->options.max_xmit; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 6a15c25eb9..4ff11f3a69 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -190,7 +190,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service_type = service_type; io.in.credentials = credentials; io.in.fallback_to_anonymous = False; - io.in.workgroup = lp_workgroup(); + io.in.workgroup = lp_workgroup(global_loadparm); status = smb_composite_connect(&io, parent_ctx, ev); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index eff22ee8bc..c58ac1f0df 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -58,7 +58,7 @@ struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport } flags2 |= FLAGS2_32_BIT_ERROR_CODES; - if (lp_unicode()) { + if (lp_unicode(global_loadparm)) { flags2 |= FLAGS2_UNICODE_STRINGS; } flags2 |= FLAGS2_EXTENDED_ATTRIBUTES; @@ -174,11 +174,11 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) } /* a way to force ascii SMB */ - if (!lp_unicode()) { + if (!lp_unicode(global_loadparm)) { transport->negotiate.capabilities &= ~CAP_UNICODE; } - if (!lp_nt_status_support()) { + if (!lp_nt_status_support(global_loadparm)) { transport->negotiate.capabilities &= ~CAP_STATUS32; } diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 1a82ea0536..59c13bbeb6 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -383,7 +383,7 @@ bool smbcli_init_signing(struct smbcli_transport *transport) return False; } - switch (lp_client_signing()) { + switch (lp_client_signing(global_loadparm)) { case SMB_SIGNING_OFF: transport->negotiate.sign_info.allow_smb_signing = False; break; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 9315c0f354..02e1fbdc04 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -190,7 +190,7 @@ NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **r struct event_context *ev) { struct composite_context *c = resolve_name_send(name, ev, - lp_name_resolve_order()); + lp_name_resolve_order(global_loadparm)); return resolve_name_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 8c88950f53..05a2d4da31 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -32,7 +32,7 @@ struct composite_context *resolve_name_wins_send( struct event_context *event_ctx, struct nbt_name *name) { - const char **address_list = lp_wins_server_list(); + const char **address_list = lp_wins_server_list(global_loadparm); if (address_list == NULL) return NULL; return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, False, True); } diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 0edf64c5df..6a2e9d09e9 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -187,7 +187,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, ZERO_STRUCT(name); name.name = host; - creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); + creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order(global_loadparm)); composite_continue(c, creq, continue_resolve, c); return c; } diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 27b16ecc41..22b2cdb0e2 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -63,7 +63,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - state->req = smb_raw_negotiate_send(state->transport, lp_cli_maxprotocol()); + state->req = smb_raw_negotiate_send(state->transport, lp_cli_maxprotocol(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(state->req); state->req->async.fn = request_handler; @@ -172,7 +172,7 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->io_setup->in.credentials = cli_credentials_init(state); NT_STATUS_HAVE_NO_MEMORY(state->io_setup->in.credentials); - cli_credentials_set_conf(state->io_setup->in.credentials); + cli_credentials_set_conf(state->io_setup->in.credentials, global_loadparm); cli_credentials_set_anonymous(state->io_setup->in.credentials); /* If the preceding attempt was with extended security, we @@ -459,7 +459,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec state->stage = CONNECT_RESOLVE; make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order()); + state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order(global_loadparm)); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 6a14e57ad0..6f9e6b0de3 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -223,14 +223,14 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup()); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = CLI_CRED_NTLM_AUTH; - if (lp_client_lanman_auth()) { + if (lp_client_lanman_auth(global_loadparm)) { flags |= CLI_CRED_LANMAN_AUTH; } - if (lp_client_ntlmv2_auth()) { + if (lp_client_ntlmv2_auth(global_loadparm)) { flags |= CLI_CRED_NTLMv2_AUTH; } @@ -263,7 +263,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, set_user_session_key(session, &session_key); data_blob_free(&session_key); - } else if (lp_client_plaintext_auth()) { + } else if (lp_client_plaintext_auth(global_loadparm)) { state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); } else { @@ -290,14 +290,14 @@ static NTSTATUS session_setup_old(struct composite_context *c, NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup()); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = 0; - if (lp_client_lanman_auth()) { + if (lp_client_lanman_auth(global_loadparm)) { flags |= CLI_CRED_LANMAN_AUTH; } - if (lp_client_ntlmv2_auth()) { + if (lp_client_ntlmv2_auth(global_loadparm)) { flags |= CLI_CRED_NTLMv2_AUTH; } @@ -324,7 +324,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, set_user_session_key(session, &session_key); data_blob_free(&session_key); - } else if (lp_client_plaintext_auth()) { + } else if (lp_client_plaintext_auth(global_loadparm)) { state->setup.old.in.password = data_blob_talloc(state, password, strlen(password)); } else { /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 347d513e9c..49384817b6 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1168,7 +1168,7 @@ BOOL ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2) the mapping of dos codes, as we want to catch the cases where a forced dos code is needed */ - if (lp_nt_status_support()) { + if (lp_nt_status_support(global_loadparm)) { return NT_STATUS_V(status1) == NT_STATUS_V(status2); } -- cgit From 60a1046c5c5783799bd64fe18e03534670f83d82 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Sep 2007 18:00:19 +0000 Subject: r25430: Add the loadparm context to all parametric options. (This used to be commit fd697d77c9fe67a00939a1f04b35c451316fff58) --- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/resolve/nbtlist.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 453f0afcff..174b08ddf6 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -244,7 +244,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req->received_wack = True; /* although there can be a timeout in the packet, w2k3 screws it up, so better to set it ourselves */ - req->timeout = lp_parm_int(NULL, "nbt", "wack_timeout", 30); + req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30); req->te = event_add_timed(req->nbtsock->event_ctx, req, timeval_current_ofs(req->timeout, 0), nbt_name_socket_timeout, req); diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index be4d01b79a..9720434cb9 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -155,7 +155,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, state->io_queries[i].in.broadcast = broadcast; state->io_queries[i].in.wins_lookup = wins_lookup; - state->io_queries[i].in.timeout = lp_parm_int(NULL, "nbt", "timeout", 1); + state->io_queries[i].in.timeout = lp_parm_int(global_loadparm, NULL, "nbt", "timeout", 1); state->io_queries[i].in.retries = 2; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); -- cgit From 2f3551ca7cee59d4d053cceb87abdf1da1b3a1ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Oct 2007 18:52:55 +0000 Subject: r25446: Merge some changes I made on the way home from SFO: 2007-09-29 More higher-level passing around of lp_ctx. 2007-09-29 Fix warning. 2007-09-29 Pass loadparm contexts on a higher level. 2007-09-29 Avoid using global loadparm context. (This used to be commit 3468952e771ab31f90b6c374ade01c5550810f42) --- source4/libcli/cliconnect.c | 3 ++- source4/libcli/finddcs.c | 2 +- source4/libcli/smb2/connect.c | 3 ++- source4/libcli/smb_composite/connect.c | 9 ++++++--- source4/libcli/smb_composite/sesssetup.c | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 715eb875fe..96946da7fe 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -57,7 +57,8 @@ BOOL smbcli_transport_establish(struct smbcli_state *cli, /* wrapper around smb_raw_negotiate() */ NTSTATUS smbcli_negprot(struct smbcli_state *cli) { - return smb_raw_negotiate(cli->transport, lp_cli_maxprotocol(global_loadparm)); + return smb_raw_negotiate(cli->transport, + lp_cli_maxprotocol(global_loadparm)); } /* wrapper around smb_raw_sesssetup() */ diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 2ac1358197..e00697fe17 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -147,7 +147,7 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->r.in.ip_address = state->dcs[0].address; state->r.in.my_computername = lp_netbios_name(global_loadparm); state->r.in.my_accountname = talloc_asprintf(state, "%s$", - lp_netbios_name(global_loadparm)); + lp_netbios_name(global_loadparm)); if (composite_nomem(state->r.in.my_accountname, state->ctx)) return; state->r.in.account_control = ACB_WSTRUST; state->r.in.domain_sid = state->domain_sid; diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 6a2e9d09e9..bb70311c56 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -187,7 +187,8 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, ZERO_STRUCT(name); name.name = host; - creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order(global_loadparm)); + creq = resolve_name_send(&name, c->event_ctx, + lp_name_resolve_order(global_loadparm)); composite_continue(c, creq, continue_resolve, c); return c; } diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 22b2cdb0e2..23974619d6 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -63,7 +63,8 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - state->req = smb_raw_negotiate_send(state->transport, lp_cli_maxprotocol(global_loadparm)); + state->req = smb_raw_negotiate_send(state->transport, + lp_cli_maxprotocol(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(state->req); state->req->async.fn = request_handler; @@ -172,7 +173,8 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->io_setup->in.credentials = cli_credentials_init(state); NT_STATUS_HAVE_NO_MEMORY(state->io_setup->in.credentials); - cli_credentials_set_conf(state->io_setup->in.credentials, global_loadparm); + cli_credentials_set_conf(state->io_setup->in.credentials, + global_loadparm); cli_credentials_set_anonymous(state->io_setup->in.credentials); /* If the preceding attempt was with extended security, we @@ -459,7 +461,8 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec state->stage = CONNECT_RESOLVE; make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order(global_loadparm)); + state->creq = resolve_name_send(&name, c->event_ctx, + lp_name_resolve_order(global_loadparm)); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 6f9e6b0de3..622367e746 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -418,7 +418,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, } } - if (chosen_oid == GENSEC_OID_SPNEGO) { + if ((const void *)chosen_oid == (const void *)GENSEC_OID_SPNEGO) { status = gensec_update(session->gensec, state, session->transport->negotiate.secblob, &state->setup.spnego.in.secblob); -- cgit From a8f264eb2f5b3310d721e79f9ca7e8c47064267e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Oct 2007 19:30:27 +0000 Subject: r25448: Remove IMMEDIATE_STRUCTURES define, which was used for splint. Newer versions of splint support immediate structures just fine. (This used to be commit d54a47ecdc418ee07c9479f519bd1a207e6ba3eb) --- source4/libcli/util/ntstatus.h | 6 ------ source4/libcli/util/werror.h | 8 +------- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/ntstatus.h b/source4/libcli/util/ntstatus.h index 026b5162db..84d924c2ec 100644 --- a/source4/libcli/util/ntstatus.h +++ b/source4/libcli/util/ntstatus.h @@ -29,15 +29,9 @@ from using bool for internal functions */ -#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} NTSTATUS; #define NT_STATUS(x) ((NTSTATUS) { x }) #define NT_STATUS_V(x) ((x).v) -#else -typedef uint32_t NTSTATUS; -#define NT_STATUS(x) (x) -#define NT_STATUS_V(x) (x) -#endif /* Win32 Status codes. */ diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 0f49514b9f..3cd76816dc 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -19,7 +19,7 @@ */ #ifndef _WERROR_H_ -#define _WERROR_H +#define _WERROR_H_ #include @@ -29,15 +29,9 @@ from using bool for internal functions */ -#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} WERROR; #define W_ERROR(x) ((WERROR) { x }) #define W_ERROR_V(x) ((x).v) -#else -typedef uint32_t WERROR; -#define W_ERROR(x) (x) -#define W_ERROR_V(x) (x) -#endif #define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) #define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) -- cgit From 3b07f6aeb1a060efcf8218e76b8b84fb8850f337 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 5 Oct 2007 12:05:40 +0000 Subject: r25515: Revert r25448: Immediate structures are *not* supportet by the native C compiler at least on Solaris, Tru64 and HP-UX. Michael (This used to be commit 6d07e29de2a7e535139622fa688b407da232c816) --- source4/libcli/util/ntstatus.h | 6 ++++++ source4/libcli/util/werror.h | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/ntstatus.h b/source4/libcli/util/ntstatus.h index 84d924c2ec..026b5162db 100644 --- a/source4/libcli/util/ntstatus.h +++ b/source4/libcli/util/ntstatus.h @@ -29,9 +29,15 @@ from using bool for internal functions */ +#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} NTSTATUS; #define NT_STATUS(x) ((NTSTATUS) { x }) #define NT_STATUS_V(x) ((x).v) +#else +typedef uint32_t NTSTATUS; +#define NT_STATUS(x) (x) +#define NT_STATUS_V(x) (x) +#endif /* Win32 Status codes. */ diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 3cd76816dc..0f49514b9f 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -19,7 +19,7 @@ */ #ifndef _WERROR_H_ -#define _WERROR_H_ +#define _WERROR_H #include @@ -29,9 +29,15 @@ from using bool for internal functions */ +#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32_t v;} WERROR; #define W_ERROR(x) ((WERROR) { x }) #define W_ERROR_V(x) ((x).v) +#else +typedef uint32_t WERROR; +#define W_ERROR(x) (x) +#define W_ERROR_V(x) (x) +#endif #define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) #define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) -- cgit From 20480a795306d1634db5c3cd5ce0ae6c8a13ba47 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 5 Oct 2007 12:41:22 +0000 Subject: r25516: Sorry, I reverted too much of r25448 in r25515. These two fixes should have remained! Thanks to Metze for pointing this out. Michael (This used to be commit 294b2bf593445a79c500f02569f10ff72e1d6933) --- source4/libcli/util/werror.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 0f49514b9f..55a4faa6a5 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -19,7 +19,7 @@ */ #ifndef _WERROR_H_ -#define _WERROR_H +#define _WERROR_H_ #include -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libcli/auth/credentials.c | 12 +- source4/libcli/auth/session.c | 10 +- source4/libcli/auth/smbencrypt.c | 56 +-- source4/libcli/cldap/cldap.c | 6 +- source4/libcli/cliconnect.c | 22 +- source4/libcli/clideltree.c | 8 +- source4/libcli/clifile.c | 9 +- source4/libcli/clilist.c | 32 +- source4/libcli/climessage.c | 18 +- source4/libcli/clireadwrite.c | 2 +- source4/libcli/composite/composite.c | 14 +- source4/libcli/ldap/ldap.c | 30 +- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/ldap/ldap_client.c | 6 +- source4/libcli/ldap/ldap_controls.c | 530 +++++++++++++------------- source4/libcli/ldap/ldap_ildap.c | 6 +- source4/libcli/ldap/ldap_msg.c | 18 +- source4/libcli/nbt/namequery.c | 4 +- source4/libcli/nbt/namerefresh.c | 4 +- source4/libcli/nbt/nameregister.c | 18 +- source4/libcli/nbt/namerelease.c | 2 +- source4/libcli/nbt/nbtname.c | 2 +- source4/libcli/nbt/nbtsocket.c | 8 +- source4/libcli/raw/clioplock.c | 6 +- source4/libcli/raw/clisession.c | 2 +- source4/libcli/raw/clitransport.c | 17 +- source4/libcli/raw/clitree.c | 4 +- source4/libcli/raw/raweas.c | 6 +- source4/libcli/raw/rawfile.c | 4 +- source4/libcli/raw/rawnegotiate.c | 4 +- source4/libcli/raw/rawreadwrite.c | 10 +- source4/libcli/raw/rawrequest.c | 38 +- source4/libcli/raw/rawsetfileinfo.c | 40 +- source4/libcli/raw/rawshadow.c | 2 +- source4/libcli/raw/rawtrans.c | 8 +- source4/libcli/raw/smb_signing.c | 88 ++--- source4/libcli/resolve/bcast.c | 2 +- source4/libcli/resolve/nbtlist.c | 6 +- source4/libcli/resolve/wins.c | 2 +- source4/libcli/security/dom_sid.c | 10 +- source4/libcli/security/privilege.c | 10 +- source4/libcli/security/sddl.c | 36 +- source4/libcli/security/security_descriptor.c | 72 ++-- source4/libcli/security/security_token.c | 32 +- source4/libcli/smb2/cancel.c | 2 +- source4/libcli/smb2/close.c | 4 +- source4/libcli/smb2/connect.c | 4 +- source4/libcli/smb2/create.c | 10 +- source4/libcli/smb2/find.c | 4 +- source4/libcli/smb2/flush.c | 4 +- source4/libcli/smb2/getinfo.c | 4 +- source4/libcli/smb2/ioctl.c | 4 +- source4/libcli/smb2/keepalive.c | 4 +- source4/libcli/smb2/lock.c | 4 +- source4/libcli/smb2/logoff.c | 4 +- source4/libcli/smb2/negprot.c | 4 +- source4/libcli/smb2/notify.c | 4 +- source4/libcli/smb2/read.c | 4 +- source4/libcli/smb2/request.c | 20 +- source4/libcli/smb2/session.c | 6 +- source4/libcli/smb2/setinfo.c | 4 +- source4/libcli/smb2/tcon.c | 6 +- source4/libcli/smb2/tdis.c | 4 +- source4/libcli/smb2/transport.c | 2 +- source4/libcli/smb2/write.c | 4 +- source4/libcli/smb_composite/connect.c | 10 +- source4/libcli/smb_composite/fetchfile.c | 2 +- source4/libcli/smb_composite/fsinfo.c | 2 +- source4/libcli/smb_composite/loadfile.c | 2 +- source4/libcli/util/asn1.c | 294 +++++++------- source4/libcli/util/clilsa.c | 2 +- source4/libcli/util/errormap.c | 2 +- source4/libcli/wrepl/winsrepl.c | 18 +- source4/libcli/wrepl/winsrepl.h | 2 +- 74 files changed, 830 insertions(+), 828 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index feb8c92a0b..a6cb17c12e 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -235,15 +235,15 @@ void creds_client_authenticator(struct creds_CredentialState *creds, /* check that a credentials reply from a server is correct */ -BOOL creds_client_check(struct creds_CredentialState *creds, +bool creds_client_check(struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { if (!received_credentials || memcmp(received_credentials->data, creds->server.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); - return False; + return false; } - return True; + return true; } @@ -278,16 +278,16 @@ void creds_server_init(struct creds_CredentialState *creds, /* check that a credentials reply from a server is correct */ -BOOL creds_server_check(const struct creds_CredentialState *creds, +bool creds_server_check(const struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { if (memcmp(received_credentials->data, creds->client.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); dump_data_pw("client creds", creds->client.data, 8); dump_data_pw("calc creds", received_credentials->data, 8); - return False; + return false; } - return True; + return true; } NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c index 7f44b6b5a9..29af7fafe8 100644 --- a/source4/libcli/auth/session.c +++ b/source4/libcli/auth/session.c @@ -30,7 +30,7 @@ as the in blob */ static void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, - BOOL forward) + bool forward) { int i, k; @@ -84,7 +84,7 @@ DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key) memset(src.data+8, 0, dlen); memcpy(src.data+8, str, slen); - sess_crypt_blob(&ret, &src, session_key, True); + sess_crypt_blob(&ret, &src, session_key, true); data_blob_free(&src); @@ -112,7 +112,7 @@ char *sess_decrypt_string(TALLOC_CTX *mem_ctx, return NULL; } - sess_crypt_blob(&out, blob, session_key, False); + sess_crypt_blob(&out, blob, session_key, false); if (IVAL(out.data, 4) != 1) { DEBUG(0,("Unexpected revision number %d in session crypted string\n", @@ -166,7 +166,7 @@ DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_ memset(src.data+8, 0, dlen); memcpy(src.data+8, blob_in->data, blob_in->length); - sess_crypt_blob(&ret, &src, session_key, True); + sess_crypt_blob(&ret, &src, session_key, true); data_blob_free(&src); @@ -193,7 +193,7 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT return NT_STATUS_NO_MEMORY; } - sess_crypt_blob(&out, blob, session_key, False); + sess_crypt_blob(&out, blob, session_key, false); if (IVAL(out.data, 4) != 1) { DEBUG(2,("Unexpected revision number %d in session crypted secret (BLOB)\n", diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 1f940fb79d..bfac395ef9 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -34,11 +34,11 @@ It takes a password ('unix' string), a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 - Returns False if password must have been truncated to create LM hash + Returns false if password must have been truncated to create LM hash */ -BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) +bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) { - BOOL ret; + bool ret; uint8_t p21[21]; memset(p21,'\0',21); @@ -62,7 +62,7 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -_PUBLIC_ BOOL E_md4hash(const char *passwd, uint8_t p16[16]) +_PUBLIC_ bool E_md4hash(const char *passwd, uint8_t p16[16]) { int len; void *wpwd; @@ -72,27 +72,27 @@ _PUBLIC_ BOOL E_md4hash(const char *passwd, uint8_t p16[16]) /* We don't want to return fixed data, as most callers * don't check */ mdfour(p16, (const uint8_t *)passwd, strlen(passwd)); - return False; + return false; } len -= 2; mdfour(p16, wpwd, len); talloc_free(wpwd); - return True; + return true; } /** * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. * @param p16 return password hashed with DES, caller allocated 16 byte buffer - * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True + * @return false if password was > 14 characters, and therefore may be incorrect, otherwise true * @note p16 is filled in regardless */ -_PUBLIC_ BOOL E_deshash(const char *passwd, uint8_t p16[16]) +_PUBLIC_ bool E_deshash(const char *passwd, uint8_t p16[16]) { - BOOL ret = True; + bool ret = true; fstring dospwd; ZERO_STRUCT(dospwd); @@ -103,7 +103,7 @@ _PUBLIC_ BOOL E_deshash(const char *passwd, uint8_t p16[16]) E_P16((const uint8_t *)dospwd, p16); if (strlen(dospwd) > 14) { - ret = False; + ret = false; } ZERO_STRUCT(dospwd); @@ -112,9 +112,9 @@ _PUBLIC_ BOOL E_deshash(const char *passwd, uint8_t p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -BOOL ntv2_owf_gen(const uint8_t owf[16], +bool ntv2_owf_gen(const uint8_t owf[16], const char *user_in, const char *domain_in, - BOOL upper_case_domain, /* Transform the domain into UPPER case */ + bool upper_case_domain, /* Transform the domain into UPPER case */ uint8_t kr_buf[16]) { void *user; @@ -125,7 +125,7 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], HMACMD5Context ctx; TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); if (!mem_ctx) { - return False; + return false; } if (!user_in) { @@ -139,14 +139,14 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], user_in = strupper_talloc(mem_ctx, user_in); if (user_in == NULL) { talloc_free(mem_ctx); - return False; + return false; } if (upper_case_domain) { domain_in = strupper_talloc(mem_ctx, domain_in); if (domain_in == NULL) { talloc_free(mem_ctx); - return False; + return false; } } @@ -154,14 +154,14 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], if (user_byte_len == (ssize_t)-1) { DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); - return False; + return false; } domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in); if (domain_byte_len == (ssize_t)-1) { DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); - return False; + return false; } SMB_ASSERT(user_byte_len >= 2); @@ -185,7 +185,7 @@ BOOL ntv2_owf_gen(const uint8_t owf[16], #endif talloc_free(mem_ctx); - return True; + return true; } /* Does the des encryption from the NT or LM MD4 hash. */ @@ -393,7 +393,7 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, return final_response; } -BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, +bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, @@ -406,8 +406,8 @@ BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, the username and domain. This prevents username swapping during the auth exchange */ - if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { - return False; + if (!ntv2_owf_gen(nt_hash, user, domain, true, ntlm_v2_hash)) { + return false; } if (nt_response) { @@ -437,10 +437,10 @@ BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, } } - return True; + return true; } -BOOL SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, +bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, const char *user, const char *domain, const char *password, const DATA_BLOB *server_chal, @@ -460,7 +460,7 @@ BOOL SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) +bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) { uint8_t new_pw[512]; size_t new_pw_len; @@ -482,7 +482,7 @@ BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag */ SIVAL(buffer, 512, new_pw_len); ZERO_STRUCT(new_pw); - return True; + return true; } @@ -491,7 +491,7 @@ BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ -BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, +bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32_t *new_pw_len, int string_flags) { @@ -517,7 +517,7 @@ BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, /* Password cannot be longer than the size of the password buffer */ if ( (byte_len < 0) || (byte_len > 512)) { - return False; + return false; } /* decode into the return buffer. Buffer length supplied */ @@ -531,5 +531,5 @@ BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, DEBUG(100,("original char len:%d\n", byte_len/2)); #endif - return True; + return true; } diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 8ef511ed79..f2f661acaa 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -309,7 +309,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->state = CLDAP_REQUEST_SEND; req->timeout = io->in.timeout; req->num_retries = io->in.retries; - req->is_reply = False; + req->is_reply = false; req->asn1 = asn1_init(req); if (!req->asn1) { goto failed; @@ -337,7 +337,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, search->deref = LDAP_DEREFERENCE_NEVER; search->timelimit = 0; search->sizelimit = 0; - search->attributesonly = False; + search->attributesonly = false; search->num_attributes = str_list_length(io->in.attributes); search->attributes = io->in.attributes; search->tree = ldb_parse_tree(req, io->in.filter); @@ -378,7 +378,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) req->cldap = cldap; req->state = CLDAP_REQUEST_SEND; - req->is_reply = True; + req->is_reply = true; req->asn1 = asn1_init(req); if (!req->asn1) { goto failed; diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 96946da7fe..a56100fc80 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -30,24 +30,24 @@ /* wrapper around smbcli_sock_connect() */ -BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server) +bool smbcli_socket_connect(struct smbcli_state *cli, const char *server) { struct smbcli_socket *sock; sock = smbcli_sock_connect_byname(server, 0, NULL, NULL); - if (sock == NULL) return False; + if (sock == NULL) return false; - cli->transport = smbcli_transport_init(sock, cli, True); + cli->transport = smbcli_transport_init(sock, cli, true); if (!cli->transport) { - return False; + return false; } - return True; + return true; } /* wrapper around smbcli_transport_connect() */ -BOOL smbcli_transport_establish(struct smbcli_state *cli, +bool smbcli_transport_establish(struct smbcli_state *cli, struct nbt_name *calling, struct nbt_name *called) { @@ -68,7 +68,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, struct smb_composite_sesssetup setup; NTSTATUS status; - cli->session = smbcli_session_init(cli->transport, cli, True); + cli->session = smbcli_session_init(cli->transport, cli, true); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; setup.in.sesskey = cli->transport->negotiate.sesskey; @@ -91,7 +91,7 @@ NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, TALLOC_CTX *mem_ctx; NTSTATUS status; - cli->tree = smbcli_tree_init(cli->session, cli, True); + cli->tree = smbcli_tree_init(cli->session, cli, true); if (!cli->tree) return NT_STATUS_UNSUCCESSFUL; mem_ctx = talloc_init("tcon"); @@ -216,7 +216,7 @@ bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, if (strncmp(unc_name, "\\\\", 2) && strncmp(unc_name, "//", 2)) { - return False; + return false; } *hostname = talloc_strdup(mem_ctx, &unc_name[2]); @@ -228,13 +228,13 @@ bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, } if (*hostname && *sharename) { - return True; + return true; } talloc_free(*hostname); talloc_free(*sharename); *hostname = *sharename = NULL; - return False; + return false; } diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index d191bd277a..2c306e501e 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -25,7 +25,7 @@ struct delete_state { struct smbcli_tree *tree; int total_deleted; - BOOL failed; + bool failed; }; /* @@ -61,14 +61,14 @@ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *s if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate->tree, s))) { DEBUG(2,("Failed to delete %s - %s\n", s, smbcli_errstr(dstate->tree))); - dstate->failed = True; + dstate->failed = true; } dstate->total_deleted++; } else { if (NT_STATUS_IS_ERR(smbcli_unlink(dstate->tree, s))) { DEBUG(2,("Failed to delete %s - %s\n", s, smbcli_errstr(dstate->tree))); - dstate->failed = True; + dstate->failed = true; } dstate->total_deleted++; } @@ -87,7 +87,7 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) dstate.tree = tree; dstate.total_deleted = 0; - dstate.failed = False; + dstate.failed = false; /* it might be a file */ if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index b30b82bd79..e59b7f9af3 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -30,7 +30,7 @@ static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, const char *fname_src, - const char *fname_dst, BOOL hard_link) + const char *fname_dst, bool hard_link) { union smb_setfileinfo parms; NTSTATUS status; @@ -84,7 +84,7 @@ uint32_t unix_perms_to_wire(mode_t perms) NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src, const char *fname_dst) { - return smbcli_link_internal(tree, fname_src, fname_dst, False); + return smbcli_link_internal(tree, fname_src, fname_dst, false); } /**************************************************************************** @@ -93,7 +93,7 @@ NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src, NTSTATUS smbcli_unix_hardlink(struct smbcli_tree *tree, const char *fname_src, const char *fname_dst) { - return smbcli_link_internal(tree, fname_src, fname_dst, True); + return smbcli_link_internal(tree, fname_src, fname_dst, true); } @@ -206,7 +206,8 @@ NTSTATUS smbcli_rmdir(struct smbcli_tree *tree, const char *dname) /**************************************************************************** Set or clear the delete on close flag. ****************************************************************************/ -NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum, BOOL flag) +NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum, + bool flag) { union smb_setfileinfo parms; NTSTATUS status; diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 14fd3ee4f7..07393a3491 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -37,7 +37,7 @@ struct search_private { /**************************************************************************** Interpret a long filename structure. ****************************************************************************/ -static BOOL interpret_long_filename(enum smb_search_data_level level, +static bool interpret_long_filename(enum smb_search_data_level level, const union smb_search_data *info, struct clilist_file_info *finfo) { @@ -65,14 +65,14 @@ static BOOL interpret_long_filename(enum smb_search_data_level level, default: DEBUG(0,("Unhandled level %d in interpret_long_filename\n", (int)level)); - return False; + return false; } - return True; + return true; } /* callback function used for trans2 search */ -static BOOL smbcli_list_new_callback(void *private, const union smb_search_data *file) +static bool smbcli_list_new_callback(void *private, const union smb_search_data *file) { struct search_private *state = (struct search_private*) private; struct clilist_file_info *tdl; @@ -83,7 +83,7 @@ static BOOL smbcli_list_new_callback(void *private, const union smb_search_data struct clilist_file_info, state->dirlist_len + 1); if (!tdl) { - return False; + return false; } state->dirlist = tdl; state->dirlist_len++; @@ -94,7 +94,7 @@ static BOOL smbcli_list_new_callback(void *private, const union smb_search_data state->total_received++; state->ff_searchcount++; - return True; + return true; } int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, @@ -106,7 +106,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu union smb_search_next next_parms; struct search_private state; /* for callbacks */ int received = 0; - BOOL first = True; + bool first = true; int num_received = 0; int max_matches = 512; char *mask; @@ -159,7 +159,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu received = first_parms.t2ffirst.out.count; if (received <= 0) break; if (ff_eos) break; - first = False; + first = false; } else { NTSTATUS status; @@ -203,7 +203,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu Interpret a short filename structure. The length of the structure is returned. ****************************************************************************/ -static BOOL interpret_short_filename(enum smb_search_data_level level, +static bool interpret_short_filename(enum smb_search_data_level level, const union smb_search_data *info, struct clilist_file_info *finfo) { @@ -223,14 +223,14 @@ static BOOL interpret_short_filename(enum smb_search_data_level level, default: DEBUG(0,("Unhandled level %d in interpret_short_filename\n", (int)level)); - return False; + return false; } - return True; + return true; } /* callback function used for smb_search */ -static BOOL smbcli_list_old_callback(void *private, const union smb_search_data *file) +static bool smbcli_list_old_callback(void *private, const union smb_search_data *file) { struct search_private *state = (struct search_private*) private; struct clilist_file_info *tdl; @@ -242,7 +242,7 @@ static BOOL smbcli_list_old_callback(void *private, const union smb_search_data state->dirlist_len + 1); if (!tdl) { - return False; + return false; } state->dirlist = tdl; state->dirlist_len++; @@ -253,7 +253,7 @@ static BOOL smbcli_list_old_callback(void *private, const union smb_search_data state->ff_searchcount++; state->id = file->search.id; /* return resume info */ - return True; + return true; } int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, @@ -265,7 +265,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu struct search_private state; /* for callbacks */ const int num_asked = 500; int received = 0; - BOOL first = True; + bool first = true; int num_received = 0; char *mask; int i; @@ -303,7 +303,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu received = first_parms.search_first.out.count; if (received <= 0) break; - first = False; + first = false; } else { NTSTATUS status; diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 35607ba45b..6002ccfc59 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -26,7 +26,7 @@ /**************************************************************************** start a message sequence ****************************************************************************/ -BOOL smbcli_message_start(struct smbcli_tree *tree, const char *host, const char *username, +bool smbcli_message_start(struct smbcli_tree *tree, const char *host, const char *username, int *grp) { struct smbcli_request *req; @@ -38,20 +38,20 @@ BOOL smbcli_message_start(struct smbcli_tree *tree, const char *host, const char !smbcli_request_receive(req) || smbcli_is_error(tree)) { smbcli_request_destroy(req); - return False; + return false; } *grp = SVAL(req->in.vwv, VWV(0)); smbcli_request_destroy(req); - return True; + return true; } /**************************************************************************** send a message ****************************************************************************/ -BOOL smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp) +bool smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp) { struct smbcli_request *req; @@ -64,17 +64,17 @@ BOOL smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp) !smbcli_request_receive(req) || smbcli_is_error(tree)) { smbcli_request_destroy(req); - return False; + return false; } smbcli_request_destroy(req); - return True; + return true; } /**************************************************************************** end a message ****************************************************************************/ -BOOL smbcli_message_end(struct smbcli_tree *tree, int grp) +bool smbcli_message_end(struct smbcli_tree *tree, int grp) { struct smbcli_request *req; @@ -85,10 +85,10 @@ BOOL smbcli_message_end(struct smbcli_tree *tree, int grp) !smbcli_request_receive(req) || smbcli_is_error(tree)) { smbcli_request_destroy(req); - return False; + return false; } smbcli_request_destroy(req); - return True; + return true; } diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index 89ae157042..f5ba799bbc 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -56,7 +56,7 @@ ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset parms.readx.in.mincnt = readsize; parms.readx.in.maxcnt = readsize; parms.readx.in.remaining = size - total; - parms.readx.in.read_for_execute = False; + parms.readx.in.read_for_execute = false; parms.readx.out.data = buf + total; status = smb_raw_read(tree, &parms); diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 3e21c3823c..67d5885497 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -53,7 +53,7 @@ _PUBLIC_ NTSTATUS composite_wait(struct composite_context *c) { if (c == NULL) return NT_STATUS_NO_MEMORY; - c->used_wait = True; + c->used_wait = true; while (c->state < COMPOSITE_STATE_DONE) { if (event_loop_once(c->event_ctx) != 0) { @@ -69,16 +69,16 @@ _PUBLIC_ NTSTATUS composite_wait(struct composite_context *c) * Some composite helpers that are handy if you write larger composite * functions. */ -_PUBLIC_ BOOL composite_is_ok(struct composite_context *ctx) +_PUBLIC_ bool composite_is_ok(struct composite_context *ctx) { if (NT_STATUS_IS_OK(ctx->status)) { - return True; + return true; } ctx->state = COMPOSITE_STATE_ERROR; if (ctx->async.fn != NULL) { ctx->async.fn(ctx); } - return False; + return false; } /* @@ -113,13 +113,13 @@ _PUBLIC_ void composite_error(struct composite_context *ctx, NTSTATUS status) SMB_ASSERT(!composite_is_ok(ctx)); } -_PUBLIC_ BOOL composite_nomem(const void *p, struct composite_context *ctx) +_PUBLIC_ bool composite_nomem(const void *p, struct composite_context *ctx) { if (p != NULL) { - return False; + return false; } composite_error(ctx, NT_STATUS_NO_MEMORY); - return True; + return true; } _PUBLIC_ void composite_done(struct composite_context *ctx) diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 06ff000acf..11689fbd79 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -27,7 +27,7 @@ #include "libcli/ldap/ldap.h" -static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { int i; @@ -37,7 +37,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); for (i=0; iu.list.num_elements; i++) { if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return False; + return false; } } asn1_pop_tag(data); @@ -46,7 +46,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree case LDB_OP_NOT: asn1_push_tag(data, ASN1_CONTEXT(2)); if (!ldap_push_filter(data, tree->u.isnot.child)) { - return False; + return false; } asn1_pop_tag(data); break; @@ -166,7 +166,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree break; default: - return False; + return false; } return !data->has_error; } @@ -187,12 +187,12 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data *data = asn1_init(mem_ctx); int i, j; - if (!data) return False; + if (!data) return false; asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_Integer(data, msg->messageid); @@ -225,7 +225,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_pop_tag(data); break; default: - return False; + return false; } asn1_pop_tag(data); @@ -256,7 +256,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_write_BOOLEAN(data, r->attributesonly); if (!ldap_push_filter(data, r->tree)) { - return False; + return false; } asn1_push_tag(data, ASN1_SEQUENCE(0)); @@ -467,7 +467,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct break; } default: - return False; + return false; } if (msg->controls != NULL) { @@ -475,7 +475,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct for (i = 0; msg->controls[i] != NULL; i++) { if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return False; + return false; } } @@ -486,12 +486,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct if (data->has_error) { asn1_free(data); - return False; + return false; } *result = data_blob_talloc(mem_ctx, data->data, data->length); asn1_free(data); - return True; + return true; } static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, @@ -503,16 +503,16 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, return result; } -static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, +static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, struct asn1_data *data, const char **result) { DATA_BLOB string; if (!asn1_read_OctetString(data, mem_ctx, &string)) - return False; + return false; *result = blob2string_talloc(mem_ctx, string); data_blob_free(&string); - return True; + return true; } static void ldap_decode_response(TALLOC_CTX *mem_ctx, diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index cbe8772414..d285735d4e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -258,7 +258,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, - False, NULL, NULL, &sasl_mechs_msgs); + false, NULL, NULL, &sasl_mechs_msgs); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", nt_errstr(status))); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8476a4977b..aea95de161 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -226,7 +226,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, parse a ldap URL */ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16_t *port, BOOL *ldaps) + char **host, uint16_t *port, bool *ldaps) { int tmp_port = 0; char protocol[11]; @@ -243,10 +243,10 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, if (strequal(protocol, "ldap")) { *port = 389; - *ldaps = False; + *ldaps = false; } else if (strequal(protocol, "ldaps")) { *port = 636; - *ldaps = True; + *ldaps = true; } else { DEBUG(0, ("unrecognised ldap protocol (%s)!\n", protocol)); return NT_STATUS_PROTOCOL_UNREACHABLE; diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 3a5d14c0c9..b7fd1ce178 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -26,56 +26,56 @@ struct control_handler { const char *oid; - BOOL (*decode)(void *mem_ctx, DATA_BLOB in, void **out); - BOOL (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); + bool (*decode)(void *mem_ctx, DATA_BLOB in, void **out); + bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); }; -static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lsrc = talloc(mem_ctx, struct ldb_sort_resp_control); if (!lsrc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_enumerated(data, &(lsrc->result))) { - return False; + return false; } lsrc->attr_desc = NULL; if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - return False; + return false; } lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); if (!lsrc->attr_desc) { - return False; + return false; } } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lsrc; - return True; + return true; } -static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; DATA_BLOB rule; @@ -83,14 +83,14 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) struct ldb_server_sort_control **lssc; int num; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } lssc = NULL; @@ -98,46 +98,46 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) for (num = 0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); num++) { lssc = talloc_realloc(mem_ctx, lssc, struct ldb_server_sort_control *, num + 2); if (!lssc) { - return False; + return false; } lssc[num] = talloc_zero(lssc, struct ldb_server_sort_control); if (!lssc[num]) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - return False; + return false; } lssc[num]->attributeName = talloc_strndup(lssc[num], (const char *)attr.data, attr.length); if (!lssc [num]->attributeName) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &rule)) { - return False; + return false; } lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); if (!lssc[num]->orderingRule) { - return False; + return false; } } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - BOOL reverse; + bool reverse; if (!asn1_read_BOOLEAN(data, &reverse)) { - return False; + return false; } lssc[num]->reverse = reverse; } if (!asn1_end_tag(data)) { - return False; + return false; } } @@ -146,248 +146,248 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lssc; - return True; + return true; } -static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) { struct asn1_data *data = asn1_init(mem_ctx); struct ldb_extended_dn_control *ledc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } ledc = talloc(mem_ctx, struct ldb_extended_dn_control); if (!ledc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(ledc->type))) { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = ledc; - return True; + return true; } -static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) { struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lsdfc = talloc(mem_ctx, struct ldb_sd_flags_control); if (!lsdfc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lsdfc; - return True; + return true; } -static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) { struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lsoc = talloc(mem_ctx, struct ldb_search_options_control); if (!lsoc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lsoc->search_options))) { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lsoc; - return True; + return true; } -static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lprc = talloc(mem_ctx, struct ldb_paged_control); if (!lprc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lprc->size))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { - return False; + return false; } lprc->cookie_len = cookie.length; if (lprc->cookie_len) { lprc->cookie = talloc_memdup(lprc, cookie.data, cookie.length); if (!(lprc->cookie)) { - return False; + return false; } } else { lprc->cookie = NULL; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lprc; - return True; + return true; } -static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } ldc = talloc(mem_ctx, struct ldb_dirsync_control); if (!ldc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(ldc->flags))) { - return False; + return false; } if (!asn1_read_Integer(data, &(ldc->max_attributes))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { - return False; + return false; } ldc->cookie_len = cookie.length; if (ldc->cookie_len) { ldc->cookie = talloc_memdup(ldc, cookie.data, cookie.length); if (!(ldc->cookie)) { - return False; + return false; } } else { ldc->cookie = NULL; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = ldc; - return True; + return true; } /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB source_attribute; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lac = talloc(mem_ctx, struct ldb_asq_control); if (!lac) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) { - return False; + return false; } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { lac->source_attribute = talloc_strndup(lac, (const char *)source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { - return False; + return false; } } else { lac->source_attribute = NULL; @@ -398,96 +398,96 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) { if (!asn1_read_enumerated(data, &(lac->result))) { - return False; + return false; } lac->request = 0; } else { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lac; - return True; + return true; } -static BOOL decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB assertion_value, context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lvrc = talloc(mem_ctx, struct ldb_vlv_req_control); if (!lvrc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->beforeCount))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->afterCount))) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { @@ -495,27 +495,27 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 0; if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) { - return False; + return false; } if (!asn1_end_tag(data)) { /*SEQUENCE*/ - return False; + return false; } if (!asn1_end_tag(data)) { /*CONTEXT*/ - return False; + return false; } } else { @@ -523,38 +523,38 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 1; if (!asn1_start_tag(data, ASN1_CONTEXT(1))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) { - return False; + return false; } lvrc->match.gtOrEq.value_len = assertion_value.length; if (lvrc->match.gtOrEq.value_len) { lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length); if (!(lvrc->match.gtOrEq.value)) { - return False; + return false; } } else { lvrc->match.gtOrEq.value = NULL; } if (!asn1_end_tag(data)) { /*CONTEXT*/ - return False; + return false; } } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { - return False; + return false; } lvrc->ctxid_len = context_id.length; if (lvrc->ctxid_len) { lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length); if (!(lvrc->contextId)) { - return False; + return false; } } else { lvrc->contextId = NULL; @@ -565,54 +565,54 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lvrc; - return True; + return true; } -static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control); if (!lvrc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->targetPosition))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->contentCount))) { - return False; + return false; } if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { - return False; + return false; } lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); if (!lvrc->contextId) { - return False; + return false; } lvrc->ctxid_len = context_id.length; } else { @@ -621,455 +621,455 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lvrc; - return True; + return true; } -static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_enumerated(data, lsrc->result)) { - return False; + return false; } if (lsrc->attr_desc) { if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *); struct asn1_data *data = asn1_init(mem_ctx); int num; - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } for (num = 0; lssc[num]; num++) { if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { - return False; + return false; } if (lssc[num]->orderingRule) { if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) { - return False; + return false; } } if (lssc[num]->reverse) { if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, ledc->type)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lsoc->search_options)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lprc->size)) { - return False; + return false; } if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (lac->request) { if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) { - return False; + return false; } } else { if (!asn1_write_enumerated(data, lac->result)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, ldc->flags)) { - return False; + return false; } if (!asn1_write_Integer(data, ldc->max_attributes)) { - return False; + return false; } if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->beforeCount)) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->afterCount)) { - return False; + return false; } if (lvrc->type == 0) { if (!asn1_push_tag(data, ASN1_CONTEXT(0))) { - return False; + return false; } if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) { - return False; + return false; } if (!asn1_pop_tag(data)) { /*SEQUENCE*/ - return False; + return false; } if (!asn1_pop_tag(data)) { /*CONTEXT*/ - return False; + return false; } } else { if (!asn1_push_tag(data, ASN1_CONTEXT(1))) { - return False; + return false; } if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { - return False; + return false; } if (!asn1_pop_tag(data)) { /*CONTEXT*/ - return False; + return false; } } if (lvrc->ctxid_len) { if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->targetPosition)) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->contentCount)) { - return False; + return false; } if (!asn1_write_enumerated(data, lvrc->vlv_result)) { - return False; + return false; } if (lvrc->ctxid_len) { if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } struct control_handler ldap_known_controls[] = { @@ -1095,49 +1095,49 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -BOOL ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) +bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) { int i; for (i = 0; ldap_known_controls[i].oid != NULL; i++) { if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { if (!ldap_known_controls[i].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { - return False; + return false; } break; } } if (ldap_known_controls[i].oid == NULL) { - return False; + return false; } - return True; + return true; } -BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) +bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) { DATA_BLOB oid; if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &oid)) { - return False; + return false; } ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); if (!ctrl->oid) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - BOOL critical; + bool critical; if (!asn1_read_BOOLEAN(data, &critical)) { - return False; + return false; } ctrl->critical = critical; } else { - ctrl->critical = False; + ctrl->critical = false; } ctrl->data = NULL; @@ -1148,18 +1148,18 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l } if (!asn1_read_OctetString(data, mem_ctx, value)) { - return False; + return false; } end_tag: if (!asn1_end_tag(data)) { - return False; + return false; } - return True; + return true; } -BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) +bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) { DATA_BLOB value; int i; @@ -1168,33 +1168,33 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { if (!ldap_known_controls[i].encode) { if (ctrl->critical) { - return False; + return false; } else { /* not encoding this control */ - return True; + return true; } } if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { - return False; + return false; } break; } } if (ldap_known_controls[i].oid == NULL) { - return False; + return false; } if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { - return False; + return false; } if (ctrl->critical) { if (!asn1_write_BOOLEAN(data, ctrl->critical)) { - return False; + return false; } } @@ -1203,13 +1203,13 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr } if (!asn1_write_OctetString(data, value.data, value.length)) { - return False; + return false; } pop_tag: if (!asn1_pop_tag(data)) { - return False; + return false; } - return True; + return true; } diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 62019b8cc1..7b592c65ae 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -41,7 +41,7 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) */ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, int scope, struct ldb_parse_tree *tree, - const char * const *attrs, BOOL attributesonly, + const char * const *attrs, bool attributesonly, struct ldb_control **control_req, struct ldb_control ***control_res, struct ldap_message ***results) @@ -75,7 +75,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, req = ldap_request_send(conn, msg); talloc_steal(msg, req); - for (i=n=0;True;i++) { + for (i=n=0;true;i++) { struct ldap_message *res; status = ldap_result_n(req, i, &res); if (!NT_STATUS_IS_OK(status)) break; @@ -114,7 +114,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, */ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, int scope, const char *expression, - const char * const *attrs, BOOL attributesonly, + const char * const *attrs, bool attributesonly, struct ldb_control **control_req, struct ldb_control ***control_res, struct ldap_message ***results) diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index c9643dafda..12832b8ec4 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -32,7 +32,7 @@ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) } -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, +bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldb_message_element *attrib) { attrib->values = talloc_realloc(mem_ctx, @@ -40,16 +40,16 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, DATA_BLOB, attrib->num_values+1); if (attrib->values == NULL) - return False; + return false; attrib->values[attrib->num_values].data = talloc_steal(attrib->values, value->data); attrib->values[attrib->num_values].length = value->length; attrib->num_values += 1; - return True; + return true; } -BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, +bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldb_message_element *attrib, struct ldb_message_element **attribs, int *num_attribs) @@ -60,16 +60,16 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, *num_attribs+1); if (*attribs == NULL) - return False; + return false; (*attribs)[*num_attribs] = *attrib; talloc_steal(*attribs, attrib->values); talloc_steal(*attribs, attrib->name); *num_attribs += 1; - return True; + return true; } -BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, +bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod *mod, struct ldap_mod **mods, int *num_mods) @@ -77,10 +77,10 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); if (*mods == NULL) - return False; + return false; (*mods)[*num_mods] = *mod; *num_mods += 1; - return True; + return true; } diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index a55d743efb..755e06e880 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -57,7 +57,7 @@ _PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nb io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, False); + io->in.timeout, io->in.retries, false); if (req == NULL) goto failed; talloc_free(packet); @@ -161,7 +161,7 @@ _PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *n io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, False); + io->in.timeout, io->in.retries, false); if (req == NULL) goto failed; talloc_free(packet); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 3114cb2b10..d723eed9f5 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -72,7 +72,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, False); + io->in.timeout, io->in.retries, false); if (req == NULL) goto failed; talloc_free(packet); @@ -242,7 +242,7 @@ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbt state->io->in.dest_addr = state->wins_servers[0]; state->io->in.address = io->in.addresses[0]; state->io->in.nb_flags = io->in.nb_flags; - state->io->in.broadcast = False; + state->io->in.broadcast = false; state->io->in.ttl = io->in.ttl; state->io->in.timeout = 2; state->io->in.retries = 2; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index b8fe362694..fd4a94dd44 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -80,7 +80,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, False); + io->in.timeout, io->in.retries, false); if (req == NULL) goto failed; talloc_free(packet); @@ -166,7 +166,7 @@ static void name_register_bcast_handler(struct nbt_name_request *req) status = nbt_name_register_recv(state->req, state, state->io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - if (state->io->in.register_demand == True) { + if (state->io->in.register_demand == true) { /* all done */ c->state = COMPOSITE_STATE_DONE; c->status = NT_STATUS_OK; @@ -174,7 +174,7 @@ static void name_register_bcast_handler(struct nbt_name_request *req) } /* the registration timed out - good, send the demand */ - state->io->in.register_demand = True; + state->io->in.register_demand = true; state->io->in.retries = 0; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { @@ -226,9 +226,9 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n state->io->in.dest_addr = io->in.dest_addr; state->io->in.address = io->in.address; state->io->in.nb_flags = io->in.nb_flags; - state->io->in.register_demand = False; - state->io->in.broadcast = True; - state->io->in.multi_homed = False; + state->io->in.register_demand = false; + state->io->in.broadcast = true; + state->io->in.multi_homed = false; state->io->in.ttl = io->in.ttl; state->io->in.timeout = 1; state->io->in.retries = 2; @@ -379,9 +379,9 @@ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nb state->io->in.dest_addr = state->wins_servers[0]; state->io->in.address = io->in.addresses[0]; state->io->in.nb_flags = io->in.nb_flags; - state->io->in.broadcast = False; - state->io->in.register_demand = False; - state->io->in.multi_homed = (io->in.nb_flags & NBT_NM_GROUP)?False:True; + state->io->in.broadcast = false; + state->io->in.register_demand = false; + state->io->in.multi_homed = (io->in.nb_flags & NBT_NM_GROUP)?false:true; state->io->in.ttl = io->in.ttl; state->io->in.timeout = 3; state->io->in.retries = 2; diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index a72a5c706f..1b3c9ae17e 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -70,7 +70,7 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, io->in.dest_addr, lp_nbt_port(global_loadparm)); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, False); + io->in.timeout, io->in.retries, false); if (req == NULL) goto failed; talloc_free(packet); diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 416814220b..37cdf64023 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -149,7 +149,7 @@ _PUBLIC_ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const /* see if we have pushed the remaing string allready, * if so we use a label pointer to this string */ - status = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, False); + status = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); if (NT_STATUS_IS_OK(status)) { uint8_t b[2]; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 174b08ddf6..7d88c83044 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -241,7 +241,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) /* we know we won't need any more retries - the server has received our request */ req->num_retries = 0; - req->received_wack = True; + req->received_wack = true; /* although there can be a timeout in the packet, w2k3 screws it up, so better to set it ourselves */ req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30); @@ -355,7 +355,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, struct socket_address *dest, struct nbt_name_packet *request, int timeout, int retries, - BOOL allow_multiple_replies) + bool allow_multiple_replies) { struct nbt_name_request *req; int id; @@ -367,7 +367,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, req->nbtsock = nbtsock; req->allow_multiple_replies = allow_multiple_replies; req->state = NBT_REQUEST_SEND; - req->is_reply = False; + req->is_reply = false; req->timeout = timeout; req->num_retries = retries; req->dest = dest; @@ -431,7 +431,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, req->dest = dest; if (talloc_reference(req, dest) == NULL) goto failed; req->state = NBT_REQUEST_SEND; - req->is_reply = True; + req->is_reply = true; talloc_set_destructor(req, nbt_name_request_destructor); diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index 12b586aafa..ae4e58ae01 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -23,9 +23,9 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ -_PUBLIC_ BOOL smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_level) +_PUBLIC_ bool smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_level) { - BOOL ret; + bool ret; struct smbcli_request *req; req = smbcli_request_setup(tree, SMBlockingX, 8, 0); @@ -53,7 +53,7 @@ _PUBLIC_ BOOL smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_ set the oplock handler for a connection ****************************************************************************/ _PUBLIC_ void smbcli_oplock_handler(struct smbcli_transport *transport, - BOOL (*handler)(struct smbcli_transport *, uint16_t, uint16_t, uint8_t, void *), + bool (*handler)(struct smbcli_transport *, uint16_t, uint16_t, uint8_t, void *), void *private) { transport->oplock.handler = handler; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index c6c575b818..617131c53c 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -33,7 +33,7 @@ Initialize the session context ****************************************************************************/ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, - TALLOC_CTX *parent_ctx, BOOL primary) + TALLOC_CTX *parent_ctx, bool primary) { struct smbcli_session *session; uint16_t flags2; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 6b2c4c37fe..0bf805910e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -72,7 +72,8 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob); create a transport structure based on an established socket */ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, - TALLOC_CTX *parent_ctx, BOOL primary) + TALLOC_CTX *parent_ctx, + bool primary) { struct smbcli_transport *transport; @@ -261,7 +262,7 @@ NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req) /* send a session request (if needed) */ -BOOL smbcli_transport_connect(struct smbcli_transport *transport, +bool smbcli_transport_connect(struct smbcli_transport *transport, struct nbt_name *calling, struct nbt_name *called) { @@ -269,7 +270,7 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, NTSTATUS status; if (transport->socket->port == 445) { - return True; + return true; } req = smbcli_transport_connect_send(transport, @@ -500,16 +501,16 @@ error: /* process some read/write requests that are pending - return False if the socket is dead + return false if the socket is dead */ -BOOL smbcli_transport_process(struct smbcli_transport *transport) +bool smbcli_transport_process(struct smbcli_transport *transport) { NTSTATUS status; size_t npending; packet_queue_run(transport->packet); if (transport->socket->sock == NULL) { - return False; + return false; } status = socket_pending(transport->socket->sock, &npending); @@ -517,9 +518,9 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) packet_recv(transport->packet); } if (transport->socket->sock == NULL) { - return False; + return false; } - return True; + return true; } /* diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 4ff11f3a69..54f8ac95a4 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -34,7 +34,7 @@ Initialize the tree context ****************************************************************************/ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session, - TALLOC_CTX *parent_ctx, BOOL primary) + TALLOC_CTX *parent_ctx, bool primary) { struct smbcli_tree *tree; @@ -189,7 +189,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service = service; io.in.service_type = service_type; io.in.credentials = credentials; - io.in.fallback_to_anonymous = False; + io.in.fallback_to_anonymous = false; io.in.workgroup = lp_workgroup(global_loadparm); status = smb_composite_connect(&io, parent_ctx, ev); diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 06b5b4fc4d..8ea8e621c9 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -333,7 +333,7 @@ NTSTATUS ea_pull_name_list(const DATA_BLOB *blob, /* put a ea_name list into a data blob */ -BOOL ea_push_name_list(TALLOC_CTX *mem_ctx, +bool ea_push_name_list(TALLOC_CTX *mem_ctx, DATA_BLOB *data, uint_t num_names, struct ea_name *eas) { int i; @@ -344,7 +344,7 @@ BOOL ea_push_name_list(TALLOC_CTX *mem_ctx, *data = data_blob_talloc(mem_ctx, NULL, ea_size); if (data->data == NULL) { - return False; + return false; } SIVAL(data->data, 0, ea_size); @@ -357,5 +357,5 @@ BOOL ea_push_name_list(TALLOC_CTX *mem_ctx, off += 1+nlen+1; } - return True; + return true; } diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 60a9bf2656..83303cf470 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -426,7 +426,7 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope { int len; struct smbcli_request *req = NULL; - BOOL bigoffset = False; + bool bigoffset = false; switch (parms->generic.level) { case RAW_OPEN_T2OPEN: @@ -527,7 +527,7 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE); if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { - bigoffset = True; + bigoffset = true; } smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index c58ac1f0df..82d6fe5236 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -144,8 +144,8 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) } if (transport->negotiate.capabilities & CAP_RAW_MODE) { - transport->negotiate.readbraw_supported = True; - transport->negotiate.writebraw_supported = True; + transport->negotiate.readbraw_supported = true; + transport->negotiate.writebraw_supported = true; } } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) { SMBCLI_CHECK_WCT(req, 13); diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index a288b7ec54..b0c49ddab7 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -31,13 +31,13 @@ ****************************************************************************/ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms) { - BOOL bigoffset = False; + bool bigoffset = false; struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_READ_READBRAW: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { - bigoffset = True; + bigoffset = true; } SETUP_REQUEST(SMBreadbraw, bigoffset? 10:8, 0); SSVAL(req->out.vwv, VWV(0), parms->readbraw.in.file.fnum); @@ -69,7 +69,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea case RAW_READ_READX: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { - bigoffset = True; + bigoffset = true; } SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); @@ -206,7 +206,7 @@ NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms) ****************************************************************************/ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms) { - BOOL bigoffset = False; + bool bigoffset = false; struct smbcli_request *req = NULL; switch (parms->generic.level) { @@ -253,7 +253,7 @@ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_wr case RAW_WRITE_WRITEX: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { - bigoffset = True; + bigoffset = true; } SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 778b896abd..6a4f432088 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -309,7 +309,7 @@ NTSTATUS smbcli_chained_advance(struct smbcli_request *req) /* send a message */ -BOOL smbcli_request_send(struct smbcli_request *req) +bool smbcli_request_send(struct smbcli_request *req) { if (IVAL(req->out.buffer, 0) == 0) { _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); @@ -319,23 +319,23 @@ BOOL smbcli_request_send(struct smbcli_request *req) smbcli_transport_send(req); - return True; + return true; } /* receive a response to a packet */ -BOOL smbcli_request_receive(struct smbcli_request *req) +bool smbcli_request_receive(struct smbcli_request *req) { /* req can be NULL when a send has failed. This eliminates lots of NULL checks in each module */ - if (!req) return False; + if (!req) return false; /* keep receiving packets until this one is replied to */ while (req->state <= SMBCLI_REQUEST_RECV) { if (event_loop_once(req->transport->socket->event.ctx) != 0) { - return False; + return false; } } @@ -347,7 +347,7 @@ BOOL smbcli_request_receive(struct smbcli_request *req) receive another reply to a request - this is used for requests that have multi-part replies (such as SMBtrans2) */ -BOOL smbcli_request_receive_more(struct smbcli_request *req) +bool smbcli_request_receive_more(struct smbcli_request *req) { req->state = SMBCLI_REQUEST_RECV; DLIST_ADD(req->transport->pending_recv, req); @@ -357,10 +357,10 @@ BOOL smbcli_request_receive_more(struct smbcli_request *req) /* - handle oplock break requests from the server - return True if the request was + handle oplock break requests from the server - return true if the request was an oplock break */ -BOOL smbcli_handle_oplock_break(struct smbcli_transport *transport, uint_t len, const uint8_t *hdr, const uint8_t *vwv) +bool smbcli_handle_oplock_break(struct smbcli_transport *transport, uint_t len, const uint8_t *hdr, const uint8_t *vwv) { /* we must be very fussy about what we consider an oplock break to avoid matching readbraw replies */ @@ -370,7 +370,7 @@ BOOL smbcli_handle_oplock_break(struct smbcli_transport *transport, uint_t len, SVAL(hdr, HDR_MID) != 0xFFFF || SVAL(vwv,VWV(6)) != 0 || SVAL(vwv,VWV(7)) != 0) { - return False; + return false; } if (transport->oplock.handler) { @@ -380,7 +380,7 @@ BOOL smbcli_handle_oplock_break(struct smbcli_transport *transport, uint_t len, transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private); } - return True; + return true; } /* @@ -395,7 +395,7 @@ NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req) /* Return true if the last packet was in error */ -BOOL smbcli_request_is_error(struct smbcli_request *req) +bool smbcli_request_is_error(struct smbcli_request *req) { return NT_STATUS_IS_ERR(req->status); } @@ -676,33 +676,33 @@ DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, /* check that a lump of data in a request is within the bounds of the data section of the packet */ -static BOOL smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count) +static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count) { /* be careful with wraparound! */ if (ptr < req->in.data || ptr >= req->in.data + req->in.data_size || count > req->in.data_size || ptr + count > req->in.data + req->in.data_size) { - return True; + return true; } - return False; + return false; } /* pull a lump of data from a request packet - return False if any part is outside the data portion of the packet + return false if any part is outside the data portion of the packet */ -BOOL smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest) +bool smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest) { - if (len == 0) return True; + if (len == 0) return true; if (smbcli_req_data_oob(req, src, len)) { - return False; + return false; } memcpy(dest, src, len); - return True; + return true; } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 7738e849e8..5fa0c1f2da 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -27,7 +27,7 @@ /* Handle setfileinfo/setpathinfo passthu constructions */ -BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, +bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, enum smb_setfileinfo_level level, union smb_setfileinfo *parms, DATA_BLOB *blob) @@ -36,7 +36,7 @@ BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, #define NEED_BLOB(n) do { \ *blob = data_blob_talloc(mem_ctx, NULL, n); \ - if (blob->data == NULL) return False; \ + if (blob->data == NULL) return false; \ } while (0) switch (level) { @@ -48,22 +48,22 @@ BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, smbcli_push_nttime(blob->data, 24, parms->basic_info.in.change_time); SIVAL(blob->data, 32, parms->basic_info.in.attrib); SIVAL(blob->data, 36, 0); /* padding */ - return True; + return true; case RAW_SFILEINFO_DISPOSITION_INFORMATION: NEED_BLOB(4); SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close); - return True; + return true; case RAW_SFILEINFO_ALLOCATION_INFORMATION: NEED_BLOB(8); SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size); - return True; + return true; case RAW_SFILEINFO_END_OF_FILE_INFORMATION: NEED_BLOB(8); SBVAL(blob->data, 0, parms->end_of_file_info.in.size); - return True; + return true; case RAW_SFILEINFO_RENAME_INFORMATION: NEED_BLOB(12); @@ -73,17 +73,17 @@ BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, parms->rename_information.in.new_name, STR_UNICODE|STR_TERMINATE); SIVAL(blob->data, 8, len - 2); - return True; + return true; case RAW_SFILEINFO_POSITION_INFORMATION: NEED_BLOB(8); SBVAL(blob->data, 0, parms->position_information.in.position); - return True; + return true; case RAW_SFILEINFO_MODE_INFORMATION: NEED_BLOB(4); SIVAL(blob->data, 0, parms->mode_information.in.mode); - return True; + return true; case RAW_FILEINFO_SEC_DESC: { NTSTATUS status; @@ -91,9 +91,9 @@ BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, status = ndr_push_struct_blob(blob, mem_ctx, parms->set_secdesc.in.sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor); - if (!NT_STATUS_IS_OK(status)) return False; + if (!NT_STATUS_IS_OK(status)) return false; - return True; + return true; } /* Unhandled levels */ @@ -107,16 +107,16 @@ BOOL smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, default: DEBUG(0,("Unhandled setfileinfo passthru level %d\n", level)); - return False; + return false; } - return False; + return false; } /* Handle setfileinfo/setpathinfo trans2 backend. */ -static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, +static bool smb_raw_setinfo_backend(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_setfileinfo *parms, DATA_BLOB *blob) @@ -127,7 +127,7 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, case RAW_SFILEINFO_SETATTRE: case RAW_SFILEINFO_SEC_DESC: /* not handled here */ - return False; + return false; case RAW_SFILEINFO_STANDARD: NEED_BLOB(12); @@ -137,12 +137,12 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, blob->data, 4, parms->standard.in.access_time); raw_push_dos_date2(tree->session->transport, blob->data, 8, parms->standard.in.write_time); - return True; + return true; case RAW_SFILEINFO_EA_SET: NEED_BLOB(ea_list_size(parms->ea_set.in.num_eas, parms->ea_set.in.eas)); ea_put_list(blob->data, parms->ea_set.in.num_eas, parms->ea_set.in.eas); - return True; + return true; case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: @@ -164,7 +164,7 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, SBVAL(blob->data, 76, parms->unix_basic.in.unique_id); SBVAL(blob->data, 84, parms->unix_basic.in.permissions); SBVAL(blob->data, 92, parms->unix_basic.in.nlink); - return True; + return true; case RAW_SFILEINFO_UNIX_INFO2: NEED_BLOB(116); @@ -184,7 +184,7 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, smbcli_push_nttime(blob->data, 100, parms->unix_info2.in.create_time); SIVAL(blob->data, 108, parms->unix_info2.in.file_flags); SIVAL(blob->data, 112, parms->unix_info2.in.flags_mask); - return True; + return true; case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: @@ -230,7 +230,7 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, break; } - return False; + return false; } /**************************************************************************** diff --git a/source4/libcli/raw/rawshadow.c b/source4/libcli/raw/rawshadow.c index 8fc81dab4c..4c58c91383 100644 --- a/source4/libcli/raw/rawshadow.c +++ b/source4/libcli/raw/rawshadow.c @@ -39,7 +39,7 @@ _PUBLIC_ NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, nt.ntioctl.level = RAW_IOCTL_NTIOCTL; nt.ntioctl.in.function = FSCTL_GET_SHADOW_COPY_DATA; nt.ntioctl.in.file.fnum = info->in.file.fnum; - nt.ntioctl.in.fsctl = True; + nt.ntioctl.in.fsctl = true; nt.ntioctl.in.filter = 0; nt.ntioctl.in.max_data = info->in.max_data; nt.ntioctl.in.blob = data_blob(NULL, 0); diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 40a30bd067..53670d22a3 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -27,13 +27,13 @@ /* check out of bounds for incoming data */ -static BOOL raw_trans_oob(struct smbcli_request *req, +static bool raw_trans_oob(struct smbcli_request *req, uint_t offset, uint_t count) { uint8_t *ptr; if (count == 0) { - return False; + return false; } ptr = req->in.hdr + offset; @@ -43,9 +43,9 @@ static BOOL raw_trans_oob(struct smbcli_request *req, ptr >= req->in.data + req->in.data_size || count > req->in.data_size || ptr + count > req->in.data + req->in.data_size) { - return True; + return true; } - return False; + return false; } /**************************************************************************** diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 59c13bbeb6..e19e81af7e 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -28,41 +28,41 @@ /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ -BOOL set_smb_signing_common(struct smb_signing_context *sign_info) +bool set_smb_signing_common(struct smb_signing_context *sign_info) { if (sign_info->doing_signing) { DEBUG(5, ("SMB Signing already in progress, so we don't start it again\n")); - return False; + return false; } if (!sign_info->allow_smb_signing) { DEBUG(5, ("SMB Signing has been locally disabled\n")); - return False; + return false; } - return True; + return true; } /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL smbcli_set_smb_signing_common(struct smbcli_transport *transport) +static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport) { if (!set_smb_signing_common(&transport->negotiate.sign_info)) { - return False; + return false; } if (!(transport->negotiate.sec_mode & (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) { DEBUG(5, ("SMB Signing is not negotiated by the peer\n")); - return False; + return false; } /* These calls are INCOMPATIBLE with SMB signing */ - transport->negotiate.readbraw_supported = False; - transport->negotiate.writebraw_supported = False; + transport->negotiate.readbraw_supported = false; + transport->negotiate.writebraw_supported = false; - return True; + return true; } void mark_packet_signed(struct request_buffer *out) @@ -73,17 +73,17 @@ void mark_packet_signed(struct request_buffer *out) SSVAL(out->hdr, HDR_FLG2, flags2); } -BOOL signing_good(struct smb_signing_context *sign_info, - unsigned int seq, BOOL good) +bool signing_good(struct smb_signing_context *sign_info, + unsigned int seq, bool good) { if (good) { if (!sign_info->doing_signing) { DEBUG(5, ("Seen valid packet, so turning signing on\n")); - sign_info->doing_signing = True; + sign_info->doing_signing = true; } if (!sign_info->seen_valid) { DEBUG(5, ("Seen valid packet, so marking signing as 'seen valid'\n")); - sign_info->seen_valid = True; + sign_info->seen_valid = true; } } else { if (!sign_info->seen_valid) { @@ -91,14 +91,14 @@ BOOL signing_good(struct smb_signing_context *sign_info, DEBUG(5, ("signing_good: signing negotiated but not required and peer\n" "isn't sending correct signatures. Turning off.\n")); smbcli_set_signing_off(sign_info); - return True; + return true; } else { /* bad packet after signing started - fail and disconnect. */ DEBUG(0, ("signing_good: BAD SIG: seq %u\n", seq)); - return False; + return false; } } - return True; + return true; } void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) @@ -133,9 +133,9 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsig Uncomment this to test if the remote server actually verifies signitures...*/ } -BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) +bool check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) { - BOOL good; + bool good; uint8_t calc_md5_mac[16]; uint8_t *server_sent_mac; uint8_t sequence_buf[8]; @@ -146,12 +146,12 @@ BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key /* room enough for the signature? */ if (in->size < NBT_HDR_SIZE + HDR_SS_FIELD + 8) { - return False; + return false; } if (!mac_key->length) { /* NO key yet */ - return False; + return false; } /* its quite bogus to be guessing sequence numbers, but very useful @@ -258,24 +258,24 @@ void smbcli_request_calculate_sign_mac(struct smbcli_request *req) @note Used as an initialisation only - it will not correctly shut down a real signing mechanism */ -BOOL smbcli_set_signing_off(struct smb_signing_context *sign_info) +bool smbcli_set_signing_off(struct smb_signing_context *sign_info) { DEBUG(5, ("Shutdown SMB signing\n")); - sign_info->doing_signing = False; + sign_info->doing_signing = false; sign_info->next_seq_num = 0; data_blob_free(&sign_info->mac_key); sign_info->signing_state = SMB_SIGNING_ENGINE_OFF; - return True; + return true; } /** SMB signing - TEMP implementation - setup the MAC key. */ -BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) +bool smbcli_temp_set_signing(struct smbcli_transport *transport) { if (!smbcli_set_smb_signing_common(transport)) { - return False; + return false; } DEBUG(5, ("BSRSPYL SMB signing enabled\n")); smbcli_set_signing_off(&transport->negotiate.sign_info); @@ -283,7 +283,7 @@ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); transport->negotiate.sign_info.signing_state = SMB_SIGNING_ENGINE_BSRSPYL; - return True; + return true; } /*********************************************************** @@ -291,22 +291,22 @@ BOOL smbcli_temp_set_signing(struct smbcli_transport *transport) ************************************************************/ /** * Check a packet supplied by the server. - * @return False if we had an established signing connection - * which had a back checksum, True otherwise + * @return false if we had an established signing connection + * which had a back checksum, true otherwise */ -BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) +bool smbcli_request_check_sign_mac(struct smbcli_request *req) { - BOOL good; + bool good; switch (req->transport->negotiate.sign_info.signing_state) { case SMB_SIGNING_ENGINE_OFF: - return True; + return true; case SMB_SIGNING_ENGINE_BSRSPYL: case SMB_SIGNING_ENGINE_ON: { if (req->in.size < (HDR_SS_FIELD + 8)) { - return False; + return false; } else { good = check_signed_incoming_message(&req->in, &req->transport->negotiate.sign_info.mac_key, @@ -317,14 +317,14 @@ BOOL smbcli_request_check_sign_mac(struct smbcli_request *req) } } } - return False; + return false; } /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, +bool smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, struct smb_signing_context *sign_info, const DATA_BLOB *user_session_key, const DATA_BLOB *response) @@ -354,19 +354,19 @@ BOOL smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, sign_info->signing_state = SMB_SIGNING_ENGINE_ON; - return True; + return true; } /*********************************************************** SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL smbcli_transport_simple_set_signing(struct smbcli_transport *transport, +bool smbcli_transport_simple_set_signing(struct smbcli_transport *transport, const DATA_BLOB user_session_key, const DATA_BLOB response) { if (!smbcli_set_smb_signing_common(transport)) { - return False; + return false; } return smbcli_simple_set_signing(transport, @@ -380,21 +380,21 @@ bool smbcli_init_signing(struct smbcli_transport *transport) { transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) { - return False; + return false; } switch (lp_client_signing(global_loadparm)) { case SMB_SIGNING_OFF: - transport->negotiate.sign_info.allow_smb_signing = False; + transport->negotiate.sign_info.allow_smb_signing = false; break; case SMB_SIGNING_SUPPORTED: case SMB_SIGNING_AUTO: - transport->negotiate.sign_info.allow_smb_signing = True; + transport->negotiate.sign_info.allow_smb_signing = true; break; case SMB_SIGNING_REQUIRED: - transport->negotiate.sign_info.allow_smb_signing = True; - transport->negotiate.sign_info.mandatory_signing = True; + transport->negotiate.sign_info.allow_smb_signing = true; + transport->negotiate.sign_info.mandatory_signing = true; break; } - return True; + return true; } diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index f356dafdaa..3193d70789 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -51,7 +51,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, } address_list[count] = NULL; - c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, True, False); + c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, true, false); talloc_free(address_list); return c; diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 9720434cb9..baf3874aa4 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -99,8 +99,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct nbt_name *name, const char **address_list, - BOOL broadcast, - BOOL wins_lookup) + bool broadcast, + bool wins_lookup) { struct composite_context *c; struct nbtlist_state *state; @@ -193,7 +193,7 @@ NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c, NTSTATUS resolve_name_nbtlist(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **address_list, - BOOL broadcast, BOOL wins_lookup, + bool broadcast, bool wins_lookup, const char **reply_addr) { struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL, name, address_list, diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 05a2d4da31..2cbcd5f483 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -34,7 +34,7 @@ struct composite_context *resolve_name_wins_send( { const char **address_list = lp_wins_server_list(global_loadparm); if (address_list == NULL) return NULL; - return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, False, True); + return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, false, true); } /* diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index 1ba3edd9bf..f5457e7e0e 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -241,24 +241,24 @@ NTSTATUS dom_sid_split_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, } /* - return True if the 2nd sid is in the domain given by the first sid + return true if the 2nd sid is in the domain given by the first sid */ -BOOL dom_sid_in_domain(const struct dom_sid *domain_sid, +bool dom_sid_in_domain(const struct dom_sid *domain_sid, const struct dom_sid *sid) { int i; if (!domain_sid || !sid) { - return False; + return false; } if (domain_sid->num_auths > sid->num_auths) { - return False; + return false; } for (i = domain_sid->num_auths-1; i >= 0; --i) { if (domain_sid->sub_auths[i] != sid->sub_auths[i]) { - return False; + return false; } } diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 103e2e3c14..2cbef13538 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -192,21 +192,21 @@ static uint64_t sec_privilege_mask(enum sec_privilege privilege) /* - return True if a security_token has a particular privilege bit set + return true if a security_token has a particular privilege bit set */ -BOOL security_token_has_privilege(const struct security_token *token, enum sec_privilege privilege) +bool security_token_has_privilege(const struct security_token *token, enum sec_privilege privilege) { uint64_t mask; if (privilege < 1 || privilege > 64) { - return False; + return false; } mask = sec_privilege_mask(privilege); if (token->privilege_mask & mask) { - return True; + return true; } - return False; + return false; } /* diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index d4efab9b64..09522f182a 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -32,7 +32,7 @@ struct flag_map { /* map a series of letter codes into a uint32_t */ -static BOOL sddl_map_flags(const struct flag_map *map, const char *str, +static bool sddl_map_flags(const struct flag_map *map, const char *str, uint32_t *flags, size_t *len) { const char *str0 = str; @@ -51,10 +51,10 @@ static BOOL sddl_map_flags(const struct flag_map *map, const char *str, } if (map[i].name == NULL) { DEBUG(1, ("Unknown flag - %s in %s\n", str, str0)); - return False; + return false; } } - return True; + return true; } /* @@ -176,10 +176,10 @@ static const struct flag_map ace_access_mask[] = { /* decode an ACE - return True on success, False on failure + return true on success, false on failure note that this routine modifies the string */ -static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str, +static bool sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str, const struct dom_sid *domain_sid) { const char *tok[6]; @@ -194,7 +194,7 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char tok[0] = str; for (i=0;i<5;i++) { char *ptr = strchr(str, ';'); - if (ptr == NULL) return False; + if (ptr == NULL) return false; *ptr = 0; str = ptr+1; tok[i+1] = str; @@ -202,13 +202,13 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char /* parse ace type */ if (!sddl_map_flags(ace_types, tok[0], &v, NULL)) { - return False; + return false; } ace->type = v; /* ace flags */ if (!sddl_map_flags(ace_flags, tok[1], &v, NULL)) { - return False; + return false; } ace->flags = v; @@ -217,7 +217,7 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char ace->access_mask = strtol(tok[2], NULL, 16); } else { if (!sddl_map_flags(ace_access_mask, tok[2], &v, NULL)) { - return False; + return false; } ace->access_mask = v; } @@ -227,7 +227,7 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char NTSTATUS status = GUID_from_string(tok[3], &ace->object.object.type.type); if (!NT_STATUS_IS_OK(status)) { - return False; + return false; } ace->object.object.flags |= SEC_ACE_OBJECT_TYPE_PRESENT; } @@ -237,7 +237,7 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char NTSTATUS status = GUID_from_string(tok[4], &ace->object.object.inherited_type.inherited_type); if (!NT_STATUS_IS_OK(status)) { - return False; + return false; } ace->object.object.flags |= SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT; } @@ -246,13 +246,13 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char s = tok[5]; sid = sddl_decode_sid(mem_ctx, &s, domain_sid); if (sid == NULL) { - return False; + return false; } ace->trustee = *sid; talloc_steal(mem_ctx, sid->sub_auths); talloc_free(sid); - return True; + return true; } static const struct flag_map acl_flags[] = { @@ -388,7 +388,7 @@ failed: turn a set of flags into a string */ static char *sddl_flags_to_string(TALLOC_CTX *mem_ctx, const struct flag_map *map, - uint32_t flags, BOOL check_all) + uint32_t flags, bool check_all) { int i; char *s; @@ -477,13 +477,13 @@ static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace return NULL; } - s_type = sddl_flags_to_string(tmp_ctx, ace_types, ace->type, True); + s_type = sddl_flags_to_string(tmp_ctx, ace_types, ace->type, true); if (s_type == NULL) goto failed; - s_flags = sddl_flags_to_string(tmp_ctx, ace_flags, ace->flags, True); + s_flags = sddl_flags_to_string(tmp_ctx, ace_flags, ace->flags, true); if (s_flags == NULL) goto failed; - s_mask = sddl_flags_to_string(tmp_ctx, ace_access_mask, ace->access_mask, True); + s_mask = sddl_flags_to_string(tmp_ctx, ace_access_mask, ace->access_mask, true); if (s_mask == NULL) { s_mask = talloc_asprintf(tmp_ctx, "0x%08x", ace->access_mask); if (s_mask == NULL) goto failed; @@ -525,7 +525,7 @@ static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl int i; /* add any ACL flags */ - sddl = sddl_flags_to_string(mem_ctx, acl_flags, flags, False); + sddl = sddl_flags_to_string(mem_ctx, acl_flags, flags, false); if (sddl == NULL) goto failed; /* now the ACEs, encoded in braces */ diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 1e33e1950b..7ed619d0c4 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -242,77 +242,77 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, /* compare two security ace structures */ -BOOL security_ace_equal(const struct security_ace *ace1, +bool security_ace_equal(const struct security_ace *ace1, const struct security_ace *ace2) { - if (ace1 == ace2) return True; - if (!ace1 || !ace2) return False; - if (ace1->type != ace2->type) return False; - if (ace1->flags != ace2->flags) return False; - if (ace1->access_mask != ace2->access_mask) return False; - if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) return False; - - return True; + if (ace1 == ace2) return true; + if (!ace1 || !ace2) return false; + if (ace1->type != ace2->type) return false; + if (ace1->flags != ace2->flags) return false; + if (ace1->access_mask != ace2->access_mask) return false; + if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) return false; + + return true; } /* compare two security acl structures */ -BOOL security_acl_equal(const struct security_acl *acl1, +bool security_acl_equal(const struct security_acl *acl1, const struct security_acl *acl2) { int i; - if (acl1 == acl2) return True; - if (!acl1 || !acl2) return False; - if (acl1->revision != acl2->revision) return False; - if (acl1->num_aces != acl2->num_aces) return False; + if (acl1 == acl2) return true; + if (!acl1 || !acl2) return false; + if (acl1->revision != acl2->revision) return false; + if (acl1->num_aces != acl2->num_aces) return false; for (i=0;inum_aces;i++) { - if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return False; + if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return false; } - return True; + return true; } /* compare two security descriptors. */ -BOOL security_descriptor_equal(const struct security_descriptor *sd1, +bool security_descriptor_equal(const struct security_descriptor *sd1, const struct security_descriptor *sd2) { - if (sd1 == sd2) return True; - if (!sd1 || !sd2) return False; - if (sd1->revision != sd2->revision) return False; - if (sd1->type != sd2->type) return False; + if (sd1 == sd2) return true; + if (!sd1 || !sd2) return false; + if (sd1->revision != sd2->revision) return false; + if (sd1->type != sd2->type) return false; - if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False; - if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False; - if (!security_acl_equal(sd1->sacl, sd2->sacl)) return False; - if (!security_acl_equal(sd1->dacl, sd2->dacl)) return False; + if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false; + if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false; + if (!security_acl_equal(sd1->sacl, sd2->sacl)) return false; + if (!security_acl_equal(sd1->dacl, sd2->dacl)) return false; - return True; + return true; } /* compare two security descriptors, but allow certain (missing) parts to be masked out of the comparison */ -BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, +bool security_descriptor_mask_equal(const struct security_descriptor *sd1, const struct security_descriptor *sd2, uint32_t mask) { - if (sd1 == sd2) return True; - if (!sd1 || !sd2) return False; - if (sd1->revision != sd2->revision) return False; - if ((sd1->type & mask) != (sd2->type & mask)) return False; + if (sd1 == sd2) return true; + if (!sd1 || !sd2) return false; + if (sd1->revision != sd2->revision) return false; + if ((sd1->type & mask) != (sd2->type & mask)) return false; - if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False; - if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False; - if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return False; - if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return False; + if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false; + if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false; + if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return false; + if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return false; - return True; + return true; } diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index 684c3de7e6..e126340c46 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -79,19 +79,19 @@ void security_token_debug(int dbg_lev, const struct security_token *token) /* These really should be cheaper... */ -BOOL security_token_is_sid(const struct security_token *token, const struct dom_sid *sid) +bool security_token_is_sid(const struct security_token *token, const struct dom_sid *sid) { if (dom_sid_equal(token->user_sid, sid)) { - return True; + return true; } - return False; + return false; } -BOOL security_token_is_sid_string(const struct security_token *token, const char *sid_string) +bool security_token_is_sid_string(const struct security_token *token, const char *sid_string) { - BOOL ret; + bool ret; struct dom_sid *sid = dom_sid_parse_talloc(NULL, sid_string); - if (!sid) return False; + if (!sid) return false; ret = security_token_is_sid(token, sid); @@ -99,32 +99,32 @@ BOOL security_token_is_sid_string(const struct security_token *token, const char return ret; } -BOOL security_token_is_system(const struct security_token *token) +bool security_token_is_system(const struct security_token *token) { return security_token_is_sid_string(token, SID_NT_SYSTEM); } -BOOL security_token_is_anonymous(const struct security_token *token) +bool security_token_is_anonymous(const struct security_token *token) { return security_token_is_sid_string(token, SID_NT_ANONYMOUS); } -BOOL security_token_has_sid(const struct security_token *token, const struct dom_sid *sid) +bool security_token_has_sid(const struct security_token *token, const struct dom_sid *sid) { int i; for (i = 0; i < token->num_sids; i++) { if (dom_sid_equal(token->sids[i], sid)) { - return True; + return true; } } - return False; + return false; } -BOOL security_token_has_sid_string(const struct security_token *token, const char *sid_string) +bool security_token_has_sid_string(const struct security_token *token, const char *sid_string) { - BOOL ret; + bool ret; struct dom_sid *sid = dom_sid_parse_talloc(NULL, sid_string); - if (!sid) return False; + if (!sid) return false; ret = security_token_has_sid(token, sid); @@ -132,12 +132,12 @@ BOOL security_token_has_sid_string(const struct security_token *token, const cha return ret; } -BOOL security_token_has_builtin_administrators(const struct security_token *token) +bool security_token_has_builtin_administrators(const struct security_token *token) { return security_token_has_sid_string(token, SID_BUILTIN_ADMINISTRATORS); } -BOOL security_token_has_nt_authenticated_users(const struct security_token *token) +bool security_token_has_nt_authenticated_users(const struct security_token *token) { return security_token_has_sid_string(token, SID_NT_AUTHENTICATED_USERS); } diff --git a/source4/libcli/smb2/cancel.c b/source4/libcli/smb2/cancel.c index f0a0b01817..096919f177 100644 --- a/source4/libcli/smb2/cancel.c +++ b/source4/libcli/smb2/cancel.c @@ -46,7 +46,7 @@ NTSTATUS smb2_cancel(struct smb2_request *r) /* we don't want a seqmun for a SMB2 Cancel */ old_seqnum = r->transport->seqnum; - c = smb2_request_init(r->transport, SMB2_OP_CANCEL, 0x04, False, 0); + c = smb2_request_init(r->transport, SMB2_OP_CANCEL, 0x04, false, 0); r->transport->seqnum = old_seqnum; NT_STATUS_HAVE_NO_MEMORY(c); c->seqnum = 0; diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index e83f81b630..04c0c85499 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close * { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18, false, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.flags); @@ -54,7 +54,7 @@ NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x3C, False); + SMB2_CHECK_PACKET_RECV(req, 0x3C, false); io->out.flags = SVAL(req->in.body, 0x02); io->out._pad = IVAL(req->in.body, 0x04); diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index bb70311c56..6f05d56cd4 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -69,7 +69,7 @@ static void continue_session(struct composite_context *creq) c->status = smb2_session_setup_spnego_recv(creq); if (!composite_is_ok(c)) return; - state->tree = smb2_tree_init(state->session, state, True); + state->tree = smb2_tree_init(state->session, state, true); if (composite_nomem(state->tree, c)) return; state->tcon.in.unknown1 = 0x09; @@ -99,7 +99,7 @@ static void continue_negprot(struct smb2_request *req) c->status = smb2_negprot_recv(req, c, &state->negprot); if (!composite_is_ok(c)) return; - state->session = smb2_session_init(transport, state, True); + state->session = smb2_session_init(transport, state, true); if (composite_nomem(state->session, c)) return; creq = smb2_session_setup_spnego_send(state->session, state->credentials); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index c8ac271f44..ba11c22e87 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -32,7 +32,7 @@ */ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint32_t tag, - DATA_BLOB add, BOOL last) + DATA_BLOB add, bool last) { uint32_t ofs = blob->length; uint8_t pad = smb2_padding_size(add.length, 8); @@ -65,7 +65,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); - req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, True, 0); + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.oplock_flags); @@ -90,7 +90,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, False); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -100,7 +100,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), True); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), true); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -130,7 +130,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x58, True); + SMB2_CHECK_PACKET_RECV(req, 0x58, true); io->out.oplock_flags = SVAL(req->in.body, 0x02); io->out.create_action = IVAL(req->in.body, 0x04); diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index e8643f1868..6d0a9c8072 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io struct smb2_request *req; NTSTATUS status; - req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, True, 0); + req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, true, 0); if (req == NULL) return NULL; SCVAL(req->out.body, 0x02, io->in.level); @@ -67,7 +67,7 @@ NTSTATUS smb2_find_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x08, True); + SMB2_CHECK_PACKET_RECV(req, 0x08, true); status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index 2f1b7bd749..116068ed6e 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -30,7 +30,7 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush * { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, false, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); /* pad? */ @@ -53,7 +53,7 @@ NTSTATUS smb2_flush_recv(struct smb2_request *req, struct smb2_flush *io) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x04, False); + SMB2_CHECK_PACKET_RECV(req, 0x04, false); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index a9a681ea53..0665dd441c 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, false, 0); if (req == NULL) return NULL; /* this seems to be a bug, they use 0x29 but only send 0x28 bytes */ @@ -64,7 +64,7 @@ NTSTATUS smb2_getinfo_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x08, True); + SMB2_CHECK_PACKET_RECV(req, 0x08, true); status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index c13ec7943c..d81bca517f 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_ioctl_send(struct smb2_tree *tree, struct smb2_ioctl * NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_IOCTL, 0x38, True, + req = smb2_request_init_tree(tree, SMB2_OP_IOCTL, 0x38, true, io->in.in.length+io->in.out.length); if (req == NULL) return NULL; @@ -75,7 +75,7 @@ NTSTATUS smb2_ioctl_recv(struct smb2_request *req, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x30, True); + SMB2_CHECK_PACKET_RECV(req, 0x30, true); io->out._pad = SVAL(req->in.body, 0x02); io->out.function = IVAL(req->in.body, 0x04); diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c index e2b7c83b8a..402b063e81 100644 --- a/source4/libcli/smb2/keepalive.c +++ b/source4/libcli/smb2/keepalive.c @@ -30,7 +30,7 @@ struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport) { struct smb2_request *req; - req = smb2_request_init(transport, SMB2_OP_KEEPALIVE, 0x04, False, 0); + req = smb2_request_init(transport, SMB2_OP_KEEPALIVE, 0x04, false, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); @@ -51,7 +51,7 @@ NTSTATUS smb2_keepalive_recv(struct smb2_request *req) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x04, False); + SMB2_CHECK_PACKET_RECV(req, 0x04, false); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c index 470648a34c..d71a337d56 100644 --- a/source4/libcli/smb2/lock.c +++ b/source4/libcli/smb2/lock.c @@ -30,7 +30,7 @@ struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, false, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.unknown1); @@ -57,7 +57,7 @@ NTSTATUS smb2_lock_recv(struct smb2_request *req, struct smb2_lock *io) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x04, False); + SMB2_CHECK_PACKET_RECV(req, 0x04, false); io->out.unknown1 = SVAL(req->in.body, 0x02); diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index 00d5e19e82..321a4db1a6 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -30,7 +30,7 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session) { struct smb2_request *req; - req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, False, 0); + req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, false, 0); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); @@ -53,7 +53,7 @@ NTSTATUS smb2_logoff_recv(struct smb2_request *req) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x04, False); + SMB2_CHECK_PACKET_RECV(req, 0x04, false); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 07d06ca2ff..38fe0e7e53 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, { struct smb2_request *req; - req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26, False, 0); + req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26, false, 0); if (req == NULL) return NULL; /* this seems to be a bug, they use 0x24 but the length is 0x26 */ @@ -60,7 +60,7 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x40, True); + SMB2_CHECK_PACKET_RECV(req, 0x40, true); io->out._pad = SVAL(req->in.body, 0x02); io->out.unknown2 = IVAL(req->in.body, 0x04); diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 58e2876745..a3bea41eb0 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify struct smb2_request *req; uint32_t old_timeout; - req = smb2_request_init_tree(tree, SMB2_OP_NOTIFY, 0x20, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_NOTIFY, 0x20, false, 0); if (req == NULL) return NULL; SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0x0030); @@ -67,7 +67,7 @@ NTSTATUS smb2_notify_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x08, True); + SMB2_CHECK_PACKET_RECV(req, 0x08, true); status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &blob); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index f78a1a8b0e..b61f918481 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -30,7 +30,7 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x30, True, 0); + req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x30, true, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); /* pad */ @@ -59,7 +59,7 @@ NTSTATUS smb2_read_recv(struct smb2_request *req, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x10, True); + SMB2_CHECK_PACKET_RECV(req, 0x10, true); status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.data); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2d2c8252a1..576e2b6fcf 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -31,7 +31,7 @@ initialise a smb2 request */ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode, - uint16_t body_fixed_size, BOOL body_dynamic_present, + uint16_t body_fixed_size, bool body_dynamic_present, uint32_t body_dynamic_size) { struct smb2_request *req; @@ -113,7 +113,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ initialise a smb2 request for tree operations */ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode, - uint16_t body_fixed_size, BOOL body_dynamic_present, + uint16_t body_fixed_size, bool body_dynamic_present, uint32_t body_dynamic_size) { struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, @@ -157,16 +157,16 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req) /* receive a response to a packet */ -BOOL smb2_request_receive(struct smb2_request *req) +bool smb2_request_receive(struct smb2_request *req) { /* req can be NULL when a send has failed. This eliminates lots of NULL checks in each module */ - if (!req) return False; + if (!req) return false; /* keep receiving packets until this one is replied to */ while (req->state <= SMB2_REQUEST_RECV) { if (event_loop_once(req->transport->socket->event.ctx) != 0) { - return False; + return false; } } @@ -174,13 +174,13 @@ BOOL smb2_request_receive(struct smb2_request *req) } /* Return true if the last packet was in error */ -BOOL smb2_request_is_error(struct smb2_request *req) +bool smb2_request_is_error(struct smb2_request *req) { return NT_STATUS_IS_ERR(req->status); } /* Return true if the last packet was OK */ -BOOL smb2_request_is_ok(struct smb2_request *req) +bool smb2_request_is_ok(struct smb2_request *req) { return NT_STATUS_IS_OK(req->status); } @@ -188,16 +188,16 @@ BOOL smb2_request_is_ok(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) +bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) { /* be careful with wraparound! */ if (ptr < buf->body || ptr >= buf->body + buf->body_size || size > buf->body_size || ptr + size > buf->body + buf->body_size) { - return True; + return true; } - return False; + return false; } size_t smb2_padding_size(uint32_t offset, size_t n) diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 3f9b3ed55c..462f60d2c2 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -30,7 +30,7 @@ initialise a smb2_session structure */ struct smb2_session *smb2_session_init(struct smb2_transport *transport, - TALLOC_CTX *parent_ctx, BOOL primary) + TALLOC_CTX *parent_ctx, bool primary) { struct smb2_session *session; NTSTATUS status; @@ -68,7 +68,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, NTSTATUS status; req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, - 0x18, True, io->in.secblob.length); + 0x18, true, io->in.secblob.length); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); @@ -105,7 +105,7 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x08, True); + SMB2_CHECK_PACKET_RECV(req, 0x08, true); io->out._pad = SVAL(req->in.body, 0x02); io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index 67d433a48a..d942568a2d 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -32,7 +32,7 @@ struct smb2_request *smb2_setinfo_send(struct smb2_tree *tree, struct smb2_setin NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_SETINFO, 0x20, True, io->in.blob.length); + req = smb2_request_init_tree(tree, SMB2_OP_SETINFO, 0x20, true, io->in.blob.length); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.level); @@ -62,7 +62,7 @@ NTSTATUS smb2_setinfo_recv(struct smb2_request *req) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x02, False); + SMB2_CHECK_PACKET_RECV(req, 0x02, false); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 4f341d1206..ad1ba4c92d 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -27,7 +27,7 @@ initialise a smb2_session structure */ struct smb2_tree *smb2_tree_init(struct smb2_session *session, - TALLOC_CTX *parent_ctx, BOOL primary) + TALLOC_CTX *parent_ctx, bool primary) { struct smb2_tree *tree; @@ -53,7 +53,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, NTSTATUS status; req = smb2_request_init(tree->session->transport, SMB2_OP_TCON, - 0x08, True, 0); + 0x08, true, 0); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); @@ -81,7 +81,7 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x10, False); + SMB2_CHECK_PACKET_RECV(req, 0x10, false); io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID); diff --git a/source4/libcli/smb2/tdis.c b/source4/libcli/smb2/tdis.c index 6ad3120740..5adad9dc6e 100644 --- a/source4/libcli/smb2/tdis.c +++ b/source4/libcli/smb2/tdis.c @@ -30,7 +30,7 @@ struct smb2_request *smb2_tdis_send(struct smb2_tree *tree) { struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_TDIS, 0x04, False, 0); + req = smb2_request_init_tree(tree, SMB2_OP_TDIS, 0x04, false, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, 0); @@ -51,7 +51,7 @@ NTSTATUS smb2_tdis_recv(struct smb2_request *req) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x04, False); + SMB2_CHECK_PACKET_RECV(req, 0x04, false); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index de08201c8b..83e9436a58 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -193,7 +193,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { if (flags & 0x00000002) { - req->cancel.can_cancel = True; + req->cancel.can_cancel = true; req->cancel.pending_id = IVAL(hdr, SMB2_HDR_PID); for (i=0; i< req->cancel.do_cancel; i++) { smb2_cancel(req); diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c index 3d501dc915..bc283370d7 100644 --- a/source4/libcli/smb2/write.c +++ b/source4/libcli/smb2/write.c @@ -31,7 +31,7 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write * NTSTATUS status; struct smb2_request *req; - req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, True, io->in.data.length); + req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, true, io->in.data.length); if (req == NULL) return NULL; status = smb2_push_o16s32_blob(&req->out, 0x02, io->in.data); @@ -62,7 +62,7 @@ NTSTATUS smb2_write_recv(struct smb2_request *req, struct smb2_write *io) return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x10, True); + SMB2_CHECK_PACKET_RECV(req, 0x10, true); io->out._pad = SVAL(req->in.body, 0x02); io->out.nwritten = IVAL(req->in.body, 0x04); diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 23974619d6..9f18c0d924 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -116,12 +116,12 @@ static NTSTATUS connect_session_setup_anon(struct composite_context *c, status = smb_composite_sesssetup_recv(state->creq); NT_STATUS_NOT_OK_RETURN(status); - io->out.anonymous_fallback_done = True; + io->out.anonymous_fallback_done = true; state->session->vuid = state->io_setup->out.vuid; /* setup for a tconx */ - io->out.tree = smbcli_tree_init(state->session, state, True); + io->out.tree = smbcli_tree_init(state->session, state, true); NT_STATUS_HAVE_NO_MEMORY(io->out.tree); state->io_tcon = talloc(c, union smb_tcon); @@ -203,7 +203,7 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->session->vuid = state->io_setup->out.vuid; /* setup for a tconx */ - io->out.tree = smbcli_tree_init(state->session, state, True); + io->out.tree = smbcli_tree_init(state->session, state, true); NT_STATUS_HAVE_NO_MEMORY(io->out.tree); state->io_tcon = talloc(c, union smb_tcon); @@ -251,7 +251,7 @@ static NTSTATUS connect_negprot(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); /* next step is a session setup */ - state->session = smbcli_session_init(state->transport, state, True); + state->session = smbcli_session_init(state->transport, state, true); NT_STATUS_HAVE_NO_MEMORY(state->session); state->io_setup = talloc(c, struct smb_composite_sesssetup); @@ -307,7 +307,7 @@ static NTSTATUS connect_socket(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); /* the socket is up - we can initialise the smbcli transport layer */ - state->transport = smbcli_transport_init(state->sock, state, True); + state->transport = smbcli_transport_init(state->sock, state, true); NT_STATUS_HAVE_NO_MEMORY(state->transport); if (is_ipaddress(state->sock->hostname) && diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 63a10a667d..2dbaff5a66 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -142,7 +142,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; state->connect->in.credentials = io->in.credentials; - state->connect->in.fallback_to_anonymous = False; + state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; state->creq = smb_composite_connect_send(state->connect, state, event_ctx); diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index e81e3a2085..faf3723539 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -148,7 +148,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; state->connect->in.credentials = io->in.credentials; - state->connect->in.fallback_to_anonymous = False; + state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; c->state = COMPOSITE_STATE_IN_PROGRESS; diff --git a/source4/libcli/smb_composite/loadfile.c b/source4/libcli/smb_composite/loadfile.c index d42d3329b6..952f24b811 100644 --- a/source4/libcli/smb_composite/loadfile.c +++ b/source4/libcli/smb_composite/loadfile.c @@ -105,7 +105,7 @@ static NTSTATUS loadfile_open(struct composite_context *c, state->io_read->readx.in.mincnt = MIN(32768, io->out.size); state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt; state->io_read->readx.in.remaining = 0; - state->io_read->readx.in.read_for_execute = False; + state->io_read->readx.in.read_for_execute = false; state->io_read->readx.out.data = io->out.data; state->req = smb_raw_read_send(tree, state->io_read); diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index f2098de5c5..58cb5f07be 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -37,41 +37,41 @@ void asn1_free(struct asn1_data *data) } /* write to the ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_write(struct asn1_data *data, const void *p, int len) +bool asn1_write(struct asn1_data *data, const void *p, int len) { - if (data->has_error) return False; + if (data->has_error) return false; if (data->length < data->ofs+len) { uint8_t *newp; newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); if (!newp) { asn1_free(data); - data->has_error = True; - return False; + data->has_error = true; + return false; } data->data = newp; data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); data->ofs += len; - return True; + return true; } /* useful fn for writing a uint8_t */ -BOOL asn1_write_uint8(struct asn1_data *data, uint8_t v) +bool asn1_write_uint8(struct asn1_data *data, uint8_t v) { return asn1_write(data, &v, 1); } /* push a tag onto the asn1 data buffer. Used for nested structures */ -BOOL asn1_push_tag(struct asn1_data *data, uint8_t tag) +bool asn1_push_tag(struct asn1_data *data, uint8_t tag) { struct nesting *nesting; asn1_write_uint8(data, tag); nesting = talloc(data, struct nesting); if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } nesting->start = data->ofs; @@ -81,7 +81,7 @@ BOOL asn1_push_tag(struct asn1_data *data, uint8_t tag) } /* pop a tag */ -BOOL asn1_pop_tag(struct asn1_data *data) +bool asn1_pop_tag(struct asn1_data *data) { struct nesting *nesting; size_t len; @@ -89,8 +89,8 @@ BOOL asn1_pop_tag(struct asn1_data *data) nesting = data->nesting; if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } len = data->ofs - (nesting->start+1); /* yes, this is ugly. We don't know in advance how many bytes the length @@ -98,10 +98,10 @@ BOOL asn1_pop_tag(struct asn1_data *data) need to correct our mistake */ if (len > 0xFFFFFF) { data->data[nesting->start] = 0x84; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+5, data->data+nesting->start+1, len); data->data[nesting->start+1] = (len>>24) & 0xFF; data->data[nesting->start+2] = (len>>16) & 0xFF; @@ -109,23 +109,23 @@ BOOL asn1_pop_tag(struct asn1_data *data) data->data[nesting->start+4] = len&0xff; } else if (len > 0xFFFF) { data->data[nesting->start] = 0x83; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); data->data[nesting->start+1] = (len>>16) & 0xFF; data->data[nesting->start+2] = (len>>8) & 0xFF; data->data[nesting->start+3] = len&0xff; } else if (len > 255) { data->data[nesting->start] = 0x82; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); data->data[nesting->start+1] = len>>8; data->data[nesting->start+2] = len&0xff; } else if (len > 127) { data->data[nesting->start] = 0x81; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); data->data[nesting->start+1] = len; } else { @@ -134,20 +134,20 @@ BOOL asn1_pop_tag(struct asn1_data *data) data->nesting = nesting->next; talloc_free(nesting); - return True; + return true; } /* "i" is the one's complement representation, as is the normal result of an * implicit signed->unsigned conversion */ -static BOOL push_int_bigendian(struct asn1_data *data, unsigned int i, BOOL negative) +static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative) { uint8_t lowest = i & 0xFF; i = i >> 8; if (i != 0) if (!push_int_bigendian(data, i, negative)) - return False; + return false; if (data->nesting->start+1 == data->ofs) { @@ -157,14 +157,14 @@ static BOOL push_int_bigendian(struct asn1_data *data, unsigned int i, BOOL nega if (negative) { /* Don't write leading 0xff's */ if (lowest == 0xFF) - return True; + return true; if ((lowest & 0x80) == 0) { /* The only exception for a leading 0xff is if * the highest bit is 0, which would indicate * a positive value */ if (!asn1_write_uint8(data, 0xff)) - return False; + return false; } } else { if (lowest & 0x80) { @@ -172,7 +172,7 @@ static BOOL push_int_bigendian(struct asn1_data *data, unsigned int i, BOOL nega * this would indicate a negative number. Push * a 0 to indicate a positive one */ if (!asn1_write_uint8(data, 0)) - return False; + return false; } } } @@ -183,7 +183,7 @@ static BOOL push_int_bigendian(struct asn1_data *data, unsigned int i, BOOL nega /* write an Integer without the tag framing. Needed for example for the LDAP * Abandon Operation */ -BOOL asn1_write_implicit_Integer(struct asn1_data *data, int i) +bool asn1_write_implicit_Integer(struct asn1_data *data, int i) { if (i == -1) { /* -1 is special as it consists of all-0xff bytes. In @@ -198,14 +198,14 @@ BOOL asn1_write_implicit_Integer(struct asn1_data *data, int i) /* write an integer */ -BOOL asn1_write_Integer(struct asn1_data *data, int i) +bool asn1_write_Integer(struct asn1_data *data, int i) { - if (!asn1_push_tag(data, ASN1_INTEGER)) return False; - if (!asn1_write_implicit_Integer(data, i)) return False; + if (!asn1_push_tag(data, ASN1_INTEGER)) return false; + if (!asn1_write_implicit_Integer(data, i)) return false; return asn1_pop_tag(data); } -BOOL ber_write_OID_String(DATA_BLOB *blob, const char *OID) +bool ber_write_OID_String(DATA_BLOB *blob, const char *OID) { uint_t v, v2; const char *p = (const char *)OID; @@ -213,16 +213,16 @@ BOOL ber_write_OID_String(DATA_BLOB *blob, const char *OID) int i; v = strtoul(p, &newp, 10); - if (newp[0] != '.') return False; + if (newp[0] != '.') return false; p = newp + 1; v2 = strtoul(p, &newp, 10); - if (newp[0] != '.') return False; + if (newp[0] != '.') return false; p = newp + 1; /*the ber representation can't use more space then the string one */ *blob = data_blob(NULL, strlen(OID)); - if (!blob->data) return False; + if (!blob->data) return false; blob->data[0] = 40*v + v2; @@ -235,7 +235,7 @@ BOOL ber_write_OID_String(DATA_BLOB *blob, const char *OID) p = newp; } else { data_blob_free(blob); - return False; + return false; } if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f)); if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f)); @@ -246,31 +246,31 @@ BOOL ber_write_OID_String(DATA_BLOB *blob, const char *OID) blob->length = i; - return True; + return true; } /* write an object ID to a ASN1 buffer */ -BOOL asn1_write_OID(struct asn1_data *data, const char *OID) +bool asn1_write_OID(struct asn1_data *data, const char *OID) { DATA_BLOB blob; - if (!asn1_push_tag(data, ASN1_OID)) return False; + if (!asn1_push_tag(data, ASN1_OID)) return false; if (!ber_write_OID_String(&blob, OID)) { - data->has_error = True; - return False; + data->has_error = true; + return false; } if (!asn1_write(data, blob.data, blob.length)) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data_blob_free(&blob); return asn1_pop_tag(data); } /* write an octet string */ -BOOL asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) +bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) { asn1_push_tag(data, ASN1_OCTET_STRING); asn1_write(data, p, length); @@ -279,14 +279,14 @@ BOOL asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length } /* write a LDAP string */ -BOOL asn1_write_LDAPString(struct asn1_data *data, const char *s) +bool asn1_write_LDAPString(struct asn1_data *data, const char *s) { asn1_write(data, s, strlen(s)); return !data->has_error; } /* write a general string */ -BOOL asn1_write_GeneralString(struct asn1_data *data, const char *s) +bool asn1_write_GeneralString(struct asn1_data *data, const char *s) { asn1_push_tag(data, ASN1_GENERAL_STRING); asn1_write_LDAPString(data, s); @@ -294,7 +294,7 @@ BOOL asn1_write_GeneralString(struct asn1_data *data, const char *s) return !data->has_error; } -BOOL asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) +bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); asn1_write(data, blob->data, blob->length); @@ -303,7 +303,7 @@ BOOL asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *bl } /* write a BOOLEAN */ -BOOL asn1_write_BOOLEAN(struct asn1_data *data, BOOL v) +bool asn1_write_BOOLEAN(struct asn1_data *data, bool v) { asn1_push_tag(data, ASN1_BOOLEAN); asn1_write_uint8(data, v ? 0xFF : 0); @@ -311,140 +311,140 @@ BOOL asn1_write_BOOLEAN(struct asn1_data *data, BOOL v) return !data->has_error; } -BOOL asn1_read_BOOLEAN(struct asn1_data *data, BOOL *v) +bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v) { uint8_t tmp = 0; asn1_start_tag(data, ASN1_BOOLEAN); asn1_read_uint8(data, &tmp); if (tmp == 0xFF) { - *v = True; + *v = true; } else { - *v = False; + *v = false; } asn1_end_tag(data); return !data->has_error; } /* check a BOOLEAN */ -BOOL asn1_check_BOOLEAN(struct asn1_data *data, BOOL v) +bool asn1_check_BOOLEAN(struct asn1_data *data, bool v) { uint8_t b = 0; asn1_read_uint8(data, &b); if (b != ASN1_BOOLEAN) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read_uint8(data, &b); if (b != v) { - data->has_error = True; - return False; + data->has_error = true; + return false; } return !data->has_error; } /* load a struct asn1_data structure with a lump of data, ready to be parsed */ -BOOL asn1_load(struct asn1_data *data, DATA_BLOB blob) +bool asn1_load(struct asn1_data *data, DATA_BLOB blob) { ZERO_STRUCTP(data); data->data = talloc_memdup(data, blob.data, blob.length); if (!data->data) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data->length = blob.length; - return True; + return true; } /* Peek into an ASN1 buffer, not advancing the pointer */ -BOOL asn1_peek(struct asn1_data *data, void *p, int len) +bool asn1_peek(struct asn1_data *data, void *p, int len) { if (data->has_error) - return False; + return false; if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) - return False; + return false; if (data->ofs + len > data->length) { /* we need to mark the buffer as consumed, so the caller knows this was an out of data error, and not a decode error */ data->ofs = data->length; - return False; + return false; } memcpy(p, data->data + data->ofs, len); - return True; + return true; } /* read from a ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_read(struct asn1_data *data, void *p, int len) +bool asn1_read(struct asn1_data *data, void *p, int len) { if (!asn1_peek(data, p, len)) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data->ofs += len; - return True; + return true; } /* read a uint8_t from a ASN1 buffer */ -BOOL asn1_read_uint8(struct asn1_data *data, uint8_t *v) +bool asn1_read_uint8(struct asn1_data *data, uint8_t *v) { return asn1_read(data, v, 1); } -BOOL asn1_peek_uint8(struct asn1_data *data, uint8_t *v) +bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v) { return asn1_peek(data, v, 1); } -BOOL asn1_peek_tag(struct asn1_data *data, uint8_t tag) +bool asn1_peek_tag(struct asn1_data *data, uint8_t tag) { uint8_t b; if (asn1_tag_remaining(data) <= 0) { - return False; + return false; } if (!asn1_peek_uint8(data, &b)) - return False; + return false; return (b == tag); } /* start reading a nested asn1 structure */ -BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) +bool asn1_start_tag(struct asn1_data *data, uint8_t tag) { uint8_t b; struct nesting *nesting; if (!asn1_read_uint8(data, &b)) - return False; + return false; if (b != tag) { - data->has_error = True; - return False; + data->has_error = true; + return false; } nesting = talloc(data, struct nesting); if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } if (!asn1_read_uint8(data, &b)) { - return False; + return false; } if (b & 0x80) { int n = b & 0x7f; if (!asn1_read_uint8(data, &b)) - return False; + return false; nesting->taglen = b; while (n > 1) { if (!asn1_read_uint8(data, &b)) - return False; + return false; nesting->taglen = (nesting->taglen << 8) | b; n--; } @@ -455,32 +455,32 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) nesting->next = data->nesting; data->nesting = nesting; if (asn1_tag_remaining(data) == -1) { - return False; + return false; } return !data->has_error; } /* stop reading a tag */ -BOOL asn1_end_tag(struct asn1_data *data) +bool asn1_end_tag(struct asn1_data *data) { struct nesting *nesting; /* make sure we read it all */ if (asn1_tag_remaining(data) != 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } nesting = data->nesting; if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data->nesting = nesting->next; talloc_free(nesting); - return True; + return true; } /* work out how many bytes are left in this nested tag */ @@ -492,26 +492,26 @@ int asn1_tag_remaining(struct asn1_data *data) } if (!data->nesting) { - data->has_error = True; + data->has_error = true; return -1; } remaining = data->nesting->taglen - (data->ofs - data->nesting->start); if (remaining > (data->length - data->ofs)) { - data->has_error = True; + data->has_error = true; return -1; } return remaining; } /* read an object ID from a data blob */ -BOOL ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) +bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) { int i; uint8_t *b; uint_t v; char *tmp_oid = NULL; - if (blob.length < 2) return False; + if (blob.length < 2) return false; b = blob.data; @@ -531,82 +531,82 @@ BOOL ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) if (v != 0) { talloc_free(tmp_oid); - return False; + return false; } *OID = tmp_oid; - return True; + return true; nomem: - return False; + return false; } /* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID) +bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID) { DATA_BLOB blob; int len; - if (!asn1_start_tag(data, ASN1_OID)) return False; + if (!asn1_start_tag(data, ASN1_OID)) return false; len = asn1_tag_remaining(data); if (len < 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } blob = data_blob(NULL, len); if (!blob.data) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read(data, blob.data, len); asn1_end_tag(data); if (data->has_error) { data_blob_free(&blob); - return False; + return false; } if (!ber_read_OID_String(mem_ctx, blob, OID)) { - data->has_error = True; + data->has_error = true; data_blob_free(&blob); - return False; + return false; } data_blob_free(&blob); - return True; + return true; } /* check that the next object ID is correct */ -BOOL asn1_check_OID(struct asn1_data *data, const char *OID) +bool asn1_check_OID(struct asn1_data *data, const char *OID) { const char *id; - if (!asn1_read_OID(data, data, &id)) return False; + if (!asn1_read_OID(data, data, &id)) return false; if (strcmp(id, OID) != 0) { talloc_free(discard_const(id)); - data->has_error = True; - return False; + data->has_error = true; + return false; } talloc_free(discard_const(id)); - return True; + return true; } /* read a LDAPString from a ASN1 buffer */ -BOOL asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) +bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) { int len; len = asn1_tag_remaining(data); if (len < 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } *s = talloc_array(mem_ctx, char, len+1); if (! *s) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read(data, *s, len); (*s)[len] = 0; @@ -615,29 +615,29 @@ BOOL asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) /* read a GeneralString from a ASN1 buffer */ -BOOL asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) +bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) { - if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; - if (!asn1_read_LDAPString(data, mem_ctx, s)) return False; + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false; + if (!asn1_read_LDAPString(data, mem_ctx, s)) return false; return asn1_end_tag(data); } /* read a octet string blob */ -BOOL asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) +bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; + if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false; len = asn1_tag_remaining(data); if (len < 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } *blob = data_blob_talloc(mem_ctx, NULL, len+1); if (!blob->data) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read(data, blob->data, len); asn1_end_tag(data); @@ -647,25 +647,25 @@ BOOL asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLO if (data->has_error) { data_blob_free(blob); *blob = data_blob(NULL, 0); - return False; + return false; } - return True; + return true; } -BOOL asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) +bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return False; + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false; len = asn1_tag_remaining(data); if (len < 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } *blob = data_blob(NULL, len); if ((len != 0) && (!blob->data)) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read(data, blob->data, len); asn1_end_tag(data); @@ -673,13 +673,13 @@ BOOL asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blo } /* read an interger without tag*/ -BOOL asn1_read_implicit_Integer(struct asn1_data *data, int *i) +bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) { uint8_t b; *i = 0; while (!data->has_error && asn1_tag_remaining(data)>0) { - if (!asn1_read_uint8(data, &b)) return False; + if (!asn1_read_uint8(data, &b)) return false; *i = (*i << 8) + b; } return !data->has_error; @@ -687,21 +687,21 @@ BOOL asn1_read_implicit_Integer(struct asn1_data *data, int *i) } /* read an interger */ -BOOL asn1_read_Integer(struct asn1_data *data, int *i) +bool asn1_read_Integer(struct asn1_data *data, int *i) { *i = 0; - if (!asn1_start_tag(data, ASN1_INTEGER)) return False; - if (!asn1_read_implicit_Integer(data, i)) return False; + if (!asn1_start_tag(data, ASN1_INTEGER)) return false; + if (!asn1_read_implicit_Integer(data, i)) return false; return asn1_end_tag(data); } /* read an interger */ -BOOL asn1_read_enumerated(struct asn1_data *data, int *v) +bool asn1_read_enumerated(struct asn1_data *data, int *v) { *v = 0; - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; while (!data->has_error && asn1_tag_remaining(data)>0) { uint8_t b; asn1_read_uint8(data, &b); @@ -711,23 +711,23 @@ BOOL asn1_read_enumerated(struct asn1_data *data, int *v) } /* check a enumarted value is correct */ -BOOL asn1_check_enumerated(struct asn1_data *data, int v) +bool asn1_check_enumerated(struct asn1_data *data, int v) { uint8_t b; - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; asn1_read_uint8(data, &b); asn1_end_tag(data); if (v != b) - data->has_error = False; + data->has_error = false; return !data->has_error; } /* write an enumarted value to the stream */ -BOOL asn1_write_enumerated(struct asn1_data *data, uint8_t v) +bool asn1_write_enumerated(struct asn1_data *data, uint8_t v) { - if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; + if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; asn1_write_uint8(data, v); asn1_pop_tag(data); return !data->has_error; diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 0fdf8a8e3a..7c32294648 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -61,7 +61,7 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) return NT_STATUS_NO_MEMORY; } - lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, False); + lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, false); if (lsa->ipc_tree == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 49384817b6..8d088e1e4b 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1162,7 +1162,7 @@ static const struct { /* check if a DOS encoded NTSTATUS code maps to the given NTSTATUS code */ -BOOL ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2) +bool ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2) { /* when we negotiate nt status support, we don't want to consider the mapping of dos codes, as we want to catch the cases where diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 5b2a9e1e4a..90714f774b 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -37,7 +37,7 @@ static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, N */ static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket, NTSTATUS status) { - wrepl_socket->dead = True; + wrepl_socket->dead = true; if (wrepl_socket->packet) { packet_recv_disable(wrepl_socket->packet); @@ -148,7 +148,7 @@ static void wrepl_error(void *private, NTSTATUS status) static int wrepl_socket_destructor(struct wrepl_socket *sock) { if (sock->dead) { - sock->free_skipped = True; + sock->free_skipped = true; return -1; } wrepl_socket_dead(sock, NT_STATUS_LOCAL_DISCONNECT); @@ -387,7 +387,7 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed /* trigger an immediate event on a wrepl_request the return value should only be used in wrepl_request_send() - this is the only place where req->trigger is True + this is the only place where req->trigger is true */ static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status) { @@ -406,7 +406,7 @@ static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, N req->status = status; if (req->trigger) { - req->trigger = False; + req->trigger = false; /* a zero timeout means immediate */ te = event_add_timed(req->wrepl_socket->event.ctx, req, timeval_zero(), @@ -448,7 +448,7 @@ static int wrepl_send_ctrl_destructor(struct wrepl_send_ctrl_state *s) /* here, we need to make sure the async request handler is called * later in the next event_loop and now now */ - req->trigger = True; + req->trigger = true; wrepl_request_finished(req, NT_STATUS_OK); if (s->ctrl.disconnect_after_send) { @@ -473,7 +473,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, if (!req) return NULL; req->wrepl_socket = wrepl_socket; req->state = WREPL_REQUEST_RECV; - req->trigger = True; + req->trigger = true; DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *); talloc_set_destructor(req, wrepl_request_destructor); @@ -516,7 +516,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, return wrepl_request_finished(req, req->status); } - req->trigger = False; + req->trigger = false; return req; } @@ -638,8 +638,8 @@ struct wrepl_request *wrepl_associate_stop_send(struct wrepl_socket *wrepl_socke ZERO_STRUCT(ctrl); if (io->in.reason == 0) { - ctrl.send_only = True; - ctrl.disconnect_after_send = True; + ctrl.send_only = true; + ctrl.disconnect_after_send = true; } req = wrepl_request_send(wrepl_socket, packet, &ctrl); diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 3265024407..8ce8b418a2 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -120,7 +120,7 @@ struct wrepl_pull_table { #define WREPL_NAME_TYPE(flags) (flags & WREPL_FLAGS_RECORD_TYPE) #define WREPL_NAME_STATE(flags) ((flags & WREPL_FLAGS_RECORD_STATE)>>2) #define WREPL_NAME_NODE(flags) ((flags & WREPL_FLAGS_NODE_TYPE)>>5) -#define WREPL_NAME_IS_STATIC(flags) ((flags & WREPL_FLAGS_IS_STATIC)?True:False) +#define WREPL_NAME_IS_STATIC(flags) ((flags & WREPL_FLAGS_IS_STATIC)?true:false) #define WREPL_NAME_FLAGS(type, state, node, is_static) \ (type | (state << 2) | (node << 5) | \ -- cgit From b0ef52e959265932c848a888453937162e3414ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Oct 2007 14:21:22 +0000 Subject: r25578: BOOL -> bool metze (This used to be commit 198e8d7fff285fc70f2525af2a34a61d385b0d29) --- source4/libcli/swig/libcli_nbt.i | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index 9aa81acd1f..ec7632ccf4 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -39,7 +39,7 @@ %} -%apply bool { BOOL }; +%apply bool { bool }; %apply int { uint8_t }; %apply int { int8_t }; %apply unsigned int { uint16_t }; @@ -112,8 +112,8 @@ struct nbt_name_query { struct { struct nbt_name name; const char *dest_addr; - BOOL broadcast; - BOOL wins_lookup; + bool broadcast; + bool wins_lookup; int timeout; /* in seconds */ int retries; } in; -- cgit From 34d166111e4faca4dd13f0d2fc111eb1167e9b04 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 12:42:55 +0200 Subject: r25604: Add security_descriptor_append() helper function. Guenther (This used to be commit 7d8f53b1c73dc4025821d96d8f675b6866407acb) --- source4/libcli/security/security_descriptor.c | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 7ed619d0c4..1d8549a605 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -336,6 +336,48 @@ bool security_descriptor_mask_equal(const struct security_descriptor *sd1, NULL); that would create a sd with one DACL ACE */ + +struct security_descriptor *security_descriptor_append(struct security_descriptor *sd, + ...) +{ + va_list ap; + const char *sidstr; + + va_start(ap, sd); + while ((sidstr = va_arg(ap, const char *))) { + struct dom_sid *sid; + struct security_ace *ace = talloc(sd, struct security_ace); + NTSTATUS status; + + if (ace == NULL) { + talloc_free(sd); + va_end(ap); + return NULL; + } + ace->type = va_arg(ap, unsigned int); + ace->access_mask = va_arg(ap, unsigned int); + ace->flags = va_arg(ap, unsigned int); + sid = dom_sid_parse_talloc(ace, sidstr); + if (sid == NULL) { + va_end(ap); + talloc_free(sd); + return NULL; + } + ace->trustee = *sid; + status = security_descriptor_dacl_add(sd, ace); + /* TODO: check: would talloc_free(ace) here be correct? */ + if (!NT_STATUS_IS_OK(status)) { + va_end(ap); + talloc_free(sd); + return NULL; + } + } + va_end(ap); + + return sd; + +} + struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, const char *owner_sid, const char *group_sid, -- cgit From a6c4b9d1793c7ea1965a23e1d23b73012acd151b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 13:12:53 +0200 Subject: r25607: Allow to set security descriptor type flags at creation time with security_descriptor_create(). Guenther (This used to be commit 7dd0d28d254f78891b0807492baafa188b42df16) --- source4/libcli/security/security_descriptor.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 1d8549a605..9723e8ccca 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -327,6 +327,7 @@ bool security_descriptor_mask_equal(const struct security_descriptor *sd1, a typical call would be: sd = security_descriptor_create(mem_ctx, + sd_type_flags, mysid, mygroup, SID_NT_AUTHENTICATED_USERS, @@ -379,6 +380,7 @@ struct security_descriptor *security_descriptor_append(struct security_descripto } struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, + uint16_t sd_type, const char *owner_sid, const char *group_sid, ...) @@ -390,6 +392,8 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, sd = security_descriptor_initialise(mem_ctx); if (sd == NULL) return NULL; + sd->type |= sd_type; + if (owner_sid) { sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid); if (sd->owner_sid == NULL) { -- cgit From 39f1dab9ebbeb55bbc65db4f5f1c739d02ab3bb2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 13:17:28 +0200 Subject: r25608: Call security_descriptor_append from within security_descriptor_create. Guenther (This used to be commit 1ebcceb922bdb566e6a548aa1ad816eb8e9e26e9) --- source4/libcli/security/security_descriptor.c | 30 +-------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 9723e8ccca..d744f2cc8d 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -387,7 +387,6 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, { va_list ap; struct security_descriptor *sd; - const char *sidstr; sd = security_descriptor_initialise(mem_ctx); if (sd == NULL) return NULL; @@ -410,34 +409,7 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, } va_start(ap, group_sid); - while ((sidstr = va_arg(ap, const char *))) { - struct dom_sid *sid; - struct security_ace *ace = talloc(sd, struct security_ace); - NTSTATUS status; - - if (ace == NULL) { - talloc_free(sd); - va_end(ap); - return NULL; - } - ace->type = va_arg(ap, unsigned int); - ace->access_mask = va_arg(ap, unsigned int); - ace->flags = va_arg(ap, unsigned int); - sid = dom_sid_parse_talloc(ace, sidstr); - if (sid == NULL) { - va_end(ap); - talloc_free(sd); - return NULL; - } - ace->trustee = *sid; - status = security_descriptor_dacl_add(sd, ace); - /* TODO: check: would talloc_free(ace) here be correct? */ - if (!NT_STATUS_IS_OK(status)) { - va_end(ap); - talloc_free(sd); - return NULL; - } - } + sd = security_descriptor_append(sd, ap); va_end(ap); return sd; -- cgit From 4fb9aeb55650bdd10288870dd9c4e1567f73a3f8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 13:49:15 +0200 Subject: r25610: Add security_descriptor_appendv() which takes va_list directly. Guenther (This used to be commit 99408cf20c6feb745cd2dd56c37015cfa11e9b3d) --- source4/libcli/security/security_descriptor.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index d744f2cc8d..9454560c94 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -338,13 +338,11 @@ bool security_descriptor_mask_equal(const struct security_descriptor *sd1, that would create a sd with one DACL ACE */ -struct security_descriptor *security_descriptor_append(struct security_descriptor *sd, - ...) +struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd, + va_list ap) { - va_list ap; const char *sidstr; - va_start(ap, sd); while ((sidstr = va_arg(ap, const char *))) { struct dom_sid *sid; struct security_ace *ace = talloc(sd, struct security_ace); @@ -352,7 +350,6 @@ struct security_descriptor *security_descriptor_append(struct security_descripto if (ace == NULL) { talloc_free(sd); - va_end(ap); return NULL; } ace->type = va_arg(ap, unsigned int); @@ -360,7 +357,6 @@ struct security_descriptor *security_descriptor_append(struct security_descripto ace->flags = va_arg(ap, unsigned int); sid = dom_sid_parse_talloc(ace, sidstr); if (sid == NULL) { - va_end(ap); talloc_free(sd); return NULL; } @@ -368,15 +364,24 @@ struct security_descriptor *security_descriptor_append(struct security_descripto status = security_descriptor_dacl_add(sd, ace); /* TODO: check: would talloc_free(ace) here be correct? */ if (!NT_STATUS_IS_OK(status)) { - va_end(ap); talloc_free(sd); return NULL; } } - va_end(ap); return sd; +} +struct security_descriptor *security_descriptor_append(struct security_descriptor *sd, + ...) +{ + va_list ap; + + va_start(ap, sd); + sd = security_descriptor_appendv(sd, ap); + va_end(ap); + + return sd; } struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, @@ -409,7 +414,7 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, } va_start(ap, group_sid); - sd = security_descriptor_append(sd, ap); + sd = security_descriptor_appendv(sd, ap); va_end(ap); return sd; -- cgit From b09047b78e981af8ade6a72d426bfcb0e742995b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 13 Oct 2007 20:24:37 +0200 Subject: r25624: Remove ipv4_addr hack. Only causes 4 extra includes of system/network.h because we stripped down includes. (This used to be commit 262c1c23a61f1f4fae13e0a61179fe98b682cecf) --- source4/libcli/resolve/host.c | 4 ++-- source4/libcli/resolve/resolve.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index ec394309ef..e98bbc51b2 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -65,14 +65,14 @@ static int host_destructor(struct host_state *state) static void run_child(struct composite_context *c, int fd) { struct host_state *state = talloc_get_type(c->private_data, struct host_state); - struct ipv4_addr ip; + struct in_addr ip; const char *address; /* this is the blocking call we are going to lots of trouble to avoid in the parent */ ip = interpret_addr2(state->name.name); - address = sys_inet_ntoa(ip); + address = inet_ntoa(ip); if (address != NULL) { write(fd, address, strlen(address)+1); } diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 02e1fbdc04..24113db9f0 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -25,6 +25,7 @@ #include "libcli/resolve/resolve.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" +#include "system/network.h" struct resolve_state { struct nbt_name name; @@ -151,8 +152,8 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ if (is_ipaddress(state->name.name) || strcasecmp(state->name.name, "localhost") == 0) { - struct ipv4_addr ip = interpret_addr2(state->name.name); - state->reply_addr = talloc_strdup(state, sys_inet_ntoa(ip)); + struct in_addr ip = interpret_addr2(state->name.name); + state->reply_addr = talloc_strdup(state, inet_ntoa(ip)); if (composite_nomem(state->reply_addr, c)) return c; composite_done(c); return c; -- cgit From 4860557842a8b5e2c5ceba03c64f42996f0bf60c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 16 Oct 2007 11:39:40 +0200 Subject: r25665: Add some more WERR codes. Guenther (This used to be commit 846d81c0ade7a1b56366feb4338312c24dc4351b) --- source4/libcli/util/doserr.c | 3 +++ source4/libcli/util/werror.h | 8 ++++++++ 2 files changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 49818e573a..28618dbf2b 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -119,6 +119,9 @@ static const struct werror_code_struct dos_errs[] = { "WERR_SEC_E_ENCRYPT_FAILURE", WERR_SEC_E_ENCRYPT_FAILURE }, { "WERR_SEC_E_DECRYPT_FAILURE", WERR_SEC_E_DECRYPT_FAILURE }, { "WERR_SEC_E_ALGORITHM_MISMATCH", WERR_SEC_E_ALGORITHM_MISMATCH }, + { "WERR_NOT_AUTHENTICATED", WERR_NOT_AUTHENTICATED }, + { "WERR_CALL_NOT_IMPLEMENTED", WERR_CALL_NOT_IMPLEMENTED }, + { "WERR_FRS_INVALID_SERVICE_PARAMETER", WERR_FRS_INVALID_SERVICE_PARAMETER }, { NULL, W_ERROR(0) } }; diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 55a4faa6a5..bde58265d4 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -79,6 +79,7 @@ typedef uint32_t WERROR; #define WERR_FILE_EXISTS W_ERROR(80) #define WERR_BAD_PASSWORD W_ERROR(86) #define WERR_INVALID_PARAM W_ERROR(87) +#define WERR_CALL_NOT_IMPLEMENTED W_ERROR(120) #define WERR_INSUFFICIENT_BUFFER W_ERROR(122) #define WERR_INVALID_NAME W_ERROR(123) #define WERR_UNKNOWN_LEVEL W_ERROR(124) @@ -90,6 +91,7 @@ typedef uint32_t WERROR; #define WERR_NOT_FOUND W_ERROR(1168) #define WERR_INVALID_COMPUTERNAME W_ERROR(1210) #define WERR_INVALID_DOMAINNAME W_ERROR(1212) +#define WERR_NOT_AUTHENTICATED W_ERROR(1244) #define WERR_UNKNOWN_REVISION W_ERROR(1305) #define WERR_REVISION_MISMATCH W_ERROR(1306) #define WERR_INVALID_OWNER W_ERROR(1307) @@ -176,6 +178,12 @@ typedef uint32_t WERROR; #define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194) #define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) +/* FRS errors */ +#ifndef FRS_ERR_BASE +#define FRS_ERR_BASE (8000) +#endif +#define WERR_FRS_INVALID_SERVICE_PARAMETER W_ERROR(FRS_ERROR_BASE+17) + /* SEC errors */ #define WERR_SEC_E_ENCRYPT_FAILURE W_ERROR(0x80090329) #define WERR_SEC_E_DECRYPT_FAILURE W_ERROR(0x80090330) -- cgit From 6282194fe5288f0118135ea492d8ec68d093491d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 16 Oct 2007 13:50:40 +0200 Subject: r25668: Hopefully fix the build, sorry... Guenther (This used to be commit df94fbfe96200ed521fd377a01b6b7b7a7ef88d8) --- source4/libcli/util/doserr.h | 4 ++++ source4/libcli/util/werror.h | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.h b/source4/libcli/util/doserr.h index bec268a565..6c757a3fc2 100644 --- a/source4/libcli/util/doserr.h +++ b/source4/libcli/util/doserr.h @@ -165,4 +165,8 @@ #define NERR_BASE (2100) #endif +#ifndef FRS_ERR_BASE +#define FRS_ERR_BASE (8000) +#endif + #endif /* _DOSERR_H */ diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index bde58265d4..48f5b40091 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -179,9 +179,6 @@ typedef uint32_t WERROR; #define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) /* FRS errors */ -#ifndef FRS_ERR_BASE -#define FRS_ERR_BASE (8000) -#endif #define WERR_FRS_INVALID_SERVICE_PARAMETER W_ERROR(FRS_ERROR_BASE+17) /* SEC errors */ -- cgit From 47f67ef366bca56ad9b4a561d183a35aa464b4ba Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 16 Oct 2007 14:09:49 +0200 Subject: r25669: Real build fix. Guenther (This used to be commit 1b9e526bf60372e5b3731e98dbfcc029b04e4b01) --- source4/libcli/util/werror.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 48f5b40091..e058120dce 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -179,7 +179,7 @@ typedef uint32_t WERROR; #define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) /* FRS errors */ -#define WERR_FRS_INVALID_SERVICE_PARAMETER W_ERROR(FRS_ERROR_BASE+17) +#define WERR_FRS_INVALID_SERVICE_PARAMETER W_ERROR(FRS_ERR_BASE+17) /* SEC errors */ #define WERR_SEC_E_ENCRYPT_FAILURE W_ERROR(0x80090329) -- cgit From 177faf940f79398303c5566ff2771a4b742bd862 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 16 Oct 2007 17:22:03 +0200 Subject: r25672: Some more FRS werrors. Guenther (This used to be commit 8fa3de8dca9e9d0d9f7fc79e4fc78b85313f870b) --- source4/libcli/util/doserr.c | 2 ++ source4/libcli/util/werror.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 28618dbf2b..e94b50a6de 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -122,6 +122,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_NOT_AUTHENTICATED", WERR_NOT_AUTHENTICATED }, { "WERR_CALL_NOT_IMPLEMENTED", WERR_CALL_NOT_IMPLEMENTED }, { "WERR_FRS_INVALID_SERVICE_PARAMETER", WERR_FRS_INVALID_SERVICE_PARAMETER }, + { "WERR_FRS_SYSVOL_IS_BUSY", WERR_FRS_SYSVOL_IS_BUSY }, + { "WERR_FRS_INSUFFICIENT_PRIV", WERR_FRS_INSUFFICIENT_PRIV }, { NULL, W_ERROR(0) } }; diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index e058120dce..d356b160d8 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -179,6 +179,8 @@ typedef uint32_t WERROR; #define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195) /* FRS errors */ +#define WERR_FRS_INSUFFICIENT_PRIV W_ERROR(FRS_ERR_BASE+7) +#define WERR_FRS_SYSVOL_IS_BUSY W_ERROR(FRS_ERR_BASE+15) #define WERR_FRS_INVALID_SERVICE_PARAMETER W_ERROR(FRS_ERR_BASE+17) /* SEC errors */ -- cgit From 5861a17042d1dfb9ae77a519b7e0da9484c2074c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Oct 2007 03:32:07 +0200 Subject: r25692: fixed another example where the free of fde and the free of the socket causes the fd to be closed before epoll is told (This used to be commit d19686cf8a3aba0c6601c5fa58cbf74461055c1c) --- source4/libcli/ldap/ldap_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index aea95de161..fcb2d92214 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -366,12 +366,14 @@ static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_con /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, socket_get_fd(conn->sock), - EVENT_FD_READ, ldap_io_handler, conn); + EVENT_FD_READ | EVENT_FD_AUTOCLOSE, ldap_io_handler, conn); if (conn->event.fde == NULL) { composite_error(ctx, NT_STATUS_INTERNAL_ERROR); return; } + socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE); + talloc_steal(conn, conn->sock); if (conn->ldaps) { struct socket_context *tls_socket = tls_init_client(conn->sock, conn->event.fde); -- cgit From e53e4a15fd3cebc623fc9ca60823a98be846c7af Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 26 Oct 2007 12:56:02 +0200 Subject: r25739: We forgot to copy revision and type flags in security_descriptor_copy(). Guenther (This used to be commit 2e028503a36acd12009a4d2f0d217b2d940c9c30) --- source4/libcli/security/security_descriptor.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 9454560c94..75c20b52cf 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -130,6 +130,9 @@ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, } } + nsd->revision = osd->revision; + nsd->type = osd->type; + return nsd; failed: -- cgit From 2eb71ba516868576be26d122d12baf94cf52726d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 1 Nov 2007 08:15:41 +0100 Subject: r25775: use ndr_pull_union_blob_all() in CLDAP code metze (This used to be commit 58e202a39b1a0d9b9c64b9136a894257da539c6e) --- source4/libcli/cldap/cldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index f2f661acaa..54b5995377 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -614,16 +614,16 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - status = ndr_pull_union_blob(data, mem_ctx, &io->out.netlogon, - io->in.version & 0xF, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + status = ndr_pull_union_blob_all(data, mem_ctx, &io->out.netlogon, + io->in.version & 0xF, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", SVAL(data->data, 0))); dump_data(10, data->data, data->length); } - return status; + return NT_STATUS_OK; } /* -- cgit From fdb369530baf334be9f6af2dff20d7119bf3cad3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Nov 2007 09:15:12 +0100 Subject: r25791: wrepl_request_finished() sets req->status, so make this explicit and avoid req->status = req->status... metze (This used to be commit c9ee0f3e967b89033510d30136363a3b78fedb9e) --- source4/libcli/wrepl/winsrepl.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 90714f774b..29cc1f37fd 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -85,6 +85,7 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) struct wrepl_socket *wrepl_socket = talloc_get_type(private, struct wrepl_socket); struct wrepl_request *req = wrepl_socket->recv_queue; DATA_BLOB blob; + NTSTATUS status; if (!req) { DEBUG(1,("Received unexpected WINS packet of length %u!\n", @@ -99,11 +100,11 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) blob.length = packet_blob_in.length - 4; /* we have a full request - parse it */ - req->status = ndr_pull_struct_blob(&blob, - req->packet, req->packet, - (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); - if (!NT_STATUS_IS_OK(req->status)) { - wrepl_request_finished(req, req->status); + status = ndr_pull_struct_blob(&blob, + req->packet, req->packet, + (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); + if (!NT_STATUS_IS_OK(status)) { + wrepl_request_finished(req, status); return NT_STATUS_OK; } @@ -113,7 +114,7 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) NDR_PRINT_DEBUG(wrepl_packet, req->packet); } - wrepl_request_finished(req, req->status); + wrepl_request_finished(req, NT_STATUS_OK); return NT_STATUS_OK; } @@ -468,6 +469,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, struct wrepl_request *req; struct wrepl_wrap wrap; DATA_BLOB blob; + NTSTATUS status; req = talloc_zero(wrepl_socket, struct wrepl_request); if (!req) return NULL; @@ -483,10 +485,10 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, } wrap.packet = *packet; - req->status = ndr_push_struct_blob(&blob, req, &wrap, - (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); - if (!NT_STATUS_IS_OK(req->status)) { - return wrepl_request_finished(req, req->status); + status = ndr_push_struct_blob(&blob, req, &wrap, + (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); + if (!NT_STATUS_IS_OK(status)) { + return wrepl_request_finished(req, status); } if (DEBUGLVL(10)) { @@ -511,9 +513,9 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, talloc_set_destructor(s, wrepl_send_ctrl_destructor); } - req->status = packet_send(wrepl_socket->packet, blob); - if (!NT_STATUS_IS_OK(req->status)) { - return wrepl_request_finished(req, req->status); + status = packet_send(wrepl_socket->packet, blob); + if (!NT_STATUS_IS_OK(status)) { + return wrepl_request_finished(req, status); } req->trigger = false; -- cgit From 2342d611ace6e2a76cfd7e0cf408d3a497c89ba0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 2 Nov 2007 11:51:26 +0100 Subject: r25801: Add security_ace_create() function. Guenther (This used to be commit 0306e0183d4db0da331449b411814e7a93b6db2d) --- source4/libcli/security/security_descriptor.c | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 75c20b52cf..34ccab593d 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -422,3 +422,32 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, return sd; } + +struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx, + const char *sid_str, + enum security_ace_type type, + uint32_t access_mask, + uint8_t flags) + +{ + struct dom_sid *sid; + struct security_ace *ace; + + ace = talloc_zero(mem_ctx, struct security_ace); + if (ace == NULL) { + return NULL; + } + + sid = dom_sid_parse_talloc(ace, sid_str); + if (sid == NULL) { + talloc_free(ace); + return NULL; + } + + ace->trustee = *sid; + ace->type = type; + ace->access_mask = access_mask; + ace->flags = flags; + + return ace; +} -- cgit From f2002541ced97da3658348fe9ac9e212dd50c55b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 2 Nov 2007 12:54:19 +0100 Subject: r25803: Make our security descriptor acl manipulation methods more generic so that we can add and delete ACEs for SACLs as well as for DACLs. Guenther (This used to be commit 947fff994181f0ae50ac76d09621ddd684873112) --- source4/libcli/security/security_descriptor.c | 247 ++++++++++++++++++-------- 1 file changed, 174 insertions(+), 73 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 34ccab593d..6a124d7371 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -142,78 +142,123 @@ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, } /* - add an ACE to the DACL of a security_descriptor + add an ACE to an ACL of a security_descriptor */ -NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, - const struct security_ace *ace) + +static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd, + bool add_to_sacl, + const struct security_ace *ace) { - if (sd->dacl == NULL) { - sd->dacl = talloc(sd, struct security_acl); - if (sd->dacl == NULL) { + struct security_acl *acl = NULL; + + if (add_to_sacl) { + acl = sd->sacl; + } else { + acl = sd->dacl; + } + + if (acl == NULL) { + acl = talloc(sd, struct security_acl); + if (acl == NULL) { return NT_STATUS_NO_MEMORY; } - sd->dacl->revision = SECURITY_ACL_REVISION_NT4; - sd->dacl->size = 0; - sd->dacl->num_aces = 0; - sd->dacl->aces = NULL; + acl->revision = SECURITY_ACL_REVISION_NT4; + acl->size = 0; + acl->num_aces = 0; + acl->aces = NULL; } - sd->dacl->aces = talloc_realloc(sd->dacl, sd->dacl->aces, - struct security_ace, sd->dacl->num_aces+1); - if (sd->dacl->aces == NULL) { + acl->aces = talloc_realloc(acl, acl->aces, + struct security_ace, acl->num_aces+1); + if (acl->aces == NULL) { return NT_STATUS_NO_MEMORY; } - sd->dacl->aces[sd->dacl->num_aces] = *ace; - sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths = - (uint32_t *)talloc_memdup(sd->dacl->aces, - sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths, - sizeof(uint32_t) * - sd->dacl->aces[sd->dacl->num_aces].trustee.num_auths); - if (sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths == NULL) { + acl->aces[acl->num_aces] = *ace; + acl->aces[acl->num_aces].trustee.sub_auths = + (uint32_t *)talloc_memdup(acl->aces, + acl->aces[acl->num_aces].trustee.sub_auths, + sizeof(uint32_t) * + acl->aces[acl->num_aces].trustee.num_auths); + if (acl->aces[acl->num_aces].trustee.sub_auths == NULL) { return NT_STATUS_NO_MEMORY; } - switch (sd->dacl->aces[sd->dacl->num_aces].type) { + switch (acl->aces[acl->num_aces].type) { case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: - sd->dacl->revision = SECURITY_ACL_REVISION_ADS; + acl->revision = SECURITY_ACL_REVISION_ADS; break; default: break; } - sd->dacl->num_aces++; + acl->num_aces++; - sd->type |= SEC_DESC_DACL_PRESENT; + if (add_to_sacl) { + sd->sacl = acl; + sd->type |= SEC_DESC_SACL_PRESENT; + } else { + sd->dacl = acl; + sd->type |= SEC_DESC_DACL_PRESENT; + } return NT_STATUS_OK; } +/* + add an ACE to the SACL of a security_descriptor +*/ + +NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd, + const struct security_ace *ace) +{ + return security_descriptor_acl_add(sd, true, ace); +} /* - delete the ACE corresponding to the given trustee in the DACL of a security_descriptor + add an ACE to the DACL of a security_descriptor */ -NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, - struct dom_sid *trustee) + +NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, + const struct security_ace *ace) +{ + return security_descriptor_acl_add(sd, false, ace); +} + +/* + delete the ACE corresponding to the given trustee in an ACL of a + security_descriptor +*/ + +static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd, + bool sacl_del, + struct dom_sid *trustee) { int i; bool found = false; + struct security_acl *acl = NULL; - if (sd->dacl == NULL) { + if (sacl_del) { + acl = sd->sacl; + } else { + acl = sd->dacl; + } + + if (acl == NULL) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } /* there can be multiple ace's for one trustee */ - for (i=0;idacl->num_aces;i++) { - if (dom_sid_equal(trustee, &sd->dacl->aces[i].trustee)) { - memmove(&sd->dacl->aces[i], &sd->dacl->aces[i+1], - sizeof(sd->dacl->aces[i]) * (sd->dacl->num_aces - (i+1))); - sd->dacl->num_aces--; - if (sd->dacl->num_aces == 0) { - sd->dacl->aces = NULL; + for (i=0;inum_aces;i++) { + if (dom_sid_equal(trustee, &acl->aces[i].trustee)) { + memmove(&acl->aces[i], &acl->aces[i+1], + sizeof(acl->aces[i]) * (acl->num_aces - (i+1))); + acl->num_aces--; + if (acl->num_aces == 0) { + acl->aces = NULL; } found = true; } @@ -223,15 +268,15 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - sd->dacl->revision = SECURITY_ACL_REVISION_NT4; + acl->revision = SECURITY_ACL_REVISION_NT4; - for (i=0;idacl->num_aces;i++) { - switch (sd->dacl->aces[i].type) { + for (i=0;inum_aces;i++) { + switch (acl->aces[i].type) { case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: - sd->dacl->revision = SECURITY_ACL_REVISION_ADS; + acl->revision = SECURITY_ACL_REVISION_ADS; return NT_STATUS_OK; default: break; /* only for the switch statement */ @@ -241,6 +286,27 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, return NT_STATUS_OK; } +/* + delete the ACE corresponding to the given trustee in the DACL of a + security_descriptor +*/ + +NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, + struct dom_sid *trustee) +{ + return security_descriptor_acl_del(sd, false, trustee); +} + +/* + delete the ACE corresponding to the given trustee in the SACL of a + security_descriptor +*/ + +NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd, + struct dom_sid *trustee) +{ + return security_descriptor_acl_del(sd, true, trustee); +} /* compare two security ace structures @@ -319,30 +385,9 @@ bool security_descriptor_mask_equal(const struct security_descriptor *sd1, } -/* - create a security descriptor using string SIDs. This is used by the - torture code to allow the easy creation of complex ACLs - This is a varargs function. The list of DACL ACEs ends with a NULL sid. - - Each ACE contains a set of 4 parameters: - SID, ACCESS_TYPE, MASK, FLAGS - - a typical call would be: - - sd = security_descriptor_create(mem_ctx, - sd_type_flags, - mysid, - mygroup, - SID_NT_AUTHENTICATED_USERS, - SEC_ACE_TYPE_ACCESS_ALLOWED, - SEC_FILE_ALL, - SEC_ACE_FLAG_OBJECT_INHERIT, - NULL); - that would create a sd with one DACL ACE -*/ - -struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd, - va_list ap) +static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd, + bool add_ace_to_sacl, + va_list ap) { const char *sidstr; @@ -364,7 +409,11 @@ struct security_descriptor *security_descriptor_appendv(struct security_descript return NULL; } ace->trustee = *sid; - status = security_descriptor_dacl_add(sd, ace); + if (add_ace_to_sacl) { + status = security_descriptor_sacl_add(sd, ace); + } else { + status = security_descriptor_dacl_add(sd, ace); + } /* TODO: check: would talloc_free(ace) here be correct? */ if (!NT_STATUS_IS_OK(status)) { talloc_free(sd); @@ -381,23 +430,25 @@ struct security_descriptor *security_descriptor_append(struct security_descripto va_list ap; va_start(ap, sd); - sd = security_descriptor_appendv(sd, ap); + sd = security_descriptor_appendv(sd, false, ap); va_end(ap); return sd; } -struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, - uint16_t sd_type, - const char *owner_sid, - const char *group_sid, - ...) +static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx, + uint16_t sd_type, + const char *owner_sid, + const char *group_sid, + bool add_ace_to_sacl, + va_list ap) { - va_list ap; struct security_descriptor *sd; sd = security_descriptor_initialise(mem_ctx); - if (sd == NULL) return NULL; + if (sd == NULL) { + return NULL; + } sd->type |= sd_type; @@ -416,8 +467,58 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, } } + return security_descriptor_appendv(sd, add_ace_to_sacl, ap); +} + +/* + create a security descriptor using string SIDs. This is used by the + torture code to allow the easy creation of complex ACLs + This is a varargs function. The list of DACL ACEs ends with a NULL sid. + + Each ACE contains a set of 4 parameters: + SID, ACCESS_TYPE, MASK, FLAGS + + a typical call would be: + + sd = security_descriptor_dacl_create(mem_ctx, + sd_type_flags, + mysid, + mygroup, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_FILE_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); + that would create a sd with one DACL ACE +*/ + +struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx, + uint16_t sd_type, + const char *owner_sid, + const char *group_sid, + ...) +{ + struct security_descriptor *sd = NULL; + va_list ap; + va_start(ap, group_sid); + sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid, + group_sid, false, ap); + va_end(ap); + + return sd; +} + +struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx, + uint16_t sd_type, + const char *owner_sid, + const char *group_sid, + ...) +{ + struct security_descriptor *sd = NULL; + va_list ap; va_start(ap, group_sid); - sd = security_descriptor_appendv(sd, ap); + sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid, + group_sid, true, ap); va_end(ap); return sd; -- cgit From 64fc66306bdc95b619dc3b8f2318e7d08125e6a5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2007 09:40:32 +0100 Subject: r25819: make the success case more clear metze (This used to be commit 6495fe220d488ce86d53b148f76f9fe669d4bbad) --- source4/libcli/dgram/browse.c | 2 +- source4/libcli/dgram/netlogon.c | 2 +- source4/libcli/dgram/ntlogon.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index fc1162e644..9881aa4eae 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -105,5 +105,5 @@ NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, file_save("browse.dat", data.data, data.length); } } - return status; + return NT_STATUS_OK; } diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 46f6e50e7b..2e5aa26d67 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -116,5 +116,5 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, file_save("netlogon.dat", data.data, data.length); } } - return status; + return NT_STATUS_OK; } diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 25f767688a..c62f99433a 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -118,5 +118,5 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, file_save("ntlogon.dat", data.data, data.length); } } - return status; + return NT_STATUS_OK; } -- cgit From c77b796a3f93c68e3fe05baafdad1e53f48e50d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2007 09:42:18 +0100 Subject: r25820: but still return the error... (sorry, this should have been one commit) metze (This used to be commit 01c5ec7eb44956c1722d884bb97ce7730d4fc451) --- source4/libcli/dgram/browse.c | 1 + source4/libcli/dgram/netlogon.c | 1 + source4/libcli/dgram/ntlogon.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 9881aa4eae..3e78378732 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -104,6 +104,7 @@ NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, if (DEBUGLVL(10)) { file_save("browse.dat", data.data, data.length); } + return status; } return NT_STATUS_OK; } diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 2e5aa26d67..3a5510b408 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -115,6 +115,7 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, if (DEBUGLVL(10)) { file_save("netlogon.dat", data.data, data.length); } + return status; } return NT_STATUS_OK; } diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index c62f99433a..a49f011bda 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -117,6 +117,7 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, if (DEBUGLVL(10)) { file_save("ntlogon.dat", data.data, data.length); } + return status; } return NT_STATUS_OK; } -- cgit From 46ba5366bd1b2e456ef8d10c6f4b9611eb518696 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2007 10:20:45 +0100 Subject: r25821: always use ndr_push/pull_error() to report errors and not NTSTATUS directly metze (This used to be commit faa26ed52c81f7075823b460e1444f3961d3421c) --- source4/libcli/nbt/nbtname.c | 47 ++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 37cdf64023..3c2b58e0f7 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -49,7 +49,8 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, uint_t loops = 0; while (loops < 5) { if (*offset >= ndr->data_size) { - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "BAD NBT NAME component"); } len = ndr->data[*offset]; if (len == 0) { @@ -61,7 +62,8 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, if ((len & 0xC0) == 0xC0) { /* its a label pointer */ if (1 + *offset >= ndr->data_size) { - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "BAD NBT NAME component"); } *max_offset = MAX(*max_offset, *offset + 2); *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset]; @@ -71,10 +73,12 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, } if ((len & 0xC0) != 0) { /* its a reserved length field */ - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "BAD NBT NAME component"); } if (*offset + len + 2 > ndr->data_size) { - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "BAD NBT NAME component"); } *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len); NT_STATUS_HAVE_NO_MEMORY(*component); @@ -84,7 +88,7 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, } /* too many pointers */ - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component"); } /** @@ -118,7 +122,8 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const } } if (num_components == MAX_COMPONENTS) { - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "BAD NBT NAME too many components"); } if (num_components == 0) { name = talloc_strdup(ndr, ""); @@ -203,7 +208,7 @@ _PUBLIC_ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const /* decompress a 'compressed' name component */ -static NTSTATUS decompress_name(char *name, enum nbt_name_type *type) +static bool decompress_name(char *name, enum nbt_name_type *type) { int i; for (i=0;name[2*i];i++) { @@ -211,7 +216,7 @@ static NTSTATUS decompress_name(char *name, enum nbt_name_type *type) uint8_t c2 = name[1+(2*i)]; if (c1 < 'A' || c1 > 'P' || c2 < 'A' || c2 > 'P') { - return NT_STATUS_BAD_NETWORK_NAME; + return false; } name[i] = ((c1-'A')<<4) | (c2-'A'); } @@ -229,7 +234,7 @@ static NTSTATUS decompress_name(char *name, enum nbt_name_type *type) name[i-1] = 0; } - return NT_STATUS_OK; + return true; } @@ -282,6 +287,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct uint8_t *scope; char *cname; const char *s; + bool ok; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; @@ -304,12 +310,16 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct /* the first component is limited to 16 bytes in the DOS charset, which is 32 in the 'compressed' form */ if (strlen(cname) > 32) { - return NT_STATUS_BAD_NETWORK_NAME; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "NBT NAME cname > 32"); } /* decompress the first component */ - status = decompress_name(cname, &r->type); - NT_STATUS_NOT_OK_RETURN(status); + ok = decompress_name(cname, &r->type); + if (!ok) { + return ndr_pull_error(ndr, NDR_ERR_STRING, + "NBT NAME failed to decompress"); + } r->name = talloc_strdup(ndr->current_mem_ctx, cname); NT_STATUS_HAVE_NO_MEMORY(r->name); @@ -547,7 +557,10 @@ _PUBLIC_ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, c uint32_t name_len; uint32_t scope_len = 0; - if (r == NULL) return NT_STATUS_INVALID_PARAMETER_MIX; + if (r == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, + "wrepl_nbt_name NULL pointer"); + } if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; @@ -555,14 +568,18 @@ _PUBLIC_ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, c name_len = strlen(r->name); if (name_len > 15) { - return NT_STATUS_INVALID_PARAMETER_MIX; + return ndr_push_error(ndr, NDR_ERR_STRING, + "wrepl_nbt_name longer as 15 chars: %s", + r->name); } if (r->scope) { scope_len = strlen(r->scope); } if (scope_len > 238) { - return NT_STATUS_INVALID_PARAMETER_MIX; + return ndr_push_error(ndr, NDR_ERR_STRING, + "wrepl_nbt_name scope longer as 238 chars: %s", + r->scope); } namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s", -- cgit From 7fdf5656046653cca8a4870bf02bc1e2beadccc1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2007 10:45:59 +0100 Subject: r25822: use NDR_CHECK() metze (This used to be commit c81aa2ba36904281692b84bcd37300e38760da34) --- source4/libcli/nbt/nbtname.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 3c2b58e0f7..1ee421b1f7 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -96,7 +96,6 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, */ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) { - NTSTATUS status; uint32_t offset = ndr->offset; uint32_t max_offset = offset; unsigned num_components; @@ -111,8 +110,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const /* break up name into a list of components */ for (num_components=0;num_components Date: Wed, 7 Nov 2007 20:45:04 +0100 Subject: r25897: Add WERR_INVALID_FLAGS. Guenther (This used to be commit c3023eaeb389f44b64becc383552df0debfc232d) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/werror.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index e94b50a6de..19984cf2e9 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -111,6 +111,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_PRINTQ_FULL", WERR_PRINTQ_FULL }, { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE }, + { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS }, { "WERR_NOT_FOUND", WERR_NOT_FOUND }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index d356b160d8..532dc2ed8c 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -88,6 +88,7 @@ typedef uint32_t WERROR; #define WERR_NO_MORE_ITEMS W_ERROR(259) #define WERR_MORE_DATA W_ERROR(234) #define WERR_CAN_NOT_COMPLETE W_ERROR(1003) +#define WERR_INVALID_FLAGS W_ERROR(1004) #define WERR_NOT_FOUND W_ERROR(1168) #define WERR_INVALID_COMPUTERNAME W_ERROR(1210) #define WERR_INVALID_DOMAINNAME W_ERROR(1212) -- cgit From 0bccc883921cd95fdc8c732df9730e32d97c2cca Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 8 Nov 2007 00:07:17 +0100 Subject: r25903: Move more files out of torture/ (This used to be commit f734df3144cdd9ff280ee1cac2c3a7f972716f5d) --- source4/libcli/resolve/testsuite.c | 90 ++++++++++++++++++++++++++++++ source4/libcli/security/tests/sddl.c | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 source4/libcli/resolve/testsuite.c create mode 100644 source4/libcli/security/tests/sddl.c (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c new file mode 100644 index 0000000000..b87b59b81a --- /dev/null +++ b/source4/libcli/resolve/testsuite.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + local test for async resolve code + + Copyright (C) Andrew Tridgell 2004 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "libcli/resolve/resolve.h" +#include "torture/torture.h" +#include "system/network.h" + +static bool test_async_resolve(struct torture_context *tctx) +{ + struct nbt_name n; + struct event_context *ev; + int timelimit = torture_setting_int(tctx, "timelimit", 2); + const char *host = torture_setting_string(tctx, "host", NULL); + int count = 0; + struct timeval tv = timeval_current(); + TALLOC_CTX *mem_ctx = tctx; + + ev = tctx->ev; + + ZERO_STRUCT(n); + n.name = host; + + torture_comment(tctx, "Testing async resolve of '%s' for %d seconds\n", + host, timelimit); + while (timeval_elapsed(&tv) < timelimit) { + const char *s; + struct composite_context *c = resolve_name_host_send(mem_ctx, ev, &n); + torture_assert(tctx, c != NULL, "resolve_name_host_send"); + torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s), + "async resolve failed"); + count++; + } + + torture_comment(tctx, "async rate of %.1f resolves/sec\n", + count/timeval_elapsed(&tv)); + return true; +} + +/* + test resolution using sync method +*/ +static bool test_sync_resolve(struct torture_context *tctx) +{ + int timelimit = torture_setting_int(tctx, "timelimit", 2); + struct timeval tv = timeval_current(); + int count = 0; + const char *host = torture_setting_string(tctx, "host", NULL); + + torture_comment(tctx, "Testing sync resolve of '%s' for %d seconds\n", + host, timelimit); + while (timeval_elapsed(&tv) < timelimit) { + inet_ntoa(interpret_addr2(host)); + count++; + } + + torture_comment(tctx, "sync rate of %.1f resolves/sec\n", + count/timeval_elapsed(&tv)); + return true; +} + + +struct torture_suite *torture_local_resolve(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "RESOLVE"); + + torture_suite_add_simple_test(suite, "async", test_async_resolve); + torture_suite_add_simple_test(suite, "sync", test_sync_resolve); + + return suite; +} diff --git a/source4/libcli/security/tests/sddl.c b/source4/libcli/security/tests/sddl.c new file mode 100644 index 0000000000..3e6382309e --- /dev/null +++ b/source4/libcli/security/tests/sddl.c @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + + local testing of SDDL parsing + + Copyright (C) Andrew Tridgell 2005 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/security/security.h" +#include "torture/torture.h" +#include "librpc/gen_ndr/ndr_security.h" + + +/* + test one SDDL example +*/ +static bool test_sddl(struct torture_context *tctx, + const void *test_data) +{ + struct security_descriptor *sd, *sd2; + struct dom_sid *domain; + const char *sddl = (const char *)test_data; + const char *sddl2; + TALLOC_CTX *mem_ctx = tctx; + + + domain = dom_sid_parse_talloc(mem_ctx, "S-1-2-3-4"); + sd = sddl_decode(mem_ctx, sddl, domain); + torture_assert(tctx, sd != NULL, talloc_asprintf(tctx, + "Failed to decode '%s'\n", sddl)); + + sddl2 = sddl_encode(mem_ctx, sd, domain); + torture_assert(tctx, sddl2 != NULL, talloc_asprintf(tctx, + "Failed to re-encode '%s'\n", sddl)); + + sd2 = sddl_decode(mem_ctx, sddl2, domain); + torture_assert(tctx, sd2 != NULL, talloc_asprintf(tctx, + "Failed to decode2 '%s'\n", sddl2)); + + torture_assert(tctx, security_descriptor_equal(sd, sd2), + talloc_asprintf(tctx, "Failed equality test for '%s'\n", sddl)); + +#if 0 + /* flags don't have a canonical order ... */ + if (strcmp(sddl, sddl2) != 0) { + printf("Failed sddl equality test\norig: %s\n new: %s\n", sddl, sddl2); + } +#endif + + if (DEBUGLVL(2)) { + NDR_PRINT_DEBUG(security_descriptor, sd); + } + talloc_free(sd); + talloc_free(domain); + return true; +} + +static const char *examples[] = { + "D:(A;;CC;;;BA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)", + "D:(A;;GA;;;SY)", + "D:(A;;RP;;;WD)(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;ED)(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;BA)(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;BA)(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;BA)(A;;RPLCLORC;;;AU)(A;;RPWPCRLCLOCCRCWDWOSW;;;DA)(A;CI;RPWPCRLCLOCCRCWDWOSDSW;;;BA)(A;;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;SY)(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;EA)(A;CI;LC;;;RU)(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(OA;CIIO;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(OA;;RP;c7407360-20bf-11d0-a768-00aa006e0529;;RU)(OA;CIIO;RPLCLORC;;bf967a9c-0de6-11d0-a285-00aa003049e2;RU)(A;;RPRC;;;RU)(OA;CIIO;RPLCLORC;;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(A;;LCRPLORC;;;ED)(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;4828CC14-1437-45bc-9B07-AD6F015E5F28;RU)(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;4828CC14-1437-45bc-9B07-AD6F015E5F28;RU)(OA;CIIO;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;4828CC14-1437-45bc-9B07-AD6F015E5F28;RU)(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828CC14-1437-45bc-9B07-AD6F015E5F28;RU)(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;4828CC14-1437-45bc-9B07-AD6F015E5F28;RU)(OA;CIIO;RPLCLORC;;4828CC14-1437-45bc-9B07-AD6F015E5F28;RU)(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;RU)(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;AU)(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967aba-0de6-11d0-a285-00aa003049e2;ED)(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a9c-0de6-11d0-a285-00aa003049e2;ED)(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a86-0de6-11d0-a285-00aa003049e2;ED)(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;DD)(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;BA)(OA;;CR;e2a36dc9-ae17-47c3-b58b-be34c55ba633;;S-1-5-32-557)(OA;;CR;280f369c-67c7-438e-ae98-1d46f3c6f541;;AU)(OA;;CR;ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501;;AU)(OA;;CR;05c74c5e-4deb-43b4-bd9f-86664c2a7fd5;;AU)S:(AU;SA;WDWOWP;;;WD)(AU;SA;CR;;;BA)(AU;SA;CR;;;DU)(OU;CISA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)", + "D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;AO)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPCRLCLORCSDDT;;;CO)(OA;;WP;4c164200-20c0-11d0-a768-00aa006e0529;;CO)(A;;RPLCLORC;;;AU)(OA;;CR;ab721a53-1e2f-11d0-9819-00aa0040529b;;WD)(A;;CCDC;;;PS)(OA;;CCDC;bf967aa8-0de6-11d0-a285-00aa003049e2;;PO)(OA;;RPWP;bf967a7f-0de6-11d0-a285-00aa003049e2;;CA)(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;PS)(OA;;RPWP;77B5B886-944A-11d1-AEBD-0000F80367C1;;PS)(OA;;SW;72e39547-7b18-11d1-adef-00c04fd8d5cd;;PS)(OA;;SW;72e39547-7b18-11d1-adef-00c04fd8d5cd;;CO)(OA;;SW;f3a64788-5306-11d1-a9c5-0000f80367c1;;CO)(OA;;WP;3e0abfd0-126a-11d0-a060-00aa006c33ed;bf967a86-0de6-11d0-a285-00aa003049e2;CO)(OA;;WP;5f202010-79a5-11d0-9020-00c04fc2d4cf;bf967a86-0de6-11d0-a285-00aa003049e2;CO)(OA;;WP;bf967950-0de6-11d0-a285-00aa003049e2;bf967a86-0de6-11d0-a285-00aa003049e2;CO)(OA;;WP;bf967953-0de6-11d0-a285-00aa003049e2;bf967a86-0de6-11d0-a285-00aa003049e2;CO)(OA;;RP;46a9b11d-60ae-405a-b7e8-ff8a58d456d2;;S-1-5-32-560)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;AO)(A;;RPLCLORC;;;PS)(OA;;CR;ab721a55-1e2f-11d0-9819-00aa0040529b;;AU)(OA;;RP;46a9b11d-60ae-405a-b7e8-ff8a58d456d2;;S-1-5-32-560)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;CO)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)S:(AU;SA;CRWP;;;WD)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;AO)(A;;RPLCLORC;;;PS)(OA;;CR;ab721a53-1e2f-11d0-9819-00aa0040529b;;PS)(OA;;CR;ab721a54-1e2f-11d0-9819-00aa0040529b;;PS)(OA;;CR;ab721a56-1e2f-11d0-9819-00aa0040529b;;PS)(OA;;RPWP;77B5B886-944A-11d1-AEBD-0000F80367C1;;PS)(OA;;RPWP;E45795B2-9455-11d1-AEBD-0000F80367C1;;PS)(OA;;RPWP;E45795B3-9455-11d1-AEBD-0000F80367C1;;PS)(OA;;RP;037088f8-0ae1-11d2-b422-00a0c968f939;;RS)(OA;;RP;4c164200-20c0-11d0-a768-00aa006e0529;;RS)(OA;;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;;RS)(A;;RC;;;AU)(OA;;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;;AU)(OA;;RP;77B5B886-944A-11d1-AEBD-0000F80367C1;;AU)(OA;;RP;E45795B3-9455-11d1-AEBD-0000F80367C1;;AU)(OA;;RP;e48d0154-bcf8-11d1-8702-00c04fb96050;;AU)(OA;;CR;ab721a53-1e2f-11d0-9819-00aa0040529b;;WD)(OA;;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;;RS)(OA;;RPWP;bf967a7f-0de6-11d0-a285-00aa003049e2;;CA)(OA;;RP;46a9b11d-60ae-405a-b7e8-ff8a58d456d2;;S-1-5-32-560)(OA;;WPRP;6db69a1c-9422-11d1-aebd-0000f80367c1;;S-1-5-32-561)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;LCRPLORC;;;ED)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(OA;;CCDC;bf967a86-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;bf967aba-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;bf967a9c-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;bf967aa8-0de6-11d0-a285-00aa003049e2;;PO)(A;;RPLCLORC;;;AU)(A;;LCRPLORC;;;ED)(OA;;CCDC;4828CC14-1437-45bc-9B07-AD6F015E5F28;;AO)", + "D:(A;;RPWPCRCCDCLCLORCWOWDSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)", + "D:(A;CI;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)", + "D:S:", + "D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)" +}; + +/* test a set of example SDDL strings */ +struct torture_suite *torture_local_sddl(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "SDDL"); + int i; + + for (i = 0; i < ARRAY_SIZE(examples); i++) { + torture_suite_add_simple_tcase(suite, + talloc_asprintf(suite, "%d", i), + test_sddl, examples[i]); + } + + return suite; +} -- cgit From 0ce646d49a70b19d7ca54e0b83422f048dd39c1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:23:57 +0100 Subject: r25917: ndr: move ndr_map_error2ntstatus to errormap.c metze (This used to be commit 8fc2e7737fc15f7265816f077e2a48a7a98f75b8) --- source4/libcli/util/error.h | 6 +++++- source4/libcli/util/errormap.c | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/error.h b/source4/libcli/util/error.h index dd2de3da75..e054948fbe 100644 --- a/source4/libcli/util/error.h +++ b/source4/libcli/util/error.h @@ -22,6 +22,7 @@ #include "libcli/util/werror.h" #include "libcli/util/doserr.h" #include "libcli/util/ntstatus.h" +#include "librpc/ndr/libndr.h" /** NT error on DOS connection! (NT_STATUS_OK) */ bool ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2); @@ -46,6 +47,9 @@ WERROR ntstatus_to_werror(NTSTATUS error); *********************************************************************/ NTSTATUS map_nt_error_from_unix(int unix_error); - +/********************************************************************* + Map an NT error code from a NDR error code. +*********************************************************************/ +NTSTATUS ndr_map_error2ntstatus(enum ndr_err_code ndr_err); #endif /* _SAMBA_ERROR_H */ diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 8d088e1e4b..b8458d4bf3 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1375,3 +1375,28 @@ NTSTATUS map_nt_error_from_unix(int unix_error) /* Default return */ return NT_STATUS_UNSUCCESSFUL; } + +NTSTATUS ndr_map_error2ntstatus(enum ndr_err_code ndr_err) +{ + switch (ndr_err) { + case NDR_ERR_SUCCESS: + return NT_STATUS_OK; + case NDR_ERR_BUFSIZE: + return NT_STATUS_BUFFER_TOO_SMALL; + case NDR_ERR_TOKEN: + return NT_STATUS_INTERNAL_ERROR; + case NDR_ERR_ALLOC: + return NT_STATUS_NO_MEMORY; + case NDR_ERR_ARRAY_SIZE: + return NT_STATUS_ARRAY_BOUNDS_EXCEEDED; + case NDR_ERR_INVALID_POINTER: + return NT_STATUS_INVALID_PARAMETER_MIX; + case NDR_ERR_UNREAD_BYTES: + return NT_STATUS_PORT_MESSAGE_TOO_LONG; + default: + break; + } + + /* we should map all error codes to different status codes */ + return NT_STATUS_INVALID_PARAMETER; +} -- cgit From 529763a9aa192a6785ba878aceeb1683c2510913 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:24:51 +0100 Subject: r25920: ndr: change NTSTAUS into enum ndr_err_code (samba4 callers) lib/messaging/ lib/registry/ lib/ldb-samba/ librpc/rpc/ auth/auth_winbind.c auth/gensec/ auth/kerberos/ dsdb/repl/ dsdb/samdb/ dsdb/schema/ torture/ cluster/ctdb/ kdc/ ntvfs/ipc/ torture/rap/ ntvfs/ utils/getntacl.c ntptr/ smb_server/ libcli/wrepl/ wrepl_server/ libcli/cldap/ libcli/dgram/ libcli/ldap/ libcli/raw/ libcli/nbt/ libnet/ winbind/ rpc_server/ metze (This used to be commit 6223c7fddc972687eb577e04fc1c8e0604c35435) --- source4/libcli/cldap/cldap.c | 17 ++++--- source4/libcli/dgram/browse.c | 25 +++++----- source4/libcli/dgram/dgramsocket.c | 14 ++++-- source4/libcli/dgram/netlogon.c | 25 +++++----- source4/libcli/dgram/ntlogon.c | 25 +++++----- source4/libcli/ldap/ldap_ndr.c | 27 ++++++----- source4/libcli/nbt/nbtname.c | 95 +++++++++++++++++++++---------------- source4/libcli/nbt/nbtsocket.c | 26 +++++----- source4/libcli/raw/rawacl.c | 16 ++++--- source4/libcli/raw/rawfile.c | 10 ++-- source4/libcli/raw/rawfileinfo.c | 12 +++-- source4/libcli/raw/rawfsinfo.c | 8 +++- source4/libcli/raw/rawsetfileinfo.c | 14 +++--- source4/libcli/wrepl/winsrepl.c | 19 ++++---- 14 files changed, 193 insertions(+), 140 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 54b5995377..9903595dfb 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -595,6 +595,7 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, struct cldap_netlogon *io) { NTSTATUS status; + enum ndr_err_code ndr_err; struct cldap_search search; DATA_BLOB *data; @@ -614,13 +615,14 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - status = ndr_pull_union_blob_all(data, mem_ctx, &io->out.netlogon, - io->in.version & 0xF, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_pull_union_blob_all(data, mem_ctx, &io->out.netlogon, + io->in.version & 0xF, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", SVAL(data->data, 0))); dump_data(10, data->data, data->length); + return ndr_map_error2ntstatus(ndr_err); } return NT_STATUS_OK; @@ -700,17 +702,18 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, union nbt_cldap_netlogon *netlogon) { NTSTATUS status; + enum ndr_err_code ndr_err; struct cldap_reply reply; struct ldap_SearchResEntry response; struct ldap_Result result; TALLOC_CTX *tmp_ctx = talloc_new(cldap); DATA_BLOB blob; - status = ndr_push_union_blob(&blob, tmp_ctx, netlogon, version & 0xF, + ndr_err = ndr_push_union_blob(&blob, tmp_ctx, netlogon, version & 0xF, (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } reply.messageid = message_id; diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 3e78378732..3b5f67118f 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -34,14 +34,15 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_browse_packet *request) { NTSTATUS status; + enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - status = ndr_push_struct_blob(&blob, tmp_ctx, request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, request, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, @@ -58,16 +59,17 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, struct nbt_browse_packet *reply) { NTSTATUS status; + enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; struct socket_address *dest; - status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); @@ -94,13 +96,14 @@ NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_browse_packet *pkt) { DATA_BLOB data = dgram_mailslot_data(dgram); - NTSTATUS status; + enum ndr_err_code ndr_err; - status = ndr_pull_struct_blob(&data, mem_ctx, pkt, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, pkt, (ndr_pull_flags_fn_t)ndr_pull_nbt_browse_packet); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Failed to parse browse packet of length %d\n", - (int)data.length)); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse browse packet of length %d: %s\n", + (int)data.length, nt_errstr(status))); if (DEBUGLVL(10)) { file_save("browse.dat", data.data, data.length); } diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 1097c30f99..1af252c0bf 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -39,6 +39,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) size_t nread, dsize; struct nbt_dgram_packet *packet; const char *mailslot_name; + enum ndr_err_code ndr_err; status = socket_pending(dgmsock->sock, &dsize); if (!NT_STATUS_IS_OK(status)) { @@ -70,9 +71,10 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) } /* parse the request */ - status = ndr_pull_struct_blob(&blob, packet, packet, + ndr_err = ndr_pull_struct_blob(&blob, packet, packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_dgram_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); DEBUG(2,("Failed to parse incoming NBT DGRAM packet - %s\n", nt_errstr(status))); talloc_free(tmp_ctx); @@ -218,6 +220,7 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, { struct nbt_dgram_request *req; NTSTATUS status = NT_STATUS_NO_MEMORY; + enum ndr_err_code ndr_err; req = talloc(dgmsock, struct nbt_dgram_request); if (req == NULL) goto failed; @@ -225,9 +228,12 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, req->dest = dest; if (talloc_reference(req, dest) == NULL) goto failed; - status = ndr_push_struct_blob(&req->encoded, req, packet, + ndr_err = ndr_push_struct_blob(&req->encoded, req, packet, (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); - if (!NT_STATUS_IS_OK(status)) goto failed; + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + goto failed; + } DLIST_ADD_END(dgmsock->send_queue, req, struct nbt_dgram_request *); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 3a5510b408..f89c2c5644 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -36,14 +36,15 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_netlogon_packet *request) { NTSTATUS status; + enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - status = ndr_push_struct_blob(&blob, tmp_ctx, request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, request, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } @@ -65,16 +66,17 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_netlogon_packet *reply) { NTSTATUS status; + enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; struct socket_address *dest; - status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); @@ -105,13 +107,14 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_packet *netlogon) { DATA_BLOB data = dgram_mailslot_data(dgram); - NTSTATUS status; + enum ndr_err_code ndr_err; - status = ndr_pull_struct_blob(&data, mem_ctx, netlogon, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, netlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Failed to parse netlogon packet of length %d\n", - (int)data.length)); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data.length, nt_errstr(status))); if (DEBUGLVL(10)) { file_save("netlogon.dat", data.data, data.length); } diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index a49f011bda..b4b548fb27 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -37,14 +37,15 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_ntlogon_packet *request) { NTSTATUS status; + enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - status = ndr_push_struct_blob(&blob, tmp_ctx, request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, request, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } @@ -66,16 +67,17 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_ntlogon_packet *reply) { NTSTATUS status; + enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; struct socket_address *dest; - status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); @@ -107,13 +109,14 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_ntlogon_packet *ntlogon) { DATA_BLOB data = dgram_mailslot_data(dgram); - NTSTATUS status; + enum ndr_err_code ndr_err; - status = ndr_pull_struct_blob(&data, mem_ctx, ntlogon, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, ntlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Failed to parse ntlogon packet of length %d\n", - (int)data.length)); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse ntlogon packet of length %d: %s\n", + (int)data.length, nt_errstr(status))); if (DEBUGLVL(10)) { file_save("ntlogon.dat", data.data, data.length); } diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index a5f90cf82b..468c366c85 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -44,11 +44,11 @@ char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; char *ret; - status = ndr_push_struct_blob(&blob, mem_ctx, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; } ret = ldb_binary_encode(mem_ctx, blob); @@ -63,11 +63,11 @@ char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) { DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; char *ret; - status = ndr_push_struct_blob(&blob, mem_ctx, guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; } ret = ldb_binary_encode(mem_ctx, blob); @@ -81,12 +81,15 @@ char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) { DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; blob.data = val.data; blob.length = val.length; - status = ndr_pull_struct_blob(&blob, mem_ctx, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); talloc_free(val.data); - return status; + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; } diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 1ee421b1f7..bdcd012556 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -42,8 +42,10 @@ _PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, cons /* pull one component of a nbt_string */ -static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, - uint32_t *offset, uint32_t *max_offset) +static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr, + uint8_t **component, + uint32_t *offset, + uint32_t *max_offset) { uint8_t len; uint_t loops = 0; @@ -57,7 +59,7 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, *offset += 1; *max_offset = MAX(*max_offset, *offset); *component = NULL; - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } if ((len & 0xC0) == 0xC0) { /* its a label pointer */ @@ -81,10 +83,10 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, "BAD NBT NAME component"); } *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len); - NT_STATUS_HAVE_NO_MEMORY(*component); + NDR_ERR_HAVE_NO_MEMORY(*component); *offset += len + 1; *max_offset = MAX(*max_offset, *offset); - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } /* too many pointers */ @@ -94,7 +96,7 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, /** pull a nbt_string from the wire */ -_PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) +_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) { uint32_t offset = ndr->offset; uint32_t max_offset = offset; @@ -102,7 +104,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char *name; if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } name = NULL; @@ -114,7 +116,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const if (component == NULL) break; if (name) { name = talloc_asprintf_append_buffer(name, ".%s", component); - NT_STATUS_HAVE_NO_MEMORY(name); + NDR_ERR_HAVE_NO_MEMORY(name); } else { name = (char *)component; } @@ -125,26 +127,26 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const } if (num_components == 0) { name = talloc_strdup(ndr, ""); - NT_STATUS_HAVE_NO_MEMORY(name); + NDR_ERR_HAVE_NO_MEMORY(name); } (*s) = name; ndr->offset = max_offset; - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } /** push a nbt string to the wire */ -_PUBLIC_ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) +_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) { if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } while (s && *s) { - NTSTATUS status; + enum ndr_err_code ndr_err; char *compname; size_t complen; uint32_t offset; @@ -152,8 +154,8 @@ _PUBLIC_ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const /* see if we have pushed the remaing string allready, * if so we use a label pointer to this string */ - status = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); - if (NT_STATUS_IS_OK(status)) { + ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { uint8_t b[2]; if (offset > 0x3FFF) { @@ -181,7 +183,7 @@ _PUBLIC_ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const (unsigned char)complen, (unsigned char)complen, (unsigned char)complen, s); - NT_STATUS_HAVE_NO_MEMORY(compname); + NDR_ERR_HAVE_NO_MEMORY(compname); /* remember the current componemt + the rest of the string * so it can be reused later @@ -279,7 +281,7 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, /** pull a nbt name from the wire */ -_PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) +_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) { uint8_t *scope; char *cname; @@ -287,7 +289,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct bool ok; if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s)); @@ -296,7 +298,7 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct if (scope) { *scope = 0; r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]); - NT_STATUS_HAVE_NO_MEMORY(r->scope); + NDR_ERR_HAVE_NO_MEMORY(r->scope); } else { r->scope = NULL; } @@ -318,23 +320,23 @@ _PUBLIC_ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct } r->name = talloc_strdup(ndr->current_mem_ctx, cname); - NT_STATUS_HAVE_NO_MEMORY(r->name); + NDR_ERR_HAVE_NO_MEMORY(r->name); talloc_free(cname); - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } /** push a nbt name to the wire */ -_PUBLIC_ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) +_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) { uint8_t *cname, *fullname; - NTSTATUS status; + enum ndr_err_code ndr_err; if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } if (strlen(r->name) > 15) { @@ -344,19 +346,19 @@ _PUBLIC_ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const s } cname = compress_name(ndr, (const uint8_t *)r->name, r->type); - NT_STATUS_HAVE_NO_MEMORY(cname); + NDR_ERR_HAVE_NO_MEMORY(cname); if (r->scope) { fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope); - NT_STATUS_HAVE_NO_MEMORY(fullname); + NDR_ERR_HAVE_NO_MEMORY(fullname); talloc_free(cname); } else { fullname = cname; } - status = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); + ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); - return status; + return ndr_err; } @@ -380,18 +382,31 @@ _PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struc */ _PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name) { - return ndr_push_struct_blob(blob, mem_ctx, name, - (ndr_push_flags_fn_t)ndr_push_nbt_name); -} + enum ndr_err_code ndr_err; + ndr_err = ndr_push_struct_blob(blob, mem_ctx, name, + (ndr_push_flags_fn_t)ndr_push_nbt_name); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + return NT_STATUS_OK; +} /** pull a nbt name from a blob */ _PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) { - return ndr_pull_struct_blob(blob, mem_ctx, name, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name); + enum ndr_err_code ndr_err; + + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, name, + (ndr_pull_flags_fn_t)ndr_pull_nbt_name); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + return NT_STATUS_OK; } @@ -485,14 +500,14 @@ _PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) /** pull a nbt name, WINS Replication uses another on wire format for nbt name */ -_PUBLIC_ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name **_r) +_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name **_r) { struct nbt_name *r; uint8_t *namebuf; uint32_t namebuf_len; if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } NDR_CHECK(ndr_pull_align(ndr, 4)); @@ -521,7 +536,7 @@ _PUBLIC_ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, s talloc_free(namebuf); *_r = r; - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } r->type = namebuf[15]; @@ -540,13 +555,13 @@ _PUBLIC_ NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, s talloc_free(namebuf); *_r = r; - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } /** push a nbt name, WINS Replication uses another on wire format for nbt name */ -_PUBLIC_ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) +_PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) { uint8_t *namebuf; uint32_t namebuf_len; @@ -559,7 +574,7 @@ _PUBLIC_ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, c } if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } name_len = strlen(r->name); @@ -602,7 +617,7 @@ _PUBLIC_ NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, c NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); talloc_free(namebuf); - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r) diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 7d88c83044..1f34b4583b 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -157,6 +157,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) { TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); NTSTATUS status; + enum ndr_err_code ndr_err; struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; @@ -189,9 +190,10 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } /* parse the request */ - status = ndr_pull_struct_blob(&blob, packet, packet, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_pull_struct_blob(&blob, packet, packet, + (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); DEBUG(2,("Failed to parse incoming NBT name packet - %s\n", nt_errstr(status))); talloc_free(tmp_ctx); @@ -359,7 +361,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; int id; - NTSTATUS status; + enum ndr_err_code ndr_err; req = talloc_zero(nbtsock, struct nbt_name_request); if (req == NULL) goto failed; @@ -392,9 +394,9 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, talloc_set_destructor(req, nbt_name_request_destructor); - status = ndr_push_struct_blob(&req->encoded, req, request, - (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); - if (!NT_STATUS_IS_OK(status)) goto failed; + ndr_err = ndr_push_struct_blob(&req->encoded, req, request, + (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed; DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); @@ -422,7 +424,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request) { struct nbt_name_request *req; - NTSTATUS status; + enum ndr_err_code ndr_err; req = talloc_zero(nbtsock, struct nbt_name_request); NT_STATUS_HAVE_NO_MEMORY(req); @@ -439,11 +441,11 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, NDR_PRINT_DEBUG(nbt_name_packet, request); } - status = ndr_push_struct_blob(&req->encoded, req, request, - (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&req->encoded, req, request, + (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(req); - return status; + return ndr_map_error2ntstatus(ndr_err); } DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 168f9c0309..0f2fdb60af 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -61,6 +61,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, NTSTATUS status; struct smb_nttrans nt; struct ndr_pull *ndr; + enum ndr_err_code ndr_err; status = smb_raw_nttrans_recv(req, mem_ctx, &nt); if (!NT_STATUS_IS_OK(status)) { @@ -84,10 +85,13 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, if (!io->query_secdesc.out.sd) { return NT_STATUS_NO_MEMORY; } - status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, - io->query_secdesc.out.sd); + ndr_err = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, + io->query_secdesc.out.sd); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } - return status; + return NT_STATUS_OK; } @@ -114,7 +118,7 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, uint8_t params[8]; struct ndr_push *ndr; struct smbcli_request *req; - NTSTATUS status; + enum ndr_err_code ndr_err; nt.in.max_setup = 0; nt.in.max_param = 0; @@ -133,8 +137,8 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, ndr = ndr_push_init_ctx(NULL); if (!ndr) return NULL; - status = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->set_secdesc.in.sd); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->set_secdesc.in.sd); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); return NULL; } diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 83303cf470..c34cb9c52f 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -263,7 +263,6 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr uint16_t fname_len; DATA_BLOB sd_blob, ea_blob; struct smbcli_request *req; - NTSTATUS status; nt.in.max_setup = 0; nt.in.max_param = 101; @@ -276,10 +275,11 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr ea_blob = data_blob(NULL, 0); if (parms->ntcreatex.in.sec_desc) { - status = ndr_push_struct_blob(&sd_blob, mem_ctx, - parms->ntcreatex.in.sec_desc, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - if (!NT_STATUS_IS_OK(status)) { + enum ndr_err_code ndr_err; + ndr_err = ndr_push_struct_blob(&sd_blob, mem_ctx, + parms->ntcreatex.in.sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); return NULL; } diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 8481995c1a..17e1792fe3 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -245,15 +245,17 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ return NT_STATUS_OK; case RAW_FILEINFO_SEC_DESC: { - NTSTATUS status; + enum ndr_err_code ndr_err; parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor); NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd); - status = ndr_pull_struct_blob(blob, mem_ctx, - parms->query_secdesc.out.sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - NT_STATUS_NOT_OK_RETURN(status); + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, + parms->query_secdesc.out.sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } return NT_STATUS_OK; } diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index ced977333d..73f1192df0 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -158,6 +158,7 @@ NTSTATUS smb_raw_fsinfo_passthru_parse(DATA_BLOB blob, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo) { NTSTATUS status = NT_STATUS_OK; + enum ndr_err_code ndr_err; int i; /* parse the results */ @@ -215,8 +216,11 @@ NTSTATUS smb_raw_fsinfo_passthru_parse(DATA_BLOB blob, TALLOC_CTX *mem_ctx, case RAW_QFS_OBJECTID_INFORMATION: QFS_CHECK_SIZE(64); - status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + } for (i=0;i<6;i++) { fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8); } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 5fa0c1f2da..3ae2a2dd20 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -86,12 +86,14 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, return true; case RAW_FILEINFO_SEC_DESC: { - NTSTATUS status; - - status = ndr_push_struct_blob(blob, mem_ctx, - parms->set_secdesc.in.sd, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - if (!NT_STATUS_IS_OK(status)) return false; + enum ndr_err_code ndr_err; + + ndr_err = ndr_push_struct_blob(blob, mem_ctx, + parms->set_secdesc.in.sd, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } return true; } diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 29cc1f37fd..1f7ca796b6 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -85,7 +85,7 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) struct wrepl_socket *wrepl_socket = talloc_get_type(private, struct wrepl_socket); struct wrepl_request *req = wrepl_socket->recv_queue; DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; if (!req) { DEBUG(1,("Received unexpected WINS packet of length %u!\n", @@ -100,10 +100,11 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) blob.length = packet_blob_in.length - 4; /* we have a full request - parse it */ - status = ndr_pull_struct_blob(&blob, - req->packet, req->packet, - (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_pull_struct_blob(&blob, + req->packet, req->packet, + (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); wrepl_request_finished(req, status); return NT_STATUS_OK; } @@ -470,6 +471,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, struct wrepl_wrap wrap; DATA_BLOB blob; NTSTATUS status; + enum ndr_err_code ndr_err; req = talloc_zero(wrepl_socket, struct wrepl_request); if (!req) return NULL; @@ -485,9 +487,10 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, } wrap.packet = *packet; - status = ndr_push_struct_blob(&blob, req, &wrap, - (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, req, &wrap, + (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); return wrepl_request_finished(req, status); } -- cgit From 089acd77b6cfb81b8951ae6db0fefc73c2599b22 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 11 Nov 2007 13:59:01 +0100 Subject: r25924: fix bug in UNIX_INFO2 push code found make make valgrindtest metze (This used to be commit 9b151e6ceaeaa15e8cbd92f452522fe005f2382f) --- source4/libcli/raw/rawsetfileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 3ae2a2dd20..67dadf3287 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -177,7 +177,7 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree, smbcli_push_nttime(blob->data, 32, parms->unix_info2.in.change_time); SBVAL(blob->data, 40,parms->unix_info2.in.uid); SBVAL(blob->data, 48,parms->unix_info2.in.gid); - SIVAL(blob->data, 52,parms->unix_info2.in.file_type); + SIVAL(blob->data, 56,parms->unix_info2.in.file_type); SBVAL(blob->data, 60,parms->unix_info2.in.dev_major); SBVAL(blob->data, 68,parms->unix_info2.in.dev_minor); SBVAL(blob->data, 76,parms->unix_info2.in.unique_id); -- cgit From e66d7d8074f01536ad49ed1195d1503b2f162938 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Nov 2007 12:43:11 +0100 Subject: r26060: Add some error codes from remote join api. Guenther (This used to be commit 73f231cba3fde4b2c5078b7c6dd52c3dac8cd1ce) --- source4/libcli/util/doserr.c | 3 +++ source4/libcli/util/werror.h | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index 19984cf2e9..b480946401 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -62,6 +62,9 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, + { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, + { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, + { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES", WERR_STATUS_MORE_ENTRIES }, diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 532dc2ed8c..4de3092d9f 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -116,6 +116,11 @@ typedef uint32_t WERROR; #define WERR_FID_NOT_FOUND W_ERROR(2314) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) #define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453) + +#define WERR_SETUP_ALREADY_JOINED W_ERROR(2691) +#define WERR_SETUP_NOT_JOINED W_ERROR(2692) +#define WERR_SETUP_DOMAIN_CONTROLLER W_ERROR(2693) + #define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319) #define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) -- cgit From 4cb790b768755b1eb1623296aa752e5d64b5137c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 12:31:29 +0100 Subject: r26074: Add SWIG magic for NTSTATUS and WERROR return codes. (This used to be commit 0bee7cb92e8ae1b80a957dd8fe32c36db1c32032) --- source4/libcli/util/errors.i | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 source4/libcli/util/errors.i (limited to 'source4/libcli') diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i new file mode 100644 index 0000000000..61cb7a090a --- /dev/null +++ b/source4/libcli/util/errors.i @@ -0,0 +1,39 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 2007 + Copyright (C) Tim Potter 2004 + + 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 3 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, see . +*/ + +#ifdef SWIGPYTHON +%typemap(out) WERROR { + if (!W_ERROR_IS_OK($1)) { + PyObject *obj = Py_BuildValue("(i,s)", $1.v, win_errstr($1)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if ($result == NULL) { + $result = Py_None; + } +}; + +%typemap(out) NTSTATUS { + if (NT_STATUS_IS_ERR($1)) { + PyObject *obj = Py_BuildValue("(i,s)", $1.v, nt_errstr($1)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if ($result == NULL) { + $result = Py_None; + } +}; + +#endif -- cgit From d3a13a16fff6e9a9929109a37f04a0a8e91d82b7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 12:31:35 +0100 Subject: r26076: Remove some SWIG code that is already commonly available. (This used to be commit e6cd16d0fb3c7f0d4756c28b8c9300583910c4c6) --- source4/libcli/swig/libcli_nbt.i | 32 ++------------------------------ source4/libcli/swig/libcli_smb.i | 5 ++--- 2 files changed, 4 insertions(+), 33 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index ec7632ccf4..56d6d4206e 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -39,29 +39,8 @@ %} -%apply bool { bool }; -%apply int { uint8_t }; -%apply int { int8_t }; -%apply unsigned int { uint16_t }; -%apply int { int16_t }; - -%typemap(in) uint32_t { - if (PyLong_Check($input)) - $1 = PyLong_AsUnsignedLong($input); - else if (PyInt_Check($input)) - $1 = PyInt_AsLong($input); - else { - PyErr_SetString(PyExc_TypeError,"Expected a long or an int"); - return NULL; - } -} - -%typemap(out) uint32_t { - $result = PyLong_FromUnsignedLong($1); -} - -%apply unsigned long long { uint64_t }; -%apply long long { int64_t }; +%import "stdint.i" +%import "../../lib/talloc/talloc.i" %typemap(in) NTSTATUS { if (PyLong_Check($input)) @@ -78,9 +57,6 @@ $result = PyLong_FromUnsignedLong(NT_STATUS_V($1)); } -TALLOC_CTX *talloc_init(char *name); -int talloc_free(TALLOC_CTX *ptr); - /* Function prototypes */ struct event_context *event_context_init(TALLOC_CTX *mem_ctx); @@ -138,7 +114,3 @@ NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, return nbt_name_query(nbtsock, mem_ctx, io); } %} - -%init %{ - lp_load(); -%} diff --git a/source4/libcli/swig/libcli_smb.i b/source4/libcli/swig/libcli_smb.i index 8eb055c2f0..c3b8edd7e9 100644 --- a/source4/libcli/swig/libcli_smb.i +++ b/source4/libcli/swig/libcli_smb.i @@ -1,14 +1,13 @@ %module libcli_smb +%import "../../lib/talloc/talloc.i" + %{ #include "includes.h" -#include "lib/talloc/talloc.h" #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" %} -TALLOC_CTX *talloc_init(char *name); -int talloc_free(TALLOC_CTX *ptr); struct event_context *event_context_init(TALLOC_CTX *mem_ctx); struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, -- cgit From 39adc2418a0586261c6c4aea36f72596c6cf8897 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 13:07:16 +0100 Subject: r26088: Import some native-python python modules and move original python swig torture code to common python directory as well. (This used to be commit cbf656ff054ab2b0b5ca81e1d4f16ac54c8098f1) --- source4/libcli/util/errors.i | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index 61cb7a090a..d51c9e0ded 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -36,4 +36,15 @@ } }; +%typemap(in) NTSTATUS { + if (PyLong_Check($input)) + $1 = NT_STATUS(PyLong_AsUnsignedLong($input)); + else if (PyInt_Check($input)) + $1 = NT_STATUS(PyInt_AsLong($input)); + else { + PyErr_SetString(PyExc_TypeError, "Expected a long or an int"); + return NULL; + } +} + #endif -- cgit From c14de3fd893c4a44cf35c2b354e51bf7f4a81992 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 16:04:13 +0100 Subject: r26100: Also check for SWIG. (This used to be commit 1755adffecb8ed68047d6ad69087a680cc63ba8f) --- source4/libcli/config.m4 | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 source4/libcli/config.m4 (limited to 'source4/libcli') diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 deleted file mode 100644 index e31359fdaa..0000000000 --- a/source4/libcli/config.m4 +++ /dev/null @@ -1,31 +0,0 @@ -AC_MSG_CHECKING([for Python (libcli_nbt)]) - -PYTHON= - -AC_ARG_WITH(python, -[ --with-python=PYTHONNAME build Python libraries], -[ case "${withval-python}" in - yes) - PYTHON=python - ;; - no) - PYTHON= - ;; - *) - PYTHON=${withval-python} - ;; - esac ]) - -if test x"$PYTHON" != "x"; then - incdir=`python -c 'import sys; print "%s/include/python%d.%d" % (sys.prefix, sys.version_info[[0]], sys.version_info[[1]])'` - CPPFLAGS="$CPPFLAGS -I $incdir" -fi - -if test x"$PYTHON" != "x"; then - AC_MSG_RESULT([${withval-python}]) -else - AC_MSG_RESULT(no) - SMB_ENABLE(swig_libcli_nbt, NO) -fi - -AC_SUBST(PYTHON) -- cgit From 017ee874858d13cb77738a885d9320c659f49e18 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 26 Nov 2007 23:58:39 +0100 Subject: r26133: Add some more error codes from wkssvc testing. Guenther (This used to be commit 0cf974ee33ba0dbd41c554db2fd1d0458e99e3d1) --- source4/libcli/util/doserr.c | 5 +++++ source4/libcli/util/werror.h | 8 ++++++++ 2 files changed, 13 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index b480946401..d36532dcf4 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -41,6 +41,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_FILE_EXISTS", WERR_FILE_EXISTS }, { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, { "WERR_NOT_SUPPORTED", WERR_NOT_SUPPORTED }, + { "WERR_DUP_NAME", WERR_DUP_NAME }, { "WERR_BAD_PASSWORD", WERR_BAD_PASSWORD }, { "WERR_NOMEM", WERR_NOMEM }, { "WERR_INVALID_NAME", WERR_INVALID_NAME }, @@ -62,6 +63,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, + { "WERR_TIME_DIFF_AT_DC", WERR_TIME_DIFF_AT_DC }, { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, @@ -84,6 +86,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_COMPUTERNAME", WERR_INVALID_COMPUTERNAME }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_NO_SUCH_PRIVILEGE", WERR_NO_SUCH_PRIVILEGE }, { "WERR_PRIVILEGE_NOT_HELD", WERR_PRIVILEGE_NOT_HELD }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, @@ -128,6 +131,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_FRS_INVALID_SERVICE_PARAMETER", WERR_FRS_INVALID_SERVICE_PARAMETER }, { "WERR_FRS_SYSVOL_IS_BUSY", WERR_FRS_SYSVOL_IS_BUSY }, { "WERR_FRS_INSUFFICIENT_PRIV", WERR_FRS_INSUFFICIENT_PRIV }, + { "WERR_RPC_E_REMOTE_DISABLED", WERR_RPC_E_REMOTE_DISABLED }, + { "WERR_NOT_CONNECTED", WERR_NOT_CONNECTED }, { NULL, W_ERROR(0) } }; diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 4de3092d9f..83fa5469cf 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -70,6 +70,7 @@ typedef uint32_t WERROR; #define WERR_NOMEM W_ERROR(8) #define WERR_GENERAL_FAILURE W_ERROR(31) #define WERR_NOT_SUPPORTED W_ERROR(50) +#define WERR_DUP_NAME W_ERROR(52) #define WERR_BAD_NETPATH W_ERROR(53) #define WERR_BAD_NET_RESP W_ERROR(58) #define WERR_UNEXP_NET_ERR W_ERROR(59) @@ -97,6 +98,7 @@ typedef uint32_t WERROR; #define WERR_REVISION_MISMATCH W_ERROR(1306) #define WERR_INVALID_OWNER W_ERROR(1307) #define WERR_NO_LOGON_SERVERS W_ERROR(1311) +#define WERR_NO_SUCH_LOGON_SESSION W_ERROR(1312) #define WERR_NO_SUCH_PRIVILEGE W_ERROR(1313) #define WERR_PRIVILEGE_NOT_HELD W_ERROR(1314) #define WERR_NO_SUCH_USER W_ERROR(1317) @@ -112,10 +114,12 @@ typedef uint32_t WERROR; #define WERR_BUF_TOO_SMALL W_ERROR(2123) #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) +#define WERR_NOT_CONNECTED W_ERROR(2250) #define WERR_SESSION_NOT_FOUND W_ERROR(2312) #define WERR_FID_NOT_FOUND W_ERROR(2314) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) #define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453) +#define WERR_TIME_DIFF_AT_DC W_ERROR(2457) #define WERR_SETUP_ALREADY_JOINED W_ERROR(2691) #define WERR_SETUP_NOT_JOINED W_ERROR(2692) @@ -189,6 +193,10 @@ typedef uint32_t WERROR; #define WERR_FRS_SYSVOL_IS_BUSY W_ERROR(FRS_ERR_BASE+15) #define WERR_FRS_INVALID_SERVICE_PARAMETER W_ERROR(FRS_ERR_BASE+17) +/* RPC errors */ +#define WERR_RPC_E_INVALID_HEADER W_ERROR(0x80010111) +#define WERR_RPC_E_REMOTE_DISABLED W_ERROR(0x8001011c) + /* SEC errors */ #define WERR_SEC_E_ENCRYPT_FAILURE W_ERROR(0x80090329) #define WERR_SEC_E_DECRYPT_FAILURE W_ERROR(0x80090330) -- cgit From 0ac6bffdf46003517127fbd9763f74e09e96c21a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Nov 2007 02:04:38 +0100 Subject: r26136: Attempt to fix dependencies for auth. (This used to be commit abf2600a044cdbab6c5d7880d18217bff3d15c39) --- source4/libcli/config.mk | 2 +- source4/libcli/ldap/config.mk | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index d7aaac0447..3bfc1478bc 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -34,7 +34,7 @@ OBJ_FILES = \ smb_composite/fetchfile.o \ smb_composite/appendacl.o \ smb_composite/fsinfo.o -PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS +PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index e5a7133cfa..adccd23eb1 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,5 +1,3 @@ -################################# -# Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_PROTO_HEADER = ldap_proto.h PUBLIC_HEADERS = ldap.h @@ -12,6 +10,4 @@ OBJ_FILES = ldap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL GENSEC_SOCKET -#PRIVATE_DEPENDENCIES = gensec -# End SUBSYSTEM LIBCLI_LDAP -################################# +#FIXME: PRIVATE_DEPENDENCIES = gensec -- cgit From 018a61a71178ac162c0b0a1f169de12ee75927cc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 27 Nov 2007 11:58:33 +0100 Subject: r26160: Add WERR_NAME_NOT_FOUND. Guenther (This used to be commit 66be960c67787ed7355775e619f3973543a4fef8) --- source4/libcli/util/doserr.c | 1 + source4/libcli/util/werror.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c index d36532dcf4..be33ba47e2 100644 --- a/source4/libcli/util/doserr.c +++ b/source4/libcli/util/doserr.c @@ -133,6 +133,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_FRS_INSUFFICIENT_PRIV", WERR_FRS_INSUFFICIENT_PRIV }, { "WERR_RPC_E_REMOTE_DISABLED", WERR_RPC_E_REMOTE_DISABLED }, { "WERR_NOT_CONNECTED", WERR_NOT_CONNECTED }, + { "WERR_NAME_NOT_FOUND", WERR_NAME_NOT_FOUND}, { NULL, W_ERROR(0) } }; diff --git a/source4/libcli/util/werror.h b/source4/libcli/util/werror.h index 83fa5469cf..c5ec90d5dd 100644 --- a/source4/libcli/util/werror.h +++ b/source4/libcli/util/werror.h @@ -115,6 +115,7 @@ typedef uint32_t WERROR; #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) #define WERR_NOT_CONNECTED W_ERROR(2250) +#define WERR_NAME_NOT_FOUND W_ERROR(2273) #define WERR_SESSION_NOT_FOUND W_ERROR(2312) #define WERR_FID_NOT_FOUND W_ERROR(2314) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) -- cgit From 364266e22a08e730f2442cf87ec385620cff2700 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Nov 2007 08:00:04 +0100 Subject: r26192: Handle, test and implement the style of extended_dn requiest that MMC uses. It appears that the control value is optional, implying type 0 responses. Failing to parse this was causing LDAP disconnects with 'unavailable critical extension'. Andrew Bartlett (This used to be commit 833dfc2f2af84c45f954e428c9ea6babf100ba92) --- source4/libcli/ldap/ldap.c | 13 ++++++++++++- source4/libcli/ldap/ldap.h | 2 ++ source4/libcli/ldap/ldap_client.c | 15 +++++++++++++++ source4/libcli/ldap/ldap_controls.c | 18 ++++++++++++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 11689fbd79..34d715e3e5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1325,10 +1325,12 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) } msg->controls = NULL; + msg->controls_decoded = NULL; if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { int i = 0; struct ldb_control **ctrl = NULL; + bool *decoded = NULL; asn1_start_tag(data, ASN1_CONTEXT(0)); @@ -1341,6 +1343,11 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + ctrl[i] = talloc(ctrl, struct ldb_control); if (!ctrl[i]) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); @@ -1352,12 +1359,15 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { if (ctrl[i]->critical) { - return NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); + ctrl[i]->data = NULL; + decoded[i] = false; + i++; } else { talloc_free(ctrl[i]); ctrl[i] = NULL; } } else { + decoded[i] = true; i++; } } @@ -1367,6 +1377,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) } msg->controls = ctrl; + msg->controls_decoded = decoded; asn1_end_tag(data); } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index e89322213a..6f5e86744e 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -240,11 +240,13 @@ union ldap_Request { struct ldap_ExtendedResponse ExtendedResponse; }; + struct ldap_message { int messageid; enum ldap_request_tag type; union ldap_Request r; struct ldb_control **controls; + bool *controls_decoded; }; struct event_context; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index fcb2d92214..41e9c37196 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -116,6 +116,7 @@ static void ldap_error_handler(void *private_data, NTSTATUS status) static void ldap_match_message(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; + int i; for (req=conn->pending; req; req=req->next) { if (req->messageid == msg->messageid) break; @@ -132,6 +133,20 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message return; } + /* Check for undecoded critical extensions */ + for (i=0; msg->controls && msg->controls[i]; i++) { + if (!msg->controls_decoded[i] && + msg->controls[i]->critical) { + req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); + req->state = LDAP_REQUEST_DONE; + DLIST_REMOVE(conn->pending, req); + if (req->async.fn) { + req->async.fn(req); + } + return; + } + } + /* add to the list of replies received */ talloc_steal(req, msg); req->replies = talloc_realloc(req, req->replies, diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index b7fd1ce178..34e5cccf75 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -156,9 +156,16 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data *data = asn1_init(mem_ctx); + struct asn1_data *data; struct ldb_extended_dn_control *ledc; + /* The content of this control is optional */ + if (in.length == 0) { + *out = NULL; + return true; + } + + data = asn1_init(mem_ctx); if (!data) return false; if (!asn1_load(data, in)) { @@ -717,7 +724,14 @@ static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control); - struct asn1_data *data = asn1_init(mem_ctx); + struct asn1_data *data; + + if (!in) { + *out = data_blob(NULL, 0); + return true; + } + + data = asn1_init(mem_ctx); if (!data) return false; -- cgit From e1733d72441ec5aff6d48abf6dd41a91e459df01 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 14:49:35 +0100 Subject: r26194: Wrap the events subsystem in a separate file. (This used to be commit cfb6bbdc31083308dbff29cf226a092c8a137c2a) --- source4/libcli/swig/libcli_nbt.i | 21 ++------------------- source4/libcli/swig/libcli_smb.i | 3 +-- 2 files changed, 3 insertions(+), 21 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index 56d6d4206e..6fd85c2b8c 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -29,7 +29,6 @@ #include "includes.h" #include "lib/talloc/talloc.h" -#include "lib/events/events.h" #include "libcli/nbt/libnbt.h" #include "param/param.h" @@ -40,27 +39,11 @@ %} %import "stdint.i" +%import "../util/errors.i" %import "../../lib/talloc/talloc.i" - -%typemap(in) NTSTATUS { - if (PyLong_Check($input)) - $1 = NT_STATUS(PyLong_AsUnsignedLong($input)); - else if (PyInt_Check($input)) - $1 = NT_STATUS(PyInt_AsLong($input)); - else { - PyErr_SetString(PyExc_TypeError, "Expected a long or an int"); - return NULL; - } -} - -%typemap(out) NTSTATUS { - $result = PyLong_FromUnsignedLong(NT_STATUS_V($1)); -} +%import "../../lib/events/events.i" /* Function prototypes */ - -struct event_context *event_context_init(TALLOC_CTX *mem_ctx); - struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); diff --git a/source4/libcli/swig/libcli_smb.i b/source4/libcli/swig/libcli_smb.i index c3b8edd7e9..32e043b2c6 100644 --- a/source4/libcli/swig/libcli_smb.i +++ b/source4/libcli/swig/libcli_smb.i @@ -1,6 +1,7 @@ %module libcli_smb %import "../../lib/talloc/talloc.i" +%import "../../lib/events/events.i" %{ #include "includes.h" @@ -8,8 +9,6 @@ #include "libcli/raw/libcliraw.h" %} -struct event_context *event_context_init(TALLOC_CTX *mem_ctx); - struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, TALLOC_CTX *mem_ctx, struct event_context *event_ctx); -- cgit From f2f16b45b58c2bbf3053ff55e7a290fc069e0efd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 14:49:47 +0100 Subject: r26197: Add bindings for libsecurity. (This used to be commit 8625cd403ba3a7d2b1b1fccfeb5efd7e21de0135) --- source4/libcli/security/config.mk | 8 +- source4/libcli/security/security.i | 121 ++++++++++++++++++++++++++++++ source4/libcli/security/tests/bindings.py | 65 ++++++++++++++++ 3 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 source4/libcli/security/security.i create mode 100644 source4/libcli/security/tests/bindings.py (limited to 'source4/libcli') diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 3c97ec4264..ff7480c957 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,5 +1,3 @@ -################################# -# Start SUBSYSTEM LIBSECURITY [SUBSYSTEM::LIBSECURITY] PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = security_token.o \ @@ -9,5 +7,7 @@ OBJ_FILES = security_token.o \ privilege.o \ sddl.o PUBLIC_DEPENDENCIES = NDR_MISC -# End SUBSYSTEM LIBSECURITY -################################# + +[PYTHON::swig_security] +SWIG_FILE = security.i +PRIVATE_DEPENDENCIES = LIBSECURITY diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i new file mode 100644 index 0000000000..cc5afb40c0 --- /dev/null +++ b/source4/libcli/security/security.i @@ -0,0 +1,121 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 2007 + + 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 3 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, see . +*/ + +%module(package="samba.security") security + +%{ +#include "includes.h" +#include "libcli/security/security.h" + +typedef struct dom_sid dom_sid; +typedef struct security_token security_token; +typedef struct security_descriptor security_descriptor; +%} + +%import "../../lib/talloc/talloc.i" +%import "../util/errors.i" +%import "stdint.i" + +enum sec_privilege { + SEC_PRIV_SECURITY=1, + SEC_PRIV_BACKUP=2, + SEC_PRIV_RESTORE=3, + SEC_PRIV_SYSTEMTIME=4, + SEC_PRIV_SHUTDOWN=5, + SEC_PRIV_REMOTE_SHUTDOWN=6, + SEC_PRIV_TAKE_OWNERSHIP=7, + SEC_PRIV_DEBUG=8, + SEC_PRIV_SYSTEM_ENVIRONMENT=9, + SEC_PRIV_SYSTEM_PROFILE=10, + SEC_PRIV_PROFILE_SINGLE_PROCESS=11, + SEC_PRIV_INCREASE_BASE_PRIORITY=12, + SEC_PRIV_LOAD_DRIVER=13, + SEC_PRIV_CREATE_PAGEFILE=14, + SEC_PRIV_INCREASE_QUOTA=15, + SEC_PRIV_CHANGE_NOTIFY=16, + SEC_PRIV_UNDOCK=17, + SEC_PRIV_MANAGE_VOLUME=18, + SEC_PRIV_IMPERSONATE=19, + SEC_PRIV_CREATE_GLOBAL=20, + SEC_PRIV_ENABLE_DELEGATION=21, + SEC_PRIV_INTERACTIVE_LOGON=22, + SEC_PRIV_NETWORK_LOGON=23, + SEC_PRIV_REMOTE_INTERACTIVE_LOGON=24 +}; + +%rename(SecurityToken) security_token; + +typedef struct security_token { + %extend { + security_token(TALLOC_CTX *mem_ctx) { return security_token_initialise(mem_ctx); } + ~security_token() { talloc_free($self); } + bool is_sid(const struct dom_sid *sid); + bool is_system(); + bool is_anonymous(); + bool has_sid(const struct dom_sid *sid); + bool has_builtin_administrators(); + bool has_nt_authenticated_users(); + bool has_privilege(enum sec_privilege privilege); + void set_privilege(enum sec_privilege privilege); + } +} security_token; + +typedef struct security_descriptor { + %extend { + security_descriptor(TALLOC_CTX *mem_ctx) { return security_descriptor_initialise(mem_ctx); } + ~security_descriptor() { talloc_free($self); } + NTSTATUS sacl_add(const struct security_ace *ace); + NTSTATUS dacl_add(const struct security_ace *ace); + NTSTATUS dacl_del(const struct security_ace *ace); + NTSTATUS sacl_del(const struct security_ace *ace); +#ifdef SWIGPYTHON + %rename(equal) __eq__; +#endif + bool equal(const struct security_descriptor *other); + } +} security_descriptor; + +%rename(Sid) dom_sid; + +typedef struct dom_sid { + %extend { + bool equal(const struct dom_sid *other); +#ifdef SWIGPYTHON + const char *__str__(TALLOC_CTX *mem_ctx) { + return dom_sid_string(mem_ctx, $self); + } +#endif + } +} dom_sid; + +%inline %{ +static struct dom_sid *random_sid(TALLOC_CTX *mem_ctx) +{ + char *str = talloc_asprintf(mem_ctx, "S-1-5-21-%u-%u-%u", + (unsigned)generate_random(), + (unsigned)generate_random(), + (unsigned)generate_random()); + + return dom_sid_parse_talloc(mem_ctx, str); +} +%} + +%rename(privilege_name) sec_privilege_name; +const char *sec_privilege_name(enum sec_privilege privilege); +%rename(privilege_id) sec_privilege_id; +enum sec_privilege sec_privilege_id(const char *name); diff --git a/source4/libcli/security/tests/bindings.py b/source4/libcli/security/tests/bindings.py new file mode 100644 index 0000000000..15e2381a2b --- /dev/null +++ b/source4/libcli/security/tests/bindings.py @@ -0,0 +1,65 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2007 +# +# 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 3 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, see . +# + +import unittest +import security + +class SecurityTokenTests(unittest.TestCase): + def setUp(self): + self.token = security.SecurityToken() + + def test_is_system(self): + self.assertFalse(self.token.is_system()) + + def test_is_anonymous(self): + self.assertFalse(self.token.is_anonymous()) + + def test_has_builtin_administrators(self): + self.assertFalse(self.token.has_builtin_administrators()) + + def test_has_nt_authenticated_users(self): + self.assertFalse(self.token.has_nt_authenticated_users()) + + def test_has_priv(self): + self.assertFalse(self.token.has_privilege(security.SEC_PRIV_SHUTDOWN)) + + def test_set_priv(self): + self.assertFalse(self.token.has_privilege(security.SEC_PRIV_SHUTDOWN)) + self.assertFalse(self.token.set_privilege(security.SEC_PRIV_SHUTDOWN)) + self.assertTrue(self.token.has_privilege(security.SEC_PRIV_SHUTDOWN)) + + +class SecurityDescriptorTests(unittest.TestCase): + def setUp(self): + self.descriptor = security.SecurityDescriptor() + + +class RandomSidTests(unittest.TestCase): + def test_random(self): + sid = security.random_sid() + self.assertTrue(str(sid).startswith("S-1-5-21-")) + + +class PrivilegeTests(unittest.TestCase): + def test_privilege_name(self): + self.assertEquals("SeShutdownPrivilege", security.privilege_name(security.SEC_PRIV_SHUTDOWN)) + + def test_privilege_id(self): + self.assertEquals(security.SEC_PRIV_SHUTDOWN, security.privilege_id("SeShutdownPrivilege")) + -- cgit From 4004de7b7dec06e7ee0040f8a07c7f4fb967a4c1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 15:08:22 +0100 Subject: r26199: Allow constructing new sids, implement __eq__ for sids. (This used to be commit 87472e35c04fdf0c61c9133bab3c05bda11eba00) --- source4/libcli/security/security.i | 9 +++++++-- source4/libcli/security/tests/bindings.py | 12 +++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i index cc5afb40c0..1f100b0b8f 100644 --- a/source4/libcli/security/security.i +++ b/source4/libcli/security/security.i @@ -84,7 +84,7 @@ typedef struct security_descriptor { NTSTATUS dacl_del(const struct security_ace *ace); NTSTATUS sacl_del(const struct security_ace *ace); #ifdef SWIGPYTHON - %rename(equal) __eq__; + %rename(__eq__) equal; #endif bool equal(const struct security_descriptor *other); } @@ -94,12 +94,17 @@ typedef struct security_descriptor { typedef struct dom_sid { %extend { - bool equal(const struct dom_sid *other); + dom_sid(TALLOC_CTX *mem_ctx, const char *text) { + return dom_sid_parse_talloc(mem_ctx, text); + } + ~dom_sid() { talloc_free($self); } #ifdef SWIGPYTHON const char *__str__(TALLOC_CTX *mem_ctx) { return dom_sid_string(mem_ctx, $self); } + %rename(__eq__) equal; #endif + bool equal(const struct dom_sid *other); } } dom_sid; diff --git a/source4/libcli/security/tests/bindings.py b/source4/libcli/security/tests/bindings.py index 15e2381a2b..59a5e69640 100644 --- a/source4/libcli/security/tests/bindings.py +++ b/source4/libcli/security/tests/bindings.py @@ -50,7 +50,17 @@ class SecurityDescriptorTests(unittest.TestCase): self.descriptor = security.SecurityDescriptor() -class RandomSidTests(unittest.TestCase): +class DomSidTests(unittest.TestCase): + def test_parse_sid(self): + sid = security.Sid("S-1-5-21") + self.assertEquals("S-1-5-21", str(sid)) + + def test_sid_equal(self): + sid1 = security.Sid("S-1-5-21") + sid2 = security.Sid("S-1-5-21") + self.assertTrue(sid1.__eq__(sid1)) + self.assertTrue(sid1.__eq__(sid2)) + def test_random(self): sid = security.random_sid() self.assertTrue(str(sid).startswith("S-1-5-21-")) -- cgit From 25f286fdfe0cf7ac800ccf3ac62ee5e1d2ceb583 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 16:20:29 +0100 Subject: r26223: Move loadparm context up in the stack. (This used to be commit 152e2b1a283675b53affb8f7225644925f171dbd) --- source4/libcli/cldap/cldap.c | 3 ++- source4/libcli/cldap/cldap.h | 1 + source4/libcli/dgram/browse.c | 3 ++- source4/libcli/dgram/libdgram.h | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 9903595dfb..88421ad08d 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -317,7 +317,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->dest = socket_address_from_strings(req, cldap->sock->backend_name, io->in.dest_address, - lp_cldap_port(global_loadparm)); + io->in.dest_port); if (!req->dest) goto failed; req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); @@ -572,6 +572,7 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, if (filter == NULL) goto failed; search.in.dest_address = io->in.dest_address; + search.in.dest_port = lp_cldap_port(global_loadparm); search.in.filter = filter; search.in.attributes = attr; search.in.timeout = 2; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index e957ccea19..cdee775aa7 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -98,6 +98,7 @@ struct cldap_socket { struct cldap_search { struct { const char *dest_address; + uint16_t dest_port; const char *filter; const char **attributes; int timeout; diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 3b5f67118f..ab831df8cc 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -56,6 +56,7 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *mailslot_name, + const char *my_netbios_name, struct nbt_browse_packet *reply) { NTSTATUS status; @@ -72,7 +73,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, return ndr_map_error2ntstatus(ndr_err); } - make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); + make_nbt_name_client(&myname, my_netbios_name); dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, request->src_addr, request->src_port); diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 8165e445bc..9f67d58ae2 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -154,6 +154,7 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *mailslot_name, + const char *my_netbios_name, struct nbt_browse_packet *reply); NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, -- cgit From 8d8ad81437555affe0ce189ab9b7049501c708b1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 16:20:32 +0100 Subject: r26224: Remove another use of global_loadparm. (This used to be commit bd12560432b3a8faf124ae1f562b725f3b6686d9) --- source4/libcli/cliconnect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index a56100fc80..d806653758 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -55,10 +55,9 @@ bool smbcli_transport_establish(struct smbcli_state *cli, } /* wrapper around smb_raw_negotiate() */ -NTSTATUS smbcli_negprot(struct smbcli_state *cli) +NTSTATUS smbcli_negprot(struct smbcli_state *cli, int maxprotocol) { - return smb_raw_negotiate(cli->transport, - lp_cli_maxprotocol(global_loadparm)); + return smb_raw_negotiate(cli->transport, maxprotocol); } /* wrapper around smb_raw_sesssetup() */ -- cgit From fface33dd731a711688b56593bb703c38090e782 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 19:31:14 +0100 Subject: r26231: Spell check: credentails -> credentials. (This used to be commit 4b46888bd0195ab12190f76868719fc018baafd6) --- source4/libcli/smb_composite/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 622367e746..a726860647 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -375,7 +375,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, status = gensec_set_credentials(session->gensec, io->in.credentials); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", + DEBUG(1, ("Failed to start set GENSEC client credentials: %s\n", nt_errstr(status))); return status; } -- cgit From 6c999cd12344f2bb8b1d2941210b4c205b3e0aad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 22:32:11 +0100 Subject: r26236: Remove more uses of global_loadparm or specify loadparm_context explicitly. (This used to be commit 5b29ef7c03d9ae76b0ca909e9f03a58e1bad3521) --- source4/libcli/cliconnect.c | 4 ++-- source4/libcli/raw/rawnegotiate.c | 7 ++++--- source4/libcli/smb_composite/connect.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index d806653758..39f97f4d8c 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -55,9 +55,9 @@ bool smbcli_transport_establish(struct smbcli_state *cli, } /* wrapper around smb_raw_negotiate() */ -NTSTATUS smbcli_negprot(struct smbcli_state *cli, int maxprotocol) +NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) { - return smb_raw_negotiate(cli->transport, maxprotocol); + return smb_raw_negotiate(cli->transport, unicode, maxprotocol); } /* wrapper around smb_raw_sesssetup() */ diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 82d6fe5236..78b9082521 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -46,6 +46,7 @@ static const struct { Send a negprot command. */ struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport, + bool unicode, int maxprotocol) { struct smbcli_request *req; @@ -58,7 +59,7 @@ struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport } flags2 |= FLAGS2_32_BIT_ERROR_CODES; - if (lp_unicode(global_loadparm)) { + if (unicode) { flags2 |= FLAGS2_UNICODE_STRINGS; } flags2 |= FLAGS2_EXTENDED_ATTRIBUTES; @@ -190,8 +191,8 @@ failed: /* Send a negprot command (sync interface) */ -NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, int maxprotocol) +NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int maxprotocol) { - struct smbcli_request *req = smb_raw_negotiate_send(transport, maxprotocol); + struct smbcli_request *req = smb_raw_negotiate_send(transport, unicode, maxprotocol); return smb_raw_negotiate_recv(req); } diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 9f18c0d924..0238d5c550 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -63,7 +63,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - state->req = smb_raw_negotiate_send(state->transport, + state->req = smb_raw_negotiate_send(state->transport, lp_unicode(global_loadparm), lp_cli_maxprotocol(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(state->req); -- cgit From bbdfbf8d9d486aee51117976b8f825759a4c4a37 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 00:28:22 +0100 Subject: r26238: Add a loadparm context parameter to torture_context, remove more uses of global_loadparm. (This used to be commit a33a5530545086b81a3b205aa109dff11c546926) --- source4/libcli/ldap/ldap_client.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 41e9c37196..f1cfaad18b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -34,6 +34,7 @@ #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "system/time.h" +#include "param/param.h" /* @@ -391,7 +392,17 @@ static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_con talloc_steal(conn, conn->sock); if (conn->ldaps) { - struct socket_context *tls_socket = tls_init_client(conn->sock, conn->event.fde); + struct socket_context *tls_socket; + char *cafile = private_path(conn->sock, global_loadparm, lp_tls_cafile(global_loadparm)); + + if (!cafile || !*cafile) { + talloc_free(conn->sock); + return; + } + + tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile); + talloc_free(cafile); + if (tls_socket == NULL) { talloc_free(conn->sock); return; -- cgit From 53ae9bc9f6f66578948c3995073bdc1f1acae0f1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 13:48:09 +0100 Subject: r26248: Check in SWIG output so SWIG is not required when running out of svn. (This used to be commit 08501fbef38f81ce5ff4885a1696f9cb392fd631) --- source4/libcli/security/security.py | 139 + source4/libcli/security/security_wrap.c | 4132 +++++++++++++++++++++++++++ source4/libcli/swig/libcli_nbt.py | 170 ++ source4/libcli/swig/libcli_nbt_wrap.c | 4695 +++++++++++++++++++++++++++++++ source4/libcli/swig/libcli_smb.py | 55 + source4/libcli/swig/libcli_smb_wrap.c | 3342 ++++++++++++++++++++++ 6 files changed, 12533 insertions(+) create mode 100644 source4/libcli/security/security.py create mode 100644 source4/libcli/security/security_wrap.c create mode 100644 source4/libcli/swig/libcli_nbt.py create mode 100644 source4/libcli/swig/libcli_nbt_wrap.c create mode 100644 source4/libcli/swig/libcli_smb.py create mode 100644 source4/libcli/swig/libcli_smb_wrap.c (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py new file mode 100644 index 0000000000..6b69251b4a --- /dev/null +++ b/source4/libcli/security/security.py @@ -0,0 +1,139 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 1.3.33 +# +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. + +import _security +import new +new_instancemethod = new.instancemethod +try: + _swig_property = property +except NameError: + pass # Python < 2.2 doesn't have 'property'. +def _swig_setattr_nondynamic(self,class_type,name,value,static=1): + if (name == "thisown"): return self.this.own(value) + if (name == "this"): + if type(value).__name__ == 'PySwigObject': + self.__dict__[name] = value + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + if (not static) or hasattr(self,name): + self.__dict__[name] = value + else: + raise AttributeError("You cannot add attributes to %s" % self) + +def _swig_setattr(self,class_type,name,value): + return _swig_setattr_nondynamic(self,class_type,name,value,0) + +def _swig_getattr(self,class_type,name): + if (name == "thisown"): return self.this.own() + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +def _swig_repr(self): + try: strthis = "proxy of " + self.this.__repr__() + except: strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 +del types + + +SEC_PRIV_SECURITY = _security.SEC_PRIV_SECURITY +SEC_PRIV_BACKUP = _security.SEC_PRIV_BACKUP +SEC_PRIV_RESTORE = _security.SEC_PRIV_RESTORE +SEC_PRIV_SYSTEMTIME = _security.SEC_PRIV_SYSTEMTIME +SEC_PRIV_SHUTDOWN = _security.SEC_PRIV_SHUTDOWN +SEC_PRIV_REMOTE_SHUTDOWN = _security.SEC_PRIV_REMOTE_SHUTDOWN +SEC_PRIV_TAKE_OWNERSHIP = _security.SEC_PRIV_TAKE_OWNERSHIP +SEC_PRIV_DEBUG = _security.SEC_PRIV_DEBUG +SEC_PRIV_SYSTEM_ENVIRONMENT = _security.SEC_PRIV_SYSTEM_ENVIRONMENT +SEC_PRIV_SYSTEM_PROFILE = _security.SEC_PRIV_SYSTEM_PROFILE +SEC_PRIV_PROFILE_SINGLE_PROCESS = _security.SEC_PRIV_PROFILE_SINGLE_PROCESS +SEC_PRIV_INCREASE_BASE_PRIORITY = _security.SEC_PRIV_INCREASE_BASE_PRIORITY +SEC_PRIV_LOAD_DRIVER = _security.SEC_PRIV_LOAD_DRIVER +SEC_PRIV_CREATE_PAGEFILE = _security.SEC_PRIV_CREATE_PAGEFILE +SEC_PRIV_INCREASE_QUOTA = _security.SEC_PRIV_INCREASE_QUOTA +SEC_PRIV_CHANGE_NOTIFY = _security.SEC_PRIV_CHANGE_NOTIFY +SEC_PRIV_UNDOCK = _security.SEC_PRIV_UNDOCK +SEC_PRIV_MANAGE_VOLUME = _security.SEC_PRIV_MANAGE_VOLUME +SEC_PRIV_IMPERSONATE = _security.SEC_PRIV_IMPERSONATE +SEC_PRIV_CREATE_GLOBAL = _security.SEC_PRIV_CREATE_GLOBAL +SEC_PRIV_ENABLE_DELEGATION = _security.SEC_PRIV_ENABLE_DELEGATION +SEC_PRIV_INTERACTIVE_LOGON = _security.SEC_PRIV_INTERACTIVE_LOGON +SEC_PRIV_NETWORK_LOGON = _security.SEC_PRIV_NETWORK_LOGON +SEC_PRIV_REMOTE_INTERACTIVE_LOGON = _security.SEC_PRIV_REMOTE_INTERACTIVE_LOGON +class SecurityToken(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, SecurityToken, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, SecurityToken, name) + __repr__ = _swig_repr + def __init__(self, *args, **kwargs): + this = _security.new_SecurityToken(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _security.delete_SecurityToken + __del__ = lambda self : None; + def is_sid(*args, **kwargs): return _security.SecurityToken_is_sid(*args, **kwargs) + def is_system(*args, **kwargs): return _security.SecurityToken_is_system(*args, **kwargs) + def is_anonymous(*args, **kwargs): return _security.SecurityToken_is_anonymous(*args, **kwargs) + def has_sid(*args, **kwargs): return _security.SecurityToken_has_sid(*args, **kwargs) + def has_builtin_administrators(*args, **kwargs): return _security.SecurityToken_has_builtin_administrators(*args, **kwargs) + def has_nt_authenticated_users(*args, **kwargs): return _security.SecurityToken_has_nt_authenticated_users(*args, **kwargs) + def has_privilege(*args, **kwargs): return _security.SecurityToken_has_privilege(*args, **kwargs) + def set_privilege(*args, **kwargs): return _security.SecurityToken_set_privilege(*args, **kwargs) +SecurityToken_swigregister = _security.SecurityToken_swigregister +SecurityToken_swigregister(SecurityToken) + +class security_descriptor(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, security_descriptor, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, security_descriptor, name) + __repr__ = _swig_repr + def __init__(self, *args, **kwargs): + this = _security.new_security_descriptor(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _security.delete_security_descriptor + __del__ = lambda self : None; + def sacl_add(*args, **kwargs): return _security.security_descriptor_sacl_add(*args, **kwargs) + def dacl_add(*args, **kwargs): return _security.security_descriptor_dacl_add(*args, **kwargs) + def dacl_del(*args, **kwargs): return _security.security_descriptor_dacl_del(*args, **kwargs) + def sacl_del(*args, **kwargs): return _security.security_descriptor_sacl_del(*args, **kwargs) + def __eq__(*args, **kwargs): return _security.security_descriptor___eq__(*args, **kwargs) +security_descriptor_swigregister = _security.security_descriptor_swigregister +security_descriptor_swigregister(security_descriptor) + +class Sid(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, Sid, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, Sid, name) + __repr__ = _swig_repr + def __init__(self, *args, **kwargs): + this = _security.new_Sid(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _security.delete_Sid + __del__ = lambda self : None; + def __str__(*args, **kwargs): return _security.Sid___str__(*args, **kwargs) + def __eq__(*args, **kwargs): return _security.Sid___eq__(*args, **kwargs) +Sid_swigregister = _security.Sid_swigregister +Sid_swigregister(Sid) + +random_sid = _security.random_sid +privilege_name = _security.privilege_name +privilege_id = _security.privilege_id + + diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c new file mode 100644 index 0000000000..b9f9157012 --- /dev/null +++ b/source4/libcli/security/security_wrap.c @@ -0,0 +1,4132 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.33 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +#define SWIGPYTHON +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "3" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The swig conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old swig versions, you usually write code as: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit as: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + that seems to be the same, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + requires also to SWIG_ConvertPtr to return new result values, as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + swig errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() + + + */ +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store inforomation on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* think of this as a c++ template<> or a scheme macro */ +#define SWIG_TypeCheck_Template(comparison, ty) \ + if (ty) { \ + swig_cast_info *iter = ty->cast; \ + while (iter) { \ + if (comparison) { \ + if (iter == ty->cast) return iter; \ + /* Move iter to the top of the linked list */ \ + iter->prev->next = iter->next; \ + if (iter->next) \ + iter->next->prev = iter->prev; \ + iter->next = ty->cast; \ + iter->prev = 0; \ + if (ty->cast) ty->cast->prev = iter; \ + ty->cast = iter; \ + return iter; \ + } \ + iter = iter->next; \ + } \ + } \ + return 0 + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); +} + +/* Same as previous function, except strcmp is replaced with a pointer comparison */ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { + SWIG_TypeCheck_Template(iter->type == from, into); +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_Format(PyExc_RuntimeError, mesg); + } +} + + + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* PySwigClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} PySwigClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + PySwigClientData *data = (PySwigClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME PySwigClientData * +PySwigClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +PySwigClientData_Del(PySwigClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== PySwigObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} PySwigObject; + +SWIGRUNTIME PyObject * +PySwigObject_long(PySwigObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +PySwigObject_format(const char* fmt, PySwigObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { + PyObject *ofmt = PyString_FromString(fmt); + if (ofmt) { + res = PyString_Format(ofmt,args); + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +PySwigObject_oct(PySwigObject *v) +{ + return PySwigObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +PySwigObject_hex(PySwigObject *v) +{ + return PySwigObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +PySwigObject_repr(PySwigObject *v) +#else +PySwigObject_repr(PySwigObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); +#else + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); +#endif + PyString_ConcatAndDel(&repr,nrep); + } + return repr; +} + +SWIGRUNTIME int +PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = PySwigObject_repr(v); +#else + PyObject *repr = PySwigObject_repr(v, NULL); +#endif + if (repr) { + fputs(PyString_AsString(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +PySwigObject_str(PySwigObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + PyString_FromString(result) : 0; +} + +SWIGRUNTIME int +PySwigObject_compare(PySwigObject *v, PySwigObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigObject_Check(PyObject *op) { + return ((op)->ob_type == PySwigObject_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +PySwigObject_dealloc(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own) { + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } else { + const char *name = SWIG_TypePrettyName(ty); +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); +#endif + } + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) +{ + PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!PySwigObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +PySwigObject_getattr(PySwigObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods PySwigObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)PySwigObject_long, /*nb_int*/ + (unaryfunc)PySwigObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)PySwigObject_oct, /*nb_oct*/ + (unaryfunc)PySwigObject_hex, /*nb_hex*/ +#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject pyswigobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigObject", /* tp_name */ + sizeof(PySwigObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigObject_dealloc, /* tp_dealloc */ + (printfunc)PySwigObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)PySwigObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigObject_compare, /* tp_compare */ + (reprfunc)PySwigObject_repr, /* tp_repr */ + &PySwigObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigobject_type = tmp; + pyswigobject_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigobject_type; +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own) +{ + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} PySwigPacked; + +SWIGRUNTIME int +PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +PySwigPacked_repr(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return PyString_FromFormat("", result, v->ty->name); + } else { + return PyString_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +PySwigPacked_str(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return PyString_FromFormat("%s%s", result, v->ty->name); + } else { + return PyString_FromString(v->ty->name); + } +} + +SWIGRUNTIME int +PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); +} + +SWIGRUNTIME void +PySwigPacked_dealloc(PyObject *v) +{ + if (PySwigPacked_Check(v)) { + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject pyswigpacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigPacked", /* tp_name */ + sizeof(PySwigPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigPacked_dealloc, /* tp_dealloc */ + (printfunc)PySwigPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigPacked_compare, /* tp_compare */ + (reprfunc)PySwigPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigpacked_type = tmp; + pyswigpacked_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigpacked_type; +} + +SWIGRUNTIME PyObject * +PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (PySwigPacked_Check(obj)) { + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return PyString_FromString("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +SWIGRUNTIME PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !PySwigObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + PySwigObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (PySwigObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own) { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) *own = sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (!tc) return SWIG_ERROR; + *ptr = SWIG_TypeCast(tc,vptr); + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + PySwigObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = PySwigObject_New(ptr, type, own); + PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + PySwigClientData *data = (PySwigClientData *) ty->clientdata; + if (data) PySwigClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = PyString_FromString(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); + } else { + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +PySwigObject_GetDesc(PyObject *self) +{ + PySwigObject *v = (PySwigObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && PySwigObject_Check(obj)) { + const char *otype = (const char *) PySwigObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? PyString_AsString(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_TALLOC_CTX swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_dom_sid swig_types[2] +#define SWIGTYPE_p_int swig_types[3] +#define SWIGTYPE_p_long_long swig_types[4] +#define SWIGTYPE_p_security_ace swig_types[5] +#define SWIGTYPE_p_security_descriptor swig_types[6] +#define SWIGTYPE_p_security_token swig_types[7] +#define SWIGTYPE_p_short swig_types[8] +#define SWIGTYPE_p_signed_char swig_types[9] +#define SWIGTYPE_p_unsigned_char swig_types[10] +#define SWIGTYPE_p_unsigned_int swig_types[11] +#define SWIGTYPE_p_unsigned_long_long swig_types[12] +#define SWIGTYPE_p_unsigned_short swig_types[13] +static swig_type_info *swig_types[15]; +static swig_module_info swig_module = {swig_types, 14, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif + +/*----------------------------------------------- + @(target):= _security.so + ------------------------------------------------*/ +#define SWIG_init init_security + +#define SWIG_name "_security" + +#define SWIGVERSION 0x010333 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "includes.h" +#include "libcli/security/security.h" + +typedef struct dom_sid dom_sid; +typedef struct security_token security_token; +typedef struct security_descriptor security_descriptor; + + + #define SWIG_From_long PyInt_FromLong + + +SWIGINTERNINLINE PyObject * +SWIG_From_int (int value) +{ + return SWIG_From_long (value); +} + +SWIGINTERN security_token *new_security_token(TALLOC_CTX *mem_ctx){ return security_token_initialise(mem_ctx); } +SWIGINTERN void delete_security_token(security_token *self){ talloc_free(self); } + +SWIGINTERNINLINE PyObject* + SWIG_From_bool (bool value) +{ + return PyBool_FromLong(value ? 1 : 0); +} + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + +SWIGINTERN security_descriptor *new_security_descriptor(TALLOC_CTX *mem_ctx){ return security_descriptor_initialise(mem_ctx); } +SWIGINTERN void delete_security_descriptor(security_descriptor *self){ talloc_free(self); } + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ + if (PyString_Check(obj)) { + char *cstr; Py_ssize_t len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + +SWIGINTERN dom_sid *new_dom_sid(TALLOC_CTX *mem_ctx,char const *text){ + return dom_sid_parse_talloc(mem_ctx, text); + } +SWIGINTERN void delete_dom_sid(dom_sid *self){ talloc_free(self); } +SWIGINTERN char const *dom_sid___str__(dom_sid *self,TALLOC_CTX *mem_ctx){ + return dom_sid_string(mem_ctx, self); + } + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { + return PyString_FromStringAndSize(carray, (int)(size)); + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + + +static struct dom_sid *random_sid(TALLOC_CTX *mem_ctx) +{ + char *str = talloc_asprintf(mem_ctx, "S-1-5-21-%u-%u-%u", + (unsigned)generate_random(), + (unsigned)generate_random(), + (unsigned)generate_random()); + + return dom_sid_parse_talloc(mem_ctx, str); +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_new_SecurityToken(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + security_token *result = 0 ; + + { + arg1 = NULL; + } + if (!PyArg_ParseTuple(args,(char *)":new_SecurityToken")) SWIG_fail; + result = (security_token *)new_security_token(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_security_token, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SecurityToken(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_SecurityToken",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SecurityToken" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + delete_security_token(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_is_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + struct dom_sid *arg2 = (struct dom_sid *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "sid", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_is_sid",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_is_sid" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SecurityToken_is_sid" "', argument " "2"" of type '" "struct dom_sid const *""'"); + } + arg2 = (struct dom_sid *)(argp2); + result = (bool)security_token_is_sid(arg1,(struct dom_sid const *)arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_is_system(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_is_system",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_is_system" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + result = (bool)security_token_is_system(arg1); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_is_anonymous(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_is_anonymous",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_is_anonymous" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + result = (bool)security_token_is_anonymous(arg1); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_has_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + struct dom_sid *arg2 = (struct dom_sid *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "sid", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_has_sid",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_has_sid" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SecurityToken_has_sid" "', argument " "2"" of type '" "struct dom_sid const *""'"); + } + arg2 = (struct dom_sid *)(argp2); + result = (bool)security_token_has_sid(arg1,(struct dom_sid const *)arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_has_builtin_administrators(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_has_builtin_administrators",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_has_builtin_administrators" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + result = (bool)security_token_has_builtin_administrators(arg1); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_has_nt_authenticated_users(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_has_nt_authenticated_users",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_has_nt_authenticated_users" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + result = (bool)security_token_has_nt_authenticated_users(arg1); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_has_privilege(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + enum sec_privilege arg2 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "privilege", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_has_privilege",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_has_privilege" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SecurityToken_has_privilege" "', argument " "2"" of type '" "enum sec_privilege""'"); + } + arg2 = (enum sec_privilege)(val2); + result = (bool)security_token_has_privilege(arg1,arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SecurityToken_set_privilege(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + enum sec_privilege arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "privilege", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_set_privilege",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_set_privilege" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SecurityToken_set_privilege" "', argument " "2"" of type '" "enum sec_privilege""'"); + } + arg2 = (enum sec_privilege)(val2); + security_token_set_privilege(arg1,arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SecurityToken_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_security_token, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_new_security_descriptor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + security_descriptor *result = 0 ; + + { + arg1 = NULL; + } + if (!PyArg_ParseTuple(args,(char *)":new_security_descriptor")) SWIG_fail; + result = (security_descriptor *)new_security_descriptor(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_security_descriptor, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_security_descriptor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_security_descriptor",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_security_descriptor" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + delete_security_descriptor(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + struct security_ace *arg2 = (struct security_ace *) 0 ; + NTSTATUS result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "ace", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_sacl_add",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor_sacl_add" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_ace, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_sacl_add" "', argument " "2"" of type '" "struct security_ace const *""'"); + } + arg2 = (struct security_ace *)(argp2); + result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2); + { + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + struct security_ace *arg2 = (struct security_ace *) 0 ; + NTSTATUS result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "ace", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_dacl_add",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor_dacl_add" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_ace, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_dacl_add" "', argument " "2"" of type '" "struct security_ace const *""'"); + } + arg2 = (struct security_ace *)(argp2); + result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2); + { + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + struct security_ace *arg2 = (struct security_ace *) 0 ; + NTSTATUS result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "ace", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_dacl_del",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor_dacl_del" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_ace, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_dacl_del" "', argument " "2"" of type '" "struct security_ace const *""'"); + } + arg2 = (struct security_ace *)(argp2); + result = security_descriptor_dacl_del(arg1,(struct security_ace const *)arg2); + { + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + struct security_ace *arg2 = (struct security_ace *) 0 ; + NTSTATUS result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "ace", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_sacl_del",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor_sacl_del" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_ace, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_sacl_del" "', argument " "2"" of type '" "struct security_ace const *""'"); + } + arg2 = (struct security_ace *)(argp2); + result = security_descriptor_sacl_del(arg1,(struct security_ace const *)arg2); + { + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_security_descriptor___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + struct security_descriptor *arg2 = (struct security_descriptor *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "other", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor___eq__",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor___eq__" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_descriptor, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor___eq__" "', argument " "2"" of type '" "struct security_descriptor const *""'"); + } + arg2 = (struct security_descriptor *)(argp2); + result = (bool)security_descriptor_equal(arg1,(struct security_descriptor const *)arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *security_descriptor_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_security_descriptor, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_new_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + char *arg2 = (char *) 0 ; + dom_sid *result = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "text", NULL + }; + + { + arg1 = NULL; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:new_Sid",kwnames,&obj0)) SWIG_fail; + res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_Sid" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + result = (dom_sid *)new_dom_sid(arg1,(char const *)arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dom_sid, SWIG_POINTER_NEW | 0 ); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_Sid",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_dom_sid, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Sid" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + delete_dom_sid(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid___str__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + TALLOC_CTX *arg2 = (TALLOC_CTX *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + { + arg2 = NULL; + } + if (!PyArg_ParseTuple(args,(char *)"O:Sid___str__",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid___str__" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (char *)dom_sid___str__(arg1,arg2); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + struct dom_sid *arg2 = (struct dom_sid *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "other", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Sid___eq__",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid___eq__" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Sid___eq__" "', argument " "2"" of type '" "struct dom_sid const *""'"); + } + arg2 = (struct dom_sid *)(argp2); + result = (bool)dom_sid_equal(arg1,(struct dom_sid const *)arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *Sid_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_dom_sid, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_random_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + struct dom_sid *result = 0 ; + + { + arg1 = NULL; + } + if (!PyArg_ParseTuple(args,(char *)":random_sid")) SWIG_fail; + result = (struct dom_sid *)random_sid(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dom_sid, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_privilege_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + enum sec_privilege arg1 ; + char *result = 0 ; + int val1 ; + int ecode1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "privilege", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:privilege_name",kwnames,&obj0)) SWIG_fail; + ecode1 = SWIG_AsVal_int(obj0, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "privilege_name" "', argument " "1"" of type '" "enum sec_privilege""'"); + } + arg1 = (enum sec_privilege)(val1); + result = (char *)sec_privilege_name(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_privilege_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + enum sec_privilege result; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "name", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:privilege_id",kwnames,&obj0)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "privilege_id" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = (char *)(buf1); + result = (enum sec_privilege)sec_privilege_id((char const *)arg1); + resultobj = SWIG_From_int((int)(result)); + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { (char *)"new_SecurityToken", _wrap_new_SecurityToken, METH_VARARGS, NULL}, + { (char *)"delete_SecurityToken", _wrap_delete_SecurityToken, METH_VARARGS, NULL}, + { (char *)"SecurityToken_is_sid", (PyCFunction) _wrap_SecurityToken_is_sid, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"SecurityToken_is_system", _wrap_SecurityToken_is_system, METH_VARARGS, NULL}, + { (char *)"SecurityToken_is_anonymous", _wrap_SecurityToken_is_anonymous, METH_VARARGS, NULL}, + { (char *)"SecurityToken_has_sid", (PyCFunction) _wrap_SecurityToken_has_sid, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"SecurityToken_has_builtin_administrators", _wrap_SecurityToken_has_builtin_administrators, METH_VARARGS, NULL}, + { (char *)"SecurityToken_has_nt_authenticated_users", _wrap_SecurityToken_has_nt_authenticated_users, METH_VARARGS, NULL}, + { (char *)"SecurityToken_has_privilege", (PyCFunction) _wrap_SecurityToken_has_privilege, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"SecurityToken_set_privilege", (PyCFunction) _wrap_SecurityToken_set_privilege, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"SecurityToken_swigregister", SecurityToken_swigregister, METH_VARARGS, NULL}, + { (char *)"new_security_descriptor", _wrap_new_security_descriptor, METH_VARARGS, NULL}, + { (char *)"delete_security_descriptor", _wrap_delete_security_descriptor, METH_VARARGS, NULL}, + { (char *)"security_descriptor_sacl_add", (PyCFunction) _wrap_security_descriptor_sacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"security_descriptor_dacl_add", (PyCFunction) _wrap_security_descriptor_dacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"security_descriptor_dacl_del", (PyCFunction) _wrap_security_descriptor_dacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"security_descriptor_sacl_del", (PyCFunction) _wrap_security_descriptor_sacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"security_descriptor___eq__", (PyCFunction) _wrap_security_descriptor___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"security_descriptor_swigregister", security_descriptor_swigregister, METH_VARARGS, NULL}, + { (char *)"new_Sid", (PyCFunction) _wrap_new_Sid, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_Sid", _wrap_delete_Sid, METH_VARARGS, NULL}, + { (char *)"Sid___str__", _wrap_Sid___str__, METH_VARARGS, NULL}, + { (char *)"Sid___eq__", (PyCFunction) _wrap_Sid___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Sid_swigregister", Sid_swigregister, METH_VARARGS, NULL}, + { (char *)"random_sid", _wrap_random_sid, METH_VARARGS, NULL}, + { (char *)"privilege_name", (PyCFunction) _wrap_privilege_name, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"privilege_id", (PyCFunction) _wrap_privilege_id, METH_VARARGS | METH_KEYWORDS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_dom_sid = {"_p_dom_sid", "struct dom_sid *|dom_sid *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_security_ace = {"_p_security_ace", "struct security_ace *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_security_descriptor = {"_p_security_descriptor", "struct security_descriptor *|security_descriptor *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_security_token = {"_p_security_token", "struct security_token *|security_token *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_TALLOC_CTX, + &_swigt__p_char, + &_swigt__p_dom_sid, + &_swigt__p_int, + &_swigt__p_long_long, + &_swigt__p_security_ace, + &_swigt__p_security_descriptor, + &_swigt__p_security_token, + &_swigt__p_short, + &_swigt__p_signed_char, + &_swigt__p_unsigned_char, + &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long_long, + &_swigt__p_unsigned_short, +}; + +static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_dom_sid[] = { {&_swigt__p_dom_sid, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_security_ace[] = { {&_swigt__p_security_ace, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_security_descriptor[] = { {&_swigt__p_security_descriptor, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_security_token[] = { {&_swigt__p_security_token, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_TALLOC_CTX, + _swigc__p_char, + _swigc__p_dom_sid, + _swigc__p_int, + _swigc__p_long_long, + _swigc__p_security_ace, + _swigc__p_security_descriptor, + _swigc__p_security_token, + _swigc__p_short, + _swigc__p_signed_char, + _swigc__p_unsigned_char, + _swigc__p_unsigned_int, + _swigc__p_unsigned_long_long, + _swigc__p_unsigned_short, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { + return PyString_FromString(""); + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", PyString_AsString(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + varlink_type.ob_type = &PyType_Type; + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + + SWIG_Python_SetConstant(d, "SEC_PRIV_SECURITY",SWIG_From_int((int)(SEC_PRIV_SECURITY))); + SWIG_Python_SetConstant(d, "SEC_PRIV_BACKUP",SWIG_From_int((int)(SEC_PRIV_BACKUP))); + SWIG_Python_SetConstant(d, "SEC_PRIV_RESTORE",SWIG_From_int((int)(SEC_PRIV_RESTORE))); + SWIG_Python_SetConstant(d, "SEC_PRIV_SYSTEMTIME",SWIG_From_int((int)(SEC_PRIV_SYSTEMTIME))); + SWIG_Python_SetConstant(d, "SEC_PRIV_SHUTDOWN",SWIG_From_int((int)(SEC_PRIV_SHUTDOWN))); + SWIG_Python_SetConstant(d, "SEC_PRIV_REMOTE_SHUTDOWN",SWIG_From_int((int)(SEC_PRIV_REMOTE_SHUTDOWN))); + SWIG_Python_SetConstant(d, "SEC_PRIV_TAKE_OWNERSHIP",SWIG_From_int((int)(SEC_PRIV_TAKE_OWNERSHIP))); + SWIG_Python_SetConstant(d, "SEC_PRIV_DEBUG",SWIG_From_int((int)(SEC_PRIV_DEBUG))); + SWIG_Python_SetConstant(d, "SEC_PRIV_SYSTEM_ENVIRONMENT",SWIG_From_int((int)(SEC_PRIV_SYSTEM_ENVIRONMENT))); + SWIG_Python_SetConstant(d, "SEC_PRIV_SYSTEM_PROFILE",SWIG_From_int((int)(SEC_PRIV_SYSTEM_PROFILE))); + SWIG_Python_SetConstant(d, "SEC_PRIV_PROFILE_SINGLE_PROCESS",SWIG_From_int((int)(SEC_PRIV_PROFILE_SINGLE_PROCESS))); + SWIG_Python_SetConstant(d, "SEC_PRIV_INCREASE_BASE_PRIORITY",SWIG_From_int((int)(SEC_PRIV_INCREASE_BASE_PRIORITY))); + SWIG_Python_SetConstant(d, "SEC_PRIV_LOAD_DRIVER",SWIG_From_int((int)(SEC_PRIV_LOAD_DRIVER))); + SWIG_Python_SetConstant(d, "SEC_PRIV_CREATE_PAGEFILE",SWIG_From_int((int)(SEC_PRIV_CREATE_PAGEFILE))); + SWIG_Python_SetConstant(d, "SEC_PRIV_INCREASE_QUOTA",SWIG_From_int((int)(SEC_PRIV_INCREASE_QUOTA))); + SWIG_Python_SetConstant(d, "SEC_PRIV_CHANGE_NOTIFY",SWIG_From_int((int)(SEC_PRIV_CHANGE_NOTIFY))); + SWIG_Python_SetConstant(d, "SEC_PRIV_UNDOCK",SWIG_From_int((int)(SEC_PRIV_UNDOCK))); + SWIG_Python_SetConstant(d, "SEC_PRIV_MANAGE_VOLUME",SWIG_From_int((int)(SEC_PRIV_MANAGE_VOLUME))); + SWIG_Python_SetConstant(d, "SEC_PRIV_IMPERSONATE",SWIG_From_int((int)(SEC_PRIV_IMPERSONATE))); + SWIG_Python_SetConstant(d, "SEC_PRIV_CREATE_GLOBAL",SWIG_From_int((int)(SEC_PRIV_CREATE_GLOBAL))); + SWIG_Python_SetConstant(d, "SEC_PRIV_ENABLE_DELEGATION",SWIG_From_int((int)(SEC_PRIV_ENABLE_DELEGATION))); + SWIG_Python_SetConstant(d, "SEC_PRIV_INTERACTIVE_LOGON",SWIG_From_int((int)(SEC_PRIV_INTERACTIVE_LOGON))); + SWIG_Python_SetConstant(d, "SEC_PRIV_NETWORK_LOGON",SWIG_From_int((int)(SEC_PRIV_NETWORK_LOGON))); + SWIG_Python_SetConstant(d, "SEC_PRIV_REMOTE_INTERACTIVE_LOGON",SWIG_From_int((int)(SEC_PRIV_REMOTE_INTERACTIVE_LOGON))); +} + diff --git a/source4/libcli/swig/libcli_nbt.py b/source4/libcli/swig/libcli_nbt.py new file mode 100644 index 0000000000..938ab382f6 --- /dev/null +++ b/source4/libcli/swig/libcli_nbt.py @@ -0,0 +1,170 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 1.3.33 +# +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. + +import _libcli_nbt +import new +new_instancemethod = new.instancemethod +try: + _swig_property = property +except NameError: + pass # Python < 2.2 doesn't have 'property'. +def _swig_setattr_nondynamic(self,class_type,name,value,static=1): + if (name == "thisown"): return self.this.own(value) + if (name == "this"): + if type(value).__name__ == 'PySwigObject': + self.__dict__[name] = value + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + if (not static) or hasattr(self,name): + self.__dict__[name] = value + else: + raise AttributeError("You cannot add attributes to %s" % self) + +def _swig_setattr(self,class_type,name,value): + return _swig_setattr_nondynamic(self,class_type,name,value,0) + +def _swig_getattr(self,class_type,name): + if (name == "thisown"): return self.this.own() + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +def _swig_repr(self): + try: strthis = "proxy of " + self.this.__repr__() + except: strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 +del types + + +import events +nbt_name_socket_init = _libcli_nbt.nbt_name_socket_init +NBT_NAME_CLIENT = _libcli_nbt.NBT_NAME_CLIENT +NBT_NAME_MS = _libcli_nbt.NBT_NAME_MS +NBT_NAME_USER = _libcli_nbt.NBT_NAME_USER +NBT_NAME_SERVER = _libcli_nbt.NBT_NAME_SERVER +NBT_NAME_PDC = _libcli_nbt.NBT_NAME_PDC +NBT_NAME_LOGON = _libcli_nbt.NBT_NAME_LOGON +NBT_NAME_MASTER = _libcli_nbt.NBT_NAME_MASTER +NBT_NAME_BROWSER = _libcli_nbt.NBT_NAME_BROWSER +class nbt_name(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, nbt_name, name) + __repr__ = _swig_repr + __swig_setmethods__["name"] = _libcli_nbt.nbt_name_name_set + __swig_getmethods__["name"] = _libcli_nbt.nbt_name_name_get + if _newclass:name = _swig_property(_libcli_nbt.nbt_name_name_get, _libcli_nbt.nbt_name_name_set) + __swig_setmethods__["scope"] = _libcli_nbt.nbt_name_scope_set + __swig_getmethods__["scope"] = _libcli_nbt.nbt_name_scope_get + if _newclass:scope = _swig_property(_libcli_nbt.nbt_name_scope_get, _libcli_nbt.nbt_name_scope_set) + __swig_setmethods__["type"] = _libcli_nbt.nbt_name_type_set + __swig_getmethods__["type"] = _libcli_nbt.nbt_name_type_get + if _newclass:type = _swig_property(_libcli_nbt.nbt_name_type_get, _libcli_nbt.nbt_name_type_set) + def __init__(self, *args, **kwargs): + this = _libcli_nbt.new_nbt_name(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _libcli_nbt.delete_nbt_name + __del__ = lambda self : None; +nbt_name_swigregister = _libcli_nbt.nbt_name_swigregister +nbt_name_swigregister(nbt_name) + +class nbt_name_query(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name_query, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, nbt_name_query, name) + __repr__ = _swig_repr + __swig_getmethods__["data_out"] = _libcli_nbt.nbt_name_query_data_out_get + if _newclass:data_out = _swig_property(_libcli_nbt.nbt_name_query_data_out_get) + __swig_getmethods__["data_in"] = _libcli_nbt.nbt_name_query_data_in_get + if _newclass:data_in = _swig_property(_libcli_nbt.nbt_name_query_data_in_get) + def __init__(self, *args, **kwargs): + this = _libcli_nbt.new_nbt_name_query(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _libcli_nbt.delete_nbt_name_query + __del__ = lambda self : None; +nbt_name_query_swigregister = _libcli_nbt.nbt_name_query_swigregister +nbt_name_query_swigregister(nbt_name_query) + +class nbt_name_query_out(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name_query_out, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, nbt_name_query_out, name) + __repr__ = _swig_repr + __swig_setmethods__["reply_from"] = _libcli_nbt.nbt_name_query_out_reply_from_set + __swig_getmethods__["reply_from"] = _libcli_nbt.nbt_name_query_out_reply_from_get + if _newclass:reply_from = _swig_property(_libcli_nbt.nbt_name_query_out_reply_from_get, _libcli_nbt.nbt_name_query_out_reply_from_set) + __swig_setmethods__["name"] = _libcli_nbt.nbt_name_query_out_name_set + __swig_getmethods__["name"] = _libcli_nbt.nbt_name_query_out_name_get + if _newclass:name = _swig_property(_libcli_nbt.nbt_name_query_out_name_get, _libcli_nbt.nbt_name_query_out_name_set) + __swig_setmethods__["num_addrs"] = _libcli_nbt.nbt_name_query_out_num_addrs_set + __swig_getmethods__["num_addrs"] = _libcli_nbt.nbt_name_query_out_num_addrs_get + if _newclass:num_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_num_addrs_get, _libcli_nbt.nbt_name_query_out_num_addrs_set) + __swig_setmethods__["reply_addrs"] = _libcli_nbt.nbt_name_query_out_reply_addrs_set + __swig_getmethods__["reply_addrs"] = _libcli_nbt.nbt_name_query_out_reply_addrs_get + if _newclass:reply_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_reply_addrs_get, _libcli_nbt.nbt_name_query_out_reply_addrs_set) + def __init__(self, *args, **kwargs): + this = _libcli_nbt.new_nbt_name_query_out(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _libcli_nbt.delete_nbt_name_query_out + __del__ = lambda self : None; +nbt_name_query_out_swigregister = _libcli_nbt.nbt_name_query_out_swigregister +nbt_name_query_out_swigregister(nbt_name_query_out) + +class nbt_name_query_in(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name_query_in, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, nbt_name_query_in, name) + __repr__ = _swig_repr + __swig_setmethods__["name"] = _libcli_nbt.nbt_name_query_in_name_set + __swig_getmethods__["name"] = _libcli_nbt.nbt_name_query_in_name_get + if _newclass:name = _swig_property(_libcli_nbt.nbt_name_query_in_name_get, _libcli_nbt.nbt_name_query_in_name_set) + __swig_setmethods__["dest_addr"] = _libcli_nbt.nbt_name_query_in_dest_addr_set + __swig_getmethods__["dest_addr"] = _libcli_nbt.nbt_name_query_in_dest_addr_get + if _newclass:dest_addr = _swig_property(_libcli_nbt.nbt_name_query_in_dest_addr_get, _libcli_nbt.nbt_name_query_in_dest_addr_set) + __swig_setmethods__["broadcast"] = _libcli_nbt.nbt_name_query_in_broadcast_set + __swig_getmethods__["broadcast"] = _libcli_nbt.nbt_name_query_in_broadcast_get + if _newclass:broadcast = _swig_property(_libcli_nbt.nbt_name_query_in_broadcast_get, _libcli_nbt.nbt_name_query_in_broadcast_set) + __swig_setmethods__["wins_lookup"] = _libcli_nbt.nbt_name_query_in_wins_lookup_set + __swig_getmethods__["wins_lookup"] = _libcli_nbt.nbt_name_query_in_wins_lookup_get + if _newclass:wins_lookup = _swig_property(_libcli_nbt.nbt_name_query_in_wins_lookup_get, _libcli_nbt.nbt_name_query_in_wins_lookup_set) + __swig_setmethods__["timeout"] = _libcli_nbt.nbt_name_query_in_timeout_set + __swig_getmethods__["timeout"] = _libcli_nbt.nbt_name_query_in_timeout_get + if _newclass:timeout = _swig_property(_libcli_nbt.nbt_name_query_in_timeout_get, _libcli_nbt.nbt_name_query_in_timeout_set) + __swig_setmethods__["retries"] = _libcli_nbt.nbt_name_query_in_retries_set + __swig_getmethods__["retries"] = _libcli_nbt.nbt_name_query_in_retries_get + if _newclass:retries = _swig_property(_libcli_nbt.nbt_name_query_in_retries_get, _libcli_nbt.nbt_name_query_in_retries_set) + def __init__(self, *args, **kwargs): + this = _libcli_nbt.new_nbt_name_query_in(*args, **kwargs) + try: self.this.append(this) + except: self.this = this + __swig_destroy__ = _libcli_nbt.delete_nbt_name_query_in + __del__ = lambda self : None; +nbt_name_query_in_swigregister = _libcli_nbt.nbt_name_query_in_swigregister +nbt_name_query_in_swigregister(nbt_name_query_in) + +new_char_ptr_array = _libcli_nbt.new_char_ptr_array +delete_char_ptr_array = _libcli_nbt.delete_char_ptr_array +char_ptr_array_getitem = _libcli_nbt.char_ptr_array_getitem +char_ptr_array_setitem = _libcli_nbt.char_ptr_array_setitem +do_nbt_name_query = _libcli_nbt.do_nbt_name_query + + diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c new file mode 100644 index 0000000000..149e63884a --- /dev/null +++ b/source4/libcli/swig/libcli_nbt_wrap.c @@ -0,0 +1,4695 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.33 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +#define SWIGPYTHON +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "3" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The swig conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old swig versions, you usually write code as: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit as: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + that seems to be the same, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + requires also to SWIG_ConvertPtr to return new result values, as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + swig errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() + + + */ +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store inforomation on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* think of this as a c++ template<> or a scheme macro */ +#define SWIG_TypeCheck_Template(comparison, ty) \ + if (ty) { \ + swig_cast_info *iter = ty->cast; \ + while (iter) { \ + if (comparison) { \ + if (iter == ty->cast) return iter; \ + /* Move iter to the top of the linked list */ \ + iter->prev->next = iter->next; \ + if (iter->next) \ + iter->next->prev = iter->prev; \ + iter->next = ty->cast; \ + iter->prev = 0; \ + if (ty->cast) ty->cast->prev = iter; \ + ty->cast = iter; \ + return iter; \ + } \ + iter = iter->next; \ + } \ + } \ + return 0 + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); +} + +/* Same as previous function, except strcmp is replaced with a pointer comparison */ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { + SWIG_TypeCheck_Template(iter->type == from, into); +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_Format(PyExc_RuntimeError, mesg); + } +} + + + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* PySwigClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} PySwigClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + PySwigClientData *data = (PySwigClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME PySwigClientData * +PySwigClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +PySwigClientData_Del(PySwigClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== PySwigObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} PySwigObject; + +SWIGRUNTIME PyObject * +PySwigObject_long(PySwigObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +PySwigObject_format(const char* fmt, PySwigObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { + PyObject *ofmt = PyString_FromString(fmt); + if (ofmt) { + res = PyString_Format(ofmt,args); + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +PySwigObject_oct(PySwigObject *v) +{ + return PySwigObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +PySwigObject_hex(PySwigObject *v) +{ + return PySwigObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +PySwigObject_repr(PySwigObject *v) +#else +PySwigObject_repr(PySwigObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); +#else + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); +#endif + PyString_ConcatAndDel(&repr,nrep); + } + return repr; +} + +SWIGRUNTIME int +PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = PySwigObject_repr(v); +#else + PyObject *repr = PySwigObject_repr(v, NULL); +#endif + if (repr) { + fputs(PyString_AsString(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +PySwigObject_str(PySwigObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + PyString_FromString(result) : 0; +} + +SWIGRUNTIME int +PySwigObject_compare(PySwigObject *v, PySwigObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigObject_Check(PyObject *op) { + return ((op)->ob_type == PySwigObject_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +PySwigObject_dealloc(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own) { + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } else { + const char *name = SWIG_TypePrettyName(ty); +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); +#endif + } + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) +{ + PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!PySwigObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +PySwigObject_getattr(PySwigObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods PySwigObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)PySwigObject_long, /*nb_int*/ + (unaryfunc)PySwigObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)PySwigObject_oct, /*nb_oct*/ + (unaryfunc)PySwigObject_hex, /*nb_hex*/ +#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject pyswigobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigObject", /* tp_name */ + sizeof(PySwigObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigObject_dealloc, /* tp_dealloc */ + (printfunc)PySwigObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)PySwigObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigObject_compare, /* tp_compare */ + (reprfunc)PySwigObject_repr, /* tp_repr */ + &PySwigObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigobject_type = tmp; + pyswigobject_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigobject_type; +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own) +{ + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} PySwigPacked; + +SWIGRUNTIME int +PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +PySwigPacked_repr(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return PyString_FromFormat("", result, v->ty->name); + } else { + return PyString_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +PySwigPacked_str(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return PyString_FromFormat("%s%s", result, v->ty->name); + } else { + return PyString_FromString(v->ty->name); + } +} + +SWIGRUNTIME int +PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); +} + +SWIGRUNTIME void +PySwigPacked_dealloc(PyObject *v) +{ + if (PySwigPacked_Check(v)) { + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject pyswigpacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigPacked", /* tp_name */ + sizeof(PySwigPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigPacked_dealloc, /* tp_dealloc */ + (printfunc)PySwigPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigPacked_compare, /* tp_compare */ + (reprfunc)PySwigPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigpacked_type = tmp; + pyswigpacked_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigpacked_type; +} + +SWIGRUNTIME PyObject * +PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (PySwigPacked_Check(obj)) { + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return PyString_FromString("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +SWIGRUNTIME PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !PySwigObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + PySwigObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (PySwigObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own) { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) *own = sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (!tc) return SWIG_ERROR; + *ptr = SWIG_TypeCast(tc,vptr); + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + PySwigObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = PySwigObject_New(ptr, type, own); + PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + PySwigClientData *data = (PySwigClientData *) ty->clientdata; + if (data) PySwigClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = PyString_FromString(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); + } else { + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +PySwigObject_GetDesc(PyObject *self) +{ + PySwigObject *v = (PySwigObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && PySwigObject_Check(obj)) { + const char *otype = (const char *) PySwigObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? PyString_AsString(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_TALLOC_CTX swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_event_context swig_types[2] +#define SWIGTYPE_p_int swig_types[3] +#define SWIGTYPE_p_long_long swig_types[4] +#define SWIGTYPE_p_nbt_name swig_types[5] +#define SWIGTYPE_p_nbt_name_query swig_types[6] +#define SWIGTYPE_p_nbt_name_query_in swig_types[7] +#define SWIGTYPE_p_nbt_name_query_out swig_types[8] +#define SWIGTYPE_p_nbt_name_socket swig_types[9] +#define SWIGTYPE_p_p_char swig_types[10] +#define SWIGTYPE_p_short swig_types[11] +#define SWIGTYPE_p_signed_char swig_types[12] +#define SWIGTYPE_p_unsigned_char swig_types[13] +#define SWIGTYPE_p_unsigned_int swig_types[14] +#define SWIGTYPE_p_unsigned_long_long swig_types[15] +#define SWIGTYPE_p_unsigned_short swig_types[16] +static swig_type_info *swig_types[18]; +static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif + +/*----------------------------------------------- + @(target):= _libcli_nbt.so + ------------------------------------------------*/ +#define SWIG_init init_libcli_nbt + +#define SWIG_name "_libcli_nbt" + +#define SWIGVERSION 0x010333 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + + +#include "includes.h" +#include "lib/talloc/talloc.h" +#include "libcli/nbt/libnbt.h" +#include "param/param.h" + +/* Undo strcpy safety macro as it's used by swig )-: */ + +#undef strcpy + + + + #define SWIG_From_long PyInt_FromLong + + +SWIGINTERNINLINE PyObject * +SWIG_From_int (int value) +{ + return SWIG_From_long (value); +} + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ + if (PyString_Check(obj)) { + char *cstr; Py_ssize_t len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { + return PyString_FromStringAndSize(carray, (int)(size)); + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + + +typedef struct { + const char *reply_from; + struct nbt_name name; + int16_t num_addrs; + const char **reply_addrs; + } nbt_name_query_out; + + + +typedef struct { + struct nbt_name name; + const char *dest_addr; + bool broadcast; + bool wins_lookup; + int timeout; /* in seconds */ + int retries; + } nbt_name_query_in; + + + +SWIGINTERN int +SWIG_AsVal_short (PyObject * obj, short *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < SHRT_MIN || v > SHRT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (short)(v); + } + } + return res; +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_short (short value) +{ + return SWIG_From_long (value); +} + + +SWIGINTERN int +SWIG_AsVal_bool (PyObject *obj, bool *val) +{ + int r = PyObject_IsTrue(obj); + if (r == -1) + return SWIG_ERROR; + if (val) *val = r ? true : false; + return SWIG_OK; +} + + +SWIGINTERNINLINE PyObject* + SWIG_From_bool (bool value) +{ + return PyBool_FromLong(value ? 1 : 0); +} + + + static char * *new_char_ptr_array(size_t nelements) { + return (char * *)malloc((nelements)*sizeof(char *)); + } + + static void delete_char_ptr_array(char * *ary) { + free((char*)ary); + } + + static char * char_ptr_array_getitem(char * *ary, size_t index) { + return ary[index]; + } + static void char_ptr_array_setitem(char * *ary, size_t index, char * value) { + ary[index] = value; + } + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) +{ + if (PyInt_Check(obj)) { + long v = PyInt_AsLong(obj); + if (v >= 0) { + if (val) *val = v; + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else if (PyLong_Check(obj)) { + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { + if (val) *val = (unsigned long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERNINLINE int +SWIG_AsVal_size_t (PyObject * obj, size_t *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); + if (SWIG_IsOK(res) && val) *val = (size_t)(v); + return res; +} + + +NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io) +{ + return nbt_name_query(nbtsock, mem_ctx, io); +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_nbt_name_socket_init(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + struct event_context *arg2 = (struct event_context *) 0 ; + struct nbt_name_socket *result = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "event_ctx", NULL + }; + + { + arg2 = event_context_init(NULL); + } + { + arg1 = NULL; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|O:nbt_name_socket_init",kwnames,&obj0)) SWIG_fail; + if (obj0) { + res2 = SWIG_ConvertPtr(obj0, &argp2,SWIGTYPE_p_event_context, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_socket_init" "', argument " "2"" of type '" "struct event_context *""'"); + } + arg2 = (struct event_context *)(argp2); + } + result = (struct nbt_name_socket *)nbt_name_socket_init(arg1,arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_socket, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_name_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_name_set" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_name_set" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (arg2) { + size_t size = strlen((const char *)((const char *)(arg2))) + 1; + arg1->name = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); + } else { + arg1->name = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_name_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_name_get" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + result = (char *) ((arg1)->name); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_scope_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_scope_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_scope_set" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_scope_set" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (arg2) { + size_t size = strlen((const char *)((const char *)(arg2))) + 1; + arg1->scope = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); + } else { + arg1->scope = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_scope_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_scope_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_scope_get" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + result = (char *) ((arg1)->scope); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_type_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + enum nbt_name_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_type_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_type_set" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_type_set" "', argument " "2"" of type '" "enum nbt_name_type""'"); + } + arg2 = (enum nbt_name_type)(val2); + if (arg1) (arg1)->type = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_type_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + enum nbt_name_type result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_type_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_type_get" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + result = (enum nbt_name_type) ((arg1)->type); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_nbt_name")) SWIG_fail; + result = (struct nbt_name *)(struct nbt_name *) calloc(1, sizeof(struct nbt_name)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name *arg1 = (struct nbt_name *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name" "', argument " "1"" of type '" "struct nbt_name *""'"); + } + arg1 = (struct nbt_name *)(argp1); + free((char *) arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *nbt_name_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_nbt_name_query_data_out_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; + nbt_name_query_out *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_data_out_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_data_out_get" "', argument " "1"" of type '" "struct nbt_name_query *""'"); + } + arg1 = (struct nbt_name_query *)(argp1); + result = (nbt_name_query_out *)& ((arg1)->out); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_data_in_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; + nbt_name_query_in *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_data_in_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_data_in_get" "', argument " "1"" of type '" "struct nbt_name_query *""'"); + } + arg1 = (struct nbt_name_query *)(argp1); + result = (nbt_name_query_in *)& ((arg1)->in); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name_query *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_nbt_name_query")) SWIG_fail; + result = (struct nbt_name_query *)(struct nbt_name_query *) calloc(1, sizeof(struct nbt_name_query)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name_query",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query" "', argument " "1"" of type '" "struct nbt_name_query *""'"); + } + arg1 = (struct nbt_name_query *)(argp1); + free((char *) arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *nbt_name_query_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_reply_from_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_from_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_reply_from_set" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (arg2) { + size_t size = strlen((const char *)((const char *)(arg2))) + 1; + arg1->reply_from = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); + } else { + arg1->reply_from = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_reply_from_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_from_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + result = (char *) ((arg1)->reply_from); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + struct nbt_name *arg2 = (struct nbt_name *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_name_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_name_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_name_set" "', argument " "2"" of type '" "struct nbt_name *""'"); + } + arg2 = (struct nbt_name *)(argp2); + if (arg1) (arg1)->name = *arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + struct nbt_name *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_name_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_name_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + result = (struct nbt_name *)& ((arg1)->name); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_num_addrs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + int16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + short val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_num_addrs_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_num_addrs_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + ecode2 = SWIG_AsVal_short(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_out_num_addrs_set" "', argument " "2"" of type '" "int16_t""'"); + } + arg2 = (int16_t)(val2); + if (arg1) (arg1)->num_addrs = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_num_addrs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + int16_t result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_num_addrs_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_num_addrs_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + result = (int16_t) ((arg1)->num_addrs); + resultobj = SWIG_From_short((short)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_addrs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + char **arg2 = (char **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_reply_addrs_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_addrs_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_char, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_reply_addrs_set" "', argument " "2"" of type '" "char const **""'"); + } + arg2 = (char **)(argp2); + if (arg1) (arg1)->reply_addrs = (char const **)arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_addrs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + char **result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_reply_addrs_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_addrs_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + result = (char **) ((arg1)->reply_addrs); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_nbt_name_query_out")) SWIG_fail; + result = (nbt_name_query_out *)(nbt_name_query_out *) calloc(1, sizeof(nbt_name_query_out)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name_query_out",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query_out" "', argument " "1"" of type '" "nbt_name_query_out *""'"); + } + arg1 = (nbt_name_query_out *)(argp1); + free((char *) arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *nbt_name_query_out_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query_out, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + struct nbt_name *arg2 = (struct nbt_name *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_name_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_name_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_in_name_set" "', argument " "2"" of type '" "struct nbt_name *""'"); + } + arg2 = (struct nbt_name *)(argp2); + if (arg1) (arg1)->name = *arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + struct nbt_name *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_name_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_name_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + result = (struct nbt_name *)& ((arg1)->name); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_dest_addr_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_dest_addr_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_dest_addr_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_in_dest_addr_set" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (arg2) { + size_t size = strlen((const char *)((const char *)(arg2))) + 1; + arg1->dest_addr = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); + } else { + arg1->dest_addr = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_dest_addr_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_dest_addr_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_dest_addr_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + result = (char *) ((arg1)->dest_addr); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_broadcast_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_broadcast_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_broadcast_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + ecode2 = SWIG_AsVal_bool(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_broadcast_set" "', argument " "2"" of type '" "bool""'"); + } + arg2 = (bool)(val2); + if (arg1) (arg1)->broadcast = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_broadcast_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_broadcast_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_broadcast_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + result = (bool) ((arg1)->broadcast); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_wins_lookup_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_wins_lookup_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_wins_lookup_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + ecode2 = SWIG_AsVal_bool(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_wins_lookup_set" "', argument " "2"" of type '" "bool""'"); + } + arg2 = (bool)(val2); + if (arg1) (arg1)->wins_lookup = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_wins_lookup_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_wins_lookup_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_wins_lookup_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + result = (bool) ((arg1)->wins_lookup); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_timeout_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_timeout_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_timeout_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_timeout_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->timeout = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_timeout_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_timeout_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_timeout_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + result = (int) ((arg1)->timeout); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_retries_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_retries_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_retries_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_retries_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->retries = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_nbt_name_query_in_retries_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_retries_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_retries_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + result = (int) ((arg1)->retries); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_nbt_name_query_in")) SWIG_fail; + result = (nbt_name_query_in *)(nbt_name_query_in *) calloc(1, sizeof(nbt_name_query_in)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name_query_in",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query_in" "', argument " "1"" of type '" "nbt_name_query_in *""'"); + } + arg1 = (nbt_name_query_in *)(argp1); + free((char *) arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *nbt_name_query_in_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query_in, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_new_char_ptr_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + size_t arg1 ; + char **result = 0 ; + size_t val1 ; + int ecode1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "nelements", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:new_char_ptr_array",kwnames,&obj0)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(obj0, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_char_ptr_array" "', argument " "1"" of type '" "size_t""'"); + } + arg1 = (size_t)(val1); + result = (char **)new_char_ptr_array(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_char_ptr_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + char **arg1 = (char **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "ary", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:delete_char_ptr_array",kwnames,&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_char, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_char_ptr_array" "', argument " "1"" of type '" "char **""'"); + } + arg1 = (char **)(argp1); + delete_char_ptr_array(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_char_ptr_array_getitem(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + char **arg1 = (char **) 0 ; + size_t arg2 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "ary",(char *) "index", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:char_ptr_array_getitem",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_char, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "char_ptr_array_getitem" "', argument " "1"" of type '" "char **""'"); + } + arg1 = (char **)(argp1); + ecode2 = SWIG_AsVal_size_t(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "char_ptr_array_getitem" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = (size_t)(val2); + result = (char *)char_ptr_array_getitem(arg1,arg2); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_char_ptr_array_setitem(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + char **arg1 = (char **) 0 ; + size_t arg2 ; + char *arg3 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "ary",(char *) "index",(char *) "value", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:char_ptr_array_setitem",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_char, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "char_ptr_array_setitem" "', argument " "1"" of type '" "char **""'"); + } + arg1 = (char **)(argp1); + ecode2 = SWIG_AsVal_size_t(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "char_ptr_array_setitem" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = (size_t)(val2); + res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "char_ptr_array_setitem" "', argument " "3"" of type '" "char *""'"); + } + arg3 = (char *)(buf3); + char_ptr_array_setitem(arg1,arg2,arg3); + resultobj = SWIG_Py_Void(); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return resultobj; +fail: + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct nbt_name_socket *arg1 = (struct nbt_name_socket *) 0 ; + TALLOC_CTX *arg2 = (TALLOC_CTX *) 0 ; + struct nbt_name_query *arg3 = (struct nbt_name_query *) 0 ; + NTSTATUS result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "nbtsock",(char *) "io", NULL + }; + + { + arg2 = NULL; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:do_nbt_name_query",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_socket, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "do_nbt_name_query" "', argument " "1"" of type '" "struct nbt_name_socket *""'"); + } + arg1 = (struct nbt_name_socket *)(argp1); + res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_nbt_name_query, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "do_nbt_name_query" "', argument " "3"" of type '" "struct nbt_name_query *""'"); + } + arg3 = (struct nbt_name_query *)(argp3); + result = do_nbt_name_query(arg1,arg2,arg3); + { + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { (char *)"nbt_name_socket_init", (PyCFunction) _wrap_nbt_name_socket_init, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"nbt_name_name_set", _wrap_nbt_name_name_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_name_get", _wrap_nbt_name_name_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_scope_set", _wrap_nbt_name_scope_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_scope_get", _wrap_nbt_name_scope_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_type_set", _wrap_nbt_name_type_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_type_get", _wrap_nbt_name_type_get, METH_VARARGS, NULL}, + { (char *)"new_nbt_name", _wrap_new_nbt_name, METH_VARARGS, NULL}, + { (char *)"delete_nbt_name", _wrap_delete_nbt_name, METH_VARARGS, NULL}, + { (char *)"nbt_name_swigregister", nbt_name_swigregister, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_data_out_get", _wrap_nbt_name_query_data_out_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_data_in_get", _wrap_nbt_name_query_data_in_get, METH_VARARGS, NULL}, + { (char *)"new_nbt_name_query", _wrap_new_nbt_name_query, METH_VARARGS, NULL}, + { (char *)"delete_nbt_name_query", _wrap_delete_nbt_name_query, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_swigregister", nbt_name_query_swigregister, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_reply_from_set", _wrap_nbt_name_query_out_reply_from_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_reply_from_get", _wrap_nbt_name_query_out_reply_from_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_name_set", _wrap_nbt_name_query_out_name_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_name_get", _wrap_nbt_name_query_out_name_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_num_addrs_set", _wrap_nbt_name_query_out_num_addrs_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_num_addrs_get", _wrap_nbt_name_query_out_num_addrs_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_reply_addrs_set", _wrap_nbt_name_query_out_reply_addrs_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_reply_addrs_get", _wrap_nbt_name_query_out_reply_addrs_get, METH_VARARGS, NULL}, + { (char *)"new_nbt_name_query_out", _wrap_new_nbt_name_query_out, METH_VARARGS, NULL}, + { (char *)"delete_nbt_name_query_out", _wrap_delete_nbt_name_query_out, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_swigregister", nbt_name_query_out_swigregister, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_name_set", _wrap_nbt_name_query_in_name_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_name_get", _wrap_nbt_name_query_in_name_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_dest_addr_set", _wrap_nbt_name_query_in_dest_addr_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_dest_addr_get", _wrap_nbt_name_query_in_dest_addr_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_broadcast_set", _wrap_nbt_name_query_in_broadcast_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_broadcast_get", _wrap_nbt_name_query_in_broadcast_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_wins_lookup_set", _wrap_nbt_name_query_in_wins_lookup_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_wins_lookup_get", _wrap_nbt_name_query_in_wins_lookup_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_timeout_set", _wrap_nbt_name_query_in_timeout_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_timeout_get", _wrap_nbt_name_query_in_timeout_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_retries_set", _wrap_nbt_name_query_in_retries_set, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_retries_get", _wrap_nbt_name_query_in_retries_get, METH_VARARGS, NULL}, + { (char *)"new_nbt_name_query_in", _wrap_new_nbt_name_query_in, METH_VARARGS, NULL}, + { (char *)"delete_nbt_name_query_in", _wrap_delete_nbt_name_query_in, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_swigregister", nbt_name_query_in_swigregister, METH_VARARGS, NULL}, + { (char *)"new_char_ptr_array", (PyCFunction) _wrap_new_char_ptr_array, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_char_ptr_array", (PyCFunction) _wrap_delete_char_ptr_array, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"char_ptr_array_getitem", (PyCFunction) _wrap_char_ptr_array_getitem, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"char_ptr_array_setitem", (PyCFunction) _wrap_char_ptr_array_setitem, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"do_nbt_name_query", (PyCFunction) _wrap_do_nbt_name_query, METH_VARARGS | METH_KEYWORDS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_nbt_name = {"_p_nbt_name", "struct nbt_name *|nbt_name *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_nbt_name_query = {"_p_nbt_name_query", "struct nbt_name_query *|nbt_name_query *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_nbt_name_query_in = {"_p_nbt_name_query_in", "nbt_name_query_in *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_nbt_name_query_out = {"_p_nbt_name_query_out", "nbt_name_query_out *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_nbt_name_socket = {"_p_nbt_name_socket", "struct nbt_name_socket *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_TALLOC_CTX, + &_swigt__p_char, + &_swigt__p_event_context, + &_swigt__p_int, + &_swigt__p_long_long, + &_swigt__p_nbt_name, + &_swigt__p_nbt_name_query, + &_swigt__p_nbt_name_query_in, + &_swigt__p_nbt_name_query_out, + &_swigt__p_nbt_name_socket, + &_swigt__p_p_char, + &_swigt__p_short, + &_swigt__p_signed_char, + &_swigt__p_unsigned_char, + &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long_long, + &_swigt__p_unsigned_short, +}; + +static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_nbt_name[] = { {&_swigt__p_nbt_name, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_nbt_name_query[] = { {&_swigt__p_nbt_name_query, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_nbt_name_query_in[] = { {&_swigt__p_nbt_name_query_in, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_nbt_name_query_out[] = { {&_swigt__p_nbt_name_query_out, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_nbt_name_socket[] = { {&_swigt__p_nbt_name_socket, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_TALLOC_CTX, + _swigc__p_char, + _swigc__p_event_context, + _swigc__p_int, + _swigc__p_long_long, + _swigc__p_nbt_name, + _swigc__p_nbt_name_query, + _swigc__p_nbt_name_query_in, + _swigc__p_nbt_name_query_out, + _swigc__p_nbt_name_socket, + _swigc__p_p_char, + _swigc__p_short, + _swigc__p_signed_char, + _swigc__p_unsigned_char, + _swigc__p_unsigned_int, + _swigc__p_unsigned_long_long, + _swigc__p_unsigned_short, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { + return PyString_FromString(""); + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", PyString_AsString(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + varlink_type.ob_type = &PyType_Type; + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + + SWIG_Python_SetConstant(d, "NBT_NAME_CLIENT",SWIG_From_int((int)(NBT_NAME_CLIENT))); + SWIG_Python_SetConstant(d, "NBT_NAME_MS",SWIG_From_int((int)(NBT_NAME_MS))); + SWIG_Python_SetConstant(d, "NBT_NAME_USER",SWIG_From_int((int)(NBT_NAME_USER))); + SWIG_Python_SetConstant(d, "NBT_NAME_SERVER",SWIG_From_int((int)(NBT_NAME_SERVER))); + SWIG_Python_SetConstant(d, "NBT_NAME_PDC",SWIG_From_int((int)(NBT_NAME_PDC))); + SWIG_Python_SetConstant(d, "NBT_NAME_LOGON",SWIG_From_int((int)(NBT_NAME_LOGON))); + SWIG_Python_SetConstant(d, "NBT_NAME_MASTER",SWIG_From_int((int)(NBT_NAME_MASTER))); + SWIG_Python_SetConstant(d, "NBT_NAME_BROWSER",SWIG_From_int((int)(NBT_NAME_BROWSER))); +} + diff --git a/source4/libcli/swig/libcli_smb.py b/source4/libcli/swig/libcli_smb.py new file mode 100644 index 0000000000..466a04b9eb --- /dev/null +++ b/source4/libcli/swig/libcli_smb.py @@ -0,0 +1,55 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 1.3.33 +# +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. + +import _libcli_smb +import new +new_instancemethod = new.instancemethod +try: + _swig_property = property +except NameError: + pass # Python < 2.2 doesn't have 'property'. +def _swig_setattr_nondynamic(self,class_type,name,value,static=1): + if (name == "thisown"): return self.this.own(value) + if (name == "this"): + if type(value).__name__ == 'PySwigObject': + self.__dict__[name] = value + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + if (not static) or hasattr(self,name): + self.__dict__[name] = value + else: + raise AttributeError("You cannot add attributes to %s" % self) + +def _swig_setattr(self,class_type,name,value): + return _swig_setattr_nondynamic(self,class_type,name,value,0) + +def _swig_getattr(self,class_type,name): + if (name == "thisown"): return self.this.own() + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +def _swig_repr(self): + try: strthis = "proxy of " + self.this.__repr__() + except: strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 +del types + + +import events +smbcli_sock_connect_byname = _libcli_smb.smbcli_sock_connect_byname +smbcli_sock_dead = _libcli_smb.smbcli_sock_dead + + diff --git a/source4/libcli/swig/libcli_smb_wrap.c b/source4/libcli/swig/libcli_smb_wrap.c new file mode 100644 index 0000000000..313bcfeed3 --- /dev/null +++ b/source4/libcli/swig/libcli_smb_wrap.c @@ -0,0 +1,3342 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.33 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +#define SWIGPYTHON +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "3" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The swig conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old swig versions, you usually write code as: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit as: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + that seems to be the same, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + requires also to SWIG_ConvertPtr to return new result values, as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + swig errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() + + + */ +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store inforomation on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* think of this as a c++ template<> or a scheme macro */ +#define SWIG_TypeCheck_Template(comparison, ty) \ + if (ty) { \ + swig_cast_info *iter = ty->cast; \ + while (iter) { \ + if (comparison) { \ + if (iter == ty->cast) return iter; \ + /* Move iter to the top of the linked list */ \ + iter->prev->next = iter->next; \ + if (iter->next) \ + iter->next->prev = iter->prev; \ + iter->next = ty->cast; \ + iter->prev = 0; \ + if (ty->cast) ty->cast->prev = iter; \ + ty->cast = iter; \ + return iter; \ + } \ + iter = iter->next; \ + } \ + } \ + return 0 + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); +} + +/* Same as previous function, except strcmp is replaced with a pointer comparison */ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { + SWIG_TypeCheck_Template(iter->type == from, into); +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_Format(PyExc_RuntimeError, mesg); + } +} + + + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* PySwigClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} PySwigClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + PySwigClientData *data = (PySwigClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME PySwigClientData * +PySwigClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +PySwigClientData_Del(PySwigClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== PySwigObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} PySwigObject; + +SWIGRUNTIME PyObject * +PySwigObject_long(PySwigObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +PySwigObject_format(const char* fmt, PySwigObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { + PyObject *ofmt = PyString_FromString(fmt); + if (ofmt) { + res = PyString_Format(ofmt,args); + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +PySwigObject_oct(PySwigObject *v) +{ + return PySwigObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +PySwigObject_hex(PySwigObject *v) +{ + return PySwigObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +PySwigObject_repr(PySwigObject *v) +#else +PySwigObject_repr(PySwigObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); +#else + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); +#endif + PyString_ConcatAndDel(&repr,nrep); + } + return repr; +} + +SWIGRUNTIME int +PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = PySwigObject_repr(v); +#else + PyObject *repr = PySwigObject_repr(v, NULL); +#endif + if (repr) { + fputs(PyString_AsString(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +PySwigObject_str(PySwigObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + PyString_FromString(result) : 0; +} + +SWIGRUNTIME int +PySwigObject_compare(PySwigObject *v, PySwigObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigObject_Check(PyObject *op) { + return ((op)->ob_type == PySwigObject_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +PySwigObject_dealloc(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own) { + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } else { + const char *name = SWIG_TypePrettyName(ty); +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); +#endif + } + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) +{ + PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!PySwigObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +PySwigObject_getattr(PySwigObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods PySwigObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)PySwigObject_long, /*nb_int*/ + (unaryfunc)PySwigObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)PySwigObject_oct, /*nb_oct*/ + (unaryfunc)PySwigObject_hex, /*nb_hex*/ +#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject pyswigobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigObject", /* tp_name */ + sizeof(PySwigObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigObject_dealloc, /* tp_dealloc */ + (printfunc)PySwigObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)PySwigObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigObject_compare, /* tp_compare */ + (reprfunc)PySwigObject_repr, /* tp_repr */ + &PySwigObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigobject_type = tmp; + pyswigobject_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigobject_type; +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own) +{ + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} PySwigPacked; + +SWIGRUNTIME int +PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +PySwigPacked_repr(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return PyString_FromFormat("", result, v->ty->name); + } else { + return PyString_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +PySwigPacked_str(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return PyString_FromFormat("%s%s", result, v->ty->name); + } else { + return PyString_FromString(v->ty->name); + } +} + +SWIGRUNTIME int +PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); +} + +SWIGRUNTIME void +PySwigPacked_dealloc(PyObject *v) +{ + if (PySwigPacked_Check(v)) { + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject pyswigpacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigPacked", /* tp_name */ + sizeof(PySwigPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigPacked_dealloc, /* tp_dealloc */ + (printfunc)PySwigPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigPacked_compare, /* tp_compare */ + (reprfunc)PySwigPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigpacked_type = tmp; + pyswigpacked_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigpacked_type; +} + +SWIGRUNTIME PyObject * +PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (PySwigPacked_Check(obj)) { + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return PyString_FromString("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +SWIGRUNTIME PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !PySwigObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + PySwigObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (PySwigObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own) { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) *own = sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (!tc) return SWIG_ERROR; + *ptr = SWIG_TypeCast(tc,vptr); + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + PySwigObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = PySwigObject_New(ptr, type, own); + PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + PySwigClientData *data = (PySwigClientData *) ty->clientdata; + if (data) PySwigClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = PyString_FromString(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); + } else { + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +PySwigObject_GetDesc(PyObject *self) +{ + PySwigObject *v = (PySwigObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && PySwigObject_Check(obj)) { + const char *otype = (const char *) PySwigObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? PyString_AsString(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_TALLOC_CTX swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_event_context swig_types[2] +#define SWIGTYPE_p_smbcli_socket swig_types[3] +static swig_type_info *swig_types[5]; +static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif + +/*----------------------------------------------- + @(target):= _libcli_smb.so + ------------------------------------------------*/ +#define SWIG_init init_libcli_smb + +#define SWIG_name "_libcli_smb" + +#define SWIGVERSION 0x010333 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "includes.h" +#include "lib/events/events.h" +#include "libcli/raw/libcliraw.h" + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ + if (PyString_Check(obj)) { + char *cstr; Py_ssize_t len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + int arg2 ; + TALLOC_CTX *arg3 = (TALLOC_CTX *) 0 ; + struct event_context *arg4 = (struct event_context *) 0 ; + struct smbcli_socket *result = 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + int val2 ; + int ecode2 = 0 ; + void *argp4 = 0 ; + int res4 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "host",(char *) "port",(char *) "event_ctx", NULL + }; + + { + arg4 = event_context_init(NULL); + } + { + arg3 = NULL; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO|O:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smbcli_sock_connect_byname" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = (char *)(buf1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "smbcli_sock_connect_byname" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (obj2) { + res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_event_context, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "smbcli_sock_connect_byname" "', argument " "4"" of type '" "struct event_context *""'"); + } + arg4 = (struct event_context *)(argp4); + } + result = (struct smbcli_socket *)smbcli_sock_connect_byname((char const *)arg1,arg2,arg3,arg4); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_smbcli_socket, 0 | 0 ); + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_smbcli_sock_dead(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct smbcli_socket *arg1 = (struct smbcli_socket *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "sock", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:smbcli_sock_dead",kwnames,&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_smbcli_socket, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smbcli_sock_dead" "', argument " "1"" of type '" "struct smbcli_socket *""'"); + } + arg1 = (struct smbcli_socket *)(argp1); + smbcli_sock_dead(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { (char *)"smbcli_sock_connect_byname", (PyCFunction) _wrap_smbcli_sock_connect_byname, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"smbcli_sock_dead", (PyCFunction) _wrap_smbcli_sock_dead, METH_VARARGS | METH_KEYWORDS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_smbcli_socket = {"_p_smbcli_socket", "struct smbcli_socket *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_TALLOC_CTX, + &_swigt__p_char, + &_swigt__p_event_context, + &_swigt__p_smbcli_socket, +}; + +static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_smbcli_socket[] = { {&_swigt__p_smbcli_socket, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_TALLOC_CTX, + _swigc__p_char, + _swigc__p_event_context, + _swigc__p_smbcli_socket, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { + return PyString_FromString(""); + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", PyString_AsString(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + varlink_type.ob_type = &PyType_Type; + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + +} + -- cgit From ecea5ce24553989103d4a06296b24f4d29f30a36 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 17:41:50 +0100 Subject: r26260: Store loadparm context in gensec context. (This used to be commit b9e3a4862e267be39d603fed8207a237c3d72081) --- source4/libcli/ldap/ldap_bind.c | 3 ++- source4/libcli/smb2/session.c | 10 ++++++---- source4/libcli/smb_composite/sesssetup.c | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index d285735d4e..60bfb52e2d 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -29,6 +29,7 @@ #include "auth/gensec/socket.h" #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" +#include "param/param.h" struct ldap_simple_creds { const char *dn; @@ -217,7 +218,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr NULL }; - status = gensec_client_start(conn, &conn->gensec, NULL); + status = gensec_client_start(conn, &conn->gensec, NULL, global_loadparm); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 462f60d2c2..c85dc91579 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -25,8 +25,9 @@ #include "libcli/smb2/smb2_calls.h" #include "libcli/composite/composite.h" #include "auth/gensec/gensec.h" +#include "param/param.h" -/* +/** initialise a smb2_session structure */ struct smb2_session *smb2_session_init(struct smb2_transport *transport, @@ -47,7 +48,8 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, /* prepare a gensec context for later use */ status = gensec_client_start(session, &session->gensec, - session->transport->socket->event.ctx); + session->transport->socket->event.ctx, + global_loadparm); if (!NT_STATUS_IS_OK(status)) { talloc_free(session); return NULL; @@ -58,7 +60,7 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, return session; } -/* +/** send a session setup request */ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, @@ -91,7 +93,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, } -/* +/** recv a session setup reply */ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index a726860647..3ed0bb2473 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -365,7 +365,8 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, smbcli_temp_set_signing(session->transport); - status = gensec_client_start(session, &session->gensec, c->event_ctx); + status = gensec_client_start(session, &session->gensec, c->event_ctx, + global_loadparm); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); return status; -- cgit From 1fbdd6ef1dfb8704de0524fc6f5c33e1418858cd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 18:47:35 +0100 Subject: r26264: pass name resolve order explicitly, use torture context for settings in dssync tests. (This used to be commit c7eae1c7842f9ff8b70cce9e5d6f3ebbbe78e83b) --- source4/libcli/finddcs.c | 3 +-- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/resolve/resolve.c | 6 ++---- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index e00697fe17..75dc14e3f4 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -93,8 +93,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, state->msg_ctx = msg_ctx; make_nbt_name(&name, state->domain_name, name_type); - creq = resolve_name_send(&name, event_ctx, - methods); + creq = resolve_name_send(&name, event_ctx, methods); composite_continue(c, creq, finddcs_name_resolved, state); return c; } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index a748b40a32..e3420313c5 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -239,7 +239,7 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, make_nbt_name(&nbt_name, host, name_type); - status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx); + status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx, lp_name_resolve_order(global_loadparm)); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return NULL; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 24113db9f0..0f8839a3b7 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -187,11 +187,9 @@ NTSTATUS resolve_name_recv(struct composite_context *c, /* general name resolution - sync call */ -NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr, - struct event_context *ev) +NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr, struct event_context *ev, const char **name_resolve_order) { - struct composite_context *c = resolve_name_send(name, ev, - lp_name_resolve_order(global_loadparm)); + struct composite_context *c = resolve_name_send(name, ev, name_resolve_order); return resolve_name_recv(c, mem_ctx, reply_addr); } -- cgit From 2f8dc4f48f1802baa3405e7803563f6840e0d1b3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 21:25:06 +0100 Subject: r26266: Remove more global_loadparm uses. (This used to be commit 99113075c4a96679bcec4f4d6bba4acb3dee4245) --- source4/libcli/cliconnect.c | 10 +++++++--- source4/libcli/ldap/ldap_client.c | 3 ++- source4/libcli/raw/clisocket.c | 3 ++- source4/libcli/raw/clitransport.c | 8 +++++--- source4/libcli/smb2/connect.c | 6 ++++-- source4/libcli/smb_composite/connect.c | 4 +++- 6 files changed, 23 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 39f97f4d8c..b9fd06db1a 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -30,15 +30,19 @@ /* wrapper around smbcli_sock_connect() */ -bool smbcli_socket_connect(struct smbcli_state *cli, const char *server) +bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, + const char **name_resolve_order, + int max_xmit, int max_mux) { struct smbcli_socket *sock; - sock = smbcli_sock_connect_byname(server, 0, NULL, NULL); + sock = smbcli_sock_connect_byname(server, 0, NULL, name_resolve_order, + NULL); if (sock == NULL) return false; - cli->transport = smbcli_transport_init(sock, cli, true); + cli->transport = smbcli_transport_init(sock, cli, true, max_xmit, + max_mux); if (!cli->transport) { return false; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f1cfaad18b..2fe0c78555 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -377,7 +377,8 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, return NULL; } -static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_connection *conn) +static void ldap_connect_got_sock(struct composite_context *ctx, + struct ldap_connection *conn) { /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index e3420313c5..6e12d8073d 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -199,6 +199,7 @@ resolve a hostname and connect ****************************************************************************/ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, TALLOC_CTX *mem_ctx, + const char **name_resolve_order, struct event_context *event_ctx) { int name_type = NBT_NAME_SERVER; @@ -239,7 +240,7 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, make_nbt_name(&nbt_name, host, name_type); - status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx, lp_name_resolve_order(global_loadparm)); + status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx, name_resolve_order); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return NULL; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 0bf805910e..11df6c6c96 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -73,7 +73,9 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob); */ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, TALLOC_CTX *parent_ctx, - bool primary) + bool primary, + int max_xmit, + int max_mux) { struct smbcli_transport *transport; @@ -88,8 +90,8 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->negotiate.protocol = PROTOCOL_NT1; transport->options.use_spnego = lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm); - transport->options.max_xmit = lp_max_xmit(global_loadparm); - transport->options.max_mux = lp_maxmux(global_loadparm); + transport->options.max_xmit = max_xmit; + transport->options.max_mux = max_mux; transport->options.request_timeout = SMB_REQUEST_TIMEOUT; transport->negotiate.max_xmit = transport->options.max_xmit; diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 6f05d56cd4..7cfaf59a65 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -163,6 +163,7 @@ static void continue_resolve(struct composite_context *creq) struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, const char *host, const char *share, + const char **name_resolve_order, struct cli_credentials *credentials, struct event_context *ev) { @@ -187,8 +188,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, ZERO_STRUCT(name); name.name = host; - creq = resolve_name_send(&name, c->event_ctx, - lp_name_resolve_order(global_loadparm)); + creq = resolve_name_send(&name, c->event_ctx, name_resolve_order); composite_continue(c, creq, continue_resolve, c); return c; } @@ -215,11 +215,13 @@ NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, */ NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, const char *host, const char *share, + const char **name_resolve_order, struct cli_credentials *credentials, struct smb2_tree **tree, struct event_context *ev) { struct composite_context *c = smb2_connect_send(mem_ctx, host, share, + name_resolve_order, credentials, ev); return smb2_connect_recv(c, mem_ctx, tree); } diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 0238d5c550..9579cd20b5 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -307,7 +307,9 @@ static NTSTATUS connect_socket(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); /* the socket is up - we can initialise the smbcli transport layer */ - state->transport = smbcli_transport_init(state->sock, state, true); + state->transport = smbcli_transport_init(state->sock, state, true, + lp_max_xmit(global_loadparm), + lp_maxmux(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(state->transport); if (is_ipaddress(state->sock->hostname) && -- cgit From da0f222f432c4fc8bf5da80baf849ca32b315ca0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 23:33:16 +0100 Subject: r26271: Remove some more uses of global_loadparm. (This used to be commit e9875fcd56de0748ed78d7e3c9cdb4919cd96d3c) --- source4/libcli/cldap/cldap.c | 2 +- source4/libcli/cldap/cldap.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 88421ad08d..87a8957fbc 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -572,7 +572,7 @@ struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, if (filter == NULL) goto failed; search.in.dest_address = io->in.dest_address; - search.in.dest_port = lp_cldap_port(global_loadparm); + search.in.dest_port = io->in.dest_port; search.in.filter = filter; search.in.attributes = attr; search.in.timeout = 2; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index cdee775aa7..217ac0ff1b 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -73,6 +73,7 @@ struct cldap_request { struct cldap_socket { struct socket_context *sock; struct event_context *event_ctx; + struct loadparm_context *lp_ctx; /* the fd event */ struct fd_event *fde; @@ -151,6 +152,7 @@ NTSTATUS cldap_error_reply(struct cldap_socket *cldap, struct cldap_netlogon { struct { const char *dest_address; + uint16_t dest_port; const char *realm; const char *host; const char *user; -- cgit From 9ebcd7a0df117158f1817b7d3a9a21ad4e1fa97a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Dec 2007 01:51:36 +0100 Subject: r26277: Move loadparm context higher up the stack. (This used to be commit 38fa08310ce573e9b46e76c840ddda6f18863573) --- source4/libcli/ldap/ldap_bind.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 60bfb52e2d..99b471e9a6 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -199,7 +199,8 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, /* perform a sasl bind using the given credentials */ -NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) +NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, + struct cli_credentials *creds) { NTSTATUS status; TALLOC_CTX *tmp_ctx = NULL; -- cgit From b84be078c197f9752b53d68c882f4d1b44979b8e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 16:26:56 +0100 Subject: r26309: Move specification of port higher up the all stack. (This used to be commit 7de55cde7c7fe0141c05c8a38248667ebf3a9033) --- source4/libcli/nbt/libnbt.h | 1 + source4/libcli/nbt/namequery.c | 2 +- source4/libcli/resolve/nbtlist.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index e383591089..2f7ce8d1b4 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -128,6 +128,7 @@ struct nbt_name_query { struct { struct nbt_name name; const char *dest_addr; + uint16_t dest_port; bool broadcast; bool wins_lookup; int timeout; /* in seconds */ diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 755e06e880..6bc6878194 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -54,7 +54,7 @@ _PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nb packet->questions[0].question_class = NBT_QCLASS_IP; dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port(global_loadparm)); + io->in.dest_addr, io->in.dest_port); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, false); diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index baf3874aa4..13010eec3e 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -151,6 +151,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, for (i=0;inum_queries;i++) { state->io_queries[i].in.name = state->name; state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); + state->io_queries[i].in.dest_port = lp_nbt_port(global_loadparm); if (composite_nomem(state->io_queries[i].in.dest_addr, c)) return c; state->io_queries[i].in.broadcast = broadcast; -- cgit From d378cf4c15e09b980f874bb103b28e89d9dd3a26 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 16:36:54 +0100 Subject: r26310: Remove more uses of global_loadparm. (This used to be commit 9d806da113b5f0688b6193dfdee9b8765e18b38f) --- source4/libcli/dgram/libdgram.h | 2 ++ source4/libcli/dgram/netlogon.c | 3 ++- source4/libcli/dgram/ntlogon.c | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 9f67d58ae2..6d4cdb2bdf 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -123,6 +123,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, + const char *my_netbios_name, const char *mailslot_name, struct nbt_netlogon_packet *reply); NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, @@ -138,6 +139,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_ntlogon_packet *request); NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, + const char *my_netbios_name, const char *mailslot_name, struct nbt_ntlogon_packet *reply); NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index f89c2c5644..92a66cddff 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -62,6 +62,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, */ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, + const char *my_netbios_name, const char *mailslot_name, struct nbt_netlogon_packet *reply) { @@ -79,7 +80,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, return ndr_map_error2ntstatus(ndr_err); } - make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); + make_nbt_name_client(&myname, my_netbios_name); dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, request->src_addr, request->src_port); diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index b4b548fb27..8cd69176a5 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -63,6 +63,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, */ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, + const char *my_netbios_name, const char *mailslot_name, struct nbt_ntlogon_packet *reply) { @@ -80,7 +81,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, return ndr_map_error2ntstatus(ndr_err); } - make_nbt_name_client(&myname, lp_netbios_name(global_loadparm)); + make_nbt_name_client(&myname, my_netbios_name); dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, -- cgit From 0f21c092d6c33fe22fef50fef013bdaa1b9b471b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 16:41:53 +0100 Subject: r26311: Move port number specification higher up the call stack. (This used to be commit ef946ff09315d90ea0419470ffd06a70498133f2) --- source4/libcli/dgram/mailslot.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 4e94e5ee5b..4f9d0bfc7c 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -150,27 +150,20 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - struct socket_address *_dest, + struct socket_address *dest, struct nbt_name *src_name, DATA_BLOB *request) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_dgram_packet packet; - struct socket_address *dest; struct dgram_message *msg; struct dgram_smb_packet *smb; struct smb_trans_body *trans; struct socket_address *src; NTSTATUS status; - if (_dest->port == 0) { - dest = socket_address_from_strings(tmp_ctx, _dest->family, - _dest->addr, lp_dgram_port(global_loadparm)); - } else { - dest = _dest; - } - if (!dest) { - return NT_STATUS_NO_MEMORY; + if (dest->port == 0) { + return NT_STATUS_INVALID_PARAMETER; } ZERO_STRUCT(packet); -- cgit From 39ee38d9c1aabf4db065b433d067d0da053d7d61 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 17:52:23 +0100 Subject: r26316: Use contexts for conversion functions. (This used to be commit f6420d933b5b011d428974f3a2a57edf19e6f482) --- source4/libcli/auth/smbencrypt.c | 12 ++++++------ source4/libcli/raw/rawfileinfo.c | 4 +++- source4/libcli/raw/rawrequest.c | 24 ++++++++++++------------ source4/libcli/smb2/request.c | 4 ++-- 4 files changed, 23 insertions(+), 21 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index bfac395ef9..ccad1058bf 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -67,7 +67,7 @@ _PUBLIC_ bool E_md4hash(const char *passwd, uint8_t p16[16]) int len; void *wpwd; - len = push_ucs2_talloc(NULL, &wpwd, passwd); + len = push_ucs2_talloc(NULL, global_smb_iconv_convenience, &wpwd, passwd); if (len < 2) { /* We don't want to return fixed data, as most callers * don't check */ @@ -97,7 +97,7 @@ _PUBLIC_ bool E_deshash(const char *passwd, uint8_t p16[16]) ZERO_STRUCT(dospwd); /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_string(dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); + push_string(global_smb_iconv_convenience, dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const uint8_t *)dospwd, p16); @@ -150,14 +150,14 @@ bool ntv2_owf_gen(const uint8_t owf[16], } } - user_byte_len = push_ucs2_talloc(mem_ctx, &user, user_in); + user_byte_len = push_ucs2_talloc(mem_ctx, global_smb_iconv_convenience, &user, user_in); if (user_byte_len == (ssize_t)-1) { DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); return false; } - domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in); + domain_byte_len = push_ucs2_talloc(mem_ctx, global_smb_iconv_convenience, &domain, domain_in); if (domain_byte_len == (ssize_t)-1) { DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); @@ -468,7 +468,7 @@ bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag /* the incoming buffer can be any alignment. */ string_flags |= STR_NOALIGN; - new_pw_len = push_string(new_pw, + new_pw_len = push_string(global_smb_iconv_convenience, new_pw, password, sizeof(new_pw), string_flags); @@ -521,7 +521,7 @@ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, } /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + *new_pw_len = pull_string(global_smb_iconv_convenience, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, string_flags); #ifdef DEBUG_PASSWORD diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 17e1792fe3..972ae7f5e1 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -61,7 +61,9 @@ NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx, if (nlen > blob.length - (ofs + 24)) { return NT_STATUS_INFO_LENGTH_MISMATCH; } - size = convert_string_talloc(io->streams, CH_UTF16, CH_UNIX, + size = convert_string_talloc(io->streams, + global_smb_iconv_convenience, + CH_UTF16, CH_UNIX, blob.data+ofs+24, nlen, &vstr); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 6a4f432088..43c984721b 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -418,7 +418,7 @@ size_t smbcli_req_append_string(struct smbcli_request *req, const char *str, uin smbcli_req_grow_allocation(req, len + req->out.data_size); - len = push_string(req->out.data + req->out.data_size, str, len, flags); + len = push_string(global_smb_iconv_convenience, req->out.data + req->out.data_size, str, len, flags); smbcli_req_grow_data(req, len + req->out.data_size); @@ -574,7 +574,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c return 0; } - ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest); + ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest); if (ret == -1) { *dest = NULL; return 0; @@ -616,7 +616,7 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, src_len2++; } - ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest); + ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_DOS, CH_UNIX, src, src_len2, (void **)dest); if (ret == -1) { *dest = NULL; @@ -626,7 +626,7 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, return ret; } -/* +/** pull a string from a request packet, returning a talloced string the string length is limited by the 3 things: @@ -651,7 +651,7 @@ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, } -/* +/** pull a DATA_BLOB from a reply packet, returning a talloced blob make sure we don't go past end of packet @@ -723,7 +723,7 @@ NTTIME smbcli_pull_nttime(void *base, uint16_t offset) return ret; } -/* +/** pull a UCS2 string from a blob, returning a talloced unix string the string length is limited by the 3 things: @@ -769,7 +769,7 @@ size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, src_len2 = utf16_len_n(src, src_len); - ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); + ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; return 0; @@ -779,7 +779,7 @@ size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, return src_len2 + alignment; } -/* +/** pull a ascii string from a blob, returning a talloced string the string length is limited by the 3 things: @@ -815,7 +815,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, src_len2++; } - ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); + ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; @@ -826,7 +826,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, return ret; } -/* +/** pull a string from a blob, returning a talloced struct smb_wire_string the string length is limited by the 3 things: @@ -895,7 +895,7 @@ size_t smbcli_blob_pull_string(struct smbcli_session *session, blob->data+str_offset, dest->private_length, flags); } -/* +/** pull a string from a blob, returning a talloced char * Currently only used by the UNIX search info level. @@ -965,7 +965,7 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, return 0; } - len = push_string(blob->data + blob->length, str, max_len, flags); + len = push_string(global_smb_iconv_convenience, blob->data + blob->length, str, max_len, flags); blob->length += len; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 576e2b6fcf..5a7534f906 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -579,7 +579,7 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me return NT_STATUS_OK; } - size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + size = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); (*str) = (char *)vstr; @@ -604,7 +604,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } - size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, + size = convert_string_talloc(buf->buffer, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; -- cgit From 41db2ab12cea20b271d690be554ab8e6095c2b4e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 21:39:49 +0100 Subject: r26319: Split encoding functions out of libcli_ldap. (This used to be commit 95a6ef7fc8757ccfd90dbf0d6c9b5098f10b10b6) --- source4/libcli/cldap/cldap.c | 1 + source4/libcli/ldap/config.mk | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 87a8957fbc..4c6bd68c13 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -35,6 +35,7 @@ #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_ndr.h" #include "libcli/cldap/cldap.h" #include "lib/socket/socket.h" #include "libcli/security/security.h" diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index adccd23eb1..444306b328 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -5,9 +5,14 @@ OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ ldap_msg.o \ - ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL GENSEC_SOCKET -#FIXME: PRIVATE_DEPENDENCIES = gensec +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ + LDAP_ENCODE LIBNDR + + +[SUBSYSTEM::LDAP_ENCODE] +PUBLIC_PROTO_HEADER = ldap_ndr.h +OBJ_FILES = ldap_ndr.o +# FIXME PRIVATE_DEPENDENCIES = LIBLDB -- cgit From c5bf20c5fe7eaa04cd11a7ce4f365aa6ffd7b124 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 23:57:22 +0100 Subject: r26325: Remove use of global_loadparm in netif. (This used to be commit e452cb28594f23add7c00247ed39e8323aea78a6) --- source4/libcli/resolve/bcast.c | 7 ++++--- source4/libcli/resolve/nbtlist.c | 2 +- source4/libcli/wrepl/winsrepl.c | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 3193d70789..ad574e4c9e 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -23,15 +23,16 @@ #include "libcli/resolve/resolve.h" #include "system/network.h" #include "lib/socket/netif.h" +#include "param/param.h" -/* +/** broadcast name resolution method - async send */ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct nbt_name *name) { - int num_interfaces = iface_count(); + int num_interfaces = iface_count(global_loadparm); const char **address_list; struct composite_context *c; int i, count=0; @@ -40,7 +41,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, if (address_list == NULL) return NULL; for (i=0;ireply_addr = NULL; for (i=0;iout.num_addrs;i++) { - if (iface_is_local(q->out.reply_addrs[i])) { + if (iface_is_local(global_loadparm, q->out.reply_addrs[i])) { state->reply_addr = talloc_steal(state, q->out.reply_addrs[i]); break; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 1f7ca796b6..8f808198eb 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -29,6 +29,7 @@ #include "libcli/composite/composite.h" #include "system/network.h" #include "lib/socket/netif.h" +#include "param/param.h" static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status); @@ -330,7 +331,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, state->wrepl_socket = wrepl_socket; if (!our_ip) { - our_ip = iface_best_ip(peer_ip); + our_ip = iface_best_ip(global_loadparm, peer_ip); } us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, -- cgit From 949f3c726452a59555236f9fdda52e79c3e5832b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 13:30:23 +0100 Subject: r26333: No more global_loadparm in finddcs. (This used to be commit 0c91026e587ca74692bc9223a6b5493e35943aee) --- source4/libcli/finddcs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 75dc14e3f4..83bf9837f9 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -34,6 +34,7 @@ struct finddcs_state { struct composite_context *ctx; struct messaging_context *msg_ctx; + const char *my_netbios_name; const char *domain_name; struct dom_sid *domain_sid; @@ -60,6 +61,7 @@ static void fallback_node_status_replied(struct nbt_name_request *name_req); */ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, + const char *my_netbios_name, const char *domain_name, int name_type, struct dom_sid *domain_sid, @@ -80,6 +82,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, state->ctx = c; + state->my_netbios_name = talloc_strdup(state, my_netbios_name); state->domain_name = talloc_strdup(state, domain_name); if (composite_nomem(state->domain_name, c)) return c; @@ -144,9 +147,8 @@ static void finddcs_name_resolved(struct composite_context *ctx) state->r.in.domainname = state->domain_name; state->r.in.ip_address = state->dcs[0].address; - state->r.in.my_computername = lp_netbios_name(global_loadparm); - state->r.in.my_accountname = talloc_asprintf(state, "%s$", - lp_netbios_name(global_loadparm)); + state->r.in.my_computername = state->my_netbios_name; + state->r.in.my_accountname = talloc_asprintf(state, "%s$", state->my_netbios_name); if (composite_nomem(state->r.in.my_accountname, state->ctx)) return; state->r.in.account_control = ACB_WSTRUST; state->r.in.domain_sid = state->domain_sid; @@ -244,6 +246,7 @@ NTSTATUS finddcs_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, } NTSTATUS finddcs(TALLOC_CTX *mem_ctx, + const char *my_netbios_name, const char *domain_name, int name_type, struct dom_sid *domain_sid, const char **methods, @@ -252,6 +255,7 @@ NTSTATUS finddcs(TALLOC_CTX *mem_ctx, int *num_dcs, struct nbt_dc_name **dcs) { struct composite_context *c = finddcs_send(mem_ctx, + my_netbios_name, domain_name, name_type, domain_sid, methods, event_ctx, msg_ctx); -- cgit From 01d2acfdb4c4c0349a28a18c5c0da5b960b02791 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 16:04:17 +0100 Subject: r26335: Specify name_resolve_order to socket code. (This used to be commit b03e5d00110be3f1fe5809dad4eb6ca5cea7463d) --- source4/libcli/ldap/ldap_client.c | 4 ++-- source4/libcli/raw/clisocket.c | 1 + source4/libcli/wrepl/winsrepl.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 2fe0c78555..c859b4a4d1 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -352,7 +352,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, conn->event.event_ctx); + 0, lp_name_resolve_order(global_loadparm), conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; @@ -365,7 +365,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - conn->event.event_ctx); + lp_name_resolve_order(global_loadparm), conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_tcp_conn; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 6e12d8073d..9b744dcc18 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -96,6 +96,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, ctx = socket_connect_multi_send(state, host_addr, state->num_ports, state->ports, + lp_name_resolve_order(global_loadparm), state->ctx->event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = smbcli_sock_connect_recv_conn; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 8f808198eb..9f7bd91ec9 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -343,7 +343,8 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, if (composite_nomem(peer, result)) return result; state->creq = socket_connect_send(wrepl_socket->sock, us, peer, - 0, wrepl_socket->event.ctx); + 0, lp_name_resolve_order(global_loadparm), + wrepl_socket->event.ctx); composite_continue(result, state->creq, wrepl_connect_handler, state); return result; } -- cgit From da2ae4995370affe57cfecfe371a4edf553065d0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 16:04:25 +0100 Subject: r26337: Move global_loadparm to a higher caller. (This used to be commit baa5bcd303c72431dfa638edde72cded4265c612) --- source4/libcli/smb2/connect.c | 2 +- source4/libcli/smb2/session.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 7cfaf59a65..39bb992d11 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -99,7 +99,7 @@ static void continue_negprot(struct smb2_request *req) c->status = smb2_negprot_recv(req, c, &state->negprot); if (!composite_is_ok(c)) return; - state->session = smb2_session_init(transport, state, true); + state->session = smb2_session_init(transport, global_loadparm, state, true); if (composite_nomem(state->session, c)) return; creq = smb2_session_setup_spnego_send(state->session, state->credentials); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index c85dc91579..a784ea65d8 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -31,6 +31,7 @@ initialise a smb2_session structure */ struct smb2_session *smb2_session_init(struct smb2_transport *transport, + struct loadparm_context *lp_ctx, TALLOC_CTX *parent_ctx, bool primary) { struct smb2_session *session; @@ -49,7 +50,7 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, /* prepare a gensec context for later use */ status = gensec_client_start(session, &session->gensec, session->transport->socket->event.ctx, - global_loadparm); + lp_ctx); if (!NT_STATUS_IS_OK(status)) { talloc_free(session); return NULL; -- cgit From a72c5053c587f0ed6113ef514fe3739cb81e7abf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Dec 2007 23:32:43 +0100 Subject: r26353: Remove use of global_loadparm. (This used to be commit 17637e4490e42db6cdef619286c4d5a0982e9d1a) --- source4/libcli/ldap/ldap_bind.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 99b471e9a6..ba1ae90ebd 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -43,7 +43,8 @@ NTSTATUS ldap_rebind(struct ldap_connection *conn) switch (conn->bind.type) { case LDAP_BIND_SASL: - status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds); + status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds, + global_loadparm); break; case LDAP_BIND_SIMPLE: @@ -200,7 +201,8 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, perform a sasl bind using the given credentials */ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, - struct cli_credentials *creds) + struct cli_credentials *creds, + struct loadparm_context *lp_ctx) { NTSTATUS status; TALLOC_CTX *tmp_ctx = NULL; @@ -219,7 +221,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, NULL }; - status = gensec_client_start(conn, &conn->gensec, NULL, global_loadparm); + status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; -- cgit From b65dba2245bf382c47d65c95ac9b1efa43918fc0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 04:33:16 +0100 Subject: r26355: Eliminate global_loadparm in more places. (This used to be commit 5d589a0d94bd76a9b4c9fc748854e8098ea43c4d) --- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/ldap/ldap_client.c | 13 ++++++++----- source4/libcli/ldap/ldap_client.h | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index ba1ae90ebd..bd548be38e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -44,7 +44,7 @@ NTSTATUS ldap_rebind(struct ldap_connection *conn) switch (conn->bind.type) { case LDAP_BIND_SASL: status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds, - global_loadparm); + conn->lp_ctx); break; case LDAP_BIND_SIMPLE: diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c859b4a4d1..906e9c2574 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -37,11 +37,12 @@ #include "param/param.h" -/* +/** create a new ldap_connection stucture. The event context is optional */ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, - struct event_context *ev) + struct loadparm_context *lp_ctx, + struct event_context *ev) { struct ldap_connection *conn; @@ -61,6 +62,8 @@ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, conn->next_messageid = 1; conn->event.event_ctx = ev; + conn->lp_ctx = lp_ctx; + /* set a reasonable request timeout */ conn->timeout = 60; @@ -352,7 +355,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, lp_name_resolve_order(global_loadparm), conn->event.event_ctx); + 0, lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; @@ -365,7 +368,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - lp_name_resolve_order(global_loadparm), conn->event.event_ctx); + lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_tcp_conn; @@ -394,7 +397,7 @@ static void ldap_connect_got_sock(struct composite_context *ctx, talloc_steal(conn, conn->sock); if (conn->ldaps) { struct socket_context *tls_socket; - char *cafile = private_path(conn->sock, global_loadparm, lp_tls_cafile(global_loadparm)); + char *cafile = private_path(conn->sock, conn->lp_ctx, lp_tls_cafile(conn->lp_ctx)); if (!cafile || !*cafile) { talloc_free(conn->sock); diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index d2a12ee8b5..d5ff441aff 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -51,6 +51,8 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { struct socket_context *sock; + struct loadparm_context *lp_ctx; + char *host; uint16_t port; bool ldaps; -- cgit From 5f4842cf65ce64bfdf577cd549565da20ca818cf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:19 +0100 Subject: r26376: Add context for libcli_resolve. (This used to be commit 459e1466a411d6f83b7372e248566e6e71c745fc) --- source4/libcli/cliconnect.c | 4 +- source4/libcli/finddcs.c | 8 +-- source4/libcli/ldap/ldap_client.c | 5 +- source4/libcli/raw/clisocket.c | 6 +- source4/libcli/raw/libcliraw.h | 1 + source4/libcli/resolve/bcast.c | 8 ++- source4/libcli/resolve/host.c | 9 ++- source4/libcli/resolve/resolve.c | 110 ++++++++++++++++++++++----------- source4/libcli/resolve/resolve.h | 2 + source4/libcli/resolve/testsuite.c | 2 +- source4/libcli/resolve/wins.c | 26 ++++++-- source4/libcli/smb2/connect.c | 8 +-- source4/libcli/smb2/smb2_calls.h | 1 + source4/libcli/smb_composite/connect.c | 3 +- source4/libcli/wrepl/winsrepl.c | 3 +- 15 files changed, 133 insertions(+), 63 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index b9fd06db1a..d70f592d9d 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -31,12 +31,12 @@ wrapper around smbcli_sock_connect() */ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, - const char **name_resolve_order, + struct resolve_context *resolve_ctx, int max_xmit, int max_mux) { struct smbcli_socket *sock; - sock = smbcli_sock_connect_byname(server, 0, NULL, name_resolve_order, + sock = smbcli_sock_connect_byname(server, 0, NULL, resolve_ctx, NULL); if (sock == NULL) return false; diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 83bf9837f9..415c84a6bd 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -65,7 +65,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, const char *domain_name, int name_type, struct dom_sid *domain_sid, - const char **methods, + struct resolve_context *resolve_ctx, struct event_context *event_ctx, struct messaging_context *msg_ctx) { @@ -96,7 +96,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, state->msg_ctx = msg_ctx; make_nbt_name(&name, state->domain_name, name_type); - creq = resolve_name_send(&name, event_ctx, methods); + creq = resolve_name_send(resolve_ctx, &name, event_ctx); composite_continue(c, creq, finddcs_name_resolved, state); return c; } @@ -249,7 +249,7 @@ NTSTATUS finddcs(TALLOC_CTX *mem_ctx, const char *my_netbios_name, const char *domain_name, int name_type, struct dom_sid *domain_sid, - const char **methods, + struct resolve_context *resolve_ctx, struct event_context *event_ctx, struct messaging_context *msg_ctx, int *num_dcs, struct nbt_dc_name **dcs) @@ -257,7 +257,7 @@ NTSTATUS finddcs(TALLOC_CTX *mem_ctx, struct composite_context *c = finddcs_send(mem_ctx, my_netbios_name, domain_name, name_type, - domain_sid, methods, + domain_sid, resolve_ctx, event_ctx, msg_ctx); return finddcs_recv(c, mem_ctx, num_dcs, dcs); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 906e9c2574..6b8a7a3f28 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -35,6 +35,7 @@ #include "auth/gensec/gensec.h" #include "system/time.h" #include "param/param.h" +#include "libcli/resolve/resolve.h" /** @@ -355,7 +356,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); + 0, lp_resolve_context(conn->lp_ctx), conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; @@ -368,7 +369,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); + lp_resolve_context(conn->lp_ctx), conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_tcp_conn; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 9b744dcc18..c09104e256 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -96,7 +96,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, ctx = socket_connect_multi_send(state, host_addr, state->num_ports, state->ports, - lp_name_resolve_order(global_loadparm), + lp_resolve_context(global_loadparm), state->ctx->event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = smbcli_sock_connect_recv_conn; @@ -200,7 +200,7 @@ resolve a hostname and connect ****************************************************************************/ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, TALLOC_CTX *mem_ctx, - const char **name_resolve_order, + struct resolve_context *resolve_ctx, struct event_context *event_ctx) { int name_type = NBT_NAME_SERVER; @@ -241,7 +241,7 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, make_nbt_name(&nbt_name, host, name_type); - status = resolve_name(&nbt_name, tmp_ctx, &address, event_ctx, name_resolve_order); + status = resolve_name(resolve_ctx, &nbt_name, tmp_ctx, &address, event_ctx); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return NULL; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index a11a9c9e58..6c97e61f04 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -30,6 +30,7 @@ struct smbcli_request; /* forward declare */ struct smbcli_session; /* forward declare */ struct smbcli_transport; /* forward declare */ +struct resolve_context; struct cli_credentials; /* default timeout for all smb requests */ diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index ad574e4c9e..5a2c49c5ad 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -30,6 +30,7 @@ */ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, + void *userdata, struct nbt_name *name) { int num_interfaces = iface_count(global_loadparm); @@ -74,7 +75,12 @@ NTSTATUS resolve_name_bcast(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct composite_context *c = resolve_name_bcast_send(mem_ctx, NULL, name); + struct composite_context *c = resolve_name_bcast_send(mem_ctx, NULL, NULL, name); return resolve_name_bcast_recv(c, mem_ctx, reply_addr); } +bool resolve_context_add_bcast_method(struct resolve_context *ctx) +{ + return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, + NULL); +} diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index e98bbc51b2..4b8f3f9553 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -34,6 +34,7 @@ #include "system/filesys.h" #include "libcli/composite/composite.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "libcli/resolve/resolve.h" struct host_state { struct nbt_name name; @@ -123,6 +124,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, */ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, + void *privdata, struct nbt_name *name) { struct composite_context *c; @@ -213,7 +215,12 @@ NTSTATUS resolve_name_host(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr) { - struct composite_context *c = resolve_name_host_send(mem_ctx, NULL, name); + struct composite_context *c = resolve_name_host_send(mem_ctx, NULL, NULL, name); return resolve_name_host_recv(c, mem_ctx, reply_addr); } +bool resolve_context_add_host_method(struct resolve_context *ctx) +{ + return resolve_context_add_method(ctx, resolve_name_host_send, resolve_name_host_recv, + NULL); +} diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 0f8839a3b7..f0d9c07874 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -4,6 +4,7 @@ general name resolution interface Copyright (C) Andrew Tridgell 2005 + Copyright (C) Jelmer Vernooij 2007 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 @@ -26,57 +27,67 @@ #include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" #include "system/network.h" +#include "util/dlinklist.h" struct resolve_state { + struct resolve_context *ctx; + struct resolve_method *method; struct nbt_name name; - const char **methods; struct composite_context *creq; const char *reply_addr; }; static struct composite_context *setup_next_method(struct composite_context *c); -/* pointers to the resolver backends */ -static const struct resolve_method { - const char *name; - struct composite_context *(*send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, struct nbt_name *); - NTSTATUS (*recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); -} resolve_methods[] = { - { "bcast", resolve_name_bcast_send, resolve_name_bcast_recv }, - { "wins", resolve_name_wins_send, resolve_name_wins_recv }, - { "host", resolve_name_host_send, resolve_name_host_recv } +struct resolve_context { + struct resolve_method { + resolve_name_send_fn send_fn; + resolve_name_recv_fn recv_fn; + void *privdata; + struct resolve_method *prev, *next; + } *methods; }; +/** + * Initialize a resolve context + */ +struct resolve_context *resolve_context_init(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct resolve_context); +} -/* - find a matching backend -*/ -static const struct resolve_method *find_method(const char *name) +/** + * Add a resolve method + */ +bool resolve_context_add_method(struct resolve_context *ctx, resolve_name_send_fn send_fn, + resolve_name_recv_fn recv_fn, void *userdata) { - int i; - if (name == NULL) return NULL; - for (i=0;isend_fn = send_fn; + method->recv_fn = recv_fn; + method->privdata = userdata; + DLIST_ADD_END(ctx->methods, method, struct resolve_method *); + return true; } -/* +/** handle completion of one name resolve method */ static void resolve_handler(struct composite_context *creq) { struct composite_context *c = (struct composite_context *)creq->async.private_data; struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state); - const struct resolve_method *method = find_method(state->methods[0]); + const struct resolve_method *method = state->method; c->status = method->recv_fn(creq, state, &state->reply_addr); if (!NT_STATUS_IS_OK(c->status)) { - state->methods++; + state->method = state->method->next; state->creq = setup_next_method(c); if (state->creq != NULL) { return; @@ -100,13 +111,12 @@ static struct composite_context *setup_next_method(struct composite_context *c) struct composite_context *creq = NULL; do { - const struct resolve_method *method = find_method(state->methods[0]); - if (method) { - creq = method->send_fn(c, c->event_ctx, &state->name); + if (state->method) { + creq = state->method->send_fn(c, c->event_ctx, state->method->privdata, &state->name); } - if (creq == NULL && state->methods[0]) state->methods++; + if (creq == NULL && state->method) state->method = state->method->next; - } while (!creq && state->methods[0]); + } while (!creq && state->method); if (creq) { creq->async.fn = resolve_handler; @@ -119,8 +129,9 @@ static struct composite_context *setup_next_method(struct composite_context *c) /* general name resolution - async send */ -struct composite_context *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx, - const char **methods) +struct composite_context *resolve_name_send(struct resolve_context *ctx, + struct nbt_name *name, + struct event_context *event_ctx) { struct composite_context *c; struct resolve_state *state; @@ -128,7 +139,7 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ c = composite_create(event_ctx, event_ctx); if (c == NULL) return NULL; - if (methods == NULL) { + if (ctx == NULL) { composite_error(c, NT_STATUS_INVALID_PARAMETER); return c; } @@ -147,8 +158,8 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ c->status = nbt_name_dup(state, name, &state->name); if (!composite_is_ok(c)) return c; - state->methods = str_list_copy(state, methods); - if (composite_nomem(state->methods, c)) return c; + state->ctx = talloc_reference(state, ctx); + if (composite_nomem(state->ctx, c)) return c; if (is_ipaddress(state->name.name) || strcasecmp(state->name.name, "localhost") == 0) { @@ -159,6 +170,7 @@ struct composite_context *resolve_name_send(struct nbt_name *name, struct event_ return c; } + state->method = ctx->methods; state->creq = setup_next_method(c); if (composite_nomem(state->creq, c)) return c; @@ -187,9 +199,9 @@ NTSTATUS resolve_name_recv(struct composite_context *c, /* general name resolution - sync call */ -NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr, struct event_context *ev, const char **name_resolve_order) +NTSTATUS resolve_name(struct resolve_context *ctx, struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr, struct event_context *ev) { - struct composite_context *c = resolve_name_send(name, ev, name_resolve_order); + struct composite_context *c = resolve_name_send(ctx, name, ev); return resolve_name_recv(c, mem_ctx, reply_addr); } @@ -215,3 +227,27 @@ void make_nbt_name_server(struct nbt_name *nbt, const char *name) { make_nbt_name(nbt, name, NBT_NAME_SERVER); } + +struct resolve_context *lp_resolve_context(struct loadparm_context *lp_ctx) +{ + const char **methods = lp_name_resolve_order(lp_ctx); + int i; + struct resolve_context *ret = resolve_context_init(lp_ctx); + + if (ret == NULL) + return NULL; + + for (i = 0; methods != NULL && methods[i] != NULL; i++) { + if (!strcmp(methods[i], "wins")) { + resolve_context_add_wins_method(ret, lp_wins_server_list(lp_ctx)); + } else if (!strcmp(methods[i], "bcast")) { + resolve_context_add_bcast_method(ret); + } else if (!strcmp(methods[i], "host")) { + resolve_context_add_host_method(ret); + } else { + DEBUG(0, ("Unknown resolve method '%s'", methods[i])); + } + } + + return ret; +} diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 72db3839a2..73cb78c124 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -23,6 +23,8 @@ #define __RESOLVE_H__ #include "libcli/nbt/libnbt.h" +typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, struct nbt_name *); +typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); #include "libcli/resolve/proto.h" #endif /* __RESOLVE_H__ */ diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c index b87b59b81a..73a8c841bb 100644 --- a/source4/libcli/resolve/testsuite.c +++ b/source4/libcli/resolve/testsuite.c @@ -44,7 +44,7 @@ static bool test_async_resolve(struct torture_context *tctx) host, timelimit); while (timeval_elapsed(&tv) < timelimit) { const char *s; - struct composite_context *c = resolve_name_host_send(mem_ctx, ev, &n); + struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, &n); torture_assert(tctx, c != NULL, "resolve_name_host_send"); torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s), "async resolve failed"); diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 2cbcd5f483..73b9413eb4 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -24,17 +24,22 @@ #include "libcli/resolve/resolve.h" #include "param/param.h" -/* +struct resolve_wins_data { + const char **address_list; +}; + +/** wins name resolution method - async send */ struct composite_context *resolve_name_wins_send( TALLOC_CTX *mem_ctx, struct event_context *event_ctx, + void *userdata, struct nbt_name *name) { - const char **address_list = lp_wins_server_list(global_loadparm); - if (address_list == NULL) return NULL; - return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, false, true); + struct resolve_wins_data *wins_data = talloc_get_type(userdata, struct resolve_wins_data); + if (wins_data->address_list == NULL) return NULL; + return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, false, true); } /* @@ -51,9 +56,20 @@ NTSTATUS resolve_name_wins_recv(struct composite_context *c, */ NTSTATUS resolve_name_wins(struct nbt_name *name, TALLOC_CTX *mem_ctx, + const char **address_list, const char **reply_addr) { - struct composite_context *c = resolve_name_wins_send(mem_ctx, NULL, name); + struct composite_context *c; + struct resolve_wins_data *wins_data = talloc(mem_ctx, struct resolve_wins_data); + wins_data->address_list = address_list; + c = resolve_name_wins_send(mem_ctx, NULL, wins_data, name); return resolve_name_wins_recv(c, mem_ctx, reply_addr); } +bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list) +{ + struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data); + wins_data->address_list = str_list_copy(wins_data, address_list); + return resolve_context_add_method(ctx, resolve_name_wins_send, resolve_name_wins_recv, + wins_data); +} diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 39bb992d11..8b75e125b0 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -163,7 +163,7 @@ static void continue_resolve(struct composite_context *creq) struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, const char *host, const char *share, - const char **name_resolve_order, + struct resolve_context *resolve_ctx, struct cli_credentials *credentials, struct event_context *ev) { @@ -188,7 +188,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, ZERO_STRUCT(name); name.name = host; - creq = resolve_name_send(&name, c->event_ctx, name_resolve_order); + creq = resolve_name_send(resolve_ctx, &name, c->event_ctx); composite_continue(c, creq, continue_resolve, c); return c; } @@ -215,13 +215,13 @@ NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, */ NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, const char *host, const char *share, - const char **name_resolve_order, + struct resolve_context *resolve_ctx, struct cli_credentials *credentials, struct smb2_tree **tree, struct event_context *ev) { struct composite_context *c = smb2_connect_send(mem_ctx, host, share, - name_resolve_order, + resolve_ctx, credentials, ev); return smb2_connect_recv(c, mem_ctx, tree); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 318a634ac4..6a551da4ae 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -95,4 +95,5 @@ struct smb2_setinfo { struct cli_credentials; struct event_context; +struct resolve_context; #include "libcli/smb2/smb2_proto.h" diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 9579cd20b5..1a8262c76a 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -463,8 +463,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec state->stage = CONNECT_RESOLVE; make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(&name, c->event_ctx, - lp_name_resolve_order(global_loadparm)); + state->creq = resolve_name_send(lp_resolve_context(global_loadparm), &name, c->event_ctx); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 9f7bd91ec9..00346c45a4 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -30,6 +30,7 @@ #include "system/network.h" #include "lib/socket/netif.h" #include "param/param.h" +#include "libcli/resolve/resolve.h" static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status); @@ -343,7 +344,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, if (composite_nomem(peer, result)) return result; state->creq = socket_connect_send(wrepl_socket->sock, us, peer, - 0, lp_name_resolve_order(global_loadparm), + 0, lp_resolve_context(global_loadparm), wrepl_socket->event.ctx); composite_continue(result, state->creq, wrepl_connect_handler, state); return result; -- cgit From 51ef1b606fe1853b7ca2decf2a74eecf18c5a747 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:29 +0100 Subject: r26377: Specify port explicitly. (This used to be commit 8c767ca13906966cd6cccbeaef3c50033d46f206) --- source4/libcli/finddcs.c | 1 + source4/libcli/nbt/libnbt.h | 1 + source4/libcli/nbt/namequery.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 415c84a6bd..624f6cd630 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -189,6 +189,7 @@ static void fallback_node_status(struct finddcs_state *state) state->node_status.in.name.type = NBT_NAME_CLIENT; state->node_status.in.name.scope = NULL; state->node_status.in.dest_addr = state->dcs[0].address; + state->node_status.in.dest_port = lp_nbt_port(global_loadparm); state->node_status.in.timeout = 1; state->node_status.in.retries = 2; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 2f7ce8d1b4..f4bb71764a 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -147,6 +147,7 @@ struct nbt_name_status { struct { struct nbt_name name; const char *dest_addr; + uint16_t dest_port; int timeout; /* in seconds */ int retries; } in; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 6bc6878194..e3432bfda1 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -158,7 +158,7 @@ _PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *n packet->questions[0].question_class = NBT_QCLASS_IP; dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port(global_loadparm)); + io->in.dest_addr, io->in.dest_port); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, false); -- cgit From eede6b87e1dac018035bb68a675f80d6b25c20e3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:33 +0100 Subject: r26378: Remove use of global_loadparm. (This used to be commit 81333de5353ce70512a3ed1d4960c09aa78954c6) --- source4/libcli/resolve/bcast.c | 9 +++++---- source4/libcli/resolve/resolve.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 5a2c49c5ad..1733ca9d2e 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -33,7 +33,8 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, void *userdata, struct nbt_name *name) { - int num_interfaces = iface_count(global_loadparm); + struct loadparm_context *lp_ctx = userdata; + int num_interfaces = iface_count(lp_ctx); const char **address_list; struct composite_context *c; int i, count=0; @@ -42,7 +43,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, if (address_list == NULL) return NULL; for (i=0;i Date: Mon, 10 Dec 2007 18:41:41 +0100 Subject: r26380: Specify port number higher up the call stack. (This used to be commit 77273e250cacb1df0e8bd676e0948175ccd2330a) --- source4/libcli/nbt/libnbt.h | 1 + source4/libcli/nbt/namerefresh.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index f4bb71764a..88ca0e204b 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -215,6 +215,7 @@ struct nbt_name_refresh { struct { struct nbt_name name; const char *dest_addr; + uint16_t dest_port; const char *address; uint16_t nb_flags; bool broadcast; diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index d723eed9f5..3e99854215 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -69,7 +69,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, dest = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port(global_loadparm)); + io->in.dest_addr, io->in.dest_port); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, false); @@ -174,6 +174,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) goto done; } state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.dest_port = lp_nbt_port(global_loadparm); state->io->in.address = state->addresses[0]; state->req = nbt_name_refresh_send(state->nbtsock, state->io); if (state->req == NULL) { @@ -212,7 +213,7 @@ done: } } -/* +/** the async send call for a multi-server WINS refresh */ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, @@ -240,6 +241,7 @@ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbt state->io->in.name = io->in.name; state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.dest_port = lp_nbt_port(global_loadparm); state->io->in.address = io->in.addresses[0]; state->io->in.nb_flags = io->in.nb_flags; state->io->in.broadcast = false; -- cgit From 274d07ddff5c5920b9a2f3674e9104d8aab9e90c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:45 +0100 Subject: r26381: Move global_loadparm higher up the call stack. (This used to be commit 992296767492ecd7d21b06f4a08a5b8d73d00740) --- source4/libcli/nbt/libnbt.h | 1 + source4/libcli/nbt/nameregister.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 88ca0e204b..524391917d 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -163,6 +163,7 @@ struct nbt_name_register { struct { struct nbt_name name; const char *dest_addr; + uint16_t dest_port; const char *address; uint16_t nb_flags; bool register_demand; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index fd4a94dd44..9389981647 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -77,7 +77,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port(global_loadparm)); + io->in.dest_addr, io->in.dest_port); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, false); @@ -224,6 +224,7 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n state->io->in.name = io->in.name; state->io->in.dest_addr = io->in.dest_addr; + state->io->in.dest_port = lp_nbt_port(global_loadparm); state->io->in.address = io->in.address; state->io->in.nb_flags = io->in.nb_flags; state->io->in.register_demand = false; @@ -311,6 +312,7 @@ static void name_register_wins_handler(struct nbt_name_request *req) goto done; } state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.dest_port = lp_nbt_port(global_loadparm); state->io->in.address = state->addresses[0]; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { @@ -377,6 +379,7 @@ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nb state->io->in.name = io->in.name; state->io->in.dest_addr = state->wins_servers[0]; + state->io->in.dest_port = lp_nbt_port(global_loadparm); state->io->in.address = io->in.addresses[0]; state->io->in.nb_flags = io->in.nb_flags; state->io->in.broadcast = false; -- cgit From f055893ca571fbeac3675c02344c7cc53106bea1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:55 +0100 Subject: r26382: Remove more uses of global_loadparm. (This used to be commit 6d4c59853481855c232e7cf97264a391f40af2b5) --- source4/libcli/wrepl/winsrepl.c | 8 +++++--- source4/libcli/wrepl/winsrepl.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 00346c45a4..92543be487 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -313,6 +313,7 @@ static void wrepl_connect_handler(struct composite_context *creq) connect a wrepl_socket to a WINS server */ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, + struct resolve_context *resolve_ctx, const char *our_ip, const char *peer_ip) { struct composite_context *result; @@ -344,7 +345,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, if (composite_nomem(peer, result)) return result; state->creq = socket_connect_send(wrepl_socket->sock, us, peer, - 0, lp_resolve_context(global_loadparm), + 0, resolve_ctx, wrepl_socket->event.ctx); composite_continue(result, state->creq, wrepl_connect_handler, state); return result; @@ -371,9 +372,10 @@ NTSTATUS wrepl_connect_recv(struct composite_context *result) /* connect a wrepl_socket to a WINS server - sync API */ -NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *our_ip, const char *peer_ip) +NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, struct resolve_context *resolve_ctx, + const char *our_ip, const char *peer_ip) { - struct composite_context *c_req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip); + struct composite_context *c_req = wrepl_connect_send(wrepl_socket, resolve_ctx, our_ip, peer_ip); return wrepl_connect_recv(c_req); } diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 8ce8b418a2..52b0bee69e 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -154,4 +154,6 @@ struct wrepl_pull_names { } out; }; +struct resolve_context; + #include "libcli/wrepl/winsrepl_proto.h" -- cgit From 3971827b6ee7c84beaf4449e3c12dfe9f2d62c77 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:42:04 +0100 Subject: r26384: Fix another global_loadparm instance. (This used to be commit 881ec40d7a4c97863abee5740187e9aa0a1801bb) --- source4/libcli/cliconnect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index d70f592d9d..a170024def 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -66,7 +66,8 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) /* wrapper around smb_raw_sesssetup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, - struct cli_credentials *credentials) + struct cli_credentials *credentials, + const char *workgroup) { struct smb_composite_sesssetup setup; NTSTATUS status; @@ -77,7 +78,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.credentials = credentials; - setup.in.workgroup = lp_workgroup(global_loadparm); + setup.in.workgroup = workgroup; status = smb_composite_sesssetup(cli->session, &setup); -- cgit From 3da665e9ac324320fed68a21163fffdf4bd3df89 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:42:07 +0100 Subject: r26385: Integrate gensec-socket into gensec. (This used to be commit 78bb444b4b73df9a84f8702814f9b30b32ffd885) --- source4/libcli/ldap/ldap_bind.c | 3 ++- source4/libcli/nbt/namerefresh.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index bd548be38e..fd15ff2fc7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -26,7 +26,6 @@ #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" -#include "auth/gensec/socket.h" #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" #include "param/param.h" @@ -221,6 +220,8 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, NULL }; + gensec_init(lp_ctx); + status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 3e99854215..8408b4e3c3 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -137,7 +137,7 @@ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, -/* +/** a wins name refresh with multiple WINS servers and multiple addresses to refresh. Try each WINS server in turn, until we get a reply for each address @@ -152,7 +152,7 @@ struct refresh_wins_state { }; -/* +/** state handler for WINS multi-homed multi-server name refresh */ static void name_refresh_wins_handler(struct nbt_name_request *req) -- cgit From 6a56c111d7a08e5add115edcdc81653cc19d3a4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Dec 2007 09:01:56 +0100 Subject: r26391: samba4 doesn't support 'lmhosts' as resolve module metze (This used to be commit cdb64b41018928122898257f65d2573109b473cc) --- source4/libcli/resolve/resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index ad2d58a64c..fe36aa59ea 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -245,7 +245,7 @@ struct resolve_context *lp_resolve_context(struct loadparm_context *lp_ctx) } else if (!strcmp(methods[i], "host")) { resolve_context_add_host_method(ret); } else { - DEBUG(0, ("Unknown resolve method '%s'", methods[i])); + DEBUG(0, ("Unknown resolve method '%s'\n", methods[i])); } } -- cgit From 1ea47faa979ad2e4aa4cf1f4252aa33aef98dbd8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 13:38:54 +0100 Subject: r26397: Fix circular dependency in samba-socket. (This used to be commit 801c8c766cb6a104751be8829593e0e123508134) --- source4/libcli/config.mk | 13 +++++++---- source4/libcli/ldap/config.mk | 2 +- source4/libcli/resolve/resolve.c | 22 ------------------ source4/libcli/resolve/resolve.h | 1 + source4/libcli/resolve/resolve_lp.c | 46 +++++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 source4/libcli/resolve/resolve_lp.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 3bfc1478bc..4af6a9ac45 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -96,13 +96,18 @@ PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS LIBPACK [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h OBJ_FILES = \ - resolve/resolve.o \ + resolve/resolve.o +PUBLIC_DEPENDENCIES = NDR_NBT + +[SUBSYSTEM::LP_RESOLVE] +PRIVATE_PROTO_HEADER = resolve/lp_proto.h +OBJ_FILES = \ resolve/bcast.o \ resolve/nbtlist.o \ resolve/wins.o \ - resolve/host.o -PUBLIC_DEPENDENCIES = LIBNETIF -PRIVATE_DEPENDENCIES = LIBCLI_NBT + resolve/host.o \ + resolve/resolve_lp.o +PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-CONFIG LIBNETIF [SUBSYSTEM::LIBCLI_FINDDCS] PRIVATE_PROTO_HEADER = finddcs.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 444306b328..4af0f9de6d 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = ldap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR + LDAP_ENCODE LIBNDR LP_RESOLVE [SUBSYSTEM::LDAP_ENCODE] diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index fe36aa59ea..33ace09443 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -228,26 +228,4 @@ void make_nbt_name_server(struct nbt_name *nbt, const char *name) make_nbt_name(nbt, name, NBT_NAME_SERVER); } -struct resolve_context *lp_resolve_context(struct loadparm_context *lp_ctx) -{ - const char **methods = lp_name_resolve_order(lp_ctx); - int i; - struct resolve_context *ret = resolve_context_init(lp_ctx); - - if (ret == NULL) - return NULL; - - for (i = 0; methods != NULL && methods[i] != NULL; i++) { - if (!strcmp(methods[i], "wins")) { - resolve_context_add_wins_method(ret, lp_wins_server_list(lp_ctx)); - } else if (!strcmp(methods[i], "bcast")) { - resolve_context_add_bcast_method(ret, lp_ctx); - } else if (!strcmp(methods[i], "host")) { - resolve_context_add_host_method(ret); - } else { - DEBUG(0, ("Unknown resolve method '%s'\n", methods[i])); - } - } - return ret; -} diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 73cb78c124..9282074aa4 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -26,5 +26,6 @@ typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, struct nbt_name *); typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); #include "libcli/resolve/proto.h" +#include "libcli/resolve/lp_proto.h" #endif /* __RESOLVE_H__ */ diff --git a/source4/libcli/resolve/resolve_lp.c b/source4/libcli/resolve/resolve_lp.c new file mode 100644 index 0000000000..5a506dca8b --- /dev/null +++ b/source4/libcli/resolve/resolve_lp.c @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2007 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/resolve/resolve.h" +#include "param/param.h" + +struct resolve_context *lp_resolve_context(struct loadparm_context *lp_ctx) +{ + const char **methods = lp_name_resolve_order(lp_ctx); + int i; + struct resolve_context *ret = resolve_context_init(lp_ctx); + + if (ret == NULL) + return NULL; + + for (i = 0; methods != NULL && methods[i] != NULL; i++) { + if (!strcmp(methods[i], "wins")) { + resolve_context_add_wins_method(ret, lp_wins_server_list(lp_ctx)); + } else if (!strcmp(methods[i], "bcast")) { + resolve_context_add_bcast_method(ret, lp_ctx); + } else if (!strcmp(methods[i], "host")) { + resolve_context_add_host_method(ret); + } else { + DEBUG(0, ("Unknown resolve method '%s'\n", methods[i])); + } + } + + return ret; +} -- cgit From 68dc2dc526e146dd0ac68d5d68eb55b601282caf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 14:31:01 +0100 Subject: r26399: Use -O option for SWIG (less evil generated code). (This used to be commit 3378b6a559272cb702b52966692bf423f67a2b41) --- source4/libcli/security/security.py | 77 +++++++++----------- source4/libcli/security/security_wrap.c | 120 +++++++++++++++++++++----------- 2 files changed, 112 insertions(+), 85 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py index 6b69251b4a..10b263b27b 100644 --- a/source4/libcli/security/security.py +++ b/source4/libcli/security/security.py @@ -2,7 +2,6 @@ # Version 1.3.33 # # Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. import _security import new @@ -48,6 +47,16 @@ except AttributeError: del types +def _swig_setattr_nondynamic_method(set): + def set_attr(self,name,value): + if (name == "thisown"): return self.this.own(value) + if hasattr(self,name) or (name == "this"): + set(self,name,value) + else: + raise AttributeError("You cannot add attributes to %s" % self) + return set_attr + + SEC_PRIV_SECURITY = _security.SEC_PRIV_SECURITY SEC_PRIV_BACKUP = _security.SEC_PRIV_BACKUP SEC_PRIV_RESTORE = _security.SEC_PRIV_RESTORE @@ -72,63 +81,45 @@ SEC_PRIV_ENABLE_DELEGATION = _security.SEC_PRIV_ENABLE_DELEGATION SEC_PRIV_INTERACTIVE_LOGON = _security.SEC_PRIV_INTERACTIVE_LOGON SEC_PRIV_NETWORK_LOGON = _security.SEC_PRIV_NETWORK_LOGON SEC_PRIV_REMOTE_INTERACTIVE_LOGON = _security.SEC_PRIV_REMOTE_INTERACTIVE_LOGON -class SecurityToken(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, SecurityToken, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, SecurityToken, name) +class SecurityToken(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr def __init__(self, *args, **kwargs): - this = _security.new_SecurityToken(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _security.SecurityToken_swiginit(self,_security.new_SecurityToken(*args, **kwargs)) __swig_destroy__ = _security.delete_SecurityToken - __del__ = lambda self : None; - def is_sid(*args, **kwargs): return _security.SecurityToken_is_sid(*args, **kwargs) - def is_system(*args, **kwargs): return _security.SecurityToken_is_system(*args, **kwargs) - def is_anonymous(*args, **kwargs): return _security.SecurityToken_is_anonymous(*args, **kwargs) - def has_sid(*args, **kwargs): return _security.SecurityToken_has_sid(*args, **kwargs) - def has_builtin_administrators(*args, **kwargs): return _security.SecurityToken_has_builtin_administrators(*args, **kwargs) - def has_nt_authenticated_users(*args, **kwargs): return _security.SecurityToken_has_nt_authenticated_users(*args, **kwargs) - def has_privilege(*args, **kwargs): return _security.SecurityToken_has_privilege(*args, **kwargs) - def set_privilege(*args, **kwargs): return _security.SecurityToken_set_privilege(*args, **kwargs) +SecurityToken.is_sid = new_instancemethod(_security.SecurityToken_is_sid,None,SecurityToken) +SecurityToken.is_system = new_instancemethod(_security.SecurityToken_is_system,None,SecurityToken) +SecurityToken.is_anonymous = new_instancemethod(_security.SecurityToken_is_anonymous,None,SecurityToken) +SecurityToken.has_sid = new_instancemethod(_security.SecurityToken_has_sid,None,SecurityToken) +SecurityToken.has_builtin_administrators = new_instancemethod(_security.SecurityToken_has_builtin_administrators,None,SecurityToken) +SecurityToken.has_nt_authenticated_users = new_instancemethod(_security.SecurityToken_has_nt_authenticated_users,None,SecurityToken) +SecurityToken.has_privilege = new_instancemethod(_security.SecurityToken_has_privilege,None,SecurityToken) +SecurityToken.set_privilege = new_instancemethod(_security.SecurityToken_set_privilege,None,SecurityToken) SecurityToken_swigregister = _security.SecurityToken_swigregister SecurityToken_swigregister(SecurityToken) -class security_descriptor(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, security_descriptor, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, security_descriptor, name) +class security_descriptor(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr def __init__(self, *args, **kwargs): - this = _security.new_security_descriptor(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _security.security_descriptor_swiginit(self,_security.new_security_descriptor(*args, **kwargs)) __swig_destroy__ = _security.delete_security_descriptor - __del__ = lambda self : None; - def sacl_add(*args, **kwargs): return _security.security_descriptor_sacl_add(*args, **kwargs) - def dacl_add(*args, **kwargs): return _security.security_descriptor_dacl_add(*args, **kwargs) - def dacl_del(*args, **kwargs): return _security.security_descriptor_dacl_del(*args, **kwargs) - def sacl_del(*args, **kwargs): return _security.security_descriptor_sacl_del(*args, **kwargs) - def __eq__(*args, **kwargs): return _security.security_descriptor___eq__(*args, **kwargs) +security_descriptor.sacl_add = new_instancemethod(_security.security_descriptor_sacl_add,None,security_descriptor) +security_descriptor.dacl_add = new_instancemethod(_security.security_descriptor_dacl_add,None,security_descriptor) +security_descriptor.dacl_del = new_instancemethod(_security.security_descriptor_dacl_del,None,security_descriptor) +security_descriptor.sacl_del = new_instancemethod(_security.security_descriptor_sacl_del,None,security_descriptor) +security_descriptor.__eq__ = new_instancemethod(_security.security_descriptor___eq__,None,security_descriptor) security_descriptor_swigregister = _security.security_descriptor_swigregister security_descriptor_swigregister(security_descriptor) -class Sid(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, Sid, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, Sid, name) +class Sid(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr def __init__(self, *args, **kwargs): - this = _security.new_Sid(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _security.Sid_swiginit(self,_security.new_Sid(*args, **kwargs)) __swig_destroy__ = _security.delete_Sid - __del__ = lambda self : None; - def __str__(*args, **kwargs): return _security.Sid___str__(*args, **kwargs) - def __eq__(*args, **kwargs): return _security.Sid___eq__(*args, **kwargs) +Sid.__str__ = new_instancemethod(_security.Sid___str__,None,Sid) +Sid.__eq__ = new_instancemethod(_security.Sid___eq__,None,Sid) Sid_swigregister = _security.Sid_swigregister Sid_swigregister(Sid) diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index b9f9157012..633537f951 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -9,7 +9,7 @@ * ----------------------------------------------------------------------------- */ #define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +#define SWIG_PYTHON_NO_BUILD_NONE /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. @@ -2482,6 +2482,19 @@ static swig_module_info swig_module = {swig_types, 14, 0, 0, 0, 0}; # error "This python version requires swig to be run with the '-classic' option" # endif #endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodern' option" +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodernargs' option" +#endif +#ifndef METH_O +# error "This python version requires swig to be run with the '-nofastunpack' option" +#endif +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery /*----------------------------------------------- @(target):= _security.so @@ -2792,7 +2805,7 @@ SWIGINTERN PyObject *_wrap_new_SecurityToken(PyObject *SWIGUNUSEDPARM(self), PyO { arg1 = NULL; } - if (!PyArg_ParseTuple(args,(char *)":new_SecurityToken")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_SecurityToken",0,0,0)) SWIG_fail; result = (security_token *)new_security_token(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_security_token, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -2806,10 +2819,11 @@ SWIGINTERN PyObject *_wrap_delete_SecurityToken(PyObject *SWIGUNUSEDPARM(self), security_token *arg1 = (security_token *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_SecurityToken",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SecurityToken" "', argument " "1"" of type '" "security_token *""'"); } @@ -2863,10 +2877,11 @@ SWIGINTERN PyObject *_wrap_SecurityToken_is_system(PyObject *SWIGUNUSEDPARM(self bool result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_is_system",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_is_system" "', argument " "1"" of type '" "security_token *""'"); } @@ -2885,10 +2900,11 @@ SWIGINTERN PyObject *_wrap_SecurityToken_is_anonymous(PyObject *SWIGUNUSEDPARM(s bool result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_is_anonymous",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_is_anonymous" "', argument " "1"" of type '" "security_token *""'"); } @@ -2941,10 +2957,11 @@ SWIGINTERN PyObject *_wrap_SecurityToken_has_builtin_administrators(PyObject *SW bool result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_has_builtin_administrators",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_has_builtin_administrators" "', argument " "1"" of type '" "security_token *""'"); } @@ -2963,10 +2980,11 @@ SWIGINTERN PyObject *_wrap_SecurityToken_has_nt_authenticated_users(PyObject *SW bool result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:SecurityToken_has_nt_authenticated_users",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SecurityToken_has_nt_authenticated_users" "', argument " "1"" of type '" "security_token *""'"); } @@ -3048,11 +3066,15 @@ fail: SWIGINTERN PyObject *SecurityToken_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_security_token, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *SecurityToken_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_new_security_descriptor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3061,7 +3083,7 @@ SWIGINTERN PyObject *_wrap_new_security_descriptor(PyObject *SWIGUNUSEDPARM(self { arg1 = NULL; } - if (!PyArg_ParseTuple(args,(char *)":new_security_descriptor")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_security_descriptor",0,0,0)) SWIG_fail; result = (security_descriptor *)new_security_descriptor(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_security_descriptor, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3075,10 +3097,11 @@ SWIGINTERN PyObject *_wrap_delete_security_descriptor(PyObject *SWIGUNUSEDPARM(s security_descriptor *arg1 = (security_descriptor *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_security_descriptor",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_descriptor, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_security_descriptor" "', argument " "1"" of type '" "security_descriptor *""'"); } @@ -3292,11 +3315,15 @@ fail: SWIGINTERN PyObject *security_descriptor_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_security_descriptor, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *security_descriptor_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_new_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3334,10 +3361,11 @@ SWIGINTERN PyObject *_wrap_delete_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject * dom_sid *arg1 = (dom_sid *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_Sid",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_dom_sid, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Sid" "', argument " "1"" of type '" "dom_sid *""'"); } @@ -3358,13 +3386,14 @@ SWIGINTERN PyObject *_wrap_Sid___str__(PyObject *SWIGUNUSEDPARM(self), PyObject char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; { arg2 = NULL; } - if (!PyArg_ParseTuple(args,(char *)"O:Sid___str__",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid___str__" "', argument " "1"" of type '" "dom_sid *""'"); } @@ -3413,11 +3442,15 @@ fail: SWIGINTERN PyObject *Sid_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_dom_sid, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *Sid_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_random_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3426,7 +3459,7 @@ SWIGINTERN PyObject *_wrap_random_sid(PyObject *SWIGUNUSEDPARM(self), PyObject * { arg1 = NULL; } - if (!PyArg_ParseTuple(args,(char *)":random_sid")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"random_sid",0,0,0)) SWIG_fail; result = (struct dom_sid *)random_sid(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dom_sid, 0 | 0 ); return resultobj; @@ -3489,31 +3522,34 @@ fail: static PyMethodDef SwigMethods[] = { - { (char *)"new_SecurityToken", _wrap_new_SecurityToken, METH_VARARGS, NULL}, - { (char *)"delete_SecurityToken", _wrap_delete_SecurityToken, METH_VARARGS, NULL}, + { (char *)"new_SecurityToken", (PyCFunction)_wrap_new_SecurityToken, METH_NOARGS, NULL}, + { (char *)"delete_SecurityToken", (PyCFunction)_wrap_delete_SecurityToken, METH_O, NULL}, { (char *)"SecurityToken_is_sid", (PyCFunction) _wrap_SecurityToken_is_sid, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SecurityToken_is_system", _wrap_SecurityToken_is_system, METH_VARARGS, NULL}, - { (char *)"SecurityToken_is_anonymous", _wrap_SecurityToken_is_anonymous, METH_VARARGS, NULL}, + { (char *)"SecurityToken_is_system", (PyCFunction)_wrap_SecurityToken_is_system, METH_O, NULL}, + { (char *)"SecurityToken_is_anonymous", (PyCFunction)_wrap_SecurityToken_is_anonymous, METH_O, NULL}, { (char *)"SecurityToken_has_sid", (PyCFunction) _wrap_SecurityToken_has_sid, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SecurityToken_has_builtin_administrators", _wrap_SecurityToken_has_builtin_administrators, METH_VARARGS, NULL}, - { (char *)"SecurityToken_has_nt_authenticated_users", _wrap_SecurityToken_has_nt_authenticated_users, METH_VARARGS, NULL}, + { (char *)"SecurityToken_has_builtin_administrators", (PyCFunction)_wrap_SecurityToken_has_builtin_administrators, METH_O, NULL}, + { (char *)"SecurityToken_has_nt_authenticated_users", (PyCFunction)_wrap_SecurityToken_has_nt_authenticated_users, METH_O, NULL}, { (char *)"SecurityToken_has_privilege", (PyCFunction) _wrap_SecurityToken_has_privilege, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"SecurityToken_set_privilege", (PyCFunction) _wrap_SecurityToken_set_privilege, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"SecurityToken_swigregister", SecurityToken_swigregister, METH_VARARGS, NULL}, - { (char *)"new_security_descriptor", _wrap_new_security_descriptor, METH_VARARGS, NULL}, - { (char *)"delete_security_descriptor", _wrap_delete_security_descriptor, METH_VARARGS, NULL}, + { (char *)"SecurityToken_swiginit", SecurityToken_swiginit, METH_VARARGS, NULL}, + { (char *)"new_security_descriptor", (PyCFunction)_wrap_new_security_descriptor, METH_NOARGS, NULL}, + { (char *)"delete_security_descriptor", (PyCFunction)_wrap_delete_security_descriptor, METH_O, NULL}, { (char *)"security_descriptor_sacl_add", (PyCFunction) _wrap_security_descriptor_sacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_dacl_add", (PyCFunction) _wrap_security_descriptor_dacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_dacl_del", (PyCFunction) _wrap_security_descriptor_dacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_sacl_del", (PyCFunction) _wrap_security_descriptor_sacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor___eq__", (PyCFunction) _wrap_security_descriptor___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_swigregister", security_descriptor_swigregister, METH_VARARGS, NULL}, + { (char *)"security_descriptor_swiginit", security_descriptor_swiginit, METH_VARARGS, NULL}, { (char *)"new_Sid", (PyCFunction) _wrap_new_Sid, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_Sid", _wrap_delete_Sid, METH_VARARGS, NULL}, - { (char *)"Sid___str__", _wrap_Sid___str__, METH_VARARGS, NULL}, + { (char *)"delete_Sid", (PyCFunction)_wrap_delete_Sid, METH_O, NULL}, + { (char *)"Sid___str__", (PyCFunction)_wrap_Sid___str__, METH_O, NULL}, { (char *)"Sid___eq__", (PyCFunction) _wrap_Sid___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Sid_swigregister", Sid_swigregister, METH_VARARGS, NULL}, - { (char *)"random_sid", _wrap_random_sid, METH_VARARGS, NULL}, + { (char *)"Sid_swiginit", Sid_swiginit, METH_VARARGS, NULL}, + { (char *)"random_sid", (PyCFunction)_wrap_random_sid, METH_NOARGS, NULL}, { (char *)"privilege_name", (PyCFunction) _wrap_privilege_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"privilege_id", (PyCFunction) _wrap_privilege_id, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } -- cgit From 6f2252dace1629d7b5c5637b103caa28d2c89b07 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 22:23:14 +0100 Subject: r26401: Don't cache interfaces context in libnetif. (This used to be commit 9f975417cc66bfd4589da38bfd23731dbe0e6153) --- source4/libcli/resolve/bcast.c | 15 ++++++++++----- source4/libcli/resolve/nbtlist.c | 4 +++- source4/libcli/resolve/resolve.h | 1 + source4/libcli/wrepl/winsrepl.c | 4 +++- 4 files changed, 17 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 1733ca9d2e..d1f3d65faf 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -33,17 +33,19 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, void *userdata, struct nbt_name *name) { - struct loadparm_context *lp_ctx = userdata; - int num_interfaces = iface_count(lp_ctx); + int num_interfaces; const char **address_list; struct composite_context *c; int i, count=0; + struct interface *ifaces = userdata; + + num_interfaces = iface_count(ifaces); address_list = talloc_array(mem_ctx, const char *, num_interfaces+1); if (address_list == NULL) return NULL; for (i=0;iprivate_data, struct nbtlist_state); struct nbt_name_query *q; + struct interface *ifaces; int i; for (i=0;inum_queries;i++) { @@ -75,9 +76,10 @@ static void nbtlist_handler(struct nbt_name_request *req) } /* favor a local address if possible */ + load_interfaces(lp_interfaces(global_loadparm), &ifaces); state->reply_addr = NULL; for (i=0;iout.num_addrs;i++) { - if (iface_is_local(global_loadparm, q->out.reply_addrs[i])) { + if (iface_is_local(ifaces, q->out.reply_addrs[i])) { state->reply_addr = talloc_steal(state, q->out.reply_addrs[i]); break; diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 9282074aa4..79b91dc836 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -26,6 +26,7 @@ typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, struct nbt_name *); typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); #include "libcli/resolve/proto.h" +struct interface; #include "libcli/resolve/lp_proto.h" #endif /* __RESOLVE_H__ */ diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 92543be487..15dc98f675 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -333,7 +333,9 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, state->wrepl_socket = wrepl_socket; if (!our_ip) { - our_ip = iface_best_ip(global_loadparm, peer_ip); + struct interface *ifaces; + load_interfaces(lp_interfaces(global_loadparm), &ifaces); + our_ip = iface_best_ip(ifaces, peer_ip); } us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, -- cgit From 70f1f33af8e6e82506d0ee9ff6cc7e0923a7d0a1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 22:23:20 +0100 Subject: r26402: Require a talloc context in libnetif. (This used to be commit a35e51871bbf1ab33fc316fa59e597b722769c50) --- source4/libcli/resolve/bcast.c | 2 +- source4/libcli/resolve/nbtlist.c | 3 ++- source4/libcli/wrepl/winsrepl.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index d1f3d65faf..1dd9328760 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -86,7 +86,7 @@ NTSTATUS resolve_name_bcast(struct nbt_name *name, bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct loadparm_context *lp_ctx) { struct interface *ifaces; - load_interfaces(lp_interfaces(lp_ctx), &ifaces); + load_interfaces(ctx, lp_interfaces(lp_ctx), &ifaces); return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, ifaces); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 6c12fe706b..595743e693 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -76,7 +76,7 @@ static void nbtlist_handler(struct nbt_name_request *req) } /* favor a local address if possible */ - load_interfaces(lp_interfaces(global_loadparm), &ifaces); + load_interfaces(NULL, lp_interfaces(global_loadparm), &ifaces); state->reply_addr = NULL; for (i=0;iout.num_addrs;i++) { if (iface_is_local(ifaces, q->out.reply_addrs[i])) { @@ -85,6 +85,7 @@ static void nbtlist_handler(struct nbt_name_request *req) break; } } + talloc_free(ifaces); if (state->reply_addr == NULL) { state->reply_addr = talloc_steal(state, diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 15dc98f675..63b0a60f6c 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -334,7 +334,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, if (!our_ip) { struct interface *ifaces; - load_interfaces(lp_interfaces(global_loadparm), &ifaces); + load_interfaces(state, lp_interfaces(global_loadparm), &ifaces); our_ip = iface_best_ip(ifaces, peer_ip); } -- cgit From 33582dffcc2d348dc042edfdcccee7500b21d928 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 12 Dec 2007 02:15:20 +0100 Subject: r26408: Remove use of global_loadparm. (This used to be commit f933b4362124bfdd25544b4e27992d9ca4405848) --- source4/libcli/finddcs.c | 6 ++++-- source4/libcli/nbt/libnbt.h | 4 ++++ source4/libcli/nbt/namerefresh.c | 6 ++++-- source4/libcli/nbt/nameregister.c | 8 +++++--- source4/libcli/nbt/namerelease.c | 2 +- source4/libcli/nbt/nbtsocket.c | 2 +- 6 files changed, 19 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 624f6cd630..4b7f2dce8c 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -43,6 +43,7 @@ struct finddcs_state { int num_dcs; struct nbt_dc_name *dcs; + uint16_t nbt_port; }; static void finddcs_name_resolved(struct composite_context *ctx); @@ -82,6 +83,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, state->ctx = c; + state->nbt_port = lp_nbt_port(global_loadparm); state->my_netbios_name = talloc_strdup(state, my_netbios_name); state->domain_name = talloc_strdup(state, domain_name); if (composite_nomem(state->domain_name, c)) return c; @@ -177,7 +179,7 @@ static void finddcs_getdc_replied(struct irpc_request *ireq) composite_done(state->ctx); } -/* The GetDC request might not be availible (such as occours when the +/* The GetDC request might not be available (such as occours when the * NBT server is down). Fallback to a node status. It is the best * hope we have... */ static void fallback_node_status(struct finddcs_state *state) @@ -189,7 +191,7 @@ static void fallback_node_status(struct finddcs_state *state) state->node_status.in.name.type = NBT_NAME_CLIENT; state->node_status.in.name.scope = NULL; state->node_status.in.dest_addr = state->dcs[0].address; - state->node_status.in.dest_port = lp_nbt_port(global_loadparm); + state->node_status.in.dest_port = state->nbt_port; state->node_status.in.timeout = 1; state->node_status.in.retries = 2; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 524391917d..c95d99db54 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -186,6 +186,7 @@ struct nbt_name_register_bcast { struct { struct nbt_name name; const char *dest_addr; + uint16_t dest_port; const char *address; uint16_t nb_flags; uint32_t ttl; @@ -199,6 +200,7 @@ struct nbt_name_register_wins { struct { struct nbt_name name; const char **wins_servers; + uint16_t wins_port; const char **addresses; uint16_t nb_flags; uint32_t ttl; @@ -238,6 +240,7 @@ struct nbt_name_refresh_wins { struct { struct nbt_name name; const char **wins_servers; + uint16_t wins_port; const char **addresses; uint16_t nb_flags; uint32_t ttl; @@ -254,6 +257,7 @@ struct nbt_name_release { struct { struct nbt_name name; const char *dest_addr; + uint16_t dest_port; const char *address; uint16_t nb_flags; bool broadcast; diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 8408b4e3c3..1157c110a1 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -146,6 +146,7 @@ struct refresh_wins_state { struct nbt_name_socket *nbtsock; struct nbt_name_refresh *io; const char **wins_servers; + uint16_t wins_port; const char **addresses; int address_idx; struct nbt_name_request *req; @@ -174,7 +175,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) goto done; } state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = lp_nbt_port(global_loadparm); + state->io->in.dest_port = state->wins_port; state->io->in.address = state->addresses[0]; state->req = nbt_name_refresh_send(state->nbtsock, state->io); if (state->req == NULL) { @@ -231,6 +232,7 @@ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbt state->io = talloc(state, struct nbt_name_refresh); if (state->io == NULL) goto failed; + state->wins_port = io->in.wins_port; state->wins_servers = str_list_copy(state, io->in.wins_servers); if (state->wins_servers == NULL || state->wins_servers[0] == NULL) goto failed; @@ -241,7 +243,7 @@ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbt state->io->in.name = io->in.name; state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = lp_nbt_port(global_loadparm); + state->io->in.dest_port = state->wins_port; state->io->in.address = io->in.addresses[0]; state->io->in.nb_flags = io->in.nb_flags; state->io->in.broadcast = false; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 9389981647..3d7ab7f72f 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -224,7 +224,7 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n state->io->in.name = io->in.name; state->io->in.dest_addr = io->in.dest_addr; - state->io->in.dest_port = lp_nbt_port(global_loadparm); + state->io->in.dest_port = io->in.dest_port; state->io->in.address = io->in.address; state->io->in.nb_flags = io->in.nb_flags; state->io->in.register_demand = false; @@ -284,6 +284,7 @@ struct register_wins_state { struct nbt_name_socket *nbtsock; struct nbt_name_register *io; const char **wins_servers; + uint16_t wins_port; const char **addresses; int address_idx; struct nbt_name_request *req; @@ -312,7 +313,7 @@ static void name_register_wins_handler(struct nbt_name_request *req) goto done; } state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = lp_nbt_port(global_loadparm); + state->io->in.dest_port = state->wins_port; state->io->in.address = state->addresses[0]; state->req = nbt_name_register_send(state->nbtsock, state->io); if (state->req == NULL) { @@ -369,6 +370,7 @@ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nb state->io = talloc(state, struct nbt_name_register); if (state->io == NULL) goto failed; + state->wins_port = lp_nbt_port(global_loadparm); state->wins_servers = str_list_copy(state, io->in.wins_servers); if (state->wins_servers == NULL || state->wins_servers[0] == NULL) goto failed; @@ -379,7 +381,7 @@ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nb state->io->in.name = io->in.name; state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = lp_nbt_port(global_loadparm); + state->io->in.dest_port = state->wins_port; state->io->in.address = io->in.addresses[0]; state->io->in.nb_flags = io->in.nb_flags; state->io->in.broadcast = false; diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index 1b3c9ae17e..d735892516 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -67,7 +67,7 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, talloc_strdup(packet->additional, io->in.address); dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, lp_nbt_port(global_loadparm)); + io->in.dest_addr, io->in.dest_port); if (dest == NULL) goto failed; req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, false); diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1f34b4583b..743f2b0f19 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -150,7 +150,7 @@ static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event -/* +/** handle recv events on a nbt name socket */ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) -- cgit From 4b0199a5493ea2b88558cc40871e63c1dc8dbb56 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 12 Dec 2007 02:15:29 +0100 Subject: r26409: Pass smb ports along. (This used to be commit 2833f320de1f1fd39c710ad0a61c3fa1bb1df31f) --- source4/libcli/cliconnect.c | 8 ++++--- source4/libcli/nbt/nameregister.c | 2 +- source4/libcli/raw/clisocket.c | 36 +++++++++------------------- source4/libcli/raw/clitree.c | 4 ++-- source4/libcli/smb2/connect.c | 5 ++-- source4/libcli/smb_composite/connect.c | 3 ++- source4/libcli/smb_composite/fetchfile.c | 2 +- source4/libcli/smb_composite/fsinfo.c | 2 +- source4/libcli/smb_composite/smb_composite.h | 6 ++--- 9 files changed, 29 insertions(+), 39 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index a170024def..7ec914e831 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -31,12 +31,12 @@ wrapper around smbcli_sock_connect() */ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, - struct resolve_context *resolve_ctx, + const char **ports, struct resolve_context *resolve_ctx, int max_xmit, int max_mux) { struct smbcli_socket *sock; - sock = smbcli_sock_connect_byname(server, 0, NULL, resolve_ctx, + sock = smbcli_sock_connect_byname(server, ports, NULL, resolve_ctx, NULL); if (sock == NULL) return false; @@ -136,6 +136,7 @@ NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_state **ret_cli, const char *host, + const char **ports, const char *sharename, const char *devtype, struct cli_credentials *credentials, @@ -147,7 +148,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, *ret_cli = NULL; status = smbcli_tree_full_connection(parent_ctx, - &tree, host, 0, sharename, devtype, + &tree, host, ports, + sharename, devtype, credentials, ev); if (!NT_STATUS_IS_OK(status)) { goto done; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 3d7ab7f72f..6667564664 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -370,7 +370,7 @@ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nb state->io = talloc(state, struct nbt_name_register); if (state->io == NULL) goto failed; - state->wins_port = lp_nbt_port(global_loadparm); + state->wins_port = io->in.wins_port; state->wins_servers = str_list_copy(state, io->in.wins_servers); if (state->wins_servers == NULL || state->wins_servers[0] == NULL) goto failed; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index c09104e256..9732ab1638 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -45,12 +45,13 @@ static void smbcli_sock_connect_recv_conn(struct composite_context *ctx); struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, const char *host_addr, - int port, + const char **ports, const char *host_name, struct event_context *event_ctx) { struct composite_context *result, *ctx; struct sock_connect_state *state; + int i; result = talloc_zero(mem_ctx, struct composite_context); if (result == NULL) goto failed; @@ -72,26 +73,11 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, state->host_name = talloc_strdup(state, host_name); if (state->host_name == NULL) goto failed; - if (port == 0) { - const char **ports = lp_smb_ports(global_loadparm); - int i; - - for (i=0;ports[i];i++) /* noop */ ; - if (i == 0) { - DEBUG(3, ("no smb ports defined\n")); - goto failed; - } - state->num_ports = i; - state->ports = talloc_array(state, uint16_t, i); - if (state->ports == NULL) goto failed; - for (i=0;ports[i];i++) { - state->ports[i] = atoi(ports[i]); - } - } else { - state->ports = talloc_array(state, uint16_t, 1); - if (state->ports == NULL) goto failed; - state->num_ports = 1; - state->ports[0] = port; + state->num_ports = str_list_length(ports); + state->ports = talloc_array(state, uint16_t, state->num_ports); + if (state->ports == NULL) goto failed; + for (i=0;ports[i];i++) { + state->ports[i] = atoi(ports[i]); } ctx = socket_connect_multi_send(state, host_addr, @@ -164,13 +150,13 @@ NTSTATUS smbcli_sock_connect_recv(struct composite_context *c, sync version of the function */ NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx, - const char *host_addr, int port, + const char *host_addr, const char **ports, const char *host_name, struct event_context *event_ctx, struct smbcli_socket **result) { struct composite_context *c = - smbcli_sock_connect_send(mem_ctx, host_addr, port, host_name, + smbcli_sock_connect_send(mem_ctx, host_addr, ports, host_name, event_ctx); return smbcli_sock_connect_recv(c, mem_ctx, result); } @@ -198,7 +184,7 @@ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) /**************************************************************************** resolve a hostname and connect ****************************************************************************/ -struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, +struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, TALLOC_CTX *mem_ctx, struct resolve_context *resolve_ctx, struct event_context *event_ctx) @@ -247,7 +233,7 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, return NULL; } - status = smbcli_sock_connect(mem_ctx, address, port, name, event_ctx, + status = smbcli_sock_connect(mem_ctx, address, ports, name, event_ctx, &result); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 54f8ac95a4..890d5470da 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -171,7 +171,7 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) */ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_tree **ret_tree, - const char *dest_host, int port, + const char *dest_host, const char **dest_ports, const char *service, const char *service_type, struct cli_credentials *credentials, struct event_context *ev) @@ -184,7 +184,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, } io.in.dest_host = dest_host; - io.in.port = port; + io.in.dest_ports = dest_ports; io.in.called_name = strupper_talloc(tmp_ctx, dest_host); io.in.service = service; io.in.service_type = service_type; diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 8b75e125b0..4d250fdded 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -147,11 +147,12 @@ static void continue_resolve(struct composite_context *creq) struct smb2_connect_state *state = talloc_get_type(c->private_data, struct smb2_connect_state); const char *addr; - + const char *ports[2] = { "445", NULL }; + c->status = resolve_name_recv(creq, state, &addr); if (!composite_is_ok(c)) return; - creq = smbcli_sock_connect_send(state, addr, 445, state->host, c->event_ctx); + creq = smbcli_sock_connect_send(state, addr, ports, state->host, c->event_ctx); composite_continue(c, creq, continue_socket, c); } diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 1a8262c76a..fafd3b0173 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -360,7 +360,8 @@ static NTSTATUS connect_resolve(struct composite_context *c, status = resolve_name_recv(state->creq, state, &address); NT_STATUS_NOT_OK_RETURN(status); - state->creq = smbcli_sock_connect_send(state, address, io->in.port, + state->creq = smbcli_sock_connect_send(state, address, + io->in.dest_ports, io->in.dest_host, c->event_ctx); NT_STATUS_HAVE_NO_MEMORY(state->creq); diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 2dbaff5a66..a4f73ffd70 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -137,7 +137,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->io = io; state->connect->in.dest_host = io->in.dest_host; - state->connect->in.port = io->in.port; + state->connect->in.dest_ports = io->in.ports; state->connect->in.called_name = io->in.called_name; state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index faf3723539..f37213e2f9 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -143,7 +143,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, if (state->connect == NULL) goto failed; state->connect->in.dest_host = io->in.dest_host; - state->connect->in.port = io->in.port; + state->connect->in.dest_ports = io->in.dest_ports; state->connect->in.called_name = io->in.called_name; state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 617daaf442..a3188c4fe2 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -45,7 +45,7 @@ struct smb_composite_loadfile { struct smb_composite_fetchfile { struct { const char *dest_host; - int port; + const char **ports; const char *called_name; const char *service; const char *service_type; @@ -84,7 +84,7 @@ struct smb_composite_savefile { struct smb_composite_connect { struct { const char *dest_host; - int port; + const char **dest_ports; const char *called_name; const char *service; const char *service_type; @@ -121,7 +121,7 @@ struct smb_composite_sesssetup { struct smb_composite_fsinfo { struct { const char *dest_host; - int port; + const char **dest_ports; const char *called_name; const char *service; const char *service_type; -- cgit From aa32619c5c910b9f5989f44de21621db5ef7c357 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 11:41:47 +0100 Subject: r26426: Remove uses of global_loadparm. (This used to be commit e1d177c8c1101965479f7ade2270490cd6fae4f2) --- source4/libcli/resolve/nbtlist.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 595743e693..21792a665a 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -38,6 +38,7 @@ struct nbtlist_state { struct nbt_name_request **queries; struct nbt_name_query *io_queries; const char *reply_addr; + struct interface *ifaces; }; /* @@ -49,7 +50,6 @@ static void nbtlist_handler(struct nbt_name_request *req) struct composite_context); struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state); struct nbt_name_query *q; - struct interface *ifaces; int i; for (i=0;inum_queries;i++) { @@ -76,16 +76,14 @@ static void nbtlist_handler(struct nbt_name_request *req) } /* favor a local address if possible */ - load_interfaces(NULL, lp_interfaces(global_loadparm), &ifaces); state->reply_addr = NULL; for (i=0;iout.num_addrs;i++) { - if (iface_is_local(ifaces, q->out.reply_addrs[i])) { + if (iface_is_local(state->ifaces, q->out.reply_addrs[i])) { state->reply_addr = talloc_steal(state, q->out.reply_addrs[i]); break; } } - talloc_free(ifaces); if (state->reply_addr == NULL) { state->reply_addr = talloc_steal(state, @@ -129,6 +127,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state->name.scope, c)) return c; } + load_interfaces(state, lp_interfaces(global_loadparm), &state->ifaces); + /* * we can't push long names on the wire, * so bail out here to give a useful error message @@ -200,7 +200,8 @@ NTSTATUS resolve_name_nbtlist(struct nbt_name *name, bool broadcast, bool wins_lookup, const char **reply_addr) { - struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL, name, address_list, + struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL, + name, address_list, broadcast, wins_lookup); return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } -- cgit From d891c0c74a03d797aed1c5ac0329fd9d1d78da63 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:09 +0100 Subject: r26429: Avoid use of global_smb_iconv_convenience. (This used to be commit d37136b7abfbba75ef2e5ab855eb3382b9648b8c) --- source4/libcli/auth/smbencrypt.c | 13 +++++++------ source4/libcli/raw/rawfileinfo.c | 3 ++- source4/libcli/raw/rawrequest.c | 13 +++++++------ source4/libcli/smb2/request.c | 5 +++-- 4 files changed, 19 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index ccad1058bf..26b78d25ef 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -28,6 +28,7 @@ #include "lib/crypto/crypto.h" #include "libcli/auth/libcli_auth.h" #include "pstring.h" +#include "param/param.h" /* This implements the X/Open SMB password encryption @@ -67,7 +68,7 @@ _PUBLIC_ bool E_md4hash(const char *passwd, uint8_t p16[16]) int len; void *wpwd; - len = push_ucs2_talloc(NULL, global_smb_iconv_convenience, &wpwd, passwd); + len = push_ucs2_talloc(NULL, lp_iconv_convenience(global_loadparm), &wpwd, passwd); if (len < 2) { /* We don't want to return fixed data, as most callers * don't check */ @@ -97,7 +98,7 @@ _PUBLIC_ bool E_deshash(const char *passwd, uint8_t p16[16]) ZERO_STRUCT(dospwd); /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_string(global_smb_iconv_convenience, dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); + push_string(lp_iconv_convenience(global_loadparm), dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const uint8_t *)dospwd, p16); @@ -150,14 +151,14 @@ bool ntv2_owf_gen(const uint8_t owf[16], } } - user_byte_len = push_ucs2_talloc(mem_ctx, global_smb_iconv_convenience, &user, user_in); + user_byte_len = push_ucs2_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), &user, user_in); if (user_byte_len == (ssize_t)-1) { DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); return false; } - domain_byte_len = push_ucs2_talloc(mem_ctx, global_smb_iconv_convenience, &domain, domain_in); + domain_byte_len = push_ucs2_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), &domain, domain_in); if (domain_byte_len == (ssize_t)-1) { DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); @@ -468,7 +469,7 @@ bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag /* the incoming buffer can be any alignment. */ string_flags |= STR_NOALIGN; - new_pw_len = push_string(global_smb_iconv_convenience, new_pw, + new_pw_len = push_string(lp_iconv_convenience(global_loadparm), new_pw, password, sizeof(new_pw), string_flags); @@ -521,7 +522,7 @@ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, } /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(global_smb_iconv_convenience, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + *new_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, string_flags); #ifdef DEBUG_PASSWORD diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 972ae7f5e1..9827217a04 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "librpc/gen_ndr/ndr_security.h" +#include "param/param.h" /* local macros to make the code more readable */ #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \ @@ -62,7 +63,7 @@ NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx, return NT_STATUS_INFO_LENGTH_MISMATCH; } size = convert_string_talloc(io->streams, - global_smb_iconv_convenience, + lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, blob.data+ofs+24, nlen, &vstr); if (size == -1) { diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 43c984721b..e7dffaf054 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -26,6 +26,7 @@ #include "libcli/raw/libcliraw.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" +#include "param/param.h" /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 0 @@ -418,7 +419,7 @@ size_t smbcli_req_append_string(struct smbcli_request *req, const char *str, uin smbcli_req_grow_allocation(req, len + req->out.data_size); - len = push_string(global_smb_iconv_convenience, req->out.data + req->out.data_size, str, len, flags); + len = push_string(lp_iconv_convenience(global_loadparm), req->out.data + req->out.data_size, str, len, flags); smbcli_req_grow_data(req, len + req->out.data_size); @@ -574,7 +575,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c return 0; } - ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest); + ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)dest); if (ret == -1) { *dest = NULL; return 0; @@ -616,7 +617,7 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, src_len2++; } - ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_DOS, CH_UNIX, src, src_len2, (void **)dest); + ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)dest); if (ret == -1) { *dest = NULL; @@ -769,7 +770,7 @@ size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx, src_len2 = utf16_len_n(src, src_len); - ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); + ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; return 0; @@ -815,7 +816,7 @@ static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx, src_len2++; } - ret = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); + ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; @@ -965,7 +966,7 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, return 0; } - len = push_string(global_smb_iconv_convenience, blob->data + blob->length, str, max_len, flags); + len = push_string(lp_iconv_convenience(global_loadparm), blob->data + blob->length, str, max_len, flags); blob->length += len; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 5a7534f906..73c74dcfeb 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -26,6 +26,7 @@ #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "libcli/smb2/smb2_calls.h" +#include "param/param.h" /* initialise a smb2 request @@ -579,7 +580,7 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me return NT_STATUS_OK; } - size = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, + size = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); (*str) = (char *)vstr; @@ -604,7 +605,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } - size = convert_string_talloc(buf->buffer, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, + size = convert_string_talloc(buf->buffer, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; -- cgit From 61873ce94c172c801a4831de5550a8e0fe54c5f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:23 +0100 Subject: r26431: Require ndr_push creators to specify a iconv_convenience context. (This used to be commit 7352206f4450fdf881b95bda064cedd9d2477e4c) --- source4/libcli/raw/rawacl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 0f2fdb60af..e7747de94c 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "librpc/gen_ndr/ndr_security.h" +#include "param/param.h" /**************************************************************************** fetch file ACL (async send) @@ -134,7 +135,7 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, nt.in.params.data = params; nt.in.params.length = 8; - ndr = ndr_push_init_ctx(NULL); + ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm)); if (!ndr) return NULL; ndr_err = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->set_secdesc.in.sd); -- cgit From d1e716cf4331bf09cfe15a6634bc5887aff81d20 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:27 +0100 Subject: r26432: Require ndr_pull users to specify iconv_convenience. (This used to be commit 28b1d36551b75241c1cf9fca5d74f45a6dc884ab) --- source4/libcli/raw/rawacl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index e7747de94c..9d2068f35f 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -77,7 +77,8 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, nt.out.data.length = IVAL(nt.out.params.data, 0); - ndr = ndr_pull_init_blob(&nt.out.data, mem_ctx); + ndr = ndr_pull_init_blob(&nt.out.data, mem_ctx, + lp_iconv_convenience(global_loadparm)); if (!ndr) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 70ccac0f05067c89bbf1503a614d09e3fd429110 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:37 +0100 Subject: r26435: Remove global_loadparm instance. (This used to be commit 66fd8d480bdfeb1c95da8843da3d18abe3f997e1) --- source4/libcli/finddcs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 4b7f2dce8c..606809751e 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -28,7 +28,6 @@ #include "libcli/libcli.h" #include "libcli/resolve/resolve.h" #include "libcli/finddcs.h" -#include "param/param.h" struct finddcs_state { struct composite_context *ctx; @@ -63,6 +62,7 @@ static void fallback_node_status_replied(struct nbt_name_request *name_req); struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, const char *my_netbios_name, + uint16_t nbt_port, const char *domain_name, int name_type, struct dom_sid *domain_sid, @@ -83,7 +83,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, state->ctx = c; - state->nbt_port = lp_nbt_port(global_loadparm); + state->nbt_port = nbt_port; state->my_netbios_name = talloc_strdup(state, my_netbios_name); state->domain_name = talloc_strdup(state, domain_name); if (composite_nomem(state->domain_name, c)) return c; @@ -250,6 +250,7 @@ NTSTATUS finddcs_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, NTSTATUS finddcs(TALLOC_CTX *mem_ctx, const char *my_netbios_name, + uint16_t nbt_port, const char *domain_name, int name_type, struct dom_sid *domain_sid, struct resolve_context *resolve_ctx, @@ -259,6 +260,7 @@ NTSTATUS finddcs(TALLOC_CTX *mem_ctx, { struct composite_context *c = finddcs_send(mem_ctx, my_netbios_name, + nbt_port, domain_name, name_type, domain_sid, resolve_ctx, event_ctx, msg_ctx); -- cgit From e8f46760e0134c45cd2b6b27aef60622c4bf58fa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:44 +0100 Subject: r26437: remove another use of global_loadparm. (This used to be commit 703f17bc0986775bf3fe489eb5c876937dabaa9d) --- source4/libcli/resolve/bcast.c | 35 +++++++++++++++++++++++++++-------- source4/libcli/resolve/nbtlist.c | 9 +++++++-- source4/libcli/resolve/resolve_lp.c | 4 ++-- source4/libcli/resolve/wins.c | 20 ++++++++++++++++++-- 4 files changed, 54 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 1dd9328760..c8d4ab2df3 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -4,6 +4,7 @@ broadcast name resolution module Copyright (C) Andrew Tridgell 2005 + Copyright (C) Jelmer Vernooij 2007 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 @@ -25,6 +26,11 @@ #include "lib/socket/netif.h" #include "param/param.h" +struct resolve_bcast_data { + struct interface *ifaces; + uint16_t nbt_port; +}; + /** broadcast name resolution method - async send */ @@ -37,15 +43,15 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, const char **address_list; struct composite_context *c; int i, count=0; - struct interface *ifaces = userdata; + struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_count(data->ifaces); address_list = talloc_array(mem_ctx, const char *, num_interfaces+1); if (address_list == NULL) return NULL; for (i=0;iifaces, i); if (bcast == NULL) continue; address_list[count] = talloc_strdup(address_list, bcast); if (address_list[count] == NULL) { @@ -56,7 +62,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, } address_list[count] = NULL; - c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, true, false); + c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, data->ifaces, data->nbt_port, true, false); talloc_free(address_list); return c; @@ -77,16 +83,29 @@ NTSTATUS resolve_name_bcast_recv(struct composite_context *c, NTSTATUS resolve_name_bcast(struct nbt_name *name, TALLOC_CTX *mem_ctx, struct interface *ifaces, + uint16_t nbt_port, const char **reply_addr) { - struct composite_context *c = resolve_name_bcast_send(mem_ctx, NULL, ifaces, name); + struct resolve_bcast_data *data = talloc(mem_ctx, struct resolve_bcast_data); + struct composite_context *c; + data->ifaces = talloc_reference(data, ifaces); + data->nbt_port = nbt_port; + + c = resolve_name_bcast_send(mem_ctx, NULL, data, name); return resolve_name_bcast_recv(c, mem_ctx, reply_addr); } -bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct loadparm_context *lp_ctx) +bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port) +{ + struct resolve_bcast_data *data = talloc(ctx, struct resolve_bcast_data); + data->ifaces = ifaces; + data->nbt_port = nbt_port; + return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, data); +} + +bool resolve_context_add_bcast_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx) { struct interface *ifaces; load_interfaces(ctx, lp_interfaces(lp_ctx), &ifaces); - return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, - ifaces); + return resolve_context_add_bcast_method(ctx, ifaces, lp_nbt_port(lp_ctx)); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 21792a665a..e1452c09d2 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -100,6 +100,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct nbt_name *name, const char **address_list, + struct interface *ifaces, + uint16_t nbt_port, bool broadcast, bool wins_lookup) { @@ -127,7 +129,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state->name.scope, c)) return c; } - load_interfaces(state, lp_interfaces(global_loadparm), &state->ifaces); + state->ifaces = talloc_reference(state, ifaces); /* * we can't push long names on the wire, @@ -154,7 +156,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, for (i=0;inum_queries;i++) { state->io_queries[i].in.name = state->name; state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); - state->io_queries[i].in.dest_port = lp_nbt_port(global_loadparm); + state->io_queries[i].in.dest_port = nbt_port; if (composite_nomem(state->io_queries[i].in.dest_addr, c)) return c; state->io_queries[i].in.broadcast = broadcast; @@ -197,11 +199,14 @@ NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c, NTSTATUS resolve_name_nbtlist(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **address_list, + struct interface *ifaces, + uint16_t nbt_port, bool broadcast, bool wins_lookup, const char **reply_addr) { struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL, name, address_list, + ifaces, nbt_port, broadcast, wins_lookup); return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/resolve_lp.c b/source4/libcli/resolve/resolve_lp.c index 5a506dca8b..b41e2b98d8 100644 --- a/source4/libcli/resolve/resolve_lp.c +++ b/source4/libcli/resolve/resolve_lp.c @@ -32,9 +32,9 @@ struct resolve_context *lp_resolve_context(struct loadparm_context *lp_ctx) for (i = 0; methods != NULL && methods[i] != NULL; i++) { if (!strcmp(methods[i], "wins")) { - resolve_context_add_wins_method(ret, lp_wins_server_list(lp_ctx)); + resolve_context_add_wins_method_lp(ret, lp_ctx); } else if (!strcmp(methods[i], "bcast")) { - resolve_context_add_bcast_method(ret, lp_ctx); + resolve_context_add_bcast_method_lp(ret, lp_ctx); } else if (!strcmp(methods[i], "host")) { resolve_context_add_host_method(ret); } else { diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 73b9413eb4..78624ad81a 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -23,9 +23,12 @@ #include "libcli/nbt/libnbt.h" #include "libcli/resolve/resolve.h" #include "param/param.h" +#include "lib/socket/netif.h" struct resolve_wins_data { const char **address_list; + struct interface *ifaces; + uint16_t nbt_port; }; /** @@ -39,7 +42,7 @@ struct composite_context *resolve_name_wins_send( { struct resolve_wins_data *wins_data = talloc_get_type(userdata, struct resolve_wins_data); if (wins_data->address_list == NULL) return NULL; - return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, false, true); + return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, wins_data->ifaces, wins_data->nbt_port, false, true); } /* @@ -57,19 +60,32 @@ NTSTATUS resolve_name_wins_recv(struct composite_context *c, NTSTATUS resolve_name_wins(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **address_list, + struct interface *ifaces, + uint16_t nbt_port, const char **reply_addr) { struct composite_context *c; struct resolve_wins_data *wins_data = talloc(mem_ctx, struct resolve_wins_data); wins_data->address_list = address_list; + wins_data->ifaces = ifaces; + wins_data->nbt_port = nbt_port; c = resolve_name_wins_send(mem_ctx, NULL, wins_data, name); return resolve_name_wins_recv(c, mem_ctx, reply_addr); } -bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list) +bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port) { struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data); wins_data->address_list = str_list_copy(wins_data, address_list); + wins_data->ifaces = talloc_reference(wins_data, ifaces); + wins_data->nbt_port = nbt_port; return resolve_context_add_method(ctx, resolve_name_wins_send, resolve_name_wins_recv, wins_data); } + +bool resolve_context_add_wins_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx) +{ + struct interface *ifaces; + load_interfaces(ctx, lp_interfaces(lp_ctx), &ifaces); + return resolve_context_add_wins_method(ctx, lp_wins_server_list(lp_ctx), ifaces, lp_nbt_port(lp_ctx)); +} -- cgit From df8c7da800f75ff45fb48de59d7ce3f0667d375f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 14:28:07 +0100 Subject: r26454: Add simple SWIG macro for wrapping talloced types. (This used to be commit 760fcc8bfa2a7cd7641465cb3bae889e9e0fbc75) --- source4/libcli/security/security.i | 9 +- source4/libcli/security/security_wrap.c | 148 ++++++++++++++++---------------- 2 files changed, 80 insertions(+), 77 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i index 1f100b0b8f..7e48251e51 100644 --- a/source4/libcli/security/security.i +++ b/source4/libcli/security/security.i @@ -60,10 +60,11 @@ enum sec_privilege { %rename(SecurityToken) security_token; +%talloctype(security_token); + typedef struct security_token { %extend { security_token(TALLOC_CTX *mem_ctx) { return security_token_initialise(mem_ctx); } - ~security_token() { talloc_free($self); } bool is_sid(const struct dom_sid *sid); bool is_system(); bool is_anonymous(); @@ -75,10 +76,11 @@ typedef struct security_token { } } security_token; +%talloctype(security_descriptor); + typedef struct security_descriptor { %extend { security_descriptor(TALLOC_CTX *mem_ctx) { return security_descriptor_initialise(mem_ctx); } - ~security_descriptor() { talloc_free($self); } NTSTATUS sacl_add(const struct security_ace *ace); NTSTATUS dacl_add(const struct security_ace *ace); NTSTATUS dacl_del(const struct security_ace *ace); @@ -92,12 +94,13 @@ typedef struct security_descriptor { %rename(Sid) dom_sid; +%talloctype(dom_sid); + typedef struct dom_sid { %extend { dom_sid(TALLOC_CTX *mem_ctx, const char *text) { return dom_sid_parse_talloc(mem_ctx, text); } - ~dom_sid() { talloc_free($self); } #ifdef SWIGPYTHON const char *__str__(TALLOC_CTX *mem_ctx) { return dom_sid_string(mem_ctx, $self); diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index 633537f951..9c572425eb 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -2529,7 +2529,6 @@ SWIG_From_int (int value) } SWIGINTERN security_token *new_security_token(TALLOC_CTX *mem_ctx){ return security_token_initialise(mem_ctx); } -SWIGINTERN void delete_security_token(security_token *self){ talloc_free(self); } SWIGINTERNINLINE PyObject* SWIG_From_bool (bool value) @@ -2682,6 +2681,7 @@ SWIG_AsVal_int (PyObject * obj, int *val) return res; } +SWIGINTERN void delete_security_token(security_token *self){ talloc_free(self); } SWIGINTERN security_descriptor *new_security_descriptor(TALLOC_CTX *mem_ctx){ return security_descriptor_initialise(mem_ctx); } SWIGINTERN void delete_security_descriptor(security_descriptor *self){ talloc_free(self); } @@ -2755,7 +2755,6 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) SWIGINTERN dom_sid *new_dom_sid(TALLOC_CTX *mem_ctx,char const *text){ return dom_sid_parse_talloc(mem_ctx, text); } -SWIGINTERN void delete_dom_sid(dom_sid *self){ talloc_free(self); } SWIGINTERN char const *dom_sid___str__(dom_sid *self,TALLOC_CTX *mem_ctx){ return dom_sid_string(mem_ctx, self); } @@ -2783,6 +2782,7 @@ SWIG_FromCharPtr(const char *cptr) return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); } +SWIGINTERN void delete_dom_sid(dom_sid *self){ talloc_free(self); } static struct dom_sid *random_sid(TALLOC_CTX *mem_ctx) { @@ -2814,29 +2814,6 @@ fail: } -SWIGINTERN PyObject *_wrap_delete_SecurityToken(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - security_token *arg1 = (security_token *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SecurityToken" "', argument " "1"" of type '" "security_token *""'"); - } - arg1 = (security_token *)(argp1); - delete_security_token(arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_SecurityToken_is_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; @@ -3064,6 +3041,29 @@ fail: } +SWIGINTERN PyObject *_wrap_delete_SecurityToken(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_token *arg1 = (security_token *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_token, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SecurityToken" "', argument " "1"" of type '" "security_token *""'"); + } + arg1 = (security_token *)(argp1); + delete_security_token(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *SecurityToken_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; @@ -3092,29 +3092,6 @@ fail: } -SWIGINTERN PyObject *_wrap_delete_security_descriptor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - security_descriptor *arg1 = (security_descriptor *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_descriptor, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_security_descriptor" "', argument " "1"" of type '" "security_descriptor *""'"); - } - arg1 = (security_descriptor *)(argp1); - delete_security_descriptor(arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; @@ -3313,6 +3290,29 @@ fail: } +SWIGINTERN PyObject *_wrap_delete_security_descriptor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + security_descriptor *arg1 = (security_descriptor *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_security_descriptor, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_security_descriptor" "', argument " "1"" of type '" "security_descriptor *""'"); + } + arg1 = (security_descriptor *)(argp1); + delete_security_descriptor(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *security_descriptor_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; @@ -3356,29 +3356,6 @@ fail: } -SWIGINTERN PyObject *_wrap_delete_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - dom_sid *arg1 = (dom_sid *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Sid" "', argument " "1"" of type '" "dom_sid *""'"); - } - arg1 = (dom_sid *)(argp1); - delete_dom_sid(arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_Sid___str__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; dom_sid *arg1 = (dom_sid *) 0 ; @@ -3440,6 +3417,29 @@ fail: } +SWIGINTERN PyObject *_wrap_delete_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Sid" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + delete_dom_sid(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *Sid_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; @@ -3523,7 +3523,6 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"new_SecurityToken", (PyCFunction)_wrap_new_SecurityToken, METH_NOARGS, NULL}, - { (char *)"delete_SecurityToken", (PyCFunction)_wrap_delete_SecurityToken, METH_O, NULL}, { (char *)"SecurityToken_is_sid", (PyCFunction) _wrap_SecurityToken_is_sid, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"SecurityToken_is_system", (PyCFunction)_wrap_SecurityToken_is_system, METH_O, NULL}, { (char *)"SecurityToken_is_anonymous", (PyCFunction)_wrap_SecurityToken_is_anonymous, METH_O, NULL}, @@ -3532,21 +3531,22 @@ static PyMethodDef SwigMethods[] = { { (char *)"SecurityToken_has_nt_authenticated_users", (PyCFunction)_wrap_SecurityToken_has_nt_authenticated_users, METH_O, NULL}, { (char *)"SecurityToken_has_privilege", (PyCFunction) _wrap_SecurityToken_has_privilege, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"SecurityToken_set_privilege", (PyCFunction) _wrap_SecurityToken_set_privilege, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_SecurityToken", (PyCFunction)_wrap_delete_SecurityToken, METH_O, NULL}, { (char *)"SecurityToken_swigregister", SecurityToken_swigregister, METH_VARARGS, NULL}, { (char *)"SecurityToken_swiginit", SecurityToken_swiginit, METH_VARARGS, NULL}, { (char *)"new_security_descriptor", (PyCFunction)_wrap_new_security_descriptor, METH_NOARGS, NULL}, - { (char *)"delete_security_descriptor", (PyCFunction)_wrap_delete_security_descriptor, METH_O, NULL}, { (char *)"security_descriptor_sacl_add", (PyCFunction) _wrap_security_descriptor_sacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_dacl_add", (PyCFunction) _wrap_security_descriptor_dacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_dacl_del", (PyCFunction) _wrap_security_descriptor_dacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_sacl_del", (PyCFunction) _wrap_security_descriptor_sacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor___eq__", (PyCFunction) _wrap_security_descriptor___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_security_descriptor", (PyCFunction)_wrap_delete_security_descriptor, METH_O, NULL}, { (char *)"security_descriptor_swigregister", security_descriptor_swigregister, METH_VARARGS, NULL}, { (char *)"security_descriptor_swiginit", security_descriptor_swiginit, METH_VARARGS, NULL}, { (char *)"new_Sid", (PyCFunction) _wrap_new_Sid, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_Sid", (PyCFunction)_wrap_delete_Sid, METH_O, NULL}, { (char *)"Sid___str__", (PyCFunction)_wrap_Sid___str__, METH_O, NULL}, { (char *)"Sid___eq__", (PyCFunction) _wrap_Sid___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_Sid", (PyCFunction)_wrap_delete_Sid, METH_O, NULL}, { (char *)"Sid_swigregister", Sid_swigregister, METH_VARARGS, NULL}, { (char *)"Sid_swiginit", Sid_swiginit, METH_VARARGS, NULL}, { (char *)"random_sid", (PyCFunction)_wrap_random_sid, METH_NOARGS, NULL}, -- cgit From 2b021f7f5922299c73578b030a7cdee5e893736f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 15 Dec 2007 20:53:45 +0100 Subject: r26459: Build ildap module as shared module by default. (This used to be commit 91cff7dad2eb0467e6b9a86963859e99ded137f8) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 4af6a9ac45..438063588e 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -134,7 +134,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) OBJ_FILES = raw/rawfile.o \ -- cgit From b04bae87154494fd0001ddc8df41d9fa01ea1ce7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 15 Dec 2007 22:23:36 +0100 Subject: r26461: Tighten dependencies. (This used to be commit a07050be33d9c8e8033063b393162884075fa2af) --- source4/libcli/auth/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 5a0b7e14dc..6cea0a08f0 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -8,6 +8,7 @@ OBJ_FILES = credentials.o \ smbencrypt.o \ smbdes.o PUBLIC_DEPENDENCIES = \ - SCHANNELDB MSRPC_PARSE + MSRPC_PARSE \ + LIBSAMBA-CONFIG # End SUBSYSTEM LIBCLI_AUTH ################################# -- cgit From 5b7ed0cd7f92de0a231c65d167c8cd5e90366b34 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 15 Dec 2007 22:23:42 +0100 Subject: r26463: Tighten dependencies. (This used to be commit d98ac96dfe7bb055f9ad49bc6864890285aa59ed) --- source4/libcli/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 438063588e..c9ed5102d1 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -17,6 +17,7 @@ OBJ_FILES = util/asn1.o PRIVATE_PROTO_HEADER = util/clilsa.h OBJ_FILES = util/clilsa.o PUBLIC_DEPENDENCIES = RPC_NDR_LSA +PRIVATE_DEPENDENCIES = LIBSECURITY [SUBSYSTEM::LIBCLI_COMPOSITE] PRIVATE_PROTO_HEADER = composite/proto.h @@ -135,8 +136,8 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE -PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) +PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ raw/clisocket.o \ -- cgit From 1bc38f9fb39eec46b31fa4ef36699b8f52f52350 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 15 Dec 2007 22:23:45 +0100 Subject: r26464: Tighten dependencies. (This used to be commit 2b7cfa5d9ab94e1ff2d60719cd3749810463ab15) --- source4/libcli/config.mk | 4 ++-- source4/libcli/security/config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c9ed5102d1..99d53c7bbd 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -35,7 +35,7 @@ OBJ_FILES = \ smb_composite/fetchfile.o \ smb_composite/appendacl.o \ smb_composite/fsinfo.o -PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec +PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec LIBCLI_RESOLVE [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h @@ -74,7 +74,7 @@ OBJ_FILES = \ dgram/netlogon.o \ dgram/ntlogon.o \ dgram/browse.o -PUBLIC_DEPENDENCIES = LIBCLI_NBT +PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE [LIBRARY::LIBCLI_CLDAP] VERSION = 0.0.1 diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index ff7480c957..8c66df0325 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -6,7 +6,7 @@ OBJ_FILES = security_token.o \ access_check.o \ privilege.o \ sddl.o -PUBLIC_DEPENDENCIES = NDR_MISC +PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR [PYTHON::swig_security] SWIG_FILE = security.i -- cgit From 71e2cafe96f4755b67d01ced497bf5b63aad30f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 04:22:44 +0100 Subject: r26483: Merge ldb module dependency fixes, fix auth python module. (This used to be commit 85eeecf997a071ca7e7ad0247e8d34d49b7ffcbb) --- source4/libcli/config.mk | 5 +++-- source4/libcli/ldap/config.mk | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 99d53c7bbd..50b3647a0d 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -92,7 +92,8 @@ SO_VERSION = 0 DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o -PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS LIBPACKET +PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \ + LIBPACKET LIBNDR [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h @@ -135,7 +136,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE CREDENTIALS gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO OBJ_FILES = raw/rawfile.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 4af0f9de6d..239ee1f161 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = ldap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR LP_RESOLVE + LDAP_ENCODE LIBNDR LP_RESOLVE gensec [SUBSYSTEM::LDAP_ENCODE] -- cgit From c2604542295d5665172019da829544202ff034d6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 11:12:42 +0100 Subject: r26504: Don't rely on system-provided kerberos headers. (This used to be commit c4b1df047663519300370508761c70b0c096b7f2) --- source4/libcli/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 50b3647a0d..adb51c6c9a 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -136,9 +136,9 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE CREDENTIALS gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) -PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO +PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ raw/clisocket.o \ -- cgit From 3e75f222bcdf114238cc4f2bcc61332dc059135f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:42 +0100 Subject: r26539: Remove unnecessary statics. (This used to be commit e53e79eebef3ece6978f0a2b4a1ee0a0814bb5d2) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index fd15ff2fc7..264a6b39ee 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -215,7 +215,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, const char **sasl_names; uint32_t old_gensec_features; - static const char *supported_sasl_mech_attrs[] = { + const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", NULL }; -- cgit From 0500b87092540d300b4e021a0fb95ce16a44fbd2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Dec 2007 00:02:15 +0100 Subject: r26540: Revert my previous commit after concerns raised by Andrew. (This used to be commit 6ac86f8be7d9a8c5ab396a93e6d1e6819e11f173) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 264a6b39ee..fd15ff2fc7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -215,7 +215,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, const char **sasl_names; uint32_t old_gensec_features; - const char *supported_sasl_mech_attrs[] = { + static const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", NULL }; -- cgit From 249cc734cebfef31320ec10b05dbfaaaa39682ca Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:03:02 -0600 Subject: r26565: Fix python registry bindings. 'PROVISION_PYTHON=yes make test' works now. (This used to be commit 485d1fa3d17fe6cc7a0ecd80e8bac42d173bbb19) --- source4/libcli/util/errors.i | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index d51c9e0ded..8d97daf537 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -22,6 +22,7 @@ if (!W_ERROR_IS_OK($1)) { PyObject *obj = Py_BuildValue("(i,s)", $1.v, win_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; } else if ($result == NULL) { $result = Py_None; } @@ -31,6 +32,7 @@ if (NT_STATUS_IS_ERR($1)) { PyObject *obj = Py_BuildValue("(i,s)", $1.v, nt_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; } else if ($result == NULL) { $result = Py_None; } -- cgit From aa0a06f13c44e0eca0b3f2f0c34f0f7995b87159 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 19:19:41 -0600 Subject: r26570: - Trim size of the swig-generated Python bindings by removing a bunch of {}'s. - Start working on Python equivalents for various EJS tests. - Fix regression in argument order for reg_diff_apply() in EJS bindings. (This used to be commit c550c03372cb260b78f6a6c132e70571bc4cb852) --- source4/libcli/security/security_wrap.c | 72 +++++++++++++-------------------- source4/libcli/util/errors.i | 6 +-- 2 files changed, 32 insertions(+), 46 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index 9c572425eb..58bfd19bec 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -2802,9 +2802,7 @@ SWIGINTERN PyObject *_wrap_new_SecurityToken(PyObject *SWIGUNUSEDPARM(self), PyO TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; security_token *result = 0 ; - { - arg1 = NULL; - } + arg1 = NULL; if (!SWIG_Python_UnpackTuple(args,"new_SecurityToken",0,0,0)) SWIG_fail; result = (security_token *)new_security_token(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_security_token, SWIG_POINTER_NEW | 0 ); @@ -3080,9 +3078,7 @@ SWIGINTERN PyObject *_wrap_new_security_descriptor(PyObject *SWIGUNUSEDPARM(self TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; security_descriptor *result = 0 ; - { - arg1 = NULL; - } + arg1 = NULL; if (!SWIG_Python_UnpackTuple(args,"new_security_descriptor",0,0,0)) SWIG_fail; result = (security_descriptor *)new_security_descriptor(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_security_descriptor, SWIG_POINTER_NEW | 0 ); @@ -3119,13 +3115,12 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM } arg2 = (struct security_ace *)(argp2); result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2); - { - if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -3160,13 +3155,12 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM } arg2 = (struct security_ace *)(argp2); result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2); - { - if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -3201,13 +3195,12 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM } arg2 = (struct security_ace *)(argp2); result = security_descriptor_dacl_del(arg1,(struct security_ace const *)arg2); - { - if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -3242,13 +3235,12 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM } arg2 = (struct security_ace *)(argp2); result = security_descriptor_sacl_del(arg1,(struct security_ace const *)arg2); - { - if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -3337,9 +3329,7 @@ SWIGINTERN PyObject *_wrap_new_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *arg (char *) "text", NULL }; - { - arg1 = NULL; - } + arg1 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:new_Sid",kwnames,&obj0)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { @@ -3365,9 +3355,7 @@ SWIGINTERN PyObject *_wrap_Sid___str__(PyObject *SWIGUNUSEDPARM(self), PyObject int res1 = 0 ; PyObject *swig_obj[1] ; - { - arg2 = NULL; - } + arg2 = NULL; if (!args) SWIG_fail; swig_obj[0] = args; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); @@ -3456,9 +3444,7 @@ SWIGINTERN PyObject *_wrap_random_sid(PyObject *SWIGUNUSEDPARM(self), PyObject * TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct dom_sid *result = 0 ; - { - arg1 = NULL; - } + arg1 = NULL; if (!SWIG_Python_UnpackTuple(args,"random_sid",0,0,0)) SWIG_fail; result = (struct dom_sid *)random_sid(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dom_sid, 0 | 0 ); diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index 8d97daf537..3f6efda468 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -18,7 +18,7 @@ */ #ifdef SWIGPYTHON -%typemap(out) WERROR { +%typemap(out,noblock=1) WERROR { if (!W_ERROR_IS_OK($1)) { PyObject *obj = Py_BuildValue("(i,s)", $1.v, win_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); @@ -28,7 +28,7 @@ } }; -%typemap(out) NTSTATUS { +%typemap(out,noblock=1) NTSTATUS { if (NT_STATUS_IS_ERR($1)) { PyObject *obj = Py_BuildValue("(i,s)", $1.v, nt_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); @@ -38,7 +38,7 @@ } }; -%typemap(in) NTSTATUS { +%typemap(in,noblock=1) NTSTATUS { if (PyLong_Check($input)) $1 = NT_STATUS(PyLong_AsUnsignedLong($input)); else if (PyInt_Check($input)) -- cgit From 3ee442c54f658e0dc9541a492e46fd8f6bf3a7f4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 20:22:46 -0600 Subject: r26571: Hide warnings about unused macros and casting qualifiers in autogenerated files. (This used to be commit cb76c60007ae1254181c09ba1ab09c419f500bc5) --- source4/libcli/util/errors.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index 3f6efda468..ec230a9c18 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -20,7 +20,7 @@ #ifdef SWIGPYTHON %typemap(out,noblock=1) WERROR { if (!W_ERROR_IS_OK($1)) { - PyObject *obj = Py_BuildValue("(i,s)", $1.v, win_errstr($1)); + PyObject *obj = Py_BuildValue("(i,s)", $1.v, (char *)win_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if ($result == NULL) { @@ -30,7 +30,7 @@ %typemap(out,noblock=1) NTSTATUS { if (NT_STATUS_IS_ERR($1)) { - PyObject *obj = Py_BuildValue("(i,s)", $1.v, nt_errstr($1)); + PyObject *obj = Py_BuildValue("(i,s)", $1.v, (char *)nt_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if ($result == NULL) { -- cgit From d0ba9f001474bfee9b1e8fb516effab736cd4050 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 20:56:41 -0600 Subject: r26572: Fix warnings in the Python code. (This used to be commit 15038d9586d0b58f301ca8c39c21ef10c4283f28) --- source4/libcli/security/security.i | 4 ++-- source4/libcli/security/security_descriptor.c | 6 ++--- source4/libcli/security/security_wrap.c | 32 +++++++++++++-------------- source4/libcli/util/errors.i | 4 ++-- 4 files changed, 23 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i index 7e48251e51..647c9aea09 100644 --- a/source4/libcli/security/security.i +++ b/source4/libcli/security/security.i @@ -83,8 +83,8 @@ typedef struct security_descriptor { security_descriptor(TALLOC_CTX *mem_ctx) { return security_descriptor_initialise(mem_ctx); } NTSTATUS sacl_add(const struct security_ace *ace); NTSTATUS dacl_add(const struct security_ace *ace); - NTSTATUS dacl_del(const struct security_ace *ace); - NTSTATUS sacl_del(const struct security_ace *ace); + NTSTATUS dacl_del(const struct dom_sid *trustee); + NTSTATUS sacl_del(const struct dom_sid *trustee); #ifdef SWIGPYTHON %rename(__eq__) equal; #endif diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 6a124d7371..882284dd9b 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -235,7 +235,7 @@ NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd, bool sacl_del, - struct dom_sid *trustee) + const struct dom_sid *trustee) { int i; bool found = false; @@ -292,7 +292,7 @@ static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd, */ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, - struct dom_sid *trustee) + const struct dom_sid *trustee) { return security_descriptor_acl_del(sd, false, trustee); } @@ -303,7 +303,7 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, */ NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd, - struct dom_sid *trustee) + const struct dom_sid *trustee) { return security_descriptor_acl_del(sd, true, trustee); } diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index 58bfd19bec..72118b2359 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -3116,7 +3116,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM arg2 = (struct security_ace *)(argp2); result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3156,7 +3156,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM arg2 = (struct security_ace *)(argp2); result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3171,7 +3171,7 @@ fail: SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; - struct security_ace *arg2 = (struct security_ace *) 0 ; + struct dom_sid *arg2 = (struct dom_sid *) 0 ; NTSTATUS result; void *argp1 = 0 ; int res1 = 0 ; @@ -3180,7 +3180,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; char * kwnames[] = { - (char *) "self",(char *) "ace", NULL + (char *) "self",(char *) "trustee", NULL }; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_dacl_del",kwnames,&obj0,&obj1)) SWIG_fail; @@ -3189,14 +3189,14 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor_dacl_del" "', argument " "1"" of type '" "security_descriptor *""'"); } arg1 = (security_descriptor *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_ace, 0 | 0 ); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_dom_sid, 0 | 0 ); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_dacl_del" "', argument " "2"" of type '" "struct security_ace const *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_dacl_del" "', argument " "2"" of type '" "struct dom_sid const *""'"); } - arg2 = (struct security_ace *)(argp2); - result = security_descriptor_dacl_del(arg1,(struct security_ace const *)arg2); + arg2 = (struct dom_sid *)(argp2); + result = security_descriptor_dacl_del(arg1,(struct dom_sid const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3211,7 +3211,7 @@ fail: SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; - struct security_ace *arg2 = (struct security_ace *) 0 ; + struct dom_sid *arg2 = (struct dom_sid *) 0 ; NTSTATUS result; void *argp1 = 0 ; int res1 = 0 ; @@ -3220,7 +3220,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; char * kwnames[] = { - (char *) "self",(char *) "ace", NULL + (char *) "self",(char *) "trustee", NULL }; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_sacl_del",kwnames,&obj0,&obj1)) SWIG_fail; @@ -3229,14 +3229,14 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "security_descriptor_sacl_del" "', argument " "1"" of type '" "security_descriptor *""'"); } arg1 = (security_descriptor *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_security_ace, 0 | 0 ); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_dom_sid, 0 | 0 ); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_sacl_del" "', argument " "2"" of type '" "struct security_ace const *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "security_descriptor_sacl_del" "', argument " "2"" of type '" "struct dom_sid const *""'"); } - arg2 = (struct security_ace *)(argp2); - result = security_descriptor_sacl_del(arg1,(struct security_ace const *)arg2); + arg2 = (struct dom_sid *)(argp2); + result = security_descriptor_sacl_del(arg1,(struct dom_sid const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index ec230a9c18..ede536a995 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -20,7 +20,7 @@ #ifdef SWIGPYTHON %typemap(out,noblock=1) WERROR { if (!W_ERROR_IS_OK($1)) { - PyObject *obj = Py_BuildValue("(i,s)", $1.v, (char *)win_errstr($1)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, win_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if ($result == NULL) { @@ -30,7 +30,7 @@ %typemap(out,noblock=1) NTSTATUS { if (NT_STATUS_IS_ERR($1)) { - PyObject *obj = Py_BuildValue("(i,s)", $1.v, (char *)nt_errstr($1)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, nt_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if ($result == NULL) { -- cgit From 3c744ddd2c33a9a06013f357261b8ea86804e8e8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 24 Dec 2007 13:04:56 -0600 Subject: r26588: Janitorial: Rename torture_*_add_*test to torture_*_add_*test_const. Also rename the corresponding wrap_ functions. (This used to be commit e59c2eaf681f076d175b9779d1c27b5f74a57c96) --- source4/libcli/security/tests/sddl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/tests/sddl.c b/source4/libcli/security/tests/sddl.c index 3e6382309e..9e7705ea92 100644 --- a/source4/libcli/security/tests/sddl.c +++ b/source4/libcli/security/tests/sddl.c @@ -96,9 +96,9 @@ struct torture_suite *torture_local_sddl(TALLOC_CTX *mem_ctx) int i; for (i = 0; i < ARRAY_SIZE(examples); i++) { - torture_suite_add_simple_tcase(suite, - talloc_asprintf(suite, "%d", i), - test_sddl, examples[i]); + torture_suite_add_simple_tcase_const(suite, + talloc_asprintf(suite, "%d", i), + test_sddl, examples[i]); } return suite; -- cgit From 70cb5ac03c476110c0348881f49ad0697037ca38 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Dec 2007 07:47:11 -0600 Subject: r26613: Add a function to write a DATA_BLOB into an LDAPString. This respects the length set in the DATA_BLOB, rather than hoping to see NULL termination of the data pointer. (found testing the Ambigious Name Resolution code against OpenLDAP). Andrew Bartlett (This used to be commit bc0022e8c7357b126dc91a945f0e53e4e4108e7d) --- source4/libcli/ldap/ldap.c | 6 +++--- source4/libcli/util/asn1.c | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 34d715e3e5..586f2fa653 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -77,7 +77,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree i = 0; if ( ! tree->u.substring.start_with_wildcard) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); asn1_pop_tag(data); i++; } @@ -91,7 +91,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree ctx = 1; } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); asn1_pop_tag(data); i++; } @@ -157,7 +157,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_LDAPString(data, (char *)tree->u.extended.value.data); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); asn1_pop_tag(data); asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); asn1_write_uint8(data, tree->u.extended.dnAttributes); diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 58cb5f07be..ca6f0dc031 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -285,6 +285,13 @@ bool asn1_write_LDAPString(struct asn1_data *data, const char *s) return !data->has_error; } +/* write a LDAP string from a DATA_BLOB */ +bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s) +{ + asn1_write(data, s->data, s->length); + return !data->has_error; +} + /* write a general string */ bool asn1_write_GeneralString(struct asn1_data *data, const char *s) { -- cgit From 86dc05e99f124db47f2743d1fc23117a7f5145ab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:05 -0600 Subject: r26638: libndr: Require explicitly specifying iconv_convenience for ndr_struct_push_blob(). (This used to be commit 61ad78ac98937ef7a9aa32075a91a1c95b7606b3) --- source4/libcli/dgram/browse.c | 4 ++-- source4/libcli/dgram/dgramsocket.c | 3 ++- source4/libcli/dgram/netlogon.c | 8 ++++++-- source4/libcli/dgram/ntlogon.c | 5 +++-- source4/libcli/ldap/ldap_ndr.c | 4 ++-- source4/libcli/nbt/nbtname.c | 4 ++-- source4/libcli/nbt/nbtsocket.c | 8 ++++++-- source4/libcli/raw/rawfile.c | 2 +- source4/libcli/raw/rawsetfileinfo.c | 2 +- source4/libcli/wrepl/winsrepl.c | 2 +- 10 files changed, 26 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index ab831df8cc..d70cda02ee 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -38,7 +38,7 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), request, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -66,7 +66,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), reply, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 1af252c0bf..cd3ac6630f 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -24,6 +24,7 @@ #include "lib/util/dlinklist.h" #include "libcli/dgram/libdgram.h" #include "lib/socket/socket.h" +#include "param/param.h" #include "librpc/gen_ndr/ndr_nbt.h" @@ -228,7 +229,7 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, req->dest = dest; if (talloc_reference(req, dest) == NULL) goto failed; - ndr_err = ndr_push_struct_blob(&req->encoded, req, packet, + ndr_err = ndr_push_struct_blob(&req->encoded, req, lp_iconv_convenience(global_loadparm), packet, (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 92a66cddff..161d48cbbc 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -40,7 +40,9 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, + lp_iconv_convenience(global_loadparm), + request, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -73,7 +75,9 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, + lp_iconv_convenience(global_loadparm), + reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 8cd69176a5..bbcfc1b2dc 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -41,7 +41,8 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), + request, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -74,7 +75,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), reply, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 468c366c85..fde623bece 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -46,7 +46,7 @@ char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) DATA_BLOB blob; enum ndr_err_code ndr_err; char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, sid, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, (ndr_push_flags_fn_t)ndr_push_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; @@ -65,7 +65,7 @@ char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) DATA_BLOB blob; enum ndr_err_code ndr_err; char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, guid, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, (ndr_push_flags_fn_t)ndr_push_GUID); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index bdcd012556..079d0595de 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_nbt.h" #include "librpc/gen_ndr/ndr_misc.h" #include "system/locale.h" +#include "param/param.h" /* don't allow an unlimited number of name components */ #define MAX_COMPONENTS 10 @@ -384,8 +385,7 @@ _PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct { enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(blob, mem_ctx, name, - (ndr_push_flags_fn_t)ndr_push_nbt_name); + ndr_err = ndr_push_struct_blob(blob, mem_ctx, lp_iconv_convenience(global_loadparm), name, (ndr_push_flags_fn_t)ndr_push_nbt_name); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 743f2b0f19..3716d40941 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -394,7 +394,9 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, talloc_set_destructor(req, nbt_name_request_destructor); - ndr_err = ndr_push_struct_blob(&req->encoded, req, request, + ndr_err = ndr_push_struct_blob(&req->encoded, req, + lp_iconv_convenience(global_loadparm), + request, (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed; @@ -441,7 +443,9 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, NDR_PRINT_DEBUG(nbt_name_packet, request); } - ndr_err = ndr_push_struct_blob(&req->encoded, req, request, + ndr_err = ndr_push_struct_blob(&req->encoded, req, + lp_iconv_convenience(global_loadparm), + request, (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(req); diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index c34cb9c52f..3b6ca68526 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -276,7 +276,7 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr if (parms->ntcreatex.in.sec_desc) { enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(&sd_blob, mem_ctx, + ndr_err = ndr_push_struct_blob(&sd_blob, mem_ctx, NULL, parms->ntcreatex.in.sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 67dadf3287..a9a1a3547e 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -88,7 +88,7 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, case RAW_FILEINFO_SEC_DESC: { enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(blob, mem_ctx, + ndr_err = ndr_push_struct_blob(blob, mem_ctx, NULL, parms->set_secdesc.in.sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 63b0a60f6c..381df902b4 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -494,7 +494,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, } wrap.packet = *packet; - ndr_err = ndr_push_struct_blob(&blob, req, &wrap, + ndr_err = ndr_push_struct_blob(&blob, req, lp_iconv_convenience(global_loadparm), &wrap, (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); -- cgit From 7d5f0e0893d42b56145a3ffa34e3b4b9906cbd91 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:13 -0600 Subject: r26639: librpc: Pass iconv convenience on from RPC connection to NDR library, so it can be overridden by OpenChange. (This used to be commit 2f29f80e07adef1f020173f2cd6d947d0ef505ce) --- source4/libcli/cldap/cldap.c | 8 ++++++-- source4/libcli/cldap/cldap.h | 1 - source4/libcli/dgram/browse.c | 2 +- source4/libcli/dgram/dgramsocket.c | 2 +- source4/libcli/dgram/netlogon.c | 2 +- source4/libcli/dgram/ntlogon.c | 2 +- source4/libcli/ldap/ldap_ndr.c | 2 +- source4/libcli/nbt/nbtname.c | 2 +- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/raw/rawfileinfo.c | 2 +- source4/libcli/raw/rawfsinfo.c | 2 +- source4/libcli/util/clilsa.c | 4 +++- source4/libcli/wrepl/winsrepl.c | 3 +-- 13 files changed, 19 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 4c6bd68c13..7c8d40e608 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -617,7 +617,9 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - ndr_err = ndr_pull_union_blob_all(data, mem_ctx, &io->out.netlogon, + ndr_err = ndr_pull_union_blob_all(data, mem_ctx, + lp_iconv_convenience(global_loadparm), + &io->out.netlogon, io->in.version & 0xF, (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -711,7 +713,9 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, TALLOC_CTX *tmp_ctx = talloc_new(cldap); DATA_BLOB blob; - ndr_err = ndr_push_union_blob(&blob, tmp_ctx, netlogon, version & 0xF, + ndr_err = ndr_push_union_blob(&blob, tmp_ctx, + lp_iconv_convenience(global_loadparm), + netlogon, version & 0xF, (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 217ac0ff1b..8aa98f0331 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -73,7 +73,6 @@ struct cldap_request { struct cldap_socket { struct socket_context *sock; struct event_context *event_ctx; - struct loadparm_context *lp_ctx; /* the fd event */ struct fd_event *fde; diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index d70cda02ee..eb19555d15 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -99,7 +99,7 @@ NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, pkt, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), pkt, (ndr_pull_flags_fn_t)ndr_pull_nbt_browse_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index cd3ac6630f..032d9de67b 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -72,7 +72,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) } /* parse the request */ - ndr_err = ndr_pull_struct_blob(&blob, packet, packet, + ndr_err = ndr_pull_struct_blob(&blob, packet, lp_iconv_convenience(global_loadparm), packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_dgram_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 161d48cbbc..670af4ea63 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -114,7 +114,7 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, netlogon, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), netlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index bbcfc1b2dc..98aad1af8c 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -113,7 +113,7 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, ntlogon, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), ntlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index fde623bece..3f7cb8f538 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -85,7 +85,7 @@ NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GU blob.data = val.data; blob.length = val.length; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, guid, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, (ndr_pull_flags_fn_t)ndr_pull_GUID); talloc_free(val.data); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 079d0595de..142dad0296 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -400,7 +400,7 @@ _PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, { enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, name, + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, name, (ndr_pull_flags_fn_t)ndr_pull_nbt_name); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 3716d40941..8bfe746294 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -190,7 +190,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } /* parse the request */ - ndr_err = ndr_pull_struct_blob(&blob, packet, packet, + ndr_err = ndr_pull_struct_blob(&blob, packet, lp_iconv_convenience(global_loadparm), packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 9827217a04..ed5475e926 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -253,7 +253,7 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor); NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd); - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, parms->query_secdesc.out.sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index 73f1192df0..bfb5db828e 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -216,7 +216,7 @@ NTSTATUS smb_raw_fsinfo_passthru_parse(DATA_BLOB blob, TALLOC_CTX *mem_ctx, case RAW_QFS_OBJECTID_INFORMATION: QFS_CHECK_SIZE(64); - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &fsinfo->objectid_information.out.guid, (ndr_pull_flags_fn_t)ndr_pull_GUID); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index 7c32294648..1eb2de83d2 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -32,6 +32,7 @@ #include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_lsa_c.h" #include "libcli/util/clilsa.h" +#include "param/param.h" struct smblsa_state { struct dcerpc_pipe *pipe; @@ -79,7 +80,8 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } lsa->ipc_tree->tid = tcon.tconx.out.tid; - lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx); + lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx, + lp_iconv_convenience(global_loadparm)); if (lsa->pipe == NULL) { talloc_free(lsa); return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 381df902b4..d027e88396 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -102,8 +102,7 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) blob.length = packet_blob_in.length - 4; /* we have a full request - parse it */ - ndr_err = ndr_pull_struct_blob(&blob, - req->packet, req->packet, + ndr_err = ndr_pull_struct_blob(&blob, req->packet, lp_iconv_convenience(global_loadparm), req->packet, (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); -- cgit From 771b347f9b185895390445be96081c781e28a26d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Jan 2008 18:39:01 -0600 Subject: r26644: Janitorial: Pass resolve_context explicitly to various SMB functions, should help fix the build for OpenChange. (This used to be commit 385ffe4f4cc9a21a760c0f00410f56e2592fd507) --- source4/libcli/cliconnect.c | 7 ++++--- source4/libcli/raw/clisocket.c | 7 +++++-- source4/libcli/raw/clitransport.c | 6 +++--- source4/libcli/raw/clitree.c | 3 ++- source4/libcli/smb2/connect.c | 4 +++- source4/libcli/smb_composite/connect.c | 12 ++++++++---- source4/libcli/smb_composite/fetchfile.c | 5 ++++- source4/libcli/smb_composite/fsinfo.c | 4 +++- source4/libcli/smb_composite/smb_composite.h | 1 + 9 files changed, 33 insertions(+), 16 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 7ec914e831..c13dde9711 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -32,7 +32,7 @@ */ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, const char **ports, struct resolve_context *resolve_ctx, - int max_xmit, int max_mux) + int max_xmit, int max_mux, bool use_spnego) { struct smbcli_socket *sock; @@ -42,7 +42,7 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, if (sock == NULL) return false; cli->transport = smbcli_transport_init(sock, cli, true, max_xmit, - max_mux); + max_mux, use_spnego); if (!cli->transport) { return false; } @@ -140,6 +140,7 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, const char *sharename, const char *devtype, struct cli_credentials *credentials, + struct resolve_context *resolve_ctx, struct event_context *ev) { struct smbcli_tree *tree; @@ -150,7 +151,7 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, status = smbcli_tree_full_connection(parent_ctx, &tree, host, ports, sharename, devtype, - credentials, ev); + credentials, resolve_ctx, ev); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 9732ab1638..8beaef3daa 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -47,6 +47,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, const char *host_addr, const char **ports, const char *host_name, + struct resolve_context *resolve_ctx, struct event_context *event_ctx) { struct composite_context *result, *ctx; @@ -152,11 +153,13 @@ NTSTATUS smbcli_sock_connect_recv(struct composite_context *c, NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx, const char *host_addr, const char **ports, const char *host_name, + struct resolve_context *resolve_ctx, struct event_context *event_ctx, struct smbcli_socket **result) { struct composite_context *c = smbcli_sock_connect_send(mem_ctx, host_addr, ports, host_name, + resolve_ctx, event_ctx); return smbcli_sock_connect_recv(c, mem_ctx, result); } @@ -233,8 +236,8 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char ** return NULL; } - status = smbcli_sock_connect(mem_ctx, address, ports, name, event_ctx, - &result); + status = smbcli_sock_connect(mem_ctx, address, ports, name, resolve_ctx, + event_ctx, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(9, ("smbcli_sock_connect failed: %s\n", diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 11df6c6c96..bdaeaeb58a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -75,7 +75,8 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, TALLOC_CTX *parent_ctx, bool primary, int max_xmit, - int max_mux) + int max_mux, + bool use_spnego) { struct smbcli_transport *transport; @@ -88,8 +89,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->socket = talloc_reference(transport, sock); } transport->negotiate.protocol = PROTOCOL_NT1; - transport->options.use_spnego = lp_use_spnego(global_loadparm) && - lp_nt_status_support(global_loadparm); + transport->options.use_spnego = use_spnego; transport->options.max_xmit = max_xmit; transport->options.max_mux = max_mux; transport->options.request_timeout = SMB_REQUEST_TIMEOUT; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 890d5470da..6b14893c4e 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -174,6 +174,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, const char *dest_host, const char **dest_ports, const char *service, const char *service_type, struct cli_credentials *credentials, + struct resolve_context *resolve_ctx, struct event_context *ev) { struct smb_composite_connect io; @@ -192,7 +193,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.fallback_to_anonymous = false; io.in.workgroup = lp_workgroup(global_loadparm); - status = smb_composite_connect(&io, parent_ctx, ev); + status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); if (NT_STATUS_IS_OK(status)) { *ret_tree = io.out.tree; } diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 4d250fdded..4518203183 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -29,6 +29,7 @@ struct smb2_connect_state { struct cli_credentials *credentials; + struct resolve_context *resolve_ctx; const char *host; const char *share; struct smb2_negprot negprot; @@ -152,7 +153,7 @@ static void continue_resolve(struct composite_context *creq) c->status = resolve_name_recv(creq, state, &addr); if (!composite_is_ok(c)) return; - creq = smbcli_sock_connect_send(state, addr, ports, state->host, c->event_ctx); + creq = smbcli_sock_connect_send(state, addr, ports, state->host, state->resolve_ctx, c->event_ctx); composite_continue(c, creq, continue_socket, c); } @@ -185,6 +186,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state->host, c)) return c; state->share = talloc_strdup(c, share); if (composite_nomem(state->share, c)) return c; + state->resolve_ctx = talloc_reference(state, resolve_ctx); ZERO_STRUCT(name); name.name = host; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index fafd3b0173..b71cfc2c19 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -309,7 +309,8 @@ static NTSTATUS connect_socket(struct composite_context *c, /* the socket is up - we can initialise the smbcli transport layer */ state->transport = smbcli_transport_init(state->sock, state, true, lp_max_xmit(global_loadparm), - lp_maxmux(global_loadparm)); + lp_maxmux(global_loadparm), + lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(state->transport); if (is_ipaddress(state->sock->hostname) && @@ -362,7 +363,8 @@ static NTSTATUS connect_resolve(struct composite_context *c, state->creq = smbcli_sock_connect_send(state, address, io->in.dest_ports, - io->in.dest_host, c->event_ctx); + io->in.dest_host, + NULL, c->event_ctx); NT_STATUS_HAVE_NO_MEMORY(state->creq); state->stage = CONNECT_SOCKET; @@ -440,6 +442,7 @@ static void composite_handler(struct composite_context *creq) */ struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, + struct resolve_context *resolve_ctx, struct event_context *event_ctx) { struct composite_context *c; @@ -464,7 +467,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec state->stage = CONNECT_RESOLVE; make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(lp_resolve_context(global_loadparm), &name, c->event_ctx); + state->creq = resolve_name_send(resolve_ctx, &name, c->event_ctx); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; @@ -498,8 +501,9 @@ NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem sync version of smb_composite_connect */ NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, + struct resolve_context *resolve_ctx, struct event_context *ev) { - struct composite_context *c = smb_composite_connect_send(io, mem_ctx, ev); + struct composite_context *c = smb_composite_connect_send(io, mem_ctx, resolve_ctx, ev); return smb_composite_connect_recv(c, mem_ctx); } diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index a4f73ffd70..f3934a2123 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -23,6 +23,8 @@ #include "includes.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" +#include "param/param.h" +#include "libcli/resolve/resolve.h" enum fetchfile_stage {FETCHFILE_CONNECT, FETCHFILE_READ}; @@ -145,7 +147,8 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; - state->creq = smb_composite_connect_send(state->connect, state, event_ctx); + state->creq = smb_composite_connect_send(state->connect, state, + lp_resolve_context(global_loadparm), event_ctx); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index f37213e2f9..2d8240572e 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -6,6 +6,8 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" +#include "param/param.h" +#include "libcli/resolve/resolve.h" /* the stages of this call */ enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY}; @@ -157,7 +159,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, c->private_data = state; state->creq = smb_composite_connect_send(state->connect, state, - c->event_ctx); + lp_resolve_context(global_loadparm), c->event_ctx); if (state->creq == NULL) goto failed; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index a3188c4fe2..5574495079 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -171,5 +171,6 @@ struct smb_composite_connectmulti { }; struct smbcli_session; +struct resolve_context; #include "libcli/smb_composite/proto.h" -- cgit From 969b8579c755441092e27b499ecedbd7d725816d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Jan 2008 18:39:15 -0600 Subject: r26646: libcli/smb_composite: Allow specifying SMB parameters in smb_composite_connect structure. AFAIK no global variables will now be used when doing RPC client connections. (This used to be commit 0ef75e4e3cb0e1bd10e367a00f5e9b725587c40a) --- source4/libcli/raw/clitree.c | 8 ++++++++ source4/libcli/smb_composite/connect.c | 9 ++++----- source4/libcli/smb_composite/fetchfile.c | 8 ++++++++ source4/libcli/smb_composite/fsinfo.c | 8 ++++++++ source4/libcli/smb_composite/smb_composite.h | 6 ++++++ 5 files changed, 34 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 6b14893c4e..94fa37383b 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -192,6 +192,14 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.credentials = credentials; io.in.fallback_to_anonymous = false; io.in.workgroup = lp_workgroup(global_loadparm); + io.in.max_xmit = lp_max_xmit(global_loadparm); + io.in.max_mux = lp_maxmux(global_loadparm); + io.in.ntstatus_support = lp_nt_status_support(global_loadparm); + io.in.max_protocol = lp_cli_maxprotocol(global_loadparm); + io.in.unicode = lp_unicode(global_loadparm); + io.in.use_spnego = lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm); + + status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index b71cfc2c19..bdefe39b71 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -63,8 +63,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - state->req = smb_raw_negotiate_send(state->transport, lp_unicode(global_loadparm), - lp_cli_maxprotocol(global_loadparm)); + state->req = smb_raw_negotiate_send(state->transport, io->in.unicode, io->in.max_protocol); NT_STATUS_HAVE_NO_MEMORY(state->req); state->req->async.fn = request_handler; @@ -308,9 +307,9 @@ static NTSTATUS connect_socket(struct composite_context *c, /* the socket is up - we can initialise the smbcli transport layer */ state->transport = smbcli_transport_init(state->sock, state, true, - lp_max_xmit(global_loadparm), - lp_maxmux(global_loadparm), - lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm)); + io->in.max_xmit, + io->in.max_mux, + io->in.use_spnego); NT_STATUS_HAVE_NO_MEMORY(state->transport); if (is_ipaddress(state->sock->hostname) && diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index f3934a2123..893eb854f5 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -147,6 +147,14 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; + state->connect->in.max_xmit = lp_max_xmit(global_loadparm); + state->connect->in.max_mux = lp_maxmux(global_loadparm); + state->connect->in.ntstatus_support = lp_nt_status_support(global_loadparm); + state->connect->in.max_protocol = lp_cli_maxprotocol(global_loadparm); + state->connect->in.unicode = lp_unicode(global_loadparm); + state->connect->in.use_spnego = lp_use_spnego(global_loadparm) && + lp_nt_status_support(global_loadparm); + state->creq = smb_composite_connect_send(state->connect, state, lp_resolve_context(global_loadparm), event_ctx); if (state->creq == NULL) goto failed; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index 2d8240572e..bf425ad7c8 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -153,6 +153,14 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; + state->connect->in.max_xmit = lp_max_xmit(global_loadparm); + state->connect->in.max_mux = lp_maxmux(global_loadparm); + state->connect->in.ntstatus_support = lp_nt_status_support(global_loadparm); + state->connect->in.max_protocol = lp_cli_maxprotocol(global_loadparm); + state->connect->in.unicode = lp_unicode(global_loadparm); + state->connect->in.use_spnego = lp_use_spnego(global_loadparm) && + lp_nt_status_support(global_loadparm); + c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 5574495079..41ce4b03bd 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -91,6 +91,12 @@ struct smb_composite_connect { struct cli_credentials *credentials; bool fallback_to_anonymous; const char *workgroup; + bool use_spnego; + bool ntstatus_support; + bool unicode; + int max_xmit; + int max_mux; + int max_protocol; } in; struct { struct smbcli_tree *tree; -- cgit From 425732f688865ebe2bfe568c8278edec50cbdedf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 17:21:58 -0600 Subject: r26651: libsmb: Allow specifying signing policy from higher up. The number of arguments is getting a bit excessive now, so it probably makes sense to pass in the smbcli_options struct rather than all members individually and add a convenience function for obtaining a smbcli_options struct from a loadparm context. (This used to be commit 9f64213463b5bf3bcbf36913139e9a5042e967a2) --- source4/libcli/cliconnect.c | 8 +++++--- source4/libcli/raw/clitransport.c | 4 +++- source4/libcli/raw/clitree.c | 3 +-- source4/libcli/raw/libcliraw.h | 1 + source4/libcli/raw/smb_signing.c | 2 +- source4/libcli/smb_composite/connect.c | 3 ++- source4/libcli/smb_composite/fetchfile.c | 3 ++- source4/libcli/smb_composite/fsinfo.c | 1 + source4/libcli/smb_composite/smb_composite.h | 3 +++ 9 files changed, 19 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index c13dde9711..c1fadaa679 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -31,8 +31,10 @@ wrapper around smbcli_sock_connect() */ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, - const char **ports, struct resolve_context *resolve_ctx, - int max_xmit, int max_mux, bool use_spnego) + const char **ports, + struct resolve_context *resolve_ctx, + int max_xmit, int max_mux, bool use_spnego, + enum smb_signing_state signing) { struct smbcli_socket *sock; @@ -42,7 +44,7 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, if (sock == NULL) return false; cli->transport = smbcli_transport_init(sock, cli, true, max_xmit, - max_mux, use_spnego); + max_mux, use_spnego, signing); if (!cli->transport) { return false; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index bdaeaeb58a..3ca828d46b 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -76,7 +76,8 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, bool primary, int max_xmit, int max_mux, - bool use_spnego) + bool use_spnego, + enum smb_signing_state signing) { struct smbcli_transport *transport; @@ -93,6 +94,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->options.max_xmit = max_xmit; transport->options.max_mux = max_mux; transport->options.request_timeout = SMB_REQUEST_TIMEOUT; + transport->options.signing = signing; transport->negotiate.max_xmit = transport->options.max_xmit; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 94fa37383b..3d8a6760a1 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -198,8 +198,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.max_protocol = lp_cli_maxprotocol(global_loadparm); io.in.unicode = lp_unicode(global_loadparm); io.in.use_spnego = lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm); - - + io.in.signing = lp_client_signing(global_loadparm); status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 6c97e61f04..dd6904dec2 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -97,6 +97,7 @@ struct smbcli_options { uint32_t max_xmit; uint16_t max_mux; int request_timeout; + enum smb_signing_state signing; }; /* this is the context for the client transport layer */ diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index e19e81af7e..0053710aaf 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -383,7 +383,7 @@ bool smbcli_init_signing(struct smbcli_transport *transport) return false; } - switch (lp_client_signing(global_loadparm)) { + switch (transport->options.signing) { case SMB_SIGNING_OFF: transport->negotiate.sign_info.allow_smb_signing = false; break; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index bdefe39b71..e45a8a25f9 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -309,7 +309,8 @@ static NTSTATUS connect_socket(struct composite_context *c, state->transport = smbcli_transport_init(state->sock, state, true, io->in.max_xmit, io->in.max_mux, - io->in.use_spnego); + io->in.use_spnego, + io->in.signing); NT_STATUS_HAVE_NO_MEMORY(state->transport); if (is_ipaddress(state->sock->hostname) && diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 893eb854f5..5fa48b4863 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -154,7 +154,8 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.unicode = lp_unicode(global_loadparm); state->connect->in.use_spnego = lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm); - + state->connect->in.signing = lp_client_signing(global_loadparm); + state->creq = smb_composite_connect_send(state->connect, state, lp_resolve_context(global_loadparm), event_ctx); if (state->creq == NULL) goto failed; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index bf425ad7c8..b6a5a5f2cc 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -160,6 +160,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.unicode = lp_unicode(global_loadparm); state->connect->in.use_spnego = lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm); + state->connect->in.signing = lp_client_signing(global_loadparm); c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 41ce4b03bd..dd193fc820 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -27,6 +27,8 @@ particularly designed to be used in async applications */ +#include "libcli/raw/signing.h" + /* a composite open/read(s)/close request that loads a whole file @@ -97,6 +99,7 @@ struct smb_composite_connect { int max_xmit; int max_mux; int max_protocol; + enum smb_signing_state signing; } in; struct { struct smbcli_tree *tree; -- cgit From 6f79af9d13cb400506e05f20fb68c7f97daccf38 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 17:22:04 -0600 Subject: r26652: msrpc_parse/msrpc_gen: Add iconv_convenience argument. (This used to be commit e886f1bc0dc694971979716d1991535c7d2e08de) --- source4/libcli/auth/smbencrypt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 26b78d25ef..4ccf568d8c 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -299,7 +299,8 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, { DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - msrpc_gen(mem_ctx, &names_blob, "aaa", + msrpc_gen(mem_ctx, lp_iconv_convenience(global_loadparm), &names_blob, + "aaa", NTLMSSP_NAME_TYPE_DOMAIN, domain, NTLMSSP_NAME_TYPE_SERVER, hostname, 0, ""); @@ -321,7 +322,7 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - msrpc_gen(mem_ctx, &response, "ddbbdb", + msrpc_gen(mem_ctx, NULL, &response, "ddbbdb", 0x00000101, /* Header */ 0, /* 'Reserved' */ long_date, 8, /* Timestamp */ -- cgit From dcc282590b34537fc1ead61c3300172528273b44 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 17:22:12 -0600 Subject: r26654: libcli/smb_composite: Rather than specifying each of the gazillion options for SMB individually, just specify the smbcli_options struct. (This used to be commit 8a97886e24a4b969aa91409c06f423b71a45f6eb) --- source4/libcli/cliconnect.c | 12 ++++++------ source4/libcli/raw/clitransport.c | 12 ++---------- source4/libcli/raw/clitree.c | 12 +++--------- source4/libcli/raw/libcliraw.h | 3 +++ source4/libcli/smb_composite/connect.c | 7 ++----- source4/libcli/smb_composite/fetchfile.c | 9 +-------- source4/libcli/smb_composite/fsinfo.c | 9 +-------- source4/libcli/smb_composite/smb_composite.h | 9 ++------- 8 files changed, 20 insertions(+), 53 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index c1fadaa679..666dfe8446 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -33,8 +33,7 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, const char **ports, struct resolve_context *resolve_ctx, - int max_xmit, int max_mux, bool use_spnego, - enum smb_signing_state signing) + struct smbcli_options *options) { struct smbcli_socket *sock; @@ -43,8 +42,7 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, if (sock == NULL) return false; - cli->transport = smbcli_transport_init(sock, cli, true, max_xmit, - max_mux, use_spnego, signing); + cli->transport = smbcli_transport_init(sock, cli, true, options); if (!cli->transport) { return false; } @@ -143,7 +141,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, const char *devtype, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, - struct event_context *ev) + struct event_context *ev, + struct smbcli_options *options) { struct smbcli_tree *tree; NTSTATUS status; @@ -153,7 +152,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, status = smbcli_tree_full_connection(parent_ctx, &tree, host, ports, sharename, devtype, - credentials, resolve_ctx, ev); + credentials, resolve_ctx, ev, + options); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 3ca828d46b..62c32d3058 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -74,10 +74,7 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob); struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, TALLOC_CTX *parent_ctx, bool primary, - int max_xmit, - int max_mux, - bool use_spnego, - enum smb_signing_state signing) + struct smbcli_options *options) { struct smbcli_transport *transport; @@ -90,12 +87,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->socket = talloc_reference(transport, sock); } transport->negotiate.protocol = PROTOCOL_NT1; - transport->options.use_spnego = use_spnego; - transport->options.max_xmit = max_xmit; - transport->options.max_mux = max_mux; - transport->options.request_timeout = SMB_REQUEST_TIMEOUT; - transport->options.signing = signing; - + transport->options = *options; transport->negotiate.max_xmit = transport->options.max_xmit; /* setup the stream -> packet parser */ diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 3d8a6760a1..ae63d94acd 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -175,7 +175,8 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, const char *service, const char *service_type, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, - struct event_context *ev) + struct event_context *ev, + struct smbcli_options *options) { struct smb_composite_connect io; NTSTATUS status; @@ -191,14 +192,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service_type = service_type; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; - io.in.workgroup = lp_workgroup(global_loadparm); - io.in.max_xmit = lp_max_xmit(global_loadparm); - io.in.max_mux = lp_maxmux(global_loadparm); - io.in.ntstatus_support = lp_nt_status_support(global_loadparm); - io.in.max_protocol = lp_cli_maxprotocol(global_loadparm); - io.in.unicode = lp_unicode(global_loadparm); - io.in.use_spnego = lp_use_spnego(global_loadparm) && lp_nt_status_support(global_loadparm); - io.in.signing = lp_client_signing(global_loadparm); + io.in.options = *options; status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index dd6904dec2..0032eb4e94 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -94,6 +94,9 @@ struct smbcli_options { uint_t use_oplocks:1; uint_t use_level2_oplocks:1; uint_t use_spnego:1; + uint_t unicode:1; + uint_t ntstatus_support:1; + int max_protocol; uint32_t max_xmit; uint16_t max_mux; int request_timeout; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index e45a8a25f9..a44765e980 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -63,7 +63,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - state->req = smb_raw_negotiate_send(state->transport, io->in.unicode, io->in.max_protocol); + state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol); NT_STATUS_HAVE_NO_MEMORY(state->req); state->req->async.fn = request_handler; @@ -307,10 +307,7 @@ static NTSTATUS connect_socket(struct composite_context *c, /* the socket is up - we can initialise the smbcli transport layer */ state->transport = smbcli_transport_init(state->sock, state, true, - io->in.max_xmit, - io->in.max_mux, - io->in.use_spnego, - io->in.signing); + &io->in.options); NT_STATUS_HAVE_NO_MEMORY(state->transport); if (is_ipaddress(state->sock->hostname) && diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 5fa48b4863..c7d02e323c 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -147,14 +147,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; - state->connect->in.max_xmit = lp_max_xmit(global_loadparm); - state->connect->in.max_mux = lp_maxmux(global_loadparm); - state->connect->in.ntstatus_support = lp_nt_status_support(global_loadparm); - state->connect->in.max_protocol = lp_cli_maxprotocol(global_loadparm); - state->connect->in.unicode = lp_unicode(global_loadparm); - state->connect->in.use_spnego = lp_use_spnego(global_loadparm) && - lp_nt_status_support(global_loadparm); - state->connect->in.signing = lp_client_signing(global_loadparm); + lp_smbcli_options(global_loadparm, &state->connect->in.options); state->creq = smb_composite_connect_send(state->connect, state, lp_resolve_context(global_loadparm), event_ctx); diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index b6a5a5f2cc..26b19e8759 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -153,14 +153,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; - state->connect->in.max_xmit = lp_max_xmit(global_loadparm); - state->connect->in.max_mux = lp_maxmux(global_loadparm); - state->connect->in.ntstatus_support = lp_nt_status_support(global_loadparm); - state->connect->in.max_protocol = lp_cli_maxprotocol(global_loadparm); - state->connect->in.unicode = lp_unicode(global_loadparm); - state->connect->in.use_spnego = lp_use_spnego(global_loadparm) && - lp_nt_status_support(global_loadparm); - state->connect->in.signing = lp_client_signing(global_loadparm); + lp_smbcli_options(global_loadparm, &state->connect->in.options); c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index dd193fc820..a732617f80 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -28,6 +28,7 @@ */ #include "libcli/raw/signing.h" +#include "libcli/raw/libcliraw.h" /* @@ -93,13 +94,7 @@ struct smb_composite_connect { struct cli_credentials *credentials; bool fallback_to_anonymous; const char *workgroup; - bool use_spnego; - bool ntstatus_support; - bool unicode; - int max_xmit; - int max_mux; - int max_protocol; - enum smb_signing_state signing; + struct smbcli_options options; } in; struct { struct smbcli_tree *tree; -- cgit From 2c8c9a535500e40084c4810da1890df8d9415659 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 15:36:33 -0600 Subject: r26669: Janitorial: Remove uses of global_loadparm. (This used to be commit 50c46160d997e0448f51ae09e0f3c79e8519fa41) --- source4/libcli/raw/clisocket.c | 2 +- source4/libcli/raw/rawacl.c | 5 ++--- source4/libcli/raw/rawnegotiate.c | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 8beaef3daa..8fcb8bb48c 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -83,7 +83,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, ctx = socket_connect_multi_send(state, host_addr, state->num_ports, state->ports, - lp_resolve_context(global_loadparm), + resolve_ctx, state->ctx->event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = smbcli_sock_connect_recv_conn; diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 9d2068f35f..847d133173 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -77,8 +77,7 @@ NTSTATUS smb_raw_query_secdesc_recv(struct smbcli_request *req, nt.out.data.length = IVAL(nt.out.params.data, 0); - ndr = ndr_pull_init_blob(&nt.out.data, mem_ctx, - lp_iconv_convenience(global_loadparm)); + ndr = ndr_pull_init_blob(&nt.out.data, mem_ctx, NULL); if (!ndr) { return NT_STATUS_INVALID_PARAMETER; } @@ -136,7 +135,7 @@ struct smbcli_request *smb_raw_set_secdesc_send(struct smbcli_tree *tree, nt.in.params.data = params; nt.in.params.length = 8; - ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm)); + ndr = ndr_push_init_ctx(NULL, NULL); if (!ndr) return NULL; ndr_err = ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->set_secdesc.in.sd); diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 78b9082521..fc7725cc55 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -175,11 +175,11 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) } /* a way to force ascii SMB */ - if (!lp_unicode(global_loadparm)) { + if (!transport->options.unicode) { transport->negotiate.capabilities &= ~CAP_UNICODE; } - if (!lp_nt_status_support(global_loadparm)) { + if (!transport->options.ntstatus_support) { transport->negotiate.capabilities &= ~CAP_STATUS32; } -- cgit From 2da3464080e1a45f5c76231668a546ad7f10e790 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 15:36:37 -0600 Subject: r26670: Janitorial: Remove global_loadparm uses. (This used to be commit 13cc6ca1d3c2b5899bdd02c4c7306a92baa260f5) --- source4/libcli/smb_composite/fsinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index 26b19e8759..e4dd4436ba 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -153,11 +153,11 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; - lp_smbcli_options(global_loadparm, &state->connect->in.options); + state->connect->in.options = tree->session->transport->options; c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; - c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); + c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); c->private_data = state; state->creq = smb_composite_connect_send(state->connect, state, -- cgit From b7e34eb62580565d1526f793b5df8b26cdd65aa4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 19:33:11 -0600 Subject: r26674: smb_composite: Avoid use of global_loadparm. Hopefully this fixes OpenChange's mapiadmin. (This used to be commit 2df0f7016e27705c3799b2f6bb20fcc17b103c36) --- source4/libcli/smb_composite/connect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index a44765e980..22573442a2 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -172,8 +172,9 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->io_setup->in.credentials = cli_credentials_init(state); NT_STATUS_HAVE_NO_MEMORY(state->io_setup->in.credentials); - cli_credentials_set_conf(state->io_setup->in.credentials, - global_loadparm); + cli_credentials_set_workstation(state->io_setup->in.credentials, + cli_credentials_get_workstation(state->io->in.credentials), + CRED_SPECIFIED); cli_credentials_set_anonymous(state->io_setup->in.credentials); /* If the preceding attempt was with extended security, we -- cgit From 9d09a06920c2de8c6312f3c0a0280faee65fd432 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 6 Jan 2008 22:01:31 -0600 Subject: r26676: libcli: Fill in lp_workgroup() again, should fix my breakage of cifsdd tests. Thanks to Andrew for catching this. Also fixes a typo in sessetup.c. (This used to be commit b97de4a655b989a481d5d001ce9a5d3969d2909c) --- source4/libcli/raw/clitree.c | 1 + source4/libcli/smb_composite/sesssetup.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index ae63d94acd..35f3335322 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -192,6 +192,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service_type = service_type; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; + io.in.workgroup = lp_workgroup(global_loadparm); io.in.options = *options; status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 3ed0bb2473..ce7bcc143e 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -129,7 +129,7 @@ static void request_handler(struct smbcli_request *req) case RAW_SESSSETUP_SPNEGO: state->io->out.vuid = state->setup.spnego.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { - /* we neet to reset the vuid for a new try */ + /* we need to reset the vuid for a new try */ session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_spnego(c, session, -- cgit From cef40813fac9363b544b22b2fa277af37a800cdf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Jan 2008 14:27:40 -0600 Subject: r26694: asn1: Fix header and some typo's. (This used to be commit f9988734bb8a1d823e14b6bff5c4d55d75471f18) --- source4/libcli/util/asn1.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index ca6f0dc031..aad55382d9 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -1,6 +1,6 @@ /* Unix SMB/CIFS implementation. - simple SPNEGO routines + simple ASN1 routines Copyright (C) Andrew Tridgell 2001 This program is free software; you can redistribute it and/or modify @@ -679,7 +679,7 @@ bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blo return !data->has_error; } -/* read an interger without tag*/ +/* read an integer without tag*/ bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) { uint8_t b; @@ -693,7 +693,7 @@ bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) } -/* read an interger */ +/* read an integer */ bool asn1_read_Integer(struct asn1_data *data, int *i) { *i = 0; @@ -703,7 +703,7 @@ bool asn1_read_Integer(struct asn1_data *data, int *i) return asn1_end_tag(data); } -/* read an interger */ +/* read an integer */ bool asn1_read_enumerated(struct asn1_data *data, int *v) { *v = 0; @@ -717,7 +717,7 @@ bool asn1_read_enumerated(struct asn1_data *data, int *v) return asn1_end_tag(data); } -/* check a enumarted value is correct */ +/* check a enumerated value is correct */ bool asn1_check_enumerated(struct asn1_data *data, int v) { uint8_t b; @@ -731,7 +731,7 @@ bool asn1_check_enumerated(struct asn1_data *data, int v) return !data->has_error; } -/* write an enumarted value to the stream */ +/* write an enumerated value to the stream */ bool asn1_write_enumerated(struct asn1_data *data, uint8_t v) { if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; -- cgit From 939edd0eb7c3952859afb802c8e542449a2c4031 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 01:04:38 +0100 Subject: util: Move asn1 to lib/util to trim down the number of subsystems. (This used to be commit 44e1cfd2d0ef62e4ee541cec00581a7151d951b3) --- source4/libcli/cldap/cldap.h | 2 +- source4/libcli/config.mk | 5 - source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/ldap/ldap_controls.c | 2 +- source4/libcli/util/asn1.c | 770 ------------------------------------ source4/libcli/util/asn_1.h | 54 --- 7 files changed, 4 insertions(+), 833 deletions(-) delete mode 100644 source4/libcli/util/asn1.c delete mode 100644 source4/libcli/util/asn_1.h (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 8aa98f0331..7a222e0652 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -19,7 +19,7 @@ along with this program. If not, see . */ -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "librpc/gen_ndr/nbt.h" struct ldap_message; diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index adb51c6c9a..eb3c56cf7f 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -8,11 +8,6 @@ OBJ_FILES = util/doserr.o \ util/errormap.o \ util/nterr.o \ -[SUBSYSTEM::ASN1_UTIL] -PUBLIC_PROTO_HEADER = util/asn1_proto.h -PUBLIC_HEADERS = util/asn_1.h -OBJ_FILES = util/asn1.o - [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h OBJ_FILES = util/clilsa.o diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 586f2fa653..00a0631753 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6b8a7a3f28..d99851ee15 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 34e5cccf75..3b94580033 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" #include "lib/ldb/include/ldb.h" diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c deleted file mode 100644 index aad55382d9..0000000000 --- a/source4/libcli/util/asn1.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple ASN1 routines - Copyright (C) Andrew Tridgell 2001 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "libcli/util/asn_1.h" - -/* allocate an asn1 structure */ -struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) -{ - struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data); - if (ret == NULL) { - DEBUG(0,("asn1_init failed! out of memory\n")); - } - return ret; -} - -/* free an asn1 structure */ -void asn1_free(struct asn1_data *data) -{ - talloc_free(data); -} - -/* write to the ASN1 buffer, advancing the buffer pointer */ -bool asn1_write(struct asn1_data *data, const void *p, int len) -{ - if (data->has_error) return false; - if (data->length < data->ofs+len) { - uint8_t *newp; - newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); - if (!newp) { - asn1_free(data); - data->has_error = true; - return false; - } - data->data = newp; - data->length = data->ofs+len; - } - memcpy(data->data + data->ofs, p, len); - data->ofs += len; - return true; -} - -/* useful fn for writing a uint8_t */ -bool asn1_write_uint8(struct asn1_data *data, uint8_t v) -{ - return asn1_write(data, &v, 1); -} - -/* push a tag onto the asn1 data buffer. Used for nested structures */ -bool asn1_push_tag(struct asn1_data *data, uint8_t tag) -{ - struct nesting *nesting; - - asn1_write_uint8(data, tag); - nesting = talloc(data, struct nesting); - if (!nesting) { - data->has_error = true; - return false; - } - - nesting->start = data->ofs; - nesting->next = data->nesting; - data->nesting = nesting; - return asn1_write_uint8(data, 0xff); -} - -/* pop a tag */ -bool asn1_pop_tag(struct asn1_data *data) -{ - struct nesting *nesting; - size_t len; - - nesting = data->nesting; - - if (!nesting) { - data->has_error = true; - return false; - } - len = data->ofs - (nesting->start+1); - /* yes, this is ugly. We don't know in advance how many bytes the length - of a tag will take, so we assumed 1 byte. If we were wrong then we - need to correct our mistake */ - if (len > 0xFFFFFF) { - data->data[nesting->start] = 0x84; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+5, data->data+nesting->start+1, len); - data->data[nesting->start+1] = (len>>24) & 0xFF; - data->data[nesting->start+2] = (len>>16) & 0xFF; - data->data[nesting->start+3] = (len>>8) & 0xFF; - data->data[nesting->start+4] = len&0xff; - } else if (len > 0xFFFF) { - data->data[nesting->start] = 0x83; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); - data->data[nesting->start+1] = (len>>16) & 0xFF; - data->data[nesting->start+2] = (len>>8) & 0xFF; - data->data[nesting->start+3] = len&0xff; - } else if (len > 255) { - data->data[nesting->start] = 0x82; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); - data->data[nesting->start+1] = len>>8; - data->data[nesting->start+2] = len&0xff; - } else if (len > 127) { - data->data[nesting->start] = 0x81; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); - data->data[nesting->start+1] = len; - } else { - data->data[nesting->start] = len; - } - - data->nesting = nesting->next; - talloc_free(nesting); - return true; -} - -/* "i" is the one's complement representation, as is the normal result of an - * implicit signed->unsigned conversion */ - -static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative) -{ - uint8_t lowest = i & 0xFF; - - i = i >> 8; - if (i != 0) - if (!push_int_bigendian(data, i, negative)) - return false; - - if (data->nesting->start+1 == data->ofs) { - - /* We did not write anything yet, looking at the highest - * valued byte */ - - if (negative) { - /* Don't write leading 0xff's */ - if (lowest == 0xFF) - return true; - - if ((lowest & 0x80) == 0) { - /* The only exception for a leading 0xff is if - * the highest bit is 0, which would indicate - * a positive value */ - if (!asn1_write_uint8(data, 0xff)) - return false; - } - } else { - if (lowest & 0x80) { - /* The highest bit of a positive integer is 1, - * this would indicate a negative number. Push - * a 0 to indicate a positive one */ - if (!asn1_write_uint8(data, 0)) - return false; - } - } - } - - return asn1_write_uint8(data, lowest); -} - -/* write an Integer without the tag framing. Needed for example for the LDAP - * Abandon Operation */ - -bool asn1_write_implicit_Integer(struct asn1_data *data, int i) -{ - if (i == -1) { - /* -1 is special as it consists of all-0xff bytes. In - push_int_bigendian this is the only case that is not - properly handled, as all 0xff bytes would be handled as - leading ones to be ignored. */ - return asn1_write_uint8(data, 0xff); - } else { - return push_int_bigendian(data, i, i<0); - } -} - - -/* write an integer */ -bool asn1_write_Integer(struct asn1_data *data, int i) -{ - if (!asn1_push_tag(data, ASN1_INTEGER)) return false; - if (!asn1_write_implicit_Integer(data, i)) return false; - return asn1_pop_tag(data); -} - -bool ber_write_OID_String(DATA_BLOB *blob, const char *OID) -{ - uint_t v, v2; - const char *p = (const char *)OID; - char *newp; - int i; - - v = strtoul(p, &newp, 10); - if (newp[0] != '.') return false; - p = newp + 1; - - v2 = strtoul(p, &newp, 10); - if (newp[0] != '.') return false; - p = newp + 1; - - /*the ber representation can't use more space then the string one */ - *blob = data_blob(NULL, strlen(OID)); - if (!blob->data) return false; - - blob->data[0] = 40*v + v2; - - i = 1; - while (*p) { - v = strtoul(p, &newp, 10); - if (newp[0] == '.') { - p = newp + 1; - } else if (newp[0] == '\0') { - p = newp; - } else { - data_blob_free(blob); - return false; - } - if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f)); - if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f)); - if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f)); - if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f)); - blob->data[i++] = (v&0x7f); - } - - blob->length = i; - - return true; -} - -/* write an object ID to a ASN1 buffer */ -bool asn1_write_OID(struct asn1_data *data, const char *OID) -{ - DATA_BLOB blob; - - if (!asn1_push_tag(data, ASN1_OID)) return false; - - if (!ber_write_OID_String(&blob, OID)) { - data->has_error = true; - return false; - } - - if (!asn1_write(data, blob.data, blob.length)) { - data->has_error = true; - return false; - } - data_blob_free(&blob); - return asn1_pop_tag(data); -} - -/* write an octet string */ -bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) -{ - asn1_push_tag(data, ASN1_OCTET_STRING); - asn1_write(data, p, length); - asn1_pop_tag(data); - return !data->has_error; -} - -/* write a LDAP string */ -bool asn1_write_LDAPString(struct asn1_data *data, const char *s) -{ - asn1_write(data, s, strlen(s)); - return !data->has_error; -} - -/* write a LDAP string from a DATA_BLOB */ -bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s) -{ - asn1_write(data, s->data, s->length); - return !data->has_error; -} - -/* write a general string */ -bool asn1_write_GeneralString(struct asn1_data *data, const char *s) -{ - asn1_push_tag(data, ASN1_GENERAL_STRING); - asn1_write_LDAPString(data, s); - asn1_pop_tag(data); - return !data->has_error; -} - -bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) -{ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); - asn1_write(data, blob->data, blob->length); - asn1_pop_tag(data); - return !data->has_error; -} - -/* write a BOOLEAN */ -bool asn1_write_BOOLEAN(struct asn1_data *data, bool v) -{ - asn1_push_tag(data, ASN1_BOOLEAN); - asn1_write_uint8(data, v ? 0xFF : 0); - asn1_pop_tag(data); - return !data->has_error; -} - -bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v) -{ - uint8_t tmp = 0; - asn1_start_tag(data, ASN1_BOOLEAN); - asn1_read_uint8(data, &tmp); - if (tmp == 0xFF) { - *v = true; - } else { - *v = false; - } - asn1_end_tag(data); - return !data->has_error; -} - -/* check a BOOLEAN */ -bool asn1_check_BOOLEAN(struct asn1_data *data, bool v) -{ - uint8_t b = 0; - - asn1_read_uint8(data, &b); - if (b != ASN1_BOOLEAN) { - data->has_error = true; - return false; - } - asn1_read_uint8(data, &b); - if (b != v) { - data->has_error = true; - return false; - } - return !data->has_error; -} - - -/* load a struct asn1_data structure with a lump of data, ready to be parsed */ -bool asn1_load(struct asn1_data *data, DATA_BLOB blob) -{ - ZERO_STRUCTP(data); - data->data = talloc_memdup(data, blob.data, blob.length); - if (!data->data) { - data->has_error = true; - return false; - } - data->length = blob.length; - return true; -} - -/* Peek into an ASN1 buffer, not advancing the pointer */ -bool asn1_peek(struct asn1_data *data, void *p, int len) -{ - if (data->has_error) - return false; - - if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) - return false; - - if (data->ofs + len > data->length) { - /* we need to mark the buffer as consumed, so the caller knows - this was an out of data error, and not a decode error */ - data->ofs = data->length; - return false; - } - - memcpy(p, data->data + data->ofs, len); - return true; -} - -/* read from a ASN1 buffer, advancing the buffer pointer */ -bool asn1_read(struct asn1_data *data, void *p, int len) -{ - if (!asn1_peek(data, p, len)) { - data->has_error = true; - return false; - } - - data->ofs += len; - return true; -} - -/* read a uint8_t from a ASN1 buffer */ -bool asn1_read_uint8(struct asn1_data *data, uint8_t *v) -{ - return asn1_read(data, v, 1); -} - -bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v) -{ - return asn1_peek(data, v, 1); -} - -bool asn1_peek_tag(struct asn1_data *data, uint8_t tag) -{ - uint8_t b; - - if (asn1_tag_remaining(data) <= 0) { - return false; - } - - if (!asn1_peek_uint8(data, &b)) - return false; - - return (b == tag); -} - -/* start reading a nested asn1 structure */ -bool asn1_start_tag(struct asn1_data *data, uint8_t tag) -{ - uint8_t b; - struct nesting *nesting; - - if (!asn1_read_uint8(data, &b)) - return false; - - if (b != tag) { - data->has_error = true; - return false; - } - nesting = talloc(data, struct nesting); - if (!nesting) { - data->has_error = true; - return false; - } - - if (!asn1_read_uint8(data, &b)) { - return false; - } - - if (b & 0x80) { - int n = b & 0x7f; - if (!asn1_read_uint8(data, &b)) - return false; - nesting->taglen = b; - while (n > 1) { - if (!asn1_read_uint8(data, &b)) - return false; - nesting->taglen = (nesting->taglen << 8) | b; - n--; - } - } else { - nesting->taglen = b; - } - nesting->start = data->ofs; - nesting->next = data->nesting; - data->nesting = nesting; - if (asn1_tag_remaining(data) == -1) { - return false; - } - return !data->has_error; -} - -/* stop reading a tag */ -bool asn1_end_tag(struct asn1_data *data) -{ - struct nesting *nesting; - - /* make sure we read it all */ - if (asn1_tag_remaining(data) != 0) { - data->has_error = true; - return false; - } - - nesting = data->nesting; - - if (!nesting) { - data->has_error = true; - return false; - } - - data->nesting = nesting->next; - talloc_free(nesting); - return true; -} - -/* work out how many bytes are left in this nested tag */ -int asn1_tag_remaining(struct asn1_data *data) -{ - int remaining; - if (data->has_error) { - return -1; - } - - if (!data->nesting) { - data->has_error = true; - return -1; - } - remaining = data->nesting->taglen - (data->ofs - data->nesting->start); - if (remaining > (data->length - data->ofs)) { - data->has_error = true; - return -1; - } - return remaining; -} - -/* read an object ID from a data blob */ -bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) -{ - int i; - uint8_t *b; - uint_t v; - char *tmp_oid = NULL; - - if (blob.length < 2) return false; - - b = blob.data; - - tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40); - if (!tmp_oid) goto nomem; - tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40); - if (!tmp_oid) goto nomem; - - for(i = 1, v = 0; i < blob.length; i++) { - v = (v<<7) | (b[i]&0x7f); - if ( ! (b[i] & 0x80)) { - tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v); - v = 0; - } - if (!tmp_oid) goto nomem; - } - - if (v != 0) { - talloc_free(tmp_oid); - return false; - } - - *OID = tmp_oid; - return true; - -nomem: - return false; -} - -/* read an object ID from a ASN1 buffer */ -bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID) -{ - DATA_BLOB blob; - int len; - - if (!asn1_start_tag(data, ASN1_OID)) return false; - - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - - blob = data_blob(NULL, len); - if (!blob.data) { - data->has_error = true; - return false; - } - - asn1_read(data, blob.data, len); - asn1_end_tag(data); - if (data->has_error) { - data_blob_free(&blob); - return false; - } - - if (!ber_read_OID_String(mem_ctx, blob, OID)) { - data->has_error = true; - data_blob_free(&blob); - return false; - } - - data_blob_free(&blob); - return true; -} - -/* check that the next object ID is correct */ -bool asn1_check_OID(struct asn1_data *data, const char *OID) -{ - const char *id; - - if (!asn1_read_OID(data, data, &id)) return false; - - if (strcmp(id, OID) != 0) { - talloc_free(discard_const(id)); - data->has_error = true; - return false; - } - talloc_free(discard_const(id)); - return true; -} - -/* read a LDAPString from a ASN1 buffer */ -bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) -{ - int len; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - *s = talloc_array(mem_ctx, char, len+1); - if (! *s) { - data->has_error = true; - return false; - } - asn1_read(data, *s, len); - (*s)[len] = 0; - return !data->has_error; -} - - -/* read a GeneralString from a ASN1 buffer */ -bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) -{ - if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false; - if (!asn1_read_LDAPString(data, mem_ctx, s)) return false; - return asn1_end_tag(data); -} - - -/* read a octet string blob */ -bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) -{ - int len; - ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - *blob = data_blob_talloc(mem_ctx, NULL, len+1); - if (!blob->data) { - data->has_error = true; - return false; - } - asn1_read(data, blob->data, len); - asn1_end_tag(data); - blob->length--; - blob->data[len] = 0; - - if (data->has_error) { - data_blob_free(blob); - *blob = data_blob(NULL, 0); - return false; - } - return true; -} - -bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) -{ - int len; - ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - *blob = data_blob(NULL, len); - if ((len != 0) && (!blob->data)) { - data->has_error = true; - return false; - } - asn1_read(data, blob->data, len); - asn1_end_tag(data); - return !data->has_error; -} - -/* read an integer without tag*/ -bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) -{ - uint8_t b; - *i = 0; - - while (!data->has_error && asn1_tag_remaining(data)>0) { - if (!asn1_read_uint8(data, &b)) return false; - *i = (*i << 8) + b; - } - return !data->has_error; - -} - -/* read an integer */ -bool asn1_read_Integer(struct asn1_data *data, int *i) -{ - *i = 0; - - if (!asn1_start_tag(data, ASN1_INTEGER)) return false; - if (!asn1_read_implicit_Integer(data, i)) return false; - return asn1_end_tag(data); -} - -/* read an integer */ -bool asn1_read_enumerated(struct asn1_data *data, int *v) -{ - *v = 0; - - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; - while (!data->has_error && asn1_tag_remaining(data)>0) { - uint8_t b; - asn1_read_uint8(data, &b); - *v = (*v << 8) + b; - } - return asn1_end_tag(data); -} - -/* check a enumerated value is correct */ -bool asn1_check_enumerated(struct asn1_data *data, int v) -{ - uint8_t b; - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; - asn1_read_uint8(data, &b); - asn1_end_tag(data); - - if (v != b) - data->has_error = false; - - return !data->has_error; -} - -/* write an enumerated value to the stream */ -bool asn1_write_enumerated(struct asn1_data *data, uint8_t v) -{ - if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; - asn1_write_uint8(data, v); - asn1_pop_tag(data); - return !data->has_error; -} - -/* - check if a ASN.1 blob is a full tag -*/ -NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) -{ - struct asn1_data *asn1 = asn1_init(NULL); - int size; - - NT_STATUS_HAVE_NO_MEMORY(asn1); - - asn1->data = blob.data; - asn1->length = blob.length; - asn1_start_tag(asn1, tag); - if (asn1->has_error) { - talloc_free(asn1); - return STATUS_MORE_ENTRIES; - } - size = asn1_tag_remaining(asn1) + asn1->ofs; - - talloc_free(asn1); - - if (size > blob.length) { - return STATUS_MORE_ENTRIES; - } - - *packet_size = size; - return NT_STATUS_OK; -} diff --git a/source4/libcli/util/asn_1.h b/source4/libcli/util/asn_1.h deleted file mode 100644 index 612a8a932f..0000000000 --- a/source4/libcli/util/asn_1.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple ASN1 code - Copyright (C) Andrew Tridgell 2001 - - 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 3 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, see . -*/ - -#ifndef _ASN_1_H -#define _ASN_1_H - -struct nesting { - off_t start; - size_t taglen; /* for parsing */ - struct nesting *next; -}; - -struct asn1_data { - uint8_t *data; - size_t length; - off_t ofs; - struct nesting *nesting; - bool has_error; -}; - -#define ASN1_APPLICATION(x) ((x)+0x60) -#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40) -#define ASN1_SEQUENCE(x) ((x)+0x30) -#define ASN1_CONTEXT(x) ((x)+0xa0) -#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80) -#define ASN1_GENERAL_STRING 0x1b -#define ASN1_OCTET_STRING 0x4 -#define ASN1_OID 0x6 -#define ASN1_BOOLEAN 0x1 -#define ASN1_INTEGER 0x2 -#define ASN1_ENUMERATED 0xa -#define ASN1_SET 0x31 - -#define ASN1_MAX_OIDS 20 - -#include "libcli/util/asn1_proto.h" - -#endif /* _ASN_1_H */ -- cgit From b126f1ca4d71b6801032478d8c56453593b27825 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 20 Jan 2008 16:24:11 +0100 Subject: python: Reenable modules for libcli_nbt and libcli_smb. (This used to be commit 4fa8a2789c7a2fa912645f08ca5a3be891d173dd) --- source4/libcli/config.mk | 27 +-- source4/libcli/swig/libcli_nbt.i | 1 + source4/libcli/swig/libcli_nbt.py | 117 ++++------- source4/libcli/swig/libcli_nbt_wrap.c | 375 ++++++++++++++++++---------------- source4/libcli/swig/libcli_smb.i | 3 +- source4/libcli/swig/libcli_smb.py | 11 +- source4/libcli/swig/libcli_smb_wrap.c | 229 +++++---------------- 7 files changed, 317 insertions(+), 446 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index eb3c56cf7f..a538d607bb 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -50,17 +50,13 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL -[LIBRARY::swig_libcli_nbt] -LIBRARY_REALNAME = swig/_libcli_nbt.$(SHLIBEXT) -OBJ_FILES = swig/libcli_nbt_wrap.o +[PYTHON::python_libcli_nbt] +SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-CONFIG -ENABLE = NO -[LIBRARY::swig_libcli_smb] -LIBRARY_REALNAME = swig/_libcli_smb.$(SHLIBEXT) -OBJ_FILES = swig/libcli_smb_wrap.o +[PYTHON::python_libcli_smb] +SWIG_FILE = swig/libcli_smb.i PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-CONFIG -ENABLE = NO [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ @@ -71,20 +67,14 @@ OBJ_FILES = \ dgram/browse.o PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE -[LIBRARY::LIBCLI_CLDAP] -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = CLDAP client library +[SUBSYSTEM::LIBCLI_CLDAP] OBJ_FILES = cldap/cldap.o PUBLIC_HEADERS = cldap/cldap.h PUBLIC_DEPENDENCIES = LIBCLI_LDAP PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB -[LIBRARY::LIBCLI_WREPL] +[SUBSYSTEM::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = WINS Replication client library OBJ_FILES = \ wrepl/winsrepl.o PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \ @@ -112,12 +102,9 @@ OBJ_FILES = \ finddcs.o PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING -[LIBRARY::LIBCLI_SMB] +[SUBSYSTEM::LIBCLI_SMB] PUBLIC_HEADERS = libcli.h PUBLIC_PROTO_HEADER = libcli_proto.h -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = SMB/CIFS client library OBJ_FILES = clireadwrite.o \ cliconnect.o \ clifile.o \ diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index 6fd85c2b8c..827230b113 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -31,6 +31,7 @@ #include "lib/talloc/talloc.h" #include "libcli/nbt/libnbt.h" #include "param/param.h" +#include "lib/events/events.h" /* Undo strcpy safety macro as it's used by swig )-: */ diff --git a/source4/libcli/swig/libcli_nbt.py b/source4/libcli/swig/libcli_nbt.py index 938ab382f6..b49e240bc2 100644 --- a/source4/libcli/swig/libcli_nbt.py +++ b/source4/libcli/swig/libcli_nbt.py @@ -2,7 +2,6 @@ # Version 1.3.33 # # Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. import _libcli_nbt import new @@ -48,6 +47,16 @@ except AttributeError: del types +def _swig_setattr_nondynamic_method(set): + def set_attr(self,name,value): + if (name == "thisown"): return self.this.own(value) + if hasattr(self,name) or (name == "this"): + set(self,name,value) + else: + raise AttributeError("You cannot add attributes to %s" % self) + return set_attr + + import events nbt_name_socket_init = _libcli_nbt.nbt_name_socket_init NBT_NAME_CLIENT = _libcli_nbt.NBT_NAME_CLIENT @@ -58,106 +67,54 @@ NBT_NAME_PDC = _libcli_nbt.NBT_NAME_PDC NBT_NAME_LOGON = _libcli_nbt.NBT_NAME_LOGON NBT_NAME_MASTER = _libcli_nbt.NBT_NAME_MASTER NBT_NAME_BROWSER = _libcli_nbt.NBT_NAME_BROWSER -class nbt_name(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, nbt_name, name) +class nbt_name(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - __swig_setmethods__["name"] = _libcli_nbt.nbt_name_name_set - __swig_getmethods__["name"] = _libcli_nbt.nbt_name_name_get - if _newclass:name = _swig_property(_libcli_nbt.nbt_name_name_get, _libcli_nbt.nbt_name_name_set) - __swig_setmethods__["scope"] = _libcli_nbt.nbt_name_scope_set - __swig_getmethods__["scope"] = _libcli_nbt.nbt_name_scope_get - if _newclass:scope = _swig_property(_libcli_nbt.nbt_name_scope_get, _libcli_nbt.nbt_name_scope_set) - __swig_setmethods__["type"] = _libcli_nbt.nbt_name_type_set - __swig_getmethods__["type"] = _libcli_nbt.nbt_name_type_get - if _newclass:type = _swig_property(_libcli_nbt.nbt_name_type_get, _libcli_nbt.nbt_name_type_set) + name = _swig_property(_libcli_nbt.nbt_name_name_get, _libcli_nbt.nbt_name_name_set) + scope = _swig_property(_libcli_nbt.nbt_name_scope_get, _libcli_nbt.nbt_name_scope_set) + type = _swig_property(_libcli_nbt.nbt_name_type_get, _libcli_nbt.nbt_name_type_set) def __init__(self, *args, **kwargs): - this = _libcli_nbt.new_nbt_name(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _libcli_nbt.nbt_name_swiginit(self,_libcli_nbt.new_nbt_name(*args, **kwargs)) __swig_destroy__ = _libcli_nbt.delete_nbt_name - __del__ = lambda self : None; nbt_name_swigregister = _libcli_nbt.nbt_name_swigregister nbt_name_swigregister(nbt_name) -class nbt_name_query(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name_query, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, nbt_name_query, name) +class nbt_name_query(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - __swig_getmethods__["data_out"] = _libcli_nbt.nbt_name_query_data_out_get - if _newclass:data_out = _swig_property(_libcli_nbt.nbt_name_query_data_out_get) - __swig_getmethods__["data_in"] = _libcli_nbt.nbt_name_query_data_in_get - if _newclass:data_in = _swig_property(_libcli_nbt.nbt_name_query_data_in_get) + data_out = _swig_property(_libcli_nbt.nbt_name_query_data_out_get) + data_in = _swig_property(_libcli_nbt.nbt_name_query_data_in_get) def __init__(self, *args, **kwargs): - this = _libcli_nbt.new_nbt_name_query(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _libcli_nbt.nbt_name_query_swiginit(self,_libcli_nbt.new_nbt_name_query(*args, **kwargs)) __swig_destroy__ = _libcli_nbt.delete_nbt_name_query - __del__ = lambda self : None; nbt_name_query_swigregister = _libcli_nbt.nbt_name_query_swigregister nbt_name_query_swigregister(nbt_name_query) -class nbt_name_query_out(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name_query_out, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, nbt_name_query_out, name) +class nbt_name_query_out(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - __swig_setmethods__["reply_from"] = _libcli_nbt.nbt_name_query_out_reply_from_set - __swig_getmethods__["reply_from"] = _libcli_nbt.nbt_name_query_out_reply_from_get - if _newclass:reply_from = _swig_property(_libcli_nbt.nbt_name_query_out_reply_from_get, _libcli_nbt.nbt_name_query_out_reply_from_set) - __swig_setmethods__["name"] = _libcli_nbt.nbt_name_query_out_name_set - __swig_getmethods__["name"] = _libcli_nbt.nbt_name_query_out_name_get - if _newclass:name = _swig_property(_libcli_nbt.nbt_name_query_out_name_get, _libcli_nbt.nbt_name_query_out_name_set) - __swig_setmethods__["num_addrs"] = _libcli_nbt.nbt_name_query_out_num_addrs_set - __swig_getmethods__["num_addrs"] = _libcli_nbt.nbt_name_query_out_num_addrs_get - if _newclass:num_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_num_addrs_get, _libcli_nbt.nbt_name_query_out_num_addrs_set) - __swig_setmethods__["reply_addrs"] = _libcli_nbt.nbt_name_query_out_reply_addrs_set - __swig_getmethods__["reply_addrs"] = _libcli_nbt.nbt_name_query_out_reply_addrs_get - if _newclass:reply_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_reply_addrs_get, _libcli_nbt.nbt_name_query_out_reply_addrs_set) + reply_from = _swig_property(_libcli_nbt.nbt_name_query_out_reply_from_get, _libcli_nbt.nbt_name_query_out_reply_from_set) + name = _swig_property(_libcli_nbt.nbt_name_query_out_name_get, _libcli_nbt.nbt_name_query_out_name_set) + num_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_num_addrs_get, _libcli_nbt.nbt_name_query_out_num_addrs_set) + reply_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_reply_addrs_get, _libcli_nbt.nbt_name_query_out_reply_addrs_set) def __init__(self, *args, **kwargs): - this = _libcli_nbt.new_nbt_name_query_out(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _libcli_nbt.nbt_name_query_out_swiginit(self,_libcli_nbt.new_nbt_name_query_out(*args, **kwargs)) __swig_destroy__ = _libcli_nbt.delete_nbt_name_query_out - __del__ = lambda self : None; nbt_name_query_out_swigregister = _libcli_nbt.nbt_name_query_out_swigregister nbt_name_query_out_swigregister(nbt_name_query_out) -class nbt_name_query_in(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, nbt_name_query_in, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, nbt_name_query_in, name) +class nbt_name_query_in(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - __swig_setmethods__["name"] = _libcli_nbt.nbt_name_query_in_name_set - __swig_getmethods__["name"] = _libcli_nbt.nbt_name_query_in_name_get - if _newclass:name = _swig_property(_libcli_nbt.nbt_name_query_in_name_get, _libcli_nbt.nbt_name_query_in_name_set) - __swig_setmethods__["dest_addr"] = _libcli_nbt.nbt_name_query_in_dest_addr_set - __swig_getmethods__["dest_addr"] = _libcli_nbt.nbt_name_query_in_dest_addr_get - if _newclass:dest_addr = _swig_property(_libcli_nbt.nbt_name_query_in_dest_addr_get, _libcli_nbt.nbt_name_query_in_dest_addr_set) - __swig_setmethods__["broadcast"] = _libcli_nbt.nbt_name_query_in_broadcast_set - __swig_getmethods__["broadcast"] = _libcli_nbt.nbt_name_query_in_broadcast_get - if _newclass:broadcast = _swig_property(_libcli_nbt.nbt_name_query_in_broadcast_get, _libcli_nbt.nbt_name_query_in_broadcast_set) - __swig_setmethods__["wins_lookup"] = _libcli_nbt.nbt_name_query_in_wins_lookup_set - __swig_getmethods__["wins_lookup"] = _libcli_nbt.nbt_name_query_in_wins_lookup_get - if _newclass:wins_lookup = _swig_property(_libcli_nbt.nbt_name_query_in_wins_lookup_get, _libcli_nbt.nbt_name_query_in_wins_lookup_set) - __swig_setmethods__["timeout"] = _libcli_nbt.nbt_name_query_in_timeout_set - __swig_getmethods__["timeout"] = _libcli_nbt.nbt_name_query_in_timeout_get - if _newclass:timeout = _swig_property(_libcli_nbt.nbt_name_query_in_timeout_get, _libcli_nbt.nbt_name_query_in_timeout_set) - __swig_setmethods__["retries"] = _libcli_nbt.nbt_name_query_in_retries_set - __swig_getmethods__["retries"] = _libcli_nbt.nbt_name_query_in_retries_get - if _newclass:retries = _swig_property(_libcli_nbt.nbt_name_query_in_retries_get, _libcli_nbt.nbt_name_query_in_retries_set) + name = _swig_property(_libcli_nbt.nbt_name_query_in_name_get, _libcli_nbt.nbt_name_query_in_name_set) + dest_addr = _swig_property(_libcli_nbt.nbt_name_query_in_dest_addr_get, _libcli_nbt.nbt_name_query_in_dest_addr_set) + broadcast = _swig_property(_libcli_nbt.nbt_name_query_in_broadcast_get, _libcli_nbt.nbt_name_query_in_broadcast_set) + wins_lookup = _swig_property(_libcli_nbt.nbt_name_query_in_wins_lookup_get, _libcli_nbt.nbt_name_query_in_wins_lookup_set) + timeout = _swig_property(_libcli_nbt.nbt_name_query_in_timeout_get, _libcli_nbt.nbt_name_query_in_timeout_set) + retries = _swig_property(_libcli_nbt.nbt_name_query_in_retries_get, _libcli_nbt.nbt_name_query_in_retries_set) def __init__(self, *args, **kwargs): - this = _libcli_nbt.new_nbt_name_query_in(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _libcli_nbt.nbt_name_query_in_swiginit(self,_libcli_nbt.new_nbt_name_query_in(*args, **kwargs)) __swig_destroy__ = _libcli_nbt.delete_nbt_name_query_in - __del__ = lambda self : None; nbt_name_query_in_swigregister = _libcli_nbt.nbt_name_query_in_swigregister nbt_name_query_in_swigregister(nbt_name_query_in) diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c index 149e63884a..6c1b501359 100644 --- a/source4/libcli/swig/libcli_nbt_wrap.c +++ b/source4/libcli/swig/libcli_nbt_wrap.c @@ -9,7 +9,7 @@ * ----------------------------------------------------------------------------- */ #define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +#define SWIG_PYTHON_NO_BUILD_NONE /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. @@ -2485,6 +2485,19 @@ static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; # error "This python version requires swig to be run with the '-classic' option" # endif #endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodern' option" +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodernargs' option" +#endif +#ifndef METH_O +# error "This python version requires swig to be run with the '-nofastunpack' option" +#endif +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery /*----------------------------------------------- @(target):= _libcli_nbt.so @@ -2506,6 +2519,7 @@ static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; #include "lib/talloc/talloc.h" #include "libcli/nbt/libnbt.h" #include "param/param.h" +#include "lib/events/events.h" /* Undo strcpy safety macro as it's used by swig )-: */ @@ -2912,12 +2926,8 @@ SWIGINTERN PyObject *_wrap_nbt_name_socket_init(PyObject *SWIGUNUSEDPARM(self), (char *) "event_ctx", NULL }; - { - arg2 = event_context_init(NULL); - } - { - arg1 = NULL; - } + arg2 = event_context_init(NULL); + arg1 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|O:nbt_name_socket_init",kwnames,&obj0)) SWIG_fail; if (obj0) { res2 = SWIG_ConvertPtr(obj0, &argp2,SWIGTYPE_p_event_context, 0 | 0 ); @@ -2943,16 +2953,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_name_set(PyObject *SWIGUNUSEDPARM(self), PyO int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_name_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_name_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_name_set" "', argument " "1"" of type '" "struct nbt_name *""'"); } arg1 = (struct nbt_name *)(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_name_set" "', argument " "2"" of type '" "char const *""'"); } @@ -2978,10 +2987,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_name_get(PyObject *SWIGUNUSEDPARM(self), PyO char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_name_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_name_get" "', argument " "1"" of type '" "struct nbt_name *""'"); } @@ -3003,16 +3013,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_scope_set(PyObject *SWIGUNUSEDPARM(self), Py int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_scope_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_scope_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_scope_set" "', argument " "1"" of type '" "struct nbt_name *""'"); } arg1 = (struct nbt_name *)(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_scope_set" "', argument " "2"" of type '" "char const *""'"); } @@ -3038,10 +3047,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_scope_get(PyObject *SWIGUNUSEDPARM(self), Py char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_scope_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_scope_get" "', argument " "1"" of type '" "struct nbt_name *""'"); } @@ -3062,16 +3072,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_type_set(PyObject *SWIGUNUSEDPARM(self), PyO int res1 = 0 ; int val2 ; int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_type_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_type_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_type_set" "', argument " "1"" of type '" "struct nbt_name *""'"); } arg1 = (struct nbt_name *)(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_type_set" "', argument " "2"" of type '" "enum nbt_name_type""'"); } @@ -3091,10 +3100,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_type_get(PyObject *SWIGUNUSEDPARM(self), PyO enum nbt_name_type result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_type_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_type_get" "', argument " "1"" of type '" "struct nbt_name *""'"); } @@ -3111,7 +3121,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject PyObject *resultobj = 0; struct nbt_name *result = 0 ; - if (!PyArg_ParseTuple(args,(char *)":new_nbt_name")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_nbt_name",0,0,0)) SWIG_fail; result = (struct nbt_name *)(struct nbt_name *) calloc(1, sizeof(struct nbt_name)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3125,10 +3135,11 @@ SWIGINTERN PyObject *_wrap_delete_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObj struct nbt_name *arg1 = (struct nbt_name *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name" "', argument " "1"" of type '" "struct nbt_name *""'"); } @@ -3144,21 +3155,26 @@ fail: SWIGINTERN PyObject *nbt_name_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *nbt_name_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_nbt_name_query_data_out_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; nbt_name_query_out *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_data_out_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_data_out_get" "', argument " "1"" of type '" "struct nbt_name_query *""'"); } @@ -3177,10 +3193,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_data_in_get(PyObject *SWIGUNUSEDPARM(s nbt_name_query_in *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_data_in_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_data_in_get" "', argument " "1"" of type '" "struct nbt_name_query *""'"); } @@ -3197,7 +3214,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), Py PyObject *resultobj = 0; struct nbt_name_query *result = 0 ; - if (!PyArg_ParseTuple(args,(char *)":new_nbt_name_query")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query",0,0,0)) SWIG_fail; result = (struct nbt_name_query *)(struct nbt_name_query *) calloc(1, sizeof(struct nbt_name_query)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3211,10 +3228,11 @@ SWIGINTERN PyObject *_wrap_delete_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name_query",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query" "', argument " "1"" of type '" "struct nbt_name_query *""'"); } @@ -3230,11 +3248,15 @@ fail: SWIGINTERN PyObject *nbt_name_query_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *nbt_name_query_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; @@ -3244,16 +3266,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_set(PyObject *SWIGUNUSE int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_reply_from_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_reply_from_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_from_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } arg1 = (nbt_name_query_out *)(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_reply_from_set" "', argument " "2"" of type '" "char const *""'"); } @@ -3279,10 +3300,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_get(PyObject *SWIGUNUSE char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_reply_from_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_from_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } @@ -3303,16 +3325,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_name_set(PyObject *SWIGUNUSEDPARM( int res1 = 0 ; void *argp2 = 0 ; int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_name_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_name_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_name_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } arg1 = (nbt_name_query_out *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_name_set" "', argument " "2"" of type '" "struct nbt_name *""'"); } @@ -3332,10 +3353,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_name_get(PyObject *SWIGUNUSEDPARM( struct nbt_name *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_name_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_name_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } @@ -3356,16 +3378,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_num_addrs_set(PyObject *SWIGUNUSED int res1 = 0 ; short val2 ; int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_num_addrs_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_num_addrs_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_num_addrs_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } arg1 = (nbt_name_query_out *)(argp1); - ecode2 = SWIG_AsVal_short(obj1, &val2); + ecode2 = SWIG_AsVal_short(swig_obj[1], &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_out_num_addrs_set" "', argument " "2"" of type '" "int16_t""'"); } @@ -3385,10 +3406,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_num_addrs_get(PyObject *SWIGUNUSED int16_t result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_num_addrs_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_num_addrs_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } @@ -3409,16 +3431,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_addrs_set(PyObject *SWIGUNUS int res1 = 0 ; void *argp2 = 0 ; int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_out_reply_addrs_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_reply_addrs_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_addrs_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } arg1 = (nbt_name_query_out *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_char, 0 | 0 ); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_p_char, 0 | 0 ); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_reply_addrs_set" "', argument " "2"" of type '" "char const **""'"); } @@ -3438,10 +3459,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_addrs_get(PyObject *SWIGUNUS char **result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_out_reply_addrs_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_addrs_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } @@ -3458,7 +3480,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self) PyObject *resultobj = 0; nbt_name_query_out *result = 0 ; - if (!PyArg_ParseTuple(args,(char *)":new_nbt_name_query_out")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_out",0,0,0)) SWIG_fail; result = (nbt_name_query_out *)(nbt_name_query_out *) calloc(1, sizeof(nbt_name_query_out)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3472,10 +3494,11 @@ SWIGINTERN PyObject *_wrap_delete_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(se nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name_query_out",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query_out" "', argument " "1"" of type '" "nbt_name_query_out *""'"); } @@ -3491,11 +3514,15 @@ fail: SWIGINTERN PyObject *nbt_name_query_out_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query_out, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *nbt_name_query_out_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; @@ -3504,16 +3531,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_set(PyObject *SWIGUNUSEDPARM(s int res1 = 0 ; void *argp2 = 0 ; int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_name_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_name_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_name_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } arg1 = (nbt_name_query_in *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_in_name_set" "', argument " "2"" of type '" "struct nbt_name *""'"); } @@ -3533,10 +3559,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_get(PyObject *SWIGUNUSEDPARM(s struct nbt_name *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_name_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_name_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3558,16 +3585,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_dest_addr_set(PyObject *SWIGUNUSEDP int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_dest_addr_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_dest_addr_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_dest_addr_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } arg1 = (nbt_name_query_in *)(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_in_dest_addr_set" "', argument " "2"" of type '" "char const *""'"); } @@ -3593,10 +3619,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_dest_addr_get(PyObject *SWIGUNUSEDP char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_dest_addr_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_dest_addr_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3617,16 +3644,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_broadcast_set(PyObject *SWIGUNUSEDP int res1 = 0 ; bool val2 ; int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_broadcast_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_broadcast_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_broadcast_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_broadcast_set" "', argument " "2"" of type '" "bool""'"); } @@ -3646,10 +3672,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_broadcast_get(PyObject *SWIGUNUSEDP bool result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_broadcast_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_broadcast_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3670,16 +3697,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_wins_lookup_set(PyObject *SWIGUNUSE int res1 = 0 ; bool val2 ; int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_wins_lookup_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_wins_lookup_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_wins_lookup_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_wins_lookup_set" "', argument " "2"" of type '" "bool""'"); } @@ -3699,10 +3725,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_wins_lookup_get(PyObject *SWIGUNUSE bool result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_wins_lookup_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_wins_lookup_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3723,16 +3750,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_timeout_set(PyObject *SWIGUNUSEDPAR int res1 = 0 ; int val2 ; int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_timeout_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_timeout_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_timeout_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_timeout_set" "', argument " "2"" of type '" "int""'"); } @@ -3752,10 +3778,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_timeout_get(PyObject *SWIGUNUSEDPAR int result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_timeout_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_timeout_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3776,16 +3803,15 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_retries_set(PyObject *SWIGUNUSEDPAR int res1 = 0 ; int val2 ; int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; + PyObject *swig_obj[2] ; - if (!PyArg_ParseTuple(args,(char *)"OO:nbt_name_query_in_retries_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_retries_set",2,2,swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_retries_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_retries_set" "', argument " "2"" of type '" "int""'"); } @@ -3805,10 +3831,11 @@ SWIGINTERN PyObject *_wrap_nbt_name_query_in_retries_get(PyObject *SWIGUNUSEDPAR int result; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:nbt_name_query_in_retries_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_retries_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3825,7 +3852,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self), PyObject *resultobj = 0; nbt_name_query_in *result = 0 ; - if (!PyArg_ParseTuple(args,(char *)":new_nbt_name_query_in")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_in",0,0,0)) SWIG_fail; result = (nbt_name_query_in *)(nbt_name_query_in *) calloc(1, sizeof(nbt_name_query_in)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3839,10 +3866,11 @@ SWIGINTERN PyObject *_wrap_delete_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(sel nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_nbt_name_query_in",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query_in" "', argument " "1"" of type '" "nbt_name_query_in *""'"); } @@ -3858,11 +3886,15 @@ fail: SWIGINTERN PyObject *nbt_name_query_in_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query_in, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *nbt_name_query_in_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_new_char_ptr_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; size_t arg1 ; @@ -4007,9 +4039,7 @@ SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyO (char *) "nbtsock",(char *) "io", NULL }; - { - arg2 = NULL; - } + arg2 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:do_nbt_name_query",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_socket, 0 | 0 ); if (!SWIG_IsOK(res1)) { @@ -4022,13 +4052,12 @@ SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyO } arg3 = (struct nbt_name_query *)(argp3); result = do_nbt_name_query(arg1,arg2,arg3); - { - if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (NT_STATUS_IS_ERR(result)) { + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -4039,45 +4068,49 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"nbt_name_socket_init", (PyCFunction) _wrap_nbt_name_socket_init, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"nbt_name_name_set", _wrap_nbt_name_name_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_name_get", _wrap_nbt_name_name_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_name_get", (PyCFunction)_wrap_nbt_name_name_get, METH_O, NULL}, { (char *)"nbt_name_scope_set", _wrap_nbt_name_scope_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_scope_get", _wrap_nbt_name_scope_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_scope_get", (PyCFunction)_wrap_nbt_name_scope_get, METH_O, NULL}, { (char *)"nbt_name_type_set", _wrap_nbt_name_type_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_type_get", _wrap_nbt_name_type_get, METH_VARARGS, NULL}, - { (char *)"new_nbt_name", _wrap_new_nbt_name, METH_VARARGS, NULL}, - { (char *)"delete_nbt_name", _wrap_delete_nbt_name, METH_VARARGS, NULL}, + { (char *)"nbt_name_type_get", (PyCFunction)_wrap_nbt_name_type_get, METH_O, NULL}, + { (char *)"new_nbt_name", (PyCFunction)_wrap_new_nbt_name, METH_NOARGS, NULL}, + { (char *)"delete_nbt_name", (PyCFunction)_wrap_delete_nbt_name, METH_O, NULL}, { (char *)"nbt_name_swigregister", nbt_name_swigregister, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_data_out_get", _wrap_nbt_name_query_data_out_get, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_data_in_get", _wrap_nbt_name_query_data_in_get, METH_VARARGS, NULL}, - { (char *)"new_nbt_name_query", _wrap_new_nbt_name_query, METH_VARARGS, NULL}, - { (char *)"delete_nbt_name_query", _wrap_delete_nbt_name_query, METH_VARARGS, NULL}, + { (char *)"nbt_name_swiginit", nbt_name_swiginit, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_data_out_get", (PyCFunction)_wrap_nbt_name_query_data_out_get, METH_O, NULL}, + { (char *)"nbt_name_query_data_in_get", (PyCFunction)_wrap_nbt_name_query_data_in_get, METH_O, NULL}, + { (char *)"new_nbt_name_query", (PyCFunction)_wrap_new_nbt_name_query, METH_NOARGS, NULL}, + { (char *)"delete_nbt_name_query", (PyCFunction)_wrap_delete_nbt_name_query, METH_O, NULL}, { (char *)"nbt_name_query_swigregister", nbt_name_query_swigregister, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_swiginit", nbt_name_query_swiginit, METH_VARARGS, NULL}, { (char *)"nbt_name_query_out_reply_from_set", _wrap_nbt_name_query_out_reply_from_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_reply_from_get", _wrap_nbt_name_query_out_reply_from_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_reply_from_get", (PyCFunction)_wrap_nbt_name_query_out_reply_from_get, METH_O, NULL}, { (char *)"nbt_name_query_out_name_set", _wrap_nbt_name_query_out_name_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_name_get", _wrap_nbt_name_query_out_name_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_name_get", (PyCFunction)_wrap_nbt_name_query_out_name_get, METH_O, NULL}, { (char *)"nbt_name_query_out_num_addrs_set", _wrap_nbt_name_query_out_num_addrs_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_num_addrs_get", _wrap_nbt_name_query_out_num_addrs_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_num_addrs_get", (PyCFunction)_wrap_nbt_name_query_out_num_addrs_get, METH_O, NULL}, { (char *)"nbt_name_query_out_reply_addrs_set", _wrap_nbt_name_query_out_reply_addrs_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_reply_addrs_get", _wrap_nbt_name_query_out_reply_addrs_get, METH_VARARGS, NULL}, - { (char *)"new_nbt_name_query_out", _wrap_new_nbt_name_query_out, METH_VARARGS, NULL}, - { (char *)"delete_nbt_name_query_out", _wrap_delete_nbt_name_query_out, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_reply_addrs_get", (PyCFunction)_wrap_nbt_name_query_out_reply_addrs_get, METH_O, NULL}, + { (char *)"new_nbt_name_query_out", (PyCFunction)_wrap_new_nbt_name_query_out, METH_NOARGS, NULL}, + { (char *)"delete_nbt_name_query_out", (PyCFunction)_wrap_delete_nbt_name_query_out, METH_O, NULL}, { (char *)"nbt_name_query_out_swigregister", nbt_name_query_out_swigregister, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_out_swiginit", nbt_name_query_out_swiginit, METH_VARARGS, NULL}, { (char *)"nbt_name_query_in_name_set", _wrap_nbt_name_query_in_name_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_name_get", _wrap_nbt_name_query_in_name_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_name_get", (PyCFunction)_wrap_nbt_name_query_in_name_get, METH_O, NULL}, { (char *)"nbt_name_query_in_dest_addr_set", _wrap_nbt_name_query_in_dest_addr_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_dest_addr_get", _wrap_nbt_name_query_in_dest_addr_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_dest_addr_get", (PyCFunction)_wrap_nbt_name_query_in_dest_addr_get, METH_O, NULL}, { (char *)"nbt_name_query_in_broadcast_set", _wrap_nbt_name_query_in_broadcast_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_broadcast_get", _wrap_nbt_name_query_in_broadcast_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_broadcast_get", (PyCFunction)_wrap_nbt_name_query_in_broadcast_get, METH_O, NULL}, { (char *)"nbt_name_query_in_wins_lookup_set", _wrap_nbt_name_query_in_wins_lookup_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_wins_lookup_get", _wrap_nbt_name_query_in_wins_lookup_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_wins_lookup_get", (PyCFunction)_wrap_nbt_name_query_in_wins_lookup_get, METH_O, NULL}, { (char *)"nbt_name_query_in_timeout_set", _wrap_nbt_name_query_in_timeout_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_timeout_get", _wrap_nbt_name_query_in_timeout_get, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_timeout_get", (PyCFunction)_wrap_nbt_name_query_in_timeout_get, METH_O, NULL}, { (char *)"nbt_name_query_in_retries_set", _wrap_nbt_name_query_in_retries_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_retries_get", _wrap_nbt_name_query_in_retries_get, METH_VARARGS, NULL}, - { (char *)"new_nbt_name_query_in", _wrap_new_nbt_name_query_in, METH_VARARGS, NULL}, - { (char *)"delete_nbt_name_query_in", _wrap_delete_nbt_name_query_in, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_retries_get", (PyCFunction)_wrap_nbt_name_query_in_retries_get, METH_O, NULL}, + { (char *)"new_nbt_name_query_in", (PyCFunction)_wrap_new_nbt_name_query_in, METH_NOARGS, NULL}, + { (char *)"delete_nbt_name_query_in", (PyCFunction)_wrap_delete_nbt_name_query_in, METH_O, NULL}, { (char *)"nbt_name_query_in_swigregister", nbt_name_query_in_swigregister, METH_VARARGS, NULL}, + { (char *)"nbt_name_query_in_swiginit", nbt_name_query_in_swiginit, METH_VARARGS, NULL}, { (char *)"new_char_ptr_array", (PyCFunction) _wrap_new_char_ptr_array, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"delete_char_ptr_array", (PyCFunction) _wrap_delete_char_ptr_array, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"char_ptr_array_getitem", (PyCFunction) _wrap_char_ptr_array_getitem, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -4091,7 +4124,7 @@ static PyMethodDef SwigMethods[] = { static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *|event *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_nbt_name = {"_p_nbt_name", "struct nbt_name *|nbt_name *", 0, 0, (void*)0, 0}; diff --git a/source4/libcli/swig/libcli_smb.i b/source4/libcli/swig/libcli_smb.i index 32e043b2c6..4125bcf5a9 100644 --- a/source4/libcli/swig/libcli_smb.i +++ b/source4/libcli/swig/libcli_smb.i @@ -9,8 +9,9 @@ #include "libcli/raw/libcliraw.h" %} -struct smbcli_socket *smbcli_sock_connect_byname(const char *host, int port, +struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, TALLOC_CTX *mem_ctx, + struct resolve_context *resolve_ctx, struct event_context *event_ctx); void smbcli_sock_dead(struct smbcli_socket *sock); diff --git a/source4/libcli/swig/libcli_smb.py b/source4/libcli/swig/libcli_smb.py index 466a04b9eb..80c4040237 100644 --- a/source4/libcli/swig/libcli_smb.py +++ b/source4/libcli/swig/libcli_smb.py @@ -2,7 +2,6 @@ # Version 1.3.33 # # Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. import _libcli_smb import new @@ -48,6 +47,16 @@ except AttributeError: del types +def _swig_setattr_nondynamic_method(set): + def set_attr(self,name,value): + if (name == "thisown"): return self.this.own(value) + if hasattr(self,name) or (name == "this"): + set(self,name,value) + else: + raise AttributeError("You cannot add attributes to %s" % self) + return set_attr + + import events smbcli_sock_connect_byname = _libcli_smb.smbcli_sock_connect_byname smbcli_sock_dead = _libcli_smb.smbcli_sock_dead diff --git a/source4/libcli/swig/libcli_smb_wrap.c b/source4/libcli/swig/libcli_smb_wrap.c index 313bcfeed3..8b71f2c3be 100644 --- a/source4/libcli/swig/libcli_smb_wrap.c +++ b/source4/libcli/swig/libcli_smb_wrap.c @@ -9,7 +9,7 @@ * ----------------------------------------------------------------------------- */ #define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +#define SWIG_PYTHON_NO_BUILD_NONE /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. @@ -2459,9 +2459,11 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_TALLOC_CTX swig_types[0] #define SWIGTYPE_p_char swig_types[1] #define SWIGTYPE_p_event_context swig_types[2] -#define SWIGTYPE_p_smbcli_socket swig_types[3] -static swig_type_info *swig_types[5]; -static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0}; +#define SWIGTYPE_p_p_char swig_types[3] +#define SWIGTYPE_p_resolve_context swig_types[4] +#define SWIGTYPE_p_smbcli_socket swig_types[5] +static swig_type_info *swig_types[7]; +static swig_module_info swig_module = {swig_types, 6, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2472,6 +2474,19 @@ static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0}; # error "This python version requires swig to be run with the '-classic' option" # endif #endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodern' option" +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodernargs' option" +#endif +#ifndef METH_O +# error "This python version requires swig to be run with the '-nofastunpack' option" +#endif +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery /*----------------------------------------------- @(target):= _libcli_smb.so @@ -2560,200 +2575,60 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) - -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; - } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (int)(v); - } - } - return res; -} - #ifdef __cplusplus extern "C" { #endif SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; char *arg1 = (char *) 0 ; - int arg2 ; + char **arg2 = (char **) 0 ; TALLOC_CTX *arg3 = (TALLOC_CTX *) 0 ; - struct event_context *arg4 = (struct event_context *) 0 ; + struct resolve_context *arg4 = (struct resolve_context *) 0 ; + struct event_context *arg5 = (struct event_context *) 0 ; struct smbcli_socket *result = 0 ; int res1 ; char *buf1 = 0 ; int alloc1 = 0 ; - int val2 ; - int ecode2 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; void *argp4 = 0 ; int res4 = 0 ; + void *argp5 = 0 ; + int res5 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; char * kwnames[] = { - (char *) "host",(char *) "port",(char *) "event_ctx", NULL + (char *) "host",(char *) "ports",(char *) "resolve_ctx",(char *) "event_ctx", NULL }; - { - arg4 = event_context_init(NULL); - } - { - arg3 = NULL; - } - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO|O:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + arg5 = event_context_init(NULL); + arg3 = NULL; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smbcli_sock_connect_byname" "', argument " "1"" of type '" "char const *""'"); } arg1 = (char *)(buf1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "smbcli_sock_connect_byname" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - if (obj2) { - res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "smbcli_sock_connect_byname" "', argument " "4"" of type '" "struct event_context *""'"); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_char, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "smbcli_sock_connect_byname" "', argument " "2"" of type '" "char const **""'"); + } + arg2 = (char **)(argp2); + res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_resolve_context, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "smbcli_sock_connect_byname" "', argument " "4"" of type '" "struct resolve_context *""'"); + } + arg4 = (struct resolve_context *)(argp4); + if (obj3) { + res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_event_context, 0 | 0 ); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "smbcli_sock_connect_byname" "', argument " "5"" of type '" "struct event_context *""'"); } - arg4 = (struct event_context *)(argp4); + arg5 = (struct event_context *)(argp5); } - result = (struct smbcli_socket *)smbcli_sock_connect_byname((char const *)arg1,arg2,arg3,arg4); + result = (struct smbcli_socket *)smbcli_sock_connect_byname((char const *)arg1,(char const **)arg2,arg3,arg4,arg5); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_smbcli_socket, 0 | 0 ); if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return resultobj; @@ -2798,25 +2673,33 @@ static PyMethodDef SwigMethods[] = { static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *|event *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_resolve_context = {"_p_resolve_context", "struct resolve_context *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_smbcli_socket = {"_p_smbcli_socket", "struct smbcli_socket *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { &_swigt__p_TALLOC_CTX, &_swigt__p_char, &_swigt__p_event_context, + &_swigt__p_p_char, + &_swigt__p_resolve_context, &_swigt__p_smbcli_socket, }; static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_resolve_context[] = { {&_swigt__p_resolve_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_smbcli_socket[] = { {&_swigt__p_smbcli_socket, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { _swigc__p_TALLOC_CTX, _swigc__p_char, _swigc__p_event_context, + _swigc__p_p_char, + _swigc__p_resolve_context, _swigc__p_smbcli_socket, }; -- cgit From a2595477869d5fee2f916bc857ca028e3b2fc677 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 22 Jan 2008 18:49:51 +0100 Subject: build: Remove support for DESCRIPTION setting that is now unused. (This used to be commit 91d7ba5202e6c375456a42c2c6861f63c7fcfc20) --- source4/libcli/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index a538d607bb..cf87e6c045 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -39,7 +39,6 @@ OBJ_FILES = nbt/nbtname.o [SUBSYSTEM::LIBCLI_NBT] #VERSION = 0.0.1 #SO_VERSION = 0 -#DESCRIPTION = NetBios over TCP/IP client library PRIVATE_PROTO_HEADER = nbt/nbt_proto.h OBJ_FILES = \ nbt/nbtsocket.o \ -- cgit From ccc27e681cbd6283513b929d58f2ebce35e6658b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 12:54:44 +1100 Subject: fixed up the .in side of SMB2 negprot fixed the input side of the SMB2 negprot structure and parsers according to the documentation (This used to be commit 55af8acc7b32c24e4b1187e9d8d1c8f060e914b0) --- source4/libcli/smb2/connect.c | 8 +++++++- source4/libcli/smb2/negprot.c | 31 ++++++++++++++++++++++++------- source4/libcli/smb2/smb2_calls.h | 13 ++++++++----- 3 files changed, 39 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 4518203183..a2ae828fa5 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -120,6 +120,7 @@ static void continue_socket(struct composite_context *creq) struct smbcli_socket *sock; struct smb2_transport *transport; struct smb2_request *req; + uint16_t dialects[1]; c->status = smbcli_sock_connect_recv(creq, state, &sock); if (!composite_is_ok(c)) return; @@ -128,7 +129,12 @@ static void continue_socket(struct composite_context *creq) if (composite_nomem(transport, c)) return; ZERO_STRUCT(state->negprot); - state->negprot.in.unknown1 = 0x0001; + state->negprot.in.dialect_count = 1; + state->negprot.in.security_mode = 0; + state->negprot.in.capabilities = 0; + unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); + dialects[0] = 0; + state->negprot.in.dialects = dialects; req = smb2_negprot_send(transport, &state->negprot); if (composite_nomem(req, c)) return; diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 38fe0e7e53..a678ebe229 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -31,16 +31,33 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, struct smb2_negprot *io) { struct smb2_request *req; - - req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26, false, 0); + uint16_t size = 0x24 + io->in.dialect_count*2; + DATA_BLOB guid_blob; + enum ndr_err_code ndr_err; + int i; + + req = smb2_request_init(transport, SMB2_OP_NEGPROT, size, false, 0); if (req == NULL) return NULL; - /* this seems to be a bug, they use 0x24 but the length is 0x26 */ - SSVAL(req->out.body, 0x00, 0x24); - SSVAL(req->out.body, 0x02, io->in.unknown1); - memcpy(req->out.body+0x04, io->in.unknown2, 32); - SSVAL(req->out.body, 0x24, io->in.unknown3); + ndr_err = ndr_push_struct_blob(&guid_blob, req, NULL, + &io->in.client_guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || guid_blob.length != 16) { + talloc_free(req); + return NULL; + } + + SSVAL(req->out.body, 0x00, 0x24); + SSVAL(req->out.body, 0x02, io->in.dialect_count); + SSVAL(req->out.body, 0x04, io->in.security_mode); + SSVAL(req->out.body, 0x06, io->in.reserved); + SIVAL(req->out.body, 0x08, io->in.capabilities); + memcpy(req->out.body+0x0C, guid_blob.data, guid_blob.length); + smbcli_push_nttime(req->out.body, 0x1C, io->in.start_time); + for (i=0;iin.dialect_count;i++) { + SSVAL(req->out.body, 0x24 + i*2, io->in.dialects[i]); + } smb2_transport_send(req); diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 6a551da4ae..41fb35b8f3 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -23,11 +23,14 @@ struct smb2_negprot { struct { - /* static body buffer 38 (0x26) bytes */ - /* uint16_t buffer_code; 0x24 (why?) */ - uint16_t unknown1; /* 0x0001 */ - uint8_t unknown2[32]; /* all zero */ - uint16_t unknown3; /* 0x00000 */ + uint16_t dialect_count; /* size of dialects array */ + uint16_t security_mode; /* 0==signing disabled + 1==signing enabled */ + uint16_t reserved; + uint32_t capabilities; + struct GUID client_guid; + NTTIME start_time; + uint16_t *dialects; } in; struct { /* static body buffer 64 (0x40) bytes */ -- cgit From 7b96c53bcbe367963da4f4fa87704e1435c35055 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 16:18:51 +1100 Subject: added some helper functions for GUID handling (This used to be commit 7d3ffd4d2b59d7c87c0a81030f349db21c071967) --- source4/libcli/raw/rawrequest.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index e7dffaf054..3551e5d441 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -972,3 +972,44 @@ size_t smbcli_blob_append_string(struct smbcli_session *session, return len; } + +/* + pull a GUID structure from the wire. The buffer must be at least 16 + bytes long + */ +enum ndr_err_code smbcli_pull_guid(void *base, uint16_t offset, + struct GUID *guid) +{ + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + enum ndr_err_code ndr_err; + + ZERO_STRUCTP(guid); + + blob.data = offset + (uint8_t *)base; + blob.length = 16; + ndr_err = ndr_pull_struct_blob(&blob, tmp_ctx, NULL, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(tmp_ctx); + return ndr_err; +} + +/* + push a guid onto the wire. The buffer must hold 16 bytes + */ +enum ndr_err_code smbcli_push_guid(void *base, uint16_t offset, + const struct GUID *guid) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + enum ndr_err_code ndr_err; + DATA_BLOB blob; + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, + guid, (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || blob.length != 16) { + talloc_free(tmp_ctx); + return ndr_err; + } + memcpy(offset + (uint8_t *)base, blob.data, blob.length); + talloc_free(tmp_ctx); + return ndr_err; +} -- cgit From 8fdb9504dcfc98080c5c2b5ce134b51ab631fa95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 16:20:13 +1100 Subject: converted the out side of SMB2 negprot handling This follows the SMB2 PFIF docs. Current versions of Vista can now connect to Samba4 as a SMB2 server and do basic operations (This used to be commit 9dc284770df9393a1a619735dc7a148713936fa7) --- source4/libcli/raw/rawnegotiate.c | 4 ++++ source4/libcli/smb2/negprot.c | 43 +++++++++++++++++++-------------------- source4/libcli/smb2/smb2_calls.h | 24 ++++++++++------------ 3 files changed, 36 insertions(+), 35 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index fc7725cc55..1f5e34779b 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -40,6 +40,10 @@ static const struct { {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, +#if 0 + /* we don't yet handle chaining a SMB transport onto SMB2 */ + {PROTOCOL_SMB2,"SMB 2.002"}, +#endif }; /* diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index a678ebe229..6b879e2add 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -32,7 +32,6 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, { struct smb2_request *req; uint16_t size = 0x24 + io->in.dialect_count*2; - DATA_BLOB guid_blob; enum ndr_err_code ndr_err; int i; @@ -40,20 +39,16 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, if (req == NULL) return NULL; - ndr_err = ndr_push_struct_blob(&guid_blob, req, NULL, - &io->in.client_guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || guid_blob.length != 16) { - talloc_free(req); - return NULL; - } - SSVAL(req->out.body, 0x00, 0x24); SSVAL(req->out.body, 0x02, io->in.dialect_count); SSVAL(req->out.body, 0x04, io->in.security_mode); SSVAL(req->out.body, 0x06, io->in.reserved); SIVAL(req->out.body, 0x08, io->in.capabilities); - memcpy(req->out.body+0x0C, guid_blob.data, guid_blob.length); + ndr_err = smbcli_push_guid(req->out.body, 0x0C, &io->in.client_guid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(req); + return NULL; + } smbcli_push_nttime(req->out.body, 0x1C, io->in.start_time); for (i=0;iin.dialect_count;i++) { SSVAL(req->out.body, 0x24 + i*2, io->in.dialects[i]); @@ -71,6 +66,7 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_negprot *io) { NTSTATUS status; + enum ndr_err_code ndr_err; if (!smb2_request_receive(req) || smb2_request_is_error(req)) { @@ -79,24 +75,27 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, SMB2_CHECK_PACKET_RECV(req, 0x40, true); - io->out._pad = SVAL(req->in.body, 0x02); - io->out.unknown2 = IVAL(req->in.body, 0x04); - memcpy(io->out.sessid, req->in.body + 0x08, 16); - io->out.unknown3 = IVAL(req->in.body, 0x18); - io->out.unknown4 = SVAL(req->in.body, 0x1C); - io->out.unknown5 = IVAL(req->in.body, 0x1E); - io->out.unknown6 = IVAL(req->in.body, 0x22); - io->out.unknown7 = SVAL(req->in.body, 0x26); - io->out.current_time = smbcli_pull_nttime(req->in.body, 0x28); - io->out.boot_time = smbcli_pull_nttime(req->in.body, 0x30); + io->out.security_mode = SVAL(req->in.body, 0x02); + io->out.dialect_revision = SVAL(req->in.body, 0x04); + io->out.reserved = SVAL(req->in.body, 0x06); + ndr_err = smbcli_pull_guid(req->in.body, 0x08, &io->in.client_guid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + smb2_request_destroy(req); + return NT_STATUS_INTERNAL_ERROR; + } + io->out.capabilities = IVAL(req->in.body, 0x18); + io->out.max_transact_size = IVAL(req->in.body, 0x1C); + io->out.max_read_size = IVAL(req->in.body, 0x20); + io->out.max_write_size = IVAL(req->in.body, 0x24); + io->out.system_time = smbcli_pull_nttime(req->in.body, 0x28); + io->out.server_start_time = smbcli_pull_nttime(req->in.body, 0x30); + io->out.reserved2 = IVAL(req->in.body, 0x3C); status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x38, &io->out.secblob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); return status; } - - io->out.unknown9 = IVAL(req->in.body, 0x3C); return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 41fb35b8f3..423d9d1579 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -35,21 +35,19 @@ struct smb2_negprot { struct { /* static body buffer 64 (0x40) bytes */ /* uint16_t buffer_code; 0x41 = 0x40 + 1 */ - uint16_t _pad; - uint32_t unknown2; /* 0x06 */ - uint8_t sessid[16]; - uint32_t unknown3; /* 0x0d */ - uint16_t unknown4; /* 0x00 */ - uint32_t unknown5; /* 0x01 */ - uint32_t unknown6; /* 0x01 */ - uint16_t unknown7; /* 0x01 */ - NTTIME current_time; - NTTIME boot_time; + uint16_t security_mode; + uint16_t dialect_revision; + uint16_t reserved; + struct GUID server_guid; + uint32_t capabilities; + uint32_t max_transact_size; + uint32_t max_read_size; + uint32_t max_write_size; + NTTIME system_time; + NTTIME server_start_time; /* uint16_t secblob_ofs */ /* uint16_t secblob_size */ - uint32_t unknown9; /* 0x204d4c20 */ - - /* dynamic body buffer */ + uint32_t reserved2; DATA_BLOB secblob; } out; }; -- cgit From 416360895f36d41ce8d29c25ef08e2b8b4e38571 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 16:43:38 +1100 Subject: converted SMB2 session setup to use WSPP protocol field names (This used to be commit 3c2af0fdc4916dce32c2690e49dde0852d1a0c50) --- source4/libcli/raw/interfaces.h | 23 ++++++++--------------- source4/libcli/smb2/session.c | 22 ++++++++++++---------- 2 files changed, 20 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 00ab788184..4211dadb2d 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -373,29 +373,22 @@ union smb_sesssetup { enum smb_sesssetup_level level; struct { - /* NOTE: this was 0x11 = 0x10 + 1 in vista-CTP - * and changed in vista-beta2, but both server's - * can handle the 0x18 clients - */ - /* static body buffer 24 (0x18) bytes */ - /* uint16_t buffer_code; 0x19 = 0x18 + 1 */ - uint16_t _pad; - uint32_t unknown2; /* 0x0000000F(vista-CTP) 0x00000007(vista-beta2) */ - uint32_t unknown3; /* 0x0000000 */ + /* static body 24 (0x18) bytes */ + uint8_t vc_number; + uint8_t security_mode; + uint32_t capabilities; + uint32_t channel; /* uint16_t secblob_ofs */ /* uint16_t secblob_size */ - uint64_t unknown4; /* 0x0000000000000000 only present in vista-beta2 */ - + uint64_t previous_sessionid; /* dynamic body */ DATA_BLOB secblob; } in; struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 +1 */ - uint16_t _pad; + /* body buffer 8 (0x08) bytes */ + uint16_t session_flags; /* uint16_t secblob_ofs */ /* uint16_t secblob_size */ - /* dynamic body */ DATA_BLOB secblob; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index a784ea65d8..d06688a598 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -75,9 +75,11 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); - SSVAL(req->out.body, 0x02, io->in._pad); /* pad */ - SIVAL(req->out.body, 0x04, io->in.unknown2); - SIVAL(req->out.body, 0x08, io->in.unknown3); + SCVAL(req->out.body, 0x02, io->in.vc_number); + SCVAL(req->out.body, 0x03, io->in.security_mode); + SIVAL(req->out.body, 0x04, io->in.capabilities); + SIVAL(req->out.body, 0x08, io->in.channel); + SBVAL(req->out.body, 0x10, io->in.previous_sessionid); req->session = session; @@ -86,7 +88,6 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, talloc_free(req); return NULL; } - SBVAL(req->out.body, 0x10, io->in.unknown4); smb2_transport_send(req); @@ -110,8 +111,8 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, SMB2_CHECK_PACKET_RECV(req, 0x08, true); - io->out._pad = SVAL(req->in.body, 0x02); - io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); + io->out.session_flags = SVAL(req->in.body, 0x02); + io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob); if (!NT_STATUS_IS_OK(status)) { @@ -206,10 +207,11 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se c->private_data = state; ZERO_STRUCT(state->io); - state->io.in._pad = 0x0000; - state->io.in.unknown2 = 0x0000000F; - state->io.in.unknown3 = 0x00000000; - state->io.in.unknown4 = 0; /* uint64_t */ + state->io.in.vc_number = 0; + state->io.in.security_mode = 0; + state->io.in.capabilities = 0; + state->io.in.channel = 0; + state->io.in.previous_sessionid = 0; c->status = gensec_set_credentials(session->gensec, credentials); if (!composite_is_ok(c)) return c; -- cgit From a2505c5a2cc2b7b692ffbcdd8c6b86000a15d2c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 17:00:35 +1100 Subject: updated SMB2 header defines to match WSPP docs (This used to be commit d2c6ad55eca27f50a38fc6e2a85032eddb3f0aae) --- source4/libcli/smb2/cancel.c | 6 +++--- source4/libcli/smb2/logoff.c | 2 +- source4/libcli/smb2/notify.c | 2 +- source4/libcli/smb2/request.c | 14 +++++++------- source4/libcli/smb2/session.c | 4 ++-- source4/libcli/smb2/smb2.h | 15 ++++++++------- source4/libcli/smb2/tcon.c | 2 +- source4/libcli/smb2/transport.c | 2 +- 8 files changed, 24 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/cancel.c b/source4/libcli/smb2/cancel.c index 096919f177..80127feea5 100644 --- a/source4/libcli/smb2/cancel.c +++ b/source4/libcli/smb2/cancel.c @@ -52,11 +52,11 @@ NTSTATUS smb2_cancel(struct smb2_request *r) c->seqnum = 0; SIVAL(c->out.hdr, SMB2_HDR_FLAGS, 0x00000002); - SSVAL(c->out.hdr, SMB2_HDR_UNKNOWN1, 0x0030); + SSVAL(c->out.hdr, SMB2_HDR_CREDIT, 0x0030); SIVAL(c->out.hdr, SMB2_HDR_PID, r->cancel.pending_id); - SBVAL(c->out.hdr, SMB2_HDR_SEQNUM, c->seqnum); + SBVAL(c->out.hdr, SMB2_HDR_MESSAGE_ID, c->seqnum); if (r->session) { - SBVAL(c->out.hdr, SMB2_HDR_UID, r->session->uid); + SBVAL(c->out.hdr, SMB2_HDR_SESSION_ID, r->session->uid); } SSVAL(c->out.body, 0x02, 0); diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index 321a4db1a6..b38a08ca43 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -33,7 +33,7 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session) req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, false, 0); if (req == NULL) return NULL; - SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid); SSVAL(req->out.body, 0x02, 0); diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index a3bea41eb0..e7c38a27f9 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -35,7 +35,7 @@ struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify req = smb2_request_init_tree(tree, SMB2_OP_NOTIFY, 0x20, false, 0); if (req == NULL) return NULL; - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0x0030); + SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0x0030); SSVAL(req->out.body, 0x02, io->in.recursive); SIVAL(req->out.body, 0x04, io->in.buffer_size); diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 73c74dcfeb..46ec24145f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -83,17 +83,17 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SIVAL(req->out.hdr, 0, SMB2_MAGIC); SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0); SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0); + SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0); SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->out.hdr, SMB2_HDR_CHAIN_OFFSET, 0); - SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, 0); + SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SBVAL(req->out.hdr, SMB2_HDR_UID, 0); - memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, 0); + memset(req->out.hdr+SMB2_HDR_SIGNATURE, 0, 16); /* set the length of the fixed body part and +1 if there's a dynamic part also */ SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0)); @@ -122,7 +122,7 @@ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opc body_dynamic_size); if (req == NULL) return NULL; - SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid); SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid); req->session = tree->session; req->tree = tree; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index d06688a598..18fe3486a4 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -74,7 +74,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, 0x18, true, io->in.secblob.length); if (req == NULL) return NULL; - SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid); SCVAL(req->out.body, 0x02, io->in.vc_number); SCVAL(req->out.body, 0x03, io->in.security_mode); SIVAL(req->out.body, 0x04, io->in.capabilities); @@ -112,7 +112,7 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, SMB2_CHECK_PACKET_RECV(req, 0x08, true); io->out.session_flags = SVAL(req->in.body, 0x02); - io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID); + io->out.uid = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID); status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 33876c6f7c..60cf3e0173 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -156,19 +156,20 @@ struct smb2_request { #define SMB2_MIN_SIZE 0x42 -/* offsets into header elements */ +/* offsets into header elements for a sync SMB2 request */ +#define SMB2_HDR_PROTOCOL_ID 0x00 #define SMB2_HDR_LENGTH 0x04 -#define SMB2_HDR_PAD1 0x06 +#define SMB2_HDR_EPOCH 0x06 #define SMB2_HDR_STATUS 0x08 #define SMB2_HDR_OPCODE 0x0c -#define SMB2_HDR_UNKNOWN1 0x0e +#define SMB2_HDR_CREDIT 0x0e #define SMB2_HDR_FLAGS 0x10 -#define SMB2_HDR_CHAIN_OFFSET 0x14 -#define SMB2_HDR_SEQNUM 0x18 +#define SMB2_HDR_NEXT_COMMAND 0x14 +#define SMB2_HDR_MESSAGE_ID 0x18 #define SMB2_HDR_PID 0x20 #define SMB2_HDR_TID 0x24 -#define SMB2_HDR_UID 0x28 /* 64 bit */ -#define SMB2_HDR_SIG 0x30 /* guess ... */ +#define SMB2_HDR_SESSION_ID 0x28 +#define SMB2_HDR_SIGNATURE 0x30 /* 16 bytes */ #define SMB2_HDR_BODY 0x40 /* SMB2 opcodes */ diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index ad1ba4c92d..5a09970584 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -56,7 +56,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, 0x08, true, 0); if (req == NULL) return NULL; - SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid); SSVAL(req->out.body, 0x02, io->in.unknown1); status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path); diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 83e9436a58..dceb78382a 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -167,7 +167,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) } flags = IVAL(hdr, SMB2_HDR_FLAGS); - seqnum = BVAL(hdr, SMB2_HDR_SEQNUM); + seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); /* match the incoming request against the list of pending requests */ for (req=transport->pending_recv; req; req=req->next) { -- cgit From e08a78abcd7cf55322cc720f47fa3a2bfe491c31 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Feb 2008 12:16:38 +0100 Subject: [PATCH] composite: make it possible to call composite_is_ok() without callback fn metze (This used to be commit 4e459f1fb3ab60c586df9a08cdc57db424a30b18) --- source4/libcli/composite/composite.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 67d5885497..aab7487a42 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -64,23 +64,6 @@ _PUBLIC_ NTSTATUS composite_wait(struct composite_context *c) return c->status; } - -/* - * Some composite helpers that are handy if you write larger composite - * functions. - */ -_PUBLIC_ bool composite_is_ok(struct composite_context *ctx) -{ - if (NT_STATUS_IS_OK(ctx->status)) { - return true; - } - ctx->state = COMPOSITE_STATE_ERROR; - if (ctx->async.fn != NULL) { - ctx->async.fn(ctx); - } - return false; -} - /* callback from composite_done() and composite_error() @@ -110,7 +93,10 @@ _PUBLIC_ void composite_error(struct composite_context *ctx, NTSTATUS status) event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); } ctx->status = status; - SMB_ASSERT(!composite_is_ok(ctx)); + ctx->state = COMPOSITE_STATE_ERROR; + if (ctx->async.fn != NULL) { + ctx->async.fn(ctx); + } } _PUBLIC_ bool composite_nomem(const void *p, struct composite_context *ctx) @@ -122,6 +108,15 @@ _PUBLIC_ bool composite_nomem(const void *p, struct composite_context *ctx) return true; } +_PUBLIC_ bool composite_is_ok(struct composite_context *ctx) +{ + if (NT_STATUS_IS_OK(ctx->status)) { + return true; + } + composite_error(ctx, ctx->status); + return false; +} + _PUBLIC_ void composite_done(struct composite_context *ctx) { if (!ctx->used_wait && !ctx->async.fn) { -- cgit From e94d710b0b959d8e69eb02ef0704ebcff56485fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 10:13:28 +1100 Subject: updated SMB2 tcon as per WSPP docs (This used to be commit 5913e3e549e71affc66c28cacb6563331fb0c790) --- source4/libcli/raw/interfaces.h | 13 ++++++------- source4/libcli/smb2/connect.c | 2 +- source4/libcli/smb2/smb2.h | 22 ++++++++++++++++++++++ source4/libcli/smb2/smb2_calls.h | 2 +- source4/libcli/smb2/tcon.c | 16 ++++++++++++---- 5 files changed, 42 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 4211dadb2d..ddbddf4c59 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -260,20 +260,19 @@ union smb_tcon { struct { /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ - uint16_t unknown1; /* 0x0000 */ + uint16_t reserved; /* uint16_t path_ofs */ /* uint16_t path_size */ - - /* dynamic body */ + /* dynamic body */ const char *path; /* as non-terminated UTF-16 on the wire */ } in; struct { /* static body buffer 16 (0x10) bytes */ /* uint16_t buffer_code; 0x10 */ - uint16_t unknown1; /* 0x02 */ - uint32_t unknown2; /* 0x00 */ - uint32_t unknown3; /* 0x00 */ + uint8_t share_type; + uint8_t reserved; + uint32_t flags; + uint32_t capabilities; uint32_t access_mask; /* extracted from the SMB2 header */ diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index a2ae828fa5..535df11d9d 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -73,7 +73,7 @@ static void continue_session(struct composite_context *creq) state->tree = smb2_tree_init(state->session, state, true); if (composite_nomem(state->tree, c)) return; - state->tcon.in.unknown1 = 0x09; + state->tcon.in.reserved = 0; state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s", state->host, state->share); if (composite_nomem(state->tcon.in.path, c)) return; diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 60cf3e0173..549b477ffd 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -195,6 +195,28 @@ struct smb2_request { #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ +/* SMB2 negotiate security_mode */ +#define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01 +#define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x02 + +/* SMB2 capabilities - only 1 so far. I'm sure more will be added */ +#define SMB2_CAP_DFS 0x0 +/* so we can spot new caps as added */ +#define SMB2_CAP_ALL SMB2_CAP_DFS + +/* SMB2 share flags */ +#define SMB2_SHAREFLAG_MANUAL_CACHING 0x0000 +#define SMB2_SHAREFLAG_AUTO_CACHING 0x0010 +#define SMB2_SHAREFLAG_VDO_CACHING 0x0020 +#define SMB2_SHAREFLAG_NO_CACHING 0x0030 +#define SMB2_SHAREFLAG_DFS 0x0001 +#define SMB2_SHAREFLAG_DFS_ROOT 0x0002 +#define SMB2_SHAREFLAG_RESTRICT_EXCLUSIVE_OPENS 0x0100 +#define SMB2_SHAREFLAG_FORCE_SHARED_DELETE 0x0200 +#define SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING 0x0400 +#define SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM 0x0800 +#define SMB2_SHAREFLAG_ALL 0x0F33 + /* check that a body has the expected size */ diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index 423d9d1579..f2e3019d83 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -35,7 +35,7 @@ struct smb2_negprot { struct { /* static body buffer 64 (0x40) bytes */ /* uint16_t buffer_code; 0x41 = 0x40 + 1 */ - uint16_t security_mode; + uint16_t security_mode; /* SMB2_NEGOTIATE_SIGNING_* */ uint16_t dialect_revision; uint16_t reserved; struct GUID server_guid; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 5a09970584..db35669d41 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -58,7 +58,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid); - SSVAL(req->out.body, 0x02, io->in.unknown1); + SSVAL(req->out.body, 0x02, io->in.reserved); status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -85,10 +85,18 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID); - io->out.unknown1 = SVAL(req->in.body, 0x02); - io->out.unknown2 = IVAL(req->in.body, 0x04); - io->out.unknown3 = IVAL(req->in.body, 0x08); + io->out.share_type = CVAL(req->in.body, 0x02); + io->out.reserved = CVAL(req->in.body, 0x03); + io->out.flags = IVAL(req->in.body, 0x04); + io->out.capabilities= IVAL(req->in.body, 0x08); io->out.access_mask = IVAL(req->in.body, 0x0C); + + if (io->out.capabilities & ~SMB2_CAP_ALL) { + DEBUG(0,("Unknown capabilities mask 0x%x\n", io->out.capabilities)); + } + if (io->out.flags & ~SMB2_SHAREFLAG_ALL) { + DEBUG(0,("Unknown tcon shareflag 0x%x\n", io->out.flags)); + } return smb2_request_destroy(req); } -- cgit From 88d2e0522737fb8856fb0f52c2af8a2f56130f19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 15:05:44 +1100 Subject: updated SMB2 create operation to match WSPP. Adding some defined for various new create options (This used to be commit d037dc23ced3df6bce98cbf4810fb5f1247336bd) --- source4/libcli/raw/interfaces.h | 25 ++++++++++---------- source4/libcli/smb2/create.c | 52 ++++++++++++++++++++--------------------- source4/libcli/smb2/smb2.h | 28 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 38 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index ddbddf4c59..ce6323f2e5 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1552,16 +1552,16 @@ union smb_open { enum smb_open_level level; struct { /* static body buffer 56 (0x38) bytes */ - /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ - uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ - uint32_t impersonation; - uint32_t unknown3[4]; - uint32_t access_mask; - - uint32_t file_attr; - uint32_t share_access; - uint32_t open_disposition; - uint32_t create_options; + uint8_t security_flags; /* SMB2_SECURITY_* */ + uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */ + uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */ + uint64_t create_flags; + uint64_t reserved; + uint32_t desired_access; + uint32_t file_attributes; + uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */ + uint32_t create_disposition; /* NTCREATEX_DISP_* */ + uint32_t create_options; /* NTCREATEX_OPTIONS_* */ /* uint16_t fname_ofs */ /* uint16_t fname_size */ @@ -1579,7 +1579,8 @@ union smb_open { /* static body buffer 88 (0x58) bytes */ /* uint16_t buffer_code; 0x59 = 0x58 + 1 */ - uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint8_t oplock_level; + uint8_t reserved; uint32_t create_action; NTTIME create_time; NTTIME access_time; @@ -1588,7 +1589,7 @@ union smb_open { uint64_t alloc_size; uint64_t size; uint32_t file_attr; - uint32_t _pad; + uint32_t reserved2; /* struct smb2_handle handle;*/ /* uint32_t blob_ofs; */ /* uint32_t blob_size; */ diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index ba11c22e87..cca83a040c 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -24,34 +24,33 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#define CREATE_TAG_EXTA 0x41747845 /* "ExtA" */ -#define CREATE_TAG_MXAC 0x6341784D /* "MxAc" */ - /* add a blob to a smb2_create attribute blob */ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - uint32_t tag, + const char *tag, DATA_BLOB add, bool last) { uint32_t ofs = blob->length; - uint8_t pad = smb2_padding_size(add.length, 8); - if (!data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad)) + size_t tag_length = strlen(tag); + uint8_t pad = smb2_padding_size(add.length+tag_length, 8); + if (!data_blob_realloc(mem_ctx, blob, + blob->length + 0x14 + tag_length + add.length + pad)) return NT_STATUS_NO_MEMORY; if (last) { SIVAL(blob->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x18 + add.length + pad); + SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad); } SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ - SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ - SSVAL(blob->data, ofs+0x0A, 0x18); /* offset of data */ + SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */ + SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ SIVAL(blob->data, ofs+0x0C, add.length); - SIVAL(blob->data, ofs+0x10, tag); - SIVAL(blob->data, ofs+0x14, 0); /* pad? */ - memcpy(blob->data+ofs+0x18, add.data, add.length); - memset(blob->data+ofs+0x18+add.length, 0, pad); + memcpy(blob->data+ofs+0x10, tag, tag_length); + SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */ + memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length); + memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad); return NT_STATUS_OK; } @@ -68,16 +67,15 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, io->in.oplock_flags); - SIVAL(req->out.body, 0x04, io->in.impersonation); - SIVAL(req->out.body, 0x08, io->in.unknown3[0]); - SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); - SIVAL(req->out.body, 0x10, io->in.unknown3[2]); - SIVAL(req->out.body, 0x14, io->in.unknown3[3]); - SIVAL(req->out.body, 0x18, io->in.access_mask); - SIVAL(req->out.body, 0x1C, io->in.file_attr); + SCVAL(req->out.body, 0x02, io->in.security_flags); + SCVAL(req->out.body, 0x03, io->in.oplock_level); + SIVAL(req->out.body, 0x04, io->in.impersonation_level); + SBVAL(req->out.body, 0x08, io->in.create_flags); + SBVAL(req->out.body, 0x10, io->in.reserved); + SIVAL(req->out.body, 0x18, io->in.desired_access); + SIVAL(req->out.body, 0x1C, io->in.file_attributes); SIVAL(req->out.body, 0x20, io->in.share_access); - SIVAL(req->out.body, 0x24, io->in.open_disposition); + SIVAL(req->out.body, 0x24, io->in.create_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname); @@ -90,7 +88,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, false); + status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -100,7 +98,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), true); + status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC, + data_blob(NULL, 0), true); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -132,7 +131,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct SMB2_CHECK_PACKET_RECV(req, 0x58, true); - io->out.oplock_flags = SVAL(req->in.body, 0x02); + io->out.oplock_level = CVAL(req->in.body, 0x02); + io->out.reserved = CVAL(req->in.body, 0x03); io->out.create_action = IVAL(req->in.body, 0x04); io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); @@ -141,7 +141,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.alloc_size = BVAL(req->in.body, 0x28); io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); - io->out._pad = IVAL(req->in.body, 0x3C); + io->out.reserved2 = IVAL(req->in.body, 0x3C); smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 549b477ffd..db13ab69b3 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -217,6 +217,34 @@ struct smb2_request { #define SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM 0x0800 #define SMB2_SHAREFLAG_ALL 0x0F33 +/* SMB2 create security flags */ +#define SMB2_SECURITY_DYNAMIC_TRACKING 0x01 +#define SMB2_SECURITY_EFFECTIVE_ONLY 0x02 + +/* SMB2 requested oplock levels */ +#define SMB2_OPLOCK_LEVEL_NONE 0x00 +#define SMB2_OPLOCK_LEVEL_II 0x01 +#define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08 +#define SMB2_OPLOCK_LEVEL_BATCH 0x09 + +/* SMB2 impersonation levels */ +#define SMB2_IMPERSONATION_ANONYMOUS 0x00 +#define SMB2_IMPERSONATION_IDENTIFICATION 0x01 +#define SMB2_IMPERSONATION_IMPERSONATION 0x02 +#define SMB2_IMPERSONATION_DELEGATE 0x03 + +/* SMB2 create tags */ +#define SMB2_CREATE_TAG_EXTA "ExtA" +#define SMB2_CREATE_TAG_MXAC "MxAc" +#define SMB2_CREATE_TAG_SECD "SecD" +#define SMB2_CREATE_TAG_DHNQ "DHnQ" +#define SMB2_CREATE_TAG_DHNC "DHnC" +#define SMB2_CREATE_TAG_ALSI "AlSi" +#define SMB2_CREATE_TAG_TWRP "TWrp" +#define SMB2_CREATE_TAG_QFID "QFid" + + + /* check that a body has the expected size */ -- cgit From e870cfec9f3512b0f1bd3110d7b975652525e28a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 10:12:33 +1100 Subject: Convert SMB and SMB2 code to use a common buffer handling structure This converts our SMB and SMB2 code to use a common structure "struct request_bufinfo" for information on the buffer bounds of a packet, alignment information and string handling. This allows us to use a common backend for SMB and SMB2 code, while still using all the same string and blob handling functions. Up to now we had been passing a NULL req handle into these common routines from the SMB2 side of the server, which meant that we failed any operation which did a bounds checked string extraction (such as a RenameInformation setinfo call, which is what Vista uses for renaming files) There is still some more work to be done on this - for example we can now remove many of the SMB2 specific buffer handling functions that we had, and use the SMB ones. (This used to be commit ca6d9be6cb6a403a81b18fa6e9a6a0518d7f0f68) --- source4/libcli/raw/clisession.c | 20 ++++++++-------- source4/libcli/raw/clitransport.c | 4 +++- source4/libcli/raw/clitree.c | 6 ++--- source4/libcli/raw/libcliraw.h | 4 ++-- source4/libcli/raw/rawfile.c | 4 ++-- source4/libcli/raw/rawioctl.c | 2 +- source4/libcli/raw/rawnegotiate.c | 10 ++++---- source4/libcli/raw/rawreadwrite.c | 6 ++--- source4/libcli/raw/rawrequest.c | 50 +++++++++++++++++++++++++-------------- source4/libcli/raw/rawsearch.c | 2 +- source4/libcli/raw/request.h | 16 ++++++++++++- source4/libcli/raw/smb_signing.c | 6 ++--- source4/libcli/smb2/request.c | 15 ++++++++++++ source4/libcli/smb2/smb2.h | 5 ++++ source4/libcli/smb2/transport.c | 2 ++ 15 files changed, 102 insertions(+), 50 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 617131c53c..55cb3ef305 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -177,9 +177,9 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, parms->old.out.action = SVAL(req->in.vwv, VWV(2)); p = req->in.data; if (p) { - p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE); } break; @@ -190,10 +190,10 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, parms->nt1.out.action = SVAL(req->in.vwv, VWV(2)); p = req->in.data; if (p) { - p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE); if (p < (req->in.data + req->in.data_size)) { - p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE); } } break; @@ -209,11 +209,11 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, break; } - parms->spnego.out.secblob = smbcli_req_pull_blob(req, mem_ctx, p, len); + parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len); p += parms->spnego.out.secblob.length; - p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE); break; case RAW_SESSSETUP_SMB2: diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 62c32d3058..288f0612de 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -444,6 +444,8 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob) req->in.ptr = req->in.data; req->flags2 = SVAL(req->in.hdr, HDR_FLG2); + smb_setup_bufinfo(req); + if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) { int class = CVAL(req->in.hdr,HDR_RCLS); int code = SVAL(req->in.hdr,HDR_ERR); @@ -637,7 +639,7 @@ NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size); NT_STATUS_HAVE_NO_MEMORY(p->out.data); - if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) { + if (!smbcli_raw_pull_data(&req->in.bufinfo, req->in.data, p->out.size, p->out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; } diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 35f3335322..507bde999a 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -123,9 +123,9 @@ NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, p = req->in.data; if (!p) break; - p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type, - p, -1, STR_ASCII | STR_TERMINATE); - p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type, + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.dev_type, + p, -1, STR_ASCII | STR_TERMINATE); + p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.fs_type, p, -1, STR_TERMINATE); break; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 0032eb4e94..7111649fc1 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -250,8 +250,8 @@ struct smbcli_request { /* the mid of this packet - used to match replies */ uint16_t mid; - struct request_buffer in; - struct request_buffer out; + struct smb_request_buffer in; + struct smb_request_buffer out; /* information on what to do with a reply when it is received asyncronously. If this is not setup when a reply is received then diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 3b6ca68526..d9383401b7 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -616,7 +616,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio case RAW_OPEN_CTEMP: SMBCLI_CHECK_WCT(req, 1); parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0)); - smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); + smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII); break; case RAW_OPEN_SPLOPEN: @@ -675,7 +675,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5)); if (parms->openxreadx.out.nread > MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) || - !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), + !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)), parms->openxreadx.out.nread, parms->openxreadx.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 9205f84e86..957e554c6b 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -59,7 +59,7 @@ static NTSTATUS smb_raw_smbioctl_recv(struct smbcli_request *req, return smbcli_request_destroy(req); } - parms->ioctl.out.blob = smbcli_req_pull_blob(req, mem_ctx, req->in.data, -1); + parms->ioctl.out.blob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, req->in.data, -1); return smbcli_request_destroy(req); } diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 1f5e34779b..ec2ada53ff 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -135,14 +135,14 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) if (req->in.data_size < 16) { goto failed; } - transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport, req->in.data, 16); - transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data + 16, req->in.data_size - 16); + transport->negotiate.server_guid = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, 16); + transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16); } else { if (req->in.data_size < (transport->negotiate.key_len)) { goto failed; } - transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data, transport->negotiate.key_len); - smbcli_req_pull_string(req, transport, &transport->negotiate.server_domain, + transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len); + smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain, req->in.data+transport->negotiate.key_len, req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN); /* here comes the server name */ @@ -168,7 +168,7 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) { transport->negotiate.writebraw_supported = 1; } - transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, + transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, req->in.data_size); } else { /* the old core protocol */ diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index b0c49ddab7..2005e36e04 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -137,7 +137,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) SMBCLI_CHECK_WCT(req, 5); parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0)); if (parms->lockread.out.nread > parms->lockread.in.count || - !smbcli_raw_pull_data(req, req->in.data+3, + !smbcli_raw_pull_data(&req->in.bufinfo, req->in.data+3, parms->lockread.out.nread, parms->lockread.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; } @@ -148,7 +148,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) SMBCLI_CHECK_WCT(req, 5); parms->read.out.nread = SVAL(req->in.vwv, VWV(0)); if (parms->read.out.nread > parms->read.in.count || - !smbcli_raw_pull_data(req, req->in.data+3, + !smbcli_raw_pull_data(&req->in.bufinfo, req->in.data+3, parms->read.out.nread, parms->read.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; } @@ -175,7 +175,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) } if (parms->readx.out.nread > MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt) || - !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), + !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)), parms->readx.out.nread, parms->readx.out.data)) { req->status = NT_STATUS_BUFFER_TOO_SMALL; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 3551e5d441..dd60cc7f62 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -34,6 +34,17 @@ /* assume that a character will not consume more than 3 bytes per char */ #define MAX_BYTES_PER_CHAR 3 +/* setup the bufinfo used for strings and range checking */ +void smb_setup_bufinfo(struct smbcli_request *req) +{ + req->in.bufinfo.mem_ctx = req; + req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false; + req->in.bufinfo.align_base = req->in.buffer; + req->in.bufinfo.data = req->in.data; + req->in.bufinfo.data_size = req->in.data_size; +} + + /* destroy a request structure and return final status */ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) { @@ -298,6 +309,9 @@ NTSTATUS smbcli_chained_advance(struct smbcli_request *req) req->in.data = req->in.vwv + 2 + req->in.wct * 2; req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct)); + /* fix the bufinfo */ + smb_setup_bufinfo(req); + if (buffer + 3 + req->in.wct*2 + req->in.data_size > req->in.buffer + req->in.size) { return NT_STATUS_BUFFER_TOO_SMALL; @@ -544,13 +558,13 @@ size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *by on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx, +static size_t smbcli_req_pull_ucs2(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, char **dest, const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; - if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) { + if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) { src++; alignment=1; if (byte_len != -1) { @@ -558,7 +572,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c } } - src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data); if (src_len < 0) { *dest = NULL; return 0; @@ -597,13 +611,13 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, +size_t smbcli_req_pull_ascii(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, char **dest, const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; - src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data); if (src_len < 0) { *dest = NULL; return 0; @@ -640,15 +654,15 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx, on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, +size_t smbcli_req_pull_string(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, char **dest, const uint8_t *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && - (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { - return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags); + (((flags & STR_UNICODE) || bufinfo->unicode))) { + return smbcli_req_pull_ucs2(bufinfo, mem_ctx, dest, src, byte_len, flags); } - return smbcli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags); + return smbcli_req_pull_ascii(bufinfo, mem_ctx, dest, src, byte_len, flags); } @@ -658,11 +672,11 @@ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, if byte_len is -1 then limit the blob only by packet size */ -DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len) +DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len) { int src_len; - src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data); if (src_len < 0) { return data_blob(NULL, 0); @@ -677,13 +691,13 @@ DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, /* check that a lump of data in a request is within the bounds of the data section of the packet */ -static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count) +static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count) { /* be careful with wraparound! */ - if (ptr < req->in.data || - ptr >= req->in.data + req->in.data_size || - count > req->in.data_size || - ptr + count > req->in.data + req->in.data_size) { + if (ptr < bufinfo->data || + ptr >= bufinfo->data + bufinfo->data_size || + count > bufinfo->data_size || + ptr + count > bufinfo->data + bufinfo->data_size) { return true; } return false; @@ -694,11 +708,11 @@ static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, return false if any part is outside the data portion of the packet */ -bool smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest) +bool smbcli_raw_pull_data(struct request_bufinfo *bufinfo, const uint8_t *src, int len, uint8_t *dest) { if (len == 0) return true; - if (smbcli_req_data_oob(req, src, len)) { + if (smbcli_req_data_oob(bufinfo, src, len)) { return false; } diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 33fa90d68d..fb2b09467c 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -54,7 +54,7 @@ static void smb_raw_search_backend(struct smbcli_request *req, search_data.search.write_time = raw_pull_dos_date(req->transport, p + 22); search_data.search.size = IVAL(p, 26); - smbcli_req_pull_ascii(req, mem_ctx, &name, p+30, 13, STR_ASCII); + smbcli_req_pull_ascii(&req->in.bufinfo, mem_ctx, &name, p+30, 13, STR_ASCII); search_data.search.name = name; if (!callback(private, &search_data)) { break; diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h index 803a450e3c..6776d3c349 100644 --- a/source4/libcli/raw/request.h +++ b/source4/libcli/raw/request.h @@ -22,11 +22,22 @@ #include "libcli/raw/signing.h" +/* + buffer limit structure used by both SMB and SMB2 + */ +struct request_bufinfo { + TALLOC_CTX *mem_ctx; + bool unicode; + const uint8_t *align_base; + const uint8_t *data; + size_t data_size; +}; + /* Shared state structure between client and server, representing the basic packet. */ -struct request_buffer { +struct smb_request_buffer { /* the raw SMB buffer, including the 4 byte length header */ uint8_t *buffer; @@ -56,6 +67,9 @@ struct request_buffer { * a send packet is done we need to move this * pointer */ uint8_t *ptr; + + /* this is used to range check and align strings and buffers */ + struct request_bufinfo bufinfo; }; #endif diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 0053710aaf..4acfb9d16d 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -65,7 +65,7 @@ static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport) return true; } -void mark_packet_signed(struct request_buffer *out) +void mark_packet_signed(struct smb_request_buffer *out) { uint16_t flags2; flags2 = SVAL(out->hdr, HDR_FLG2); @@ -101,7 +101,7 @@ bool signing_good(struct smb_signing_context *sign_info, return true; } -void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) +void sign_outgoing_message(struct smb_request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) { uint8_t calc_md5_mac[16]; struct MD5Context md5_ctx; @@ -133,7 +133,7 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsig Uncomment this to test if the remote server actually verifies signitures...*/ } -bool check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) +bool check_signed_incoming_message(struct smb_request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) { bool good; uint8_t calc_md5_mac[16]; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 46ec24145f..0b680fb166 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -28,6 +28,21 @@ #include "libcli/smb2/smb2_calls.h" #include "param/param.h" +/* fill in the bufinfo */ +void smb2_setup_bufinfo(struct smb2_request *req) +{ + req->in.bufinfo.mem_ctx = req; + req->in.bufinfo.unicode = true; + req->in.bufinfo.align_base = req->in.buffer; + if (req->in.dynamic) { + req->in.bufinfo.data = req->in.dynamic; + req->in.bufinfo.data_size = req->in.body_size - req->in.body_fixed; + } else { + req->in.bufinfo.data = NULL; + req->in.bufinfo.data_size = 0; + } +} + /* initialise a smb2 request */ diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index db13ab69b3..af08b0180a 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -19,6 +19,8 @@ along with this program. If not, see . */ +#include "libcli/raw/request.h" + struct smb2_options { uint32_t timeout; }; @@ -102,6 +104,9 @@ struct smb2_request_buffer { * this will be moved when some dynamic data is pushed */ uint8_t *dynamic; + + /* this is used to range check and align strings and buffers */ + struct request_bufinfo bufinfo; }; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index dceb78382a..1d601fdbfe 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -216,6 +216,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) } } + smb2_setup_bufinfo(req); + DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum)); dump_data(5, req->in.body, req->in.body_size); -- cgit From 839ab724dc2d204bfbb0693aeed64f6f83a4266b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 12:30:31 +1100 Subject: Fixed SMB2 rename operations from Vista clients We needed a flag in bufinfo to mark packets as SMB2, as it seems that SMB2 uses a different format for the RenameInformation buffer than SMB does Also handle the fact that SMB2 clients give the full path to the target file in the rename, not a relative path (This used to be commit 52d7972d95ddc19d22a4187b4d4428a6c3ed32d5) --- source4/libcli/raw/interfaces.h | 2 +- source4/libcli/raw/rawrequest.c | 7 +++++-- source4/libcli/raw/request.h | 5 ++++- source4/libcli/smb2/request.c | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index ce6323f2e5..16db17d7ab 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1000,7 +1000,7 @@ union smb_setfileinfo { struct { union smb_handle_or_path file; uint8_t overwrite; - uint32_t root_fid; + uint64_t root_fid; const char *new_name; } in; } rename_information; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index dd60cc7f62..355d092583 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -38,7 +38,10 @@ void smb_setup_bufinfo(struct smbcli_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false; + req->in.bufinfo.flags = 0; + if (req->flags2 & FLAGS2_UNICODE_STRINGS) { + req->in.bufinfo.flags = BUFINFO_FLAG_UNICODE; + } req->in.bufinfo.align_base = req->in.buffer; req->in.bufinfo.data = req->in.data; req->in.bufinfo.data_size = req->in.data_size; @@ -658,7 +661,7 @@ size_t smbcli_req_pull_string(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_c char **dest, const uint8_t *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && - (((flags & STR_UNICODE) || bufinfo->unicode))) { + (((flags & STR_UNICODE) || (bufinfo->flags & BUFINFO_FLAG_UNICODE)))) { return smbcli_req_pull_ucs2(bufinfo, mem_ctx, dest, src, byte_len, flags); } diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h index 6776d3c349..2a572e58ee 100644 --- a/source4/libcli/raw/request.h +++ b/source4/libcli/raw/request.h @@ -22,12 +22,15 @@ #include "libcli/raw/signing.h" +#define BUFINFO_FLAG_UNICODE 0x0001 +#define BUFINFO_FLAG_SMB2 0x0002 + /* buffer limit structure used by both SMB and SMB2 */ struct request_bufinfo { TALLOC_CTX *mem_ctx; - bool unicode; + uint32_t flags; const uint8_t *align_base; const uint8_t *data; size_t data_size; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 0b680fb166..35229dc45f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -32,7 +32,7 @@ void smb2_setup_bufinfo(struct smb2_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = true; + req->in.bufinfo.flags = BUFINFO_FLAG_UNICODE | BUFINFO_FLAG_SMB2; req->in.bufinfo.align_base = req->in.buffer; if (req->in.dynamic) { req->in.bufinfo.data = req->in.dynamic; -- cgit From 4a04a5e620a4666fc123d04cb96ef391de72c469 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 14:54:21 +1100 Subject: A better way to handle the different format of RenameInformation in SMB2 We now define a separate info level RAW_SFILEINFO_RENAME_INFORMATION_SMB2 and set that level when handling SMB2 packets. This makes the parsers clearer. (This used to be commit f6cdf3f1177f63d80be757f007eb15380839b4f5) --- source4/libcli/raw/interfaces.h | 5 ++++- source4/libcli/raw/rawsetfileinfo.c | 11 +++++++++++ source4/libcli/smb2/setinfo.c | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 16db17d7ab..24e8ad4afc 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -902,7 +902,10 @@ enum smb_setfileinfo_level { RAW_SFILEINFO_1029 = SMB_SFILEINFO_1029, RAW_SFILEINFO_1032 = SMB_SFILEINFO_1032, RAW_SFILEINFO_1039 = SMB_SFILEINFO_1039, - RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040 + RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040, + + /* cope with breakage in SMB2 */ + RAW_SFILEINFO_RENAME_INFORMATION_SMB2 = SMB_SFILEINFO_RENAME_INFORMATION|0x80000000, }; /* union used in setfileinfo() and setpathinfo() calls */ diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index a9a1a3547e..f1e4ee3686 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -75,6 +75,16 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, SIVAL(blob->data, 8, len - 2); return true; + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: + NEED_BLOB(20); + SIVAL(blob->data, 0, parms->rename_information.in.overwrite); + SBVAL(blob->data, 8, parms->rename_information.in.root_fid); + len = smbcli_blob_append_string(NULL, mem_ctx, blob, + parms->rename_information.in.new_name, + STR_UNICODE|STR_TERMINATE); + SIVAL(blob->data, 16, len - 2); + return true; + case RAW_SFILEINFO_POSITION_INFORMATION: NEED_BLOB(8); SBVAL(blob->data, 0, parms->position_information.in.position); @@ -229,6 +239,7 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree, case RAW_SFILEINFO_UNIX_LINK: case RAW_SFILEINFO_UNIX_HLINK: + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: break; } diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index d942568a2d..a6e22d9a68 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -92,6 +92,12 @@ struct smb2_request *smb2_setinfo_file_send(struct smb2_tree *tree, union smb_se ZERO_STRUCT(b); b.in.level = smb2_level; b.in.file.handle = io->generic.in.file.handle; + + /* change levels so the parsers know it is SMB2 */ + if (io->generic.level == RAW_SFILEINFO_RENAME_INFORMATION) { + io->generic.level = RAW_SFILEINFO_RENAME_INFORMATION_SMB2; + } + if (!smb_raw_setfileinfo_passthru(tree, io->generic.level, io, &b.in.blob)) { return NULL; } -- cgit From b640f475be9b0f83e7812a5c7756344c5891cba3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 17:11:36 +1100 Subject: updated SMB2 code for getinfo according to WSPP docs - Updated getinfo structures and field names - also updated the protocol revision number handling to reflect new docs (This used to be commit 3aaa2e86d94675c6c68d66d75292c3e34bfbc81b) --- source4/libcli/smb2/connect.c | 2 +- source4/libcli/smb2/getinfo.c | 45 ++++++++++++++++++++++++---------------- source4/libcli/smb2/request.c | 27 ++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 3 +++ source4/libcli/smb2/smb2_calls.h | 24 ++++++++++++++------- 5 files changed, 75 insertions(+), 26 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 535df11d9d..85ddafc031 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -133,7 +133,7 @@ static void continue_socket(struct composite_context *creq) state->negprot.in.security_mode = 0; state->negprot.in.capabilities = 0; unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); - dialects[0] = 0; + dialects[0] = SMB2_DIALECT_REVISION; state->negprot.in.dialects = dialects; req = smb2_negprot_send(transport, &state->negprot); diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index 0665dd441c..e9f47140f5 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -30,21 +30,27 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getinfo *io) { struct smb2_request *req; + NTSTATUS status; - req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, false, 0); + req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, true, + io->in.blob.length); if (req == NULL) return NULL; - /* this seems to be a bug, they use 0x29 but only send 0x28 bytes */ - SSVAL(req->out.body, 0x00, 0x29); - - SSVAL(req->out.body, 0x02, io->in.level); - SIVAL(req->out.body, 0x04, io->in.max_response_size); - SIVAL(req->out.body, 0x08, io->in.unknown1); - SIVAL(req->out.body, 0x0C, io->in.unknown2); - SIVAL(req->out.body, 0x10, io->in.flags); - SIVAL(req->out.body, 0x14, io->in.flags2); + SCVAL(req->out.body, 0x02, io->in.info_type); + SCVAL(req->out.body, 0x03, io->in.info_class); + SIVAL(req->out.body, 0x04, io->in.output_buffer_length); + SIVAL(req->out.body, 0x0C, io->in.reserved); + SIVAL(req->out.body, 0x08, io->in.input_buffer_length); + SIVAL(req->out.body, 0x10, io->in.additional_information); + SIVAL(req->out.body, 0x14, io->in.getinfo_flags); smb2_push_handle(req->out.body+0x18, &io->in.file.handle); + /* this blob is used for quota queries */ + status = smb2_push_o32s32_blob(&req->out, 0x08, io->in.blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } smb2_transport_send(req); return req; @@ -116,15 +122,17 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi } ZERO_STRUCT(b); - b.in.max_response_size = 0x10000; - b.in.file.handle = io->generic.in.file.handle; - b.in.level = smb2_level; + b.in.info_type = smb2_level & 0xFF; + b.in.info_class = smb2_level >> 8; + b.in.output_buffer_length = 0x10000; + b.in.input_buffer_length = 0; + b.in.file.handle = io->generic.in.file.handle; if (io->generic.level == RAW_FILEINFO_SEC_DESC) { - b.in.flags = io->query_secdesc.in.secinfo_flags; + b.in.additional_information = io->query_secdesc.in.secinfo_flags; } if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) { - b.in.flags2 = io->all_eas.in.continue_flags; + b.in.getinfo_flags = io->all_eas.in.continue_flags; } return smb2_getinfo_send(tree, &b); @@ -172,9 +180,10 @@ struct smb2_request *smb2_getinfo_fs_send(struct smb2_tree *tree, union smb_fsin } ZERO_STRUCT(b); - b.in.max_response_size = 0x10000; - b.in.file.handle = io->generic.handle; - b.in.level = smb2_level; + b.in.output_buffer_length = 0x10000; + b.in.file.handle = io->generic.handle; + b.in.info_type = smb2_level & 0xFF; + b.in.info_class = smb2_level >> 8; return smb2_getinfo_send(tree, &b); } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 35229dc45f..7a0311f886 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -548,6 +548,33 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } +/* + pull a uint16_t ofs/ uint32_t length/blob triple from a data blob + the ptr points to the start of the offset/length pair + + In this varient the uint16_t is padded by an extra 2 bytes, making + the size aligned on 4 byte boundary +*/ +NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +{ + uint32_t ofs, size; + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = SVAL(ptr, 0); + size = IVAL(ptr, 4); + if (ofs == 0 || size == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; +} + /* pull a uint32_t length/ uint32_t ofs/blob triple from a data blob the ptr points to the start of the offset/length pair diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index af08b0180a..726df64090 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -200,6 +200,9 @@ struct smb2_request { #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ +/* the dialect we support */ +#define SMB2_DIALECT_REVISION 0x202 + /* SMB2 negotiate security_mode */ #define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01 #define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x02 diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index f2e3019d83..f66236af30 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -56,6 +56,13 @@ struct smb2_negprot { #define SMB2_GETINFO_FILE 0x01 #define SMB2_GETINFO_FS 0x02 #define SMB2_GETINFO_SECURITY 0x03 +#define SMB2_GETINFO_QUOTA 0x04 + +#define SMB2_GETINFO_ADD_OWNER_SECURITY 0x01 +#define SMB2_GETINFO_ADD_GROUP_SECURITY 0x02 +#define SMB2_GETINFO_ADD_DACL_SECURITY 0x04 +#define SMB2_GETINFO_ADD_SACL_SECURITY 0x08 +#define SMB2_GETINFO_ADD_LABEL_SECURITY 0x10 /* NOTE! the getinfo fs and file levels exactly match up with the 'passthru' SMB levels, which are levels >= 1000. The SMB2 client @@ -64,14 +71,17 @@ struct smb2_negprot { struct smb2_getinfo { struct { /* static body buffer 40 (0x28) bytes */ - /* uint16_t buffer_code; 0x29 = 0x28 + 1 (why???) */ - uint16_t level; - uint32_t max_response_size; - uint32_t unknown1; - uint32_t unknown2; - uint32_t flags; /* level specific */ - uint32_t flags2; /* used by all_eas level */ + /* uint16_t buffer_code; 0x29 = 0x28 + 1 */ + uint8_t info_type; + uint8_t info_class; + uint32_t output_buffer_length; + /* uint32_t input_buffer_offset; */ + uint32_t reserved; + uint32_t input_buffer_length; + uint32_t additional_information; /* SMB2_GETINFO_ADD_* */ + uint32_t getinfo_flags; /* level specific */ union smb_handle file; + DATA_BLOB blob; } in; struct { -- cgit From e33177001cdd7d55e45bb9c6ed3f39bf33a9da84 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 14 Feb 2008 12:03:34 +0100 Subject: Remove type before variables in data.mk (This used to be commit 3c1a7c0dcc56ed5595e31a8df023a04ae95bfca5) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index cf87e6c045..bd96d5e8f5 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -118,7 +118,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR -LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT) +LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ -- cgit From 2e4e06c6e69d881b0fc3c53df50db607fcce4a91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Feb 2008 07:25:38 +1100 Subject: fixed handling of zero sized buffers versus NULL buffers in SMB2. Thanks to Metze for spotting this. (This used to be commit fbcf3e65b9284e5d1862c98706d7f148a36afe47) --- source4/libcli/smb2/request.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 7a0311f886..1de0531d9a 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -206,6 +206,10 @@ bool smb2_request_is_ok(struct smb2_request *req) */ bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) { + if (size == 0) { + /* zero bytes is never out of range */ + return false; + } /* be careful with wraparound! */ if (ptr < buf->body || ptr >= buf->body + buf->body_size || @@ -270,7 +274,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } ofs = SVAL(ptr, 0); size = SVAL(ptr, 2); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -310,7 +314,10 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SSVAL(ptr, 0, 0); SSVAL(ptr, 2, 0); return NT_STATUS_OK; @@ -363,7 +370,10 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SSVAL(ptr, 0, 0); SIVAL(ptr, 2, 0); return NT_STATUS_OK; @@ -416,7 +426,10 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SIVAL(ptr, 0, 0); SIVAL(ptr, 4, 0); return NT_STATUS_OK; @@ -469,7 +482,10 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SIVAL(ptr, 0, 0); SIVAL(ptr, 4, 0); return NT_STATUS_OK; @@ -512,7 +528,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } ofs = SVAL(ptr, 0); size = IVAL(ptr, 2); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -536,7 +552,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } ofs = IVAL(ptr, 0); size = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -563,7 +579,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem } ofs = SVAL(ptr, 0); size = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -587,7 +603,7 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } size = IVAL(ptr, 0); ofs = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -614,6 +630,11 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me status = smb2_pull_o16s16_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); + if (blob.data == NULL) { + *str = NULL; + return NT_STATUS_OK; + } + if (blob.length == 0) { char *s; s = talloc_strdup(mem_ctx, ""); @@ -643,7 +664,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, NTSTATUS status; ssize_t size; - if (strcmp("", str) == 0) { + if (str == NULL) { return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } -- cgit From afe8e5551e41550f40271f49ab4ded5e5f0def9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Feb 2008 13:28:37 +1100 Subject: fixed RAW-READ after the bufinfo changes. Thanks to Metze for spotting this. (This used to be commit 3c9973b695a0b5c30d3a5bfabecf62dd1a25ebc1) --- source4/libcli/raw/rawreadwrite.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 2005e36e04..9e4edaf99c 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -171,6 +171,9 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) parms->readx.out.nread <= req->in.buffer + req->in.size) { req->in.data_size += (SVAL(req->in.vwv, VWV(7)) << 16); + + /* update the bufinfo with the new size */ + smb_setup_bufinfo(req); } } -- cgit From 26b8701321909e10aac124324695f9f4891b1f8d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Feb 2008 14:53:48 +1100 Subject: handle pushing of zero length smb2 strings (This used to be commit 66d0502228b31533b5d93731128a681992c22eda) --- source4/libcli/smb2/request.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1de0531d9a..2471fcaa4d 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -668,6 +668,12 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } + if (*str == 0) { + blob.data = str; + blob.length = 0; + return smb2_push_o16s16_blob(buf, ofs, blob); + } + size = convert_string_talloc(buf->buffer, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { -- cgit From e5d7bd3821327b509ebf38232e8b972455829f88 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 13:10:30 +0100 Subject: Reenable partial linking (This used to be commit a7512fb059d5dcb6bf70418622206eec94153693) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index bd96d5e8f5..67620fac89 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -118,7 +118,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR -LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) +#LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ -- cgit From 51b0a285f02e1bc6187e64514f3f59f546bbecc5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 15:31:15 +0100 Subject: Avoid redetermining paths; use already stored values. (This used to be commit 0d223ddc39b7438dbce6716f1f00c29579a1f4c4) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 67620fac89..bd96d5e8f5 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -118,7 +118,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR -#LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) +LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ -- cgit From 80cbff3d011ad9264462812f57991ed0393b385e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 16:02:33 +0100 Subject: Fix build with partial linking. (This used to be commit bfad9610c472e8d7e3656e19c8dbb6b85727dc13) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index bd96d5e8f5..67620fac89 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -118,7 +118,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR -LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) +#LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS OBJ_FILES = raw/rawfile.o \ raw/smb_signing.o \ -- cgit From ff0315ba859421dff6aba055887e086fa68c2951 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 20:04:18 +0100 Subject: Rename include to mkinclude to emphasize it is different from make's include. (This used to be commit 0e1d0a874ae3d22b8f97a79b81fe0af3ef53a771) --- source4/libcli/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 67620fac89..e4b6c71c8c 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -1,6 +1,6 @@ -include auth/config.mk -include ldap/config.mk -include security/config.mk +mkinclude auth/config.mk +mkinclude ldap/config.mk +mkinclude security/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] PUBLIC_HEADERS = util/error.h util/ntstatus.h util/doserr.h util/werror.h @@ -144,4 +144,4 @@ OBJ_FILES = raw/rawfile.o \ raw/rawlpq.o \ raw/rawshadow.o -include smb2/config.mk +mkinclude smb2/config.mk -- cgit From 921b17648456027b6b46a582aa1d13024a5e9a90 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 14:50:57 +0100 Subject: Remove more uses of global_loadparm. (This used to be commit 47d05ecf6fef66c90994f666b8c63e2e7b5a6cd8) --- source4/libcli/auth/smbencrypt.c | 6 ++++-- source4/libcli/dgram/browse.c | 6 +++--- source4/libcli/dgram/dgramsocket.c | 5 +++-- source4/libcli/dgram/libdgram.h | 1 + source4/libcli/dgram/netlogon.c | 6 +++--- source4/libcli/dgram/ntlogon.c | 6 +++--- source4/libcli/nbt/nbtname.c | 4 ++-- source4/libcli/raw/clitransport.c | 5 +++-- source4/libcli/smb_composite/fetchfile.c | 4 ++-- source4/libcli/smb_composite/smb_composite.h | 1 + 10 files changed, 25 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 4ccf568d8c..c5223db63f 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -125,6 +125,8 @@ bool ntv2_owf_gen(const uint8_t owf[16], HMACMD5Context ctx; TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); + if (!mem_ctx) { return false; } @@ -151,14 +153,14 @@ bool ntv2_owf_gen(const uint8_t owf[16], } } - user_byte_len = push_ucs2_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), &user, user_in); + user_byte_len = push_ucs2_talloc(mem_ctx, iconv_convenience, &user, user_in); if (user_byte_len == (ssize_t)-1) { DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); return false; } - domain_byte_len = push_ucs2_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), &domain, domain_in); + domain_byte_len = push_ucs2_talloc(mem_ctx, iconv_convenience, &domain, domain_in); if (domain_byte_len == (ssize_t)-1) { DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); talloc_free(mem_ctx); diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index eb19555d15..14d8278635 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -38,7 +38,7 @@ NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), request, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, request, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -66,7 +66,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -99,7 +99,7 @@ NTSTATUS dgram_mailslot_browse_parse(struct dgram_mailslot_handler *dgmslot, DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), pkt, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, pkt, (ndr_pull_flags_fn_t)ndr_pull_nbt_browse_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 032d9de67b..7d6f5627c5 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -72,7 +72,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) } /* parse the request */ - ndr_err = ndr_pull_struct_blob(&blob, packet, lp_iconv_convenience(global_loadparm), packet, + ndr_err = ndr_pull_struct_blob(&blob, packet, dgmsock->iconv_convenience, packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_dgram_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -187,6 +187,7 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, dgmsock->send_queue = NULL; dgmsock->incoming.handler = NULL; dgmsock->mailslot_handlers = NULL; + dgmsock->iconv_convenience = lp_iconv_convenience(global_loadparm); return dgmsock; @@ -229,7 +230,7 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, req->dest = dest; if (talloc_reference(req, dest) == NULL) goto failed; - ndr_err = ndr_push_struct_blob(&req->encoded, req, lp_iconv_convenience(global_loadparm), packet, + ndr_err = ndr_push_struct_blob(&req->encoded, req, dgmsock->iconv_convenience, packet, (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 6d4cdb2bdf..4645840971 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -40,6 +40,7 @@ struct nbt_dgram_request { struct nbt_dgram_socket { struct socket_context *sock; struct event_context *event_ctx; + struct smb_iconv_convenience *iconv_convenience; /* the fd event */ struct fd_event *fde; diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 670af4ea63..5c7dedc7bb 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -41,7 +41,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, - lp_iconv_convenience(global_loadparm), + dgmsock->iconv_convenience, request, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -76,7 +76,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct socket_address *dest; ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, - lp_iconv_convenience(global_loadparm), + dgmsock->iconv_convenience, reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -114,7 +114,7 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), netlogon, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 98aad1af8c..7b26ed7c00 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -41,7 +41,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, request, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -75,7 +75,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), reply, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -113,7 +113,7 @@ NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(global_loadparm), ntlogon, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, ntlogon, (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 142dad0296..ae9f3f6b05 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -381,11 +381,11 @@ _PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struc /** push a nbt name into a blob */ -_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name) +_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name) { enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(blob, mem_ctx, lp_iconv_convenience(global_loadparm), name, (ndr_push_flags_fn_t)ndr_push_nbt_name); + ndr_err = ndr_push_struct_blob(blob, mem_ctx, iconv_convenience, name, (ndr_push_flags_fn_t)ndr_push_nbt_name); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 288f0612de..5c14e9f9b8 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -164,14 +164,15 @@ struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *tr DATA_BLOB calling_blob, called_blob; TALLOC_CTX *tmp_ctx = talloc_new(transport); NTSTATUS status; + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); status = nbt_name_dup(transport, called, &transport->called); if (!NT_STATUS_IS_OK(status)) goto failed; - status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling); + status = nbt_name_to_blob(tmp_ctx, iconv_convenience, &calling_blob, calling); if (!NT_STATUS_IS_OK(status)) goto failed; - status = nbt_name_to_blob(tmp_ctx, &called_blob, called); + status = nbt_name_to_blob(tmp_ctx, iconv_convenience, &called_blob, called); if (!NT_STATUS_IS_OK(status)) goto failed; /* allocate output buffer */ diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index c7d02e323c..e4312794c9 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -147,8 +147,8 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; - lp_smbcli_options(global_loadparm, &state->connect->in.options); - + state->connect->in.options = io->in.options; + state->creq = smb_composite_connect_send(state->connect, state, lp_resolve_context(global_loadparm), event_ctx); if (state->creq == NULL) goto failed; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index a732617f80..964ffb0936 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -55,6 +55,7 @@ struct smb_composite_fetchfile { struct cli_credentials *credentials; const char *workgroup; const char *filename; + struct smbcli_options options; } in; struct { uint8_t *data; -- cgit From 263a77c5618daddb0c1e4f0ad0a922bca55faf0d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 15:45:32 +0100 Subject: Remove more uses of global_loadparm. (This used to be commit a1715b1f48ba44bd94844418cc9299649aaf1a5e) --- source4/libcli/auth/smbencrypt.c | 5 +++-- source4/libcli/smb_composite/sesssetup.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index c5223db63f..cefb55e205 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -100,7 +100,7 @@ _PUBLIC_ bool E_deshash(const char *passwd, uint8_t p16[16]) /* Password must be converted to DOS charset - null terminated, uppercase. */ push_string(lp_iconv_convenience(global_loadparm), dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); - /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + /* Only the first 14 chars are considered, password need not be null terminated. */ E_P16((const uint8_t *)dospwd, p16); if (strlen(dospwd) > 14) { @@ -296,12 +296,13 @@ void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], } DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, const char *hostname, const char *domain) { DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - msrpc_gen(mem_ctx, lp_iconv_convenience(global_loadparm), &names_blob, + msrpc_gen(mem_ctx, iconv_convenience, &names_blob, "aaa", NTLMSSP_NAME_TYPE_DOMAIN, domain, NTLMSSP_NAME_TYPE_SERVER, hostname, diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index ce7bcc143e..f5a976958d 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -223,7 +223,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup(global_loadparm)); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = CLI_CRED_NTLM_AUTH; if (lp_client_lanman_auth(global_loadparm)) { @@ -290,7 +290,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, lp_workgroup(global_loadparm)); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = 0; if (lp_client_lanman_auth(global_loadparm)) { -- cgit From 5f9abf527a2f7d58d0b5546cb237f82928b53e49 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 16:18:23 +0100 Subject: Remove more global_loadparm uses. (This used to be commit 4d6fd9381f7fe4c823b47ebc43d7b272a92edffd) --- source4/libcli/dgram/dgramsocket.c | 5 +++-- source4/libcli/dgram/libdgram.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 7d6f5627c5..130d8ae870 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -158,7 +158,8 @@ static void dgm_socket_handler(struct event_context *ev, struct fd_event *fde, then operations will use that event context */ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience) { struct nbt_dgram_socket *dgmsock; NTSTATUS status; @@ -187,7 +188,7 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, dgmsock->send_queue = NULL; dgmsock->incoming.handler = NULL; dgmsock->mailslot_handlers = NULL; - dgmsock->iconv_convenience = lp_iconv_convenience(global_loadparm); + dgmsock->iconv_convenience = iconv_convenience; return dgmsock; diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 4645840971..707cca8cc5 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -93,7 +93,8 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, struct socket_address *), void *private); struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx); + struct event_context *event_ctx, + struct smb_iconv_convenience *); const char *dgram_mailslot_name(struct nbt_dgram_packet *packet); struct dgram_mailslot_handler *dgram_mailslot_find(struct nbt_dgram_socket *dgmsock, -- cgit From c38c2765d1059b33f044a42c6555f3d10d339911 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:17:37 +0100 Subject: Remove yet more uses of global_loadparm. (This used to be commit e01c1e87c0fe9709df7eb5b863f7ce85564174cd) --- source4/libcli/cldap/cldap.c | 8 +++++--- source4/libcli/cldap/cldap.h | 4 +++- source4/libcli/nbt/libnbt.h | 1 + source4/libcli/nbt/nbtsocket.c | 10 ++++++---- source4/libcli/resolve/bcast.c | 10 +++++++--- source4/libcli/resolve/nbtlist.c | 5 ++++- source4/libcli/resolve/wins.c | 10 +++++++--- source4/libcli/swig/libcli_nbt.i | 3 ++- source4/libcli/swig/libcli_nbt_wrap.c | 34 +++++++++++++++++++++++++--------- source4/libcli/wrepl/winsrepl.c | 9 ++++++--- source4/libcli/wrepl/winsrepl.h | 2 ++ 11 files changed, 68 insertions(+), 28 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 7c8d40e608..d10eeb8ffd 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -241,7 +241,8 @@ static void cldap_socket_handler(struct event_context *ev, struct fd_event *fde, then operations will use that event context */ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience) { struct cldap_socket *cldap; NTSTATUS status; @@ -270,6 +271,7 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, cldap->send_queue = NULL; cldap->incoming.handler = NULL; + cldap->iconv_convenience = iconv_convenience; return cldap; @@ -618,7 +620,7 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, data = search.out.response->attributes[0].values; ndr_err = ndr_pull_union_blob_all(data, mem_ctx, - lp_iconv_convenience(global_loadparm), + req->cldap->iconv_convenience, &io->out.netlogon, io->in.version & 0xF, (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); @@ -714,7 +716,7 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, DATA_BLOB blob; ndr_err = ndr_push_union_blob(&blob, tmp_ctx, - lp_iconv_convenience(global_loadparm), + cldap->iconv_convenience, netlogon, version & 0xF, (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 7a222e0652..eb0191d0f4 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -73,6 +73,7 @@ struct cldap_request { struct cldap_socket { struct socket_context *sock; struct event_context *event_ctx; + struct smb_iconv_convenience *iconv_convenience; /* the fd event */ struct fd_event *fde; @@ -111,7 +112,8 @@ struct cldap_search { }; struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx); + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience); NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, void (*handler)(struct cldap_socket *, struct ldap_message *, struct socket_address *), diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index c95d99db54..bc85d87b89 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -94,6 +94,7 @@ struct nbt_name_request { struct nbt_name_socket { struct socket_context *sock; struct event_context *event_ctx; + struct smb_iconv_convenience *iconv_convenience; /* a queue of requests pending to be sent */ struct nbt_name_request *send_queue; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 8bfe746294..95a1643efc 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -190,7 +190,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } /* parse the request */ - ndr_err = ndr_pull_struct_blob(&blob, packet, lp_iconv_convenience(global_loadparm), packet, + ndr_err = ndr_pull_struct_blob(&blob, packet, nbtsock->iconv_convenience, packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -309,7 +309,8 @@ static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *f then operations will use that event context */ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience) { struct nbt_name_socket *nbtsock; NTSTATUS status; @@ -338,6 +339,7 @@ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, nbtsock->num_pending = 0; nbtsock->incoming.handler = NULL; nbtsock->unexpected.handler = NULL; + nbtsock->iconv_convenience = iconv_convenience; nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock, socket_get_fd(nbtsock->sock), 0, @@ -395,7 +397,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, talloc_set_destructor(req, nbt_name_request_destructor); ndr_err = ndr_push_struct_blob(&req->encoded, req, - lp_iconv_convenience(global_loadparm), + req->nbtsock->iconv_convenience, request, (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed; @@ -444,7 +446,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, } ndr_err = ndr_push_struct_blob(&req->encoded, req, - lp_iconv_convenience(global_loadparm), + req->nbtsock->iconv_convenience, request, (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index c8d4ab2df3..2e2eb05397 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -29,6 +29,7 @@ struct resolve_bcast_data { struct interface *ifaces; uint16_t nbt_port; + int nbt_timeout; }; /** @@ -62,7 +63,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, } address_list[count] = NULL; - c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, data->ifaces, data->nbt_port, true, false); + c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, data->ifaces, data->nbt_port, data->nbt_timeout, true, false); talloc_free(address_list); return c; @@ -84,22 +85,25 @@ NTSTATUS resolve_name_bcast(struct nbt_name *name, TALLOC_CTX *mem_ctx, struct interface *ifaces, uint16_t nbt_port, + int nbt_timeout, const char **reply_addr) { struct resolve_bcast_data *data = talloc(mem_ctx, struct resolve_bcast_data); struct composite_context *c; data->ifaces = talloc_reference(data, ifaces); data->nbt_port = nbt_port; + data->nbt_timeout = nbt_timeout; c = resolve_name_bcast_send(mem_ctx, NULL, data, name); return resolve_name_bcast_recv(c, mem_ctx, reply_addr); } -bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port) +bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout) { struct resolve_bcast_data *data = talloc(ctx, struct resolve_bcast_data); data->ifaces = ifaces; data->nbt_port = nbt_port; + data->nbt_timeout = nbt_timeout; return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, data); } @@ -107,5 +111,5 @@ bool resolve_context_add_bcast_method_lp(struct resolve_context *ctx, struct loa { struct interface *ifaces; load_interfaces(ctx, lp_interfaces(lp_ctx), &ifaces); - return resolve_context_add_bcast_method(ctx, ifaces, lp_nbt_port(lp_ctx)); + return resolve_context_add_bcast_method(ctx, ifaces, lp_nbt_port(lp_ctx), lp_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index e1452c09d2..34578e953a 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -102,6 +102,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port, + int nbt_timeout, bool broadcast, bool wins_lookup) { @@ -161,7 +162,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, state->io_queries[i].in.broadcast = broadcast; state->io_queries[i].in.wins_lookup = wins_lookup; - state->io_queries[i].in.timeout = lp_parm_int(global_loadparm, NULL, "nbt", "timeout", 1); + state->io_queries[i].in.timeout = nbt_timeout; state->io_queries[i].in.retries = 2; state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); @@ -201,12 +202,14 @@ NTSTATUS resolve_name_nbtlist(struct nbt_name *name, const char **address_list, struct interface *ifaces, uint16_t nbt_port, + int nbt_timeout, bool broadcast, bool wins_lookup, const char **reply_addr) { struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL, name, address_list, ifaces, nbt_port, + nbt_timeout, broadcast, wins_lookup); return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); } diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 78624ad81a..3ec180f332 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -29,6 +29,7 @@ struct resolve_wins_data { const char **address_list; struct interface *ifaces; uint16_t nbt_port; + int nbt_timeout; }; /** @@ -42,7 +43,7 @@ struct composite_context *resolve_name_wins_send( { struct resolve_wins_data *wins_data = talloc_get_type(userdata, struct resolve_wins_data); if (wins_data->address_list == NULL) return NULL; - return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, wins_data->ifaces, wins_data->nbt_port, false, true); + return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, wins_data->ifaces, wins_data->nbt_port, wins_data->nbt_timeout, false, true); } /* @@ -62,6 +63,7 @@ NTSTATUS resolve_name_wins(struct nbt_name *name, const char **address_list, struct interface *ifaces, uint16_t nbt_port, + int nbt_timeout, const char **reply_addr) { struct composite_context *c; @@ -69,16 +71,18 @@ NTSTATUS resolve_name_wins(struct nbt_name *name, wins_data->address_list = address_list; wins_data->ifaces = ifaces; wins_data->nbt_port = nbt_port; + wins_data->nbt_timeout = nbt_timeout; c = resolve_name_wins_send(mem_ctx, NULL, wins_data, name); return resolve_name_wins_recv(c, mem_ctx, reply_addr); } -bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port) +bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout) { struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data); wins_data->address_list = str_list_copy(wins_data, address_list); wins_data->ifaces = talloc_reference(wins_data, ifaces); wins_data->nbt_port = nbt_port; + wins_data->nbt_timeout = nbt_timeout; return resolve_context_add_method(ctx, resolve_name_wins_send, resolve_name_wins_recv, wins_data); } @@ -87,5 +91,5 @@ bool resolve_context_add_wins_method_lp(struct resolve_context *ctx, struct load { struct interface *ifaces; load_interfaces(ctx, lp_interfaces(lp_ctx), &ifaces); - return resolve_context_add_wins_method(ctx, lp_wins_server_list(lp_ctx), ifaces, lp_nbt_port(lp_ctx)); + return resolve_context_add_wins_method(ctx, lp_wins_server_list(lp_ctx), ifaces, lp_nbt_port(lp_ctx), lp_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); } diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i index 827230b113..e4e366873f 100644 --- a/source4/libcli/swig/libcli_nbt.i +++ b/source4/libcli/swig/libcli_nbt.i @@ -46,7 +46,8 @@ /* Function prototypes */ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx); + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience); enum nbt_name_type { NBT_NAME_CLIENT=0x00, diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c index 6c1b501359..f67e6dd0e3 100644 --- a/source4/libcli/swig/libcli_nbt_wrap.c +++ b/source4/libcli/swig/libcli_nbt_wrap.c @@ -2469,12 +2469,13 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_p_char swig_types[10] #define SWIGTYPE_p_short swig_types[11] #define SWIGTYPE_p_signed_char swig_types[12] -#define SWIGTYPE_p_unsigned_char swig_types[13] -#define SWIGTYPE_p_unsigned_int swig_types[14] -#define SWIGTYPE_p_unsigned_long_long swig_types[15] -#define SWIGTYPE_p_unsigned_short swig_types[16] -static swig_type_info *swig_types[18]; -static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; +#define SWIGTYPE_p_smb_iconv_convenience swig_types[13] +#define SWIGTYPE_p_unsigned_char swig_types[14] +#define SWIGTYPE_p_unsigned_int swig_types[15] +#define SWIGTYPE_p_unsigned_long_long swig_types[16] +#define SWIGTYPE_p_unsigned_short swig_types[17] +static swig_type_info *swig_types[19]; +static swig_module_info swig_module = {swig_types, 18, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2918,17 +2919,21 @@ SWIGINTERN PyObject *_wrap_nbt_name_socket_init(PyObject *SWIGUNUSEDPARM(self), PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct event_context *arg2 = (struct event_context *) 0 ; + struct smb_iconv_convenience *arg3 = (struct smb_iconv_convenience *) 0 ; struct nbt_name_socket *result = 0 ; void *argp2 = 0 ; int res2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; char * kwnames[] = { - (char *) "event_ctx", NULL + (char *) "event_ctx",(char *) "iconv_convenience", NULL }; arg2 = event_context_init(NULL); arg1 = NULL; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|O:nbt_name_socket_init",kwnames,&obj0)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:nbt_name_socket_init",kwnames,&obj0,&obj1)) SWIG_fail; if (obj0) { res2 = SWIG_ConvertPtr(obj0, &argp2,SWIGTYPE_p_event_context, 0 | 0 ); if (!SWIG_IsOK(res2)) { @@ -2936,7 +2941,14 @@ SWIGINTERN PyObject *_wrap_nbt_name_socket_init(PyObject *SWIGUNUSEDPARM(self), } arg2 = (struct event_context *)(argp2); } - result = (struct nbt_name_socket *)nbt_name_socket_init(arg1,arg2); + if (obj1) { + res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_smb_iconv_convenience, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "nbt_name_socket_init" "', argument " "3"" of type '" "struct smb_iconv_convenience *""'"); + } + arg3 = (struct smb_iconv_convenience *)(argp3); + } + result = (struct nbt_name_socket *)nbt_name_socket_init(arg1,arg2,arg3); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_socket, 0 | 0 ); return resultobj; fail: @@ -4135,6 +4147,7 @@ static swig_type_info _swigt__p_nbt_name_socket = {"_p_nbt_name_socket", "struct static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_smb_iconv_convenience = {"_p_smb_iconv_convenience", "struct smb_iconv_convenience *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; @@ -4154,6 +4167,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_p_char, &_swigt__p_short, &_swigt__p_signed_char, + &_swigt__p_smb_iconv_convenience, &_swigt__p_unsigned_char, &_swigt__p_unsigned_int, &_swigt__p_unsigned_long_long, @@ -4173,6 +4187,7 @@ static swig_cast_info _swigc__p_nbt_name_socket[] = { {&_swigt__p_nbt_name_sock static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_smb_iconv_convenience[] = { {&_swigt__p_smb_iconv_convenience, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; @@ -4192,6 +4207,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_p_char, _swigc__p_short, _swigc__p_signed_char, + _swigc__p_smb_iconv_convenience, _swigc__p_unsigned_char, _swigc__p_unsigned_int, _swigc__p_unsigned_long_long, diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index d027e88396..87e5282539 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -102,7 +102,7 @@ static NTSTATUS wrepl_finish_recv(void *private, DATA_BLOB packet_blob_in) blob.length = packet_blob_in.length - 4; /* we have a full request - parse it */ - ndr_err = ndr_pull_struct_blob(&blob, req->packet, lp_iconv_convenience(global_loadparm), req->packet, + ndr_err = ndr_pull_struct_blob(&blob, req->packet, wrepl_socket->iconv_convenience, req->packet, (ndr_pull_flags_fn_t)ndr_pull_wrepl_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); @@ -163,7 +163,8 @@ static int wrepl_socket_destructor(struct wrepl_socket *sock) operations will use that event context */ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx) + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience) { struct wrepl_socket *wrepl_socket; NTSTATUS status; @@ -178,6 +179,8 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, } if (!wrepl_socket->event.ctx) goto failed; + wrepl_socket->iconv_convenience = iconv_convenience; + status = socket_create("ip", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0); if (!NT_STATUS_IS_OK(status)) goto failed; @@ -493,7 +496,7 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket, } wrap.packet = *packet; - ndr_err = ndr_push_struct_blob(&blob, req, lp_iconv_convenience(global_loadparm), &wrap, + ndr_err = ndr_push_struct_blob(&blob, req, wrepl_socket->iconv_convenience, &wrap, (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source4/libcli/wrepl/winsrepl.h b/source4/libcli/wrepl/winsrepl.h index 52b0bee69e..f33e63119d 100644 --- a/source4/libcli/wrepl/winsrepl.h +++ b/source4/libcli/wrepl/winsrepl.h @@ -49,6 +49,8 @@ struct wrepl_socket { /* remember if we need to free the wrepl_socket at the end of wrepl_socket_dead() */ bool free_skipped; + + struct smb_iconv_convenience *iconv_convenience; }; struct wrepl_send_ctrl { -- cgit From 10169a203019445e6d325a5c1559de3c73782237 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:54:24 +0100 Subject: Remove more global_loadparm instance.s (This used to be commit a1280252ce924df69d911e597b7f65d8038abef9) --- source4/libcli/finddcs.c | 4 +++- source4/libcli/resolve/nbtlist.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 606809751e..67ba47ddc6 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -28,6 +28,7 @@ #include "libcli/libcli.h" #include "libcli/resolve/resolve.h" #include "libcli/finddcs.h" +#include "param/param.h" struct finddcs_state { struct composite_context *ctx; @@ -195,7 +196,8 @@ static void fallback_node_status(struct finddcs_state *state) state->node_status.in.timeout = 1; state->node_status.in.retries = 2; - nbtsock = nbt_name_socket_init(state, state->ctx->event_ctx); + nbtsock = nbt_name_socket_init(state, state->ctx->event_ctx, + lp_iconv_convenience(global_loadparm)); if (composite_nomem(nbtsock, state->ctx)) return; name_req = nbt_name_status_send(nbtsock, &state->node_status); diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 34578e953a..887bdd7ecf 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -141,7 +141,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, return c; } - state->nbtsock = nbt_name_socket_init(state, event_ctx); + state->nbtsock = nbt_name_socket_init(state, event_ctx, + lp_iconv_convenience(global_loadparm)); if (composite_nomem(state->nbtsock, c)) return c; /* count the address_list size */ -- cgit From 299265d47b5b2faac39fbf908c738f336ea21e67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 18:09:47 +0100 Subject: Remove yet more global_loadparm instances. (This used to be commit 5de88728ac5c567d3711d1ac6862bbdaced84b75) --- source4/libcli/raw/clisession.c | 3 +++ source4/libcli/raw/libcliraw.h | 5 +++++ source4/libcli/smb_composite/sesssetup.c | 12 ++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 55cb3ef305..74e8d85c8e 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -51,6 +51,9 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, } session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; + session->options.lanman_auth = lp_client_lanman_auth(global_loadparm); + session->options.ntlmv2_auth = lp_client_ntlmv2_auth(global_loadparm); + session->options.plaintext_auth = lp_client_plaintext_auth(global_loadparm); capabilities = transport->negotiate.capabilities; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 7111649fc1..0ea8f9dec2 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -186,6 +186,11 @@ struct smbcli_session { /* the spnego context if we use extented security */ struct gensec_security *gensec; + + struct smbcli_session_options { + uint_t lanman_auth; + uint_t ntlmv2_auth; + } options; }; /* diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index f5a976958d..75a2a579a2 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -226,11 +226,11 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = CLI_CRED_NTLM_AUTH; - if (lp_client_lanman_auth(global_loadparm)) { + if (session->options.lanman_auth) { flags |= CLI_CRED_LANMAN_AUTH; } - if (lp_client_ntlmv2_auth(global_loadparm)) { + if (session->options.ntlmv2_auth) { flags |= CLI_CRED_NTLMv2_AUTH; } @@ -263,7 +263,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, set_user_session_key(session, &session_key); data_blob_free(&session_key); - } else if (lp_client_plaintext_auth(global_loadparm)) { + } else if (session->options.plaintext_auth) { state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); } else { @@ -293,11 +293,11 @@ static NTSTATUS session_setup_old(struct composite_context *c, DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = 0; - if (lp_client_lanman_auth(global_loadparm)) { + if (session->options.lanman_auth) { flags |= CLI_CRED_LANMAN_AUTH; } - if (lp_client_ntlmv2_auth(global_loadparm)) { + if (session->options.ntlmv2_auth) { flags |= CLI_CRED_NTLMv2_AUTH; } @@ -324,7 +324,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, set_user_session_key(session, &session_key); data_blob_free(&session_key); - } else if (lp_client_plaintext_auth(global_loadparm)) { + } else if (session->options.plaintext_auth) { state->setup.old.in.password = data_blob_talloc(state, password, strlen(password)); } else { /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ -- cgit From 3c20b3eebafe46127a7b69cca573c6a128f8de89 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 18:11:44 +0100 Subject: Fix the build. (This used to be commit f4b31ad76771d674ec85cd155b023eed377e6eb4) --- source4/libcli/raw/clisession.c | 1 + source4/libcli/raw/libcliraw.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 74e8d85c8e..5a33d9cffc 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "system/filesys.h" +#include "param/param.h" #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ req = smbcli_request_setup_session(session, cmd, wct, buflen); \ diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 0ea8f9dec2..0578a9eab1 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -188,8 +188,9 @@ struct smbcli_session { struct gensec_security *gensec; struct smbcli_session_options { - uint_t lanman_auth; - uint_t ntlmv2_auth; + uint_t lanman_auth:1; + uint_t ntlmv2_auth:1; + uint_t plaintext_auth:1; } options; }; -- cgit From 4590432d6290fd1c21a27ec5e6643d455e4fec69 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 18:43:02 +0100 Subject: Remove another global_loadparm instance. (This used to be commit ccb29c0b463f5ccb53553f0a1c411ad77a84482a) --- source4/libcli/wrepl/winsrepl.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 87e5282539..3e7793c0c7 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -311,6 +311,14 @@ static void wrepl_connect_handler(struct composite_context *creq) composite_done(result); } +const char *wrepl_best_ip(struct loadparm_context *lp_ctx, const char *peer_ip) +{ + struct interface *ifaces; + load_interfaces(lp_ctx, lp_interfaces(lp_ctx), &ifaces); + return iface_best_ip(ifaces, peer_ip); +} + + /* connect a wrepl_socket to a WINS server */ @@ -334,12 +342,6 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, state->result = result; state->wrepl_socket = wrepl_socket; - if (!our_ip) { - struct interface *ifaces; - load_interfaces(state, lp_interfaces(global_loadparm), &ifaces); - our_ip = iface_best_ip(ifaces, peer_ip); - } - us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, our_ip, 0); if (composite_nomem(us, result)) return result; -- cgit From 3101cb888d5cbad785050b8491b138d683d444fb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 25 Feb 2008 12:51:55 +0100 Subject: Remove uses of global_loadparm. (This used to be commit a16c9a2129ce92e7e1a613b2badd168e42ead436) --- source4/libcli/raw/clisocket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 8fcb8bb48c..eaa02e1047 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -33,6 +33,7 @@ struct sock_connect_state { const char *host_name; int num_ports; uint16_t *ports; + const char *socket_options; struct smbcli_socket *result; }; @@ -80,6 +81,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, for (i=0;ports[i];i++) { state->ports[i] = atoi(ports[i]); } + state->socket_options = lp_socket_options(global_loadparm); ctx = socket_connect_multi_send(state, host_addr, state->num_ports, state->ports, @@ -108,7 +110,7 @@ static void smbcli_sock_connect_recv_conn(struct composite_context *ctx) if (!composite_is_ok(state->ctx)) return; state->ctx->status = - socket_set_option(sock, lp_socket_options(global_loadparm), NULL); + socket_set_option(sock, state->socket_options, NULL); if (!composite_is_ok(state->ctx)) return; -- cgit From 2946a11dc7d367128d8c002966ac19e3e36450dd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Feb 2008 20:30:03 +0100 Subject: Remove use of global_loadparm. (This used to be commit 4472d7e1e47d4fe6b1c60e28d168cce99b237979) --- source4/libcli/smb_composite/fetchfile.c | 2 +- source4/libcli/smb_composite/smb_composite.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index e4312794c9..d8d7481270 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -150,7 +150,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.options = io->in.options; state->creq = smb_composite_connect_send(state->connect, state, - lp_resolve_context(global_loadparm), event_ctx); + io->in.resolve_ctx, event_ctx); if (state->creq == NULL) goto failed; state->creq->async.private_data = c; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 964ffb0936..e7e131869c 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -56,6 +56,7 @@ struct smb_composite_fetchfile { const char *workgroup; const char *filename; struct smbcli_options options; + struct resolve_context *resolve_ctx; } in; struct { uint8_t *data; -- cgit From 7e045915205264efdd96d7e55a9e342c2748c93e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Feb 2008 21:02:49 +0100 Subject: Remove use of global_loadparm. (This used to be commit 3cf3922c806d0e33439073d204b44bf0af3102d5) --- source4/libcli/finddcs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 67ba47ddc6..56f931ce19 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -41,6 +41,8 @@ struct finddcs_state { struct nbtd_getdcname r; struct nbt_name_status node_status; + struct smb_iconv_convenience *iconv_convenience; + int num_dcs; struct nbt_dc_name *dcs; uint16_t nbt_port; @@ -67,6 +69,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, const char *domain_name, int name_type, struct dom_sid *domain_sid, + struct smb_iconv_convenience *iconv_convenience, struct resolve_context *resolve_ctx, struct event_context *event_ctx, struct messaging_context *msg_ctx) @@ -87,6 +90,7 @@ struct composite_context *finddcs_send(TALLOC_CTX *mem_ctx, state->nbt_port = nbt_port; state->my_netbios_name = talloc_strdup(state, my_netbios_name); state->domain_name = talloc_strdup(state, domain_name); + state->iconv_convenience = iconv_convenience; if (composite_nomem(state->domain_name, c)) return c; if (domain_sid) { @@ -197,7 +201,7 @@ static void fallback_node_status(struct finddcs_state *state) state->node_status.in.retries = 2; nbtsock = nbt_name_socket_init(state, state->ctx->event_ctx, - lp_iconv_convenience(global_loadparm)); + state->iconv_convenience); if (composite_nomem(nbtsock, state->ctx)) return; name_req = nbt_name_status_send(nbtsock, &state->node_status); @@ -255,6 +259,7 @@ NTSTATUS finddcs(TALLOC_CTX *mem_ctx, uint16_t nbt_port, const char *domain_name, int name_type, struct dom_sid *domain_sid, + struct smb_iconv_convenience *iconv_convenience, struct resolve_context *resolve_ctx, struct event_context *event_ctx, struct messaging_context *msg_ctx, @@ -264,7 +269,9 @@ NTSTATUS finddcs(TALLOC_CTX *mem_ctx, my_netbios_name, nbt_port, domain_name, name_type, - domain_sid, resolve_ctx, + domain_sid, + iconv_convenience, + resolve_ctx, event_ctx, msg_ctx); return finddcs_recv(c, mem_ctx, num_dcs, dcs); } -- cgit From 1ada7108408f567f61cfbf2b625730ba898452db Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:23:38 +0100 Subject: Move public header accumulation out of the perl code. Never install generated prototype files. It's easier to break the API when using them and they're not easily readable for 3rd party users. Conflicts: source/auth/config.mk source/auth/credentials/config.mk source/auth/gensec/config.mk source/build/smb_build/config_mk.pm source/build/smb_build/main.pl source/build/smb_build/makefile.pm source/dsdb/config.mk source/lib/charset/config.mk source/lib/tdr/config.mk source/lib/util/config.mk source/libcli/config.mk source/libcli/ldap/config.mk source/librpc/config.mk source/param/config.mk source/rpc_server/config.mk source/torture/config.mk (This used to be commit 6c659689ed4081f1d7a6253c538c7f01784197ba) --- source4/libcli/auth/config.mk | 4 +++- source4/libcli/config.mk | 13 +++++++++---- source4/libcli/ldap/config.mk | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 6cea0a08f0..61d3fe8c94 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,7 +1,6 @@ ################################# # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] -PUBLIC_HEADERS = credentials.h PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = credentials.o \ session.o \ @@ -12,3 +11,6 @@ PUBLIC_DEPENDENCIES = \ LIBSAMBA-CONFIG # End SUBSYSTEM LIBCLI_AUTH ################################# + + +PUBLIC_HEADERS += libcli/auth/credentials.h diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e4b6c71c8c..d3a3beaaa9 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -3,11 +3,13 @@ mkinclude ldap/config.mk mkinclude security/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] -PUBLIC_HEADERS = util/error.h util/ntstatus.h util/doserr.h util/werror.h OBJ_FILES = util/doserr.o \ util/errormap.o \ util/nterr.o \ + +PUBLIC_HEADERS += $(addprefix libcli/, util/error.h util/ntstatus.h util/doserr.h util/werror.h) + [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h OBJ_FILES = util/clilsa.o @@ -68,10 +70,11 @@ PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE [SUBSYSTEM::LIBCLI_CLDAP] OBJ_FILES = cldap/cldap.o -PUBLIC_HEADERS = cldap/cldap.h PUBLIC_DEPENDENCIES = LIBCLI_LDAP PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB +PUBLIC_HEADERS += libcli/cldap/cldap.h + [SUBSYSTEM::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h OBJ_FILES = \ @@ -102,8 +105,7 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING [SUBSYSTEM::LIBCLI_SMB] -PUBLIC_HEADERS = libcli.h -PUBLIC_PROTO_HEADER = libcli_proto.h +PRIVATE_PROTO_HEADER = libcli_proto.h OBJ_FILES = clireadwrite.o \ cliconnect.o \ clifile.o \ @@ -115,6 +117,9 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket + +PUBLIC_HEADERS += libcli/libcli.h + [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 239ee1f161..9b0dc1a0f4 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,6 +1,5 @@ [SUBSYSTEM::LIBCLI_LDAP] -PUBLIC_PROTO_HEADER = ldap_proto.h -PUBLIC_HEADERS = ldap.h +PRIVATE_PROTO_HEADER = ldap_proto.h OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ @@ -11,6 +10,7 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec +PUBLIC_HEADERS += libcli/ldap/ldap.h [SUBSYSTEM::LDAP_ENCODE] PUBLIC_PROTO_HEADER = ldap_ndr.h -- cgit From 489f66cd422453c00afd14121fb61a41a6785249 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:36:51 +0100 Subject: Change remaining prototype headers to be private. (This used to be commit 2f7ff409e89c9682e681ddcf54439db9e3b6ccb4) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 9b0dc1a0f4..bcdedd3440 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -13,6 +13,6 @@ PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ PUBLIC_HEADERS += libcli/ldap/ldap.h [SUBSYSTEM::LDAP_ENCODE] -PUBLIC_PROTO_HEADER = ldap_ndr.h +PRIVATE_PROTO_HEADER = ldap_ndr.h OBJ_FILES = ldap_ndr.o # FIXME PRIVATE_DEPENDENCIES = LIBLDB -- cgit From 3cbe47b2aef427f7f1fe8f4aa2496fbbe31a3ade Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Mar 2008 15:11:16 +0100 Subject: libcli/raw: make it possible to not send CAP_LEVEL_II_OPLOCKS But the keep the default to always send it when the server supports it too. metze (This used to be commit 33caaef2e46557525a8ffb79d6dd0db46a079529) --- source4/libcli/raw/rawnegotiate.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index ec2ada53ff..6c16935f21 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -187,6 +187,10 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) transport->negotiate.capabilities &= ~CAP_STATUS32; } + if (!transport->options.use_level2_oplocks) { + transport->negotiate.capabilities &= ~CAP_LEVEL_II_OPLOCKS; + } + failed: return smbcli_request_destroy(req); } -- cgit From 6743de076db8f8ddadb59b13f2ceaabb17f385d0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Mar 2008 19:11:57 +0100 Subject: libcli/raw: add RAW_RENAME_NTTRANS support metze Signed-off-by: Stefan Metzmacher (This used to be commit bfe773a620640fa46efe008f38144f5452350825) --- source4/libcli/raw/interfaces.h | 13 ++++++++++++- source4/libcli/raw/rawfile.c | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 24e8ad4afc..3965c58204 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -175,7 +175,7 @@ struct smb_rmdir { }; /* struct used in rename() call */ -enum smb_rename_level {RAW_RENAME_RENAME, RAW_RENAME_NTRENAME}; +enum smb_rename_level {RAW_RENAME_RENAME, RAW_RENAME_NTRENAME, RAW_RENAME_NTTRANS}; union smb_rename { struct { @@ -206,6 +206,17 @@ union smb_rename { const char *new_name; } in; } ntrename; + + /* NT TRANS rename interface */ + struct { + enum smb_rename_level level; + + struct { + union smb_handle file; + uint16_t flags;/* see RENAME_REPLACE_IF_EXISTS */ + const char *new_name; + } in; + } nttrans; }; enum smb_tcon_level { diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index d9383401b7..725034c3a9 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -36,6 +36,8 @@ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree, union smb_rename *parms) { struct smbcli_request *req = NULL; + struct smb_nttrans nt; + TALLOC_CTX *mem_ctx; switch (parms->generic.level) { case RAW_RENAME_RENAME: @@ -53,6 +55,30 @@ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree, smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); break; + + case RAW_RENAME_NTTRANS: + + mem_ctx = talloc_new(tree); + + nt.in.max_setup = 0; + nt.in.max_param = 0; + nt.in.max_data = 0; + nt.in.setup_count = 0; + nt.in.setup = NULL; + nt.in.function = NT_TRANSACT_RENAME; + nt.in.params = data_blob_talloc(mem_ctx, NULL, 4); + nt.in.data = data_blob(NULL, 0); + + SSVAL(nt.in.params.data, VWV(0), parms->nttrans.in.file.fnum); + SSVAL(nt.in.params.data, VWV(1), parms->nttrans.in.flags); + + smbcli_blob_append_string(tree->session, mem_ctx, + &nt.in.params, parms->nttrans.in.new_name, + STR_TERMINATE); + + req = smb_raw_nttrans_send(tree, &nt); + talloc_free(mem_ctx); + return req; } if (!smbcli_request_send(req)) { -- cgit From 25a3eb0436ea7c060eedd6827e5fdc5efd6ab47b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Mar 2008 14:32:26 +0100 Subject: swig: make the code more portable and use NT_STATUS_V() and W_ERROR_V() metze (This used to be commit d6fd98a307f83fd492ef73bf6ec281f9f11286f2) --- source4/libcli/util/errors.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index ede536a995..17efcbf62a 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -20,7 +20,7 @@ #ifdef SWIGPYTHON %typemap(out,noblock=1) WERROR { if (!W_ERROR_IS_OK($1)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, win_errstr($1)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V($1), win_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if ($result == NULL) { @@ -30,7 +30,7 @@ %typemap(out,noblock=1) NTSTATUS { if (NT_STATUS_IS_ERR($1)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, nt_errstr($1)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V($1), nt_errstr($1)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if ($result == NULL) { -- cgit From 2fd59920381ea81734565637adcec96e5668ef86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Mar 2008 14:33:18 +0100 Subject: swig: regenerate _wrap.c files metze (This used to be commit 08b41e10699c7bb8058ab0ab61f17a1bbfcc1ce4) --- source4/libcli/security/security_wrap.c | 8 ++++---- source4/libcli/swig/libcli_nbt_wrap.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index 72118b2359..eb9e4c45d9 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -3116,7 +3116,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM arg2 = (struct security_ace *)(argp2); result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3156,7 +3156,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM arg2 = (struct security_ace *)(argp2); result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3196,7 +3196,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM arg2 = (struct dom_sid *)(argp2); result = security_descriptor_dacl_del(arg1,(struct dom_sid const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3236,7 +3236,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM arg2 = (struct dom_sid *)(argp2); result = security_descriptor_sacl_del(arg1,(struct dom_sid const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c index f67e6dd0e3..e0bdb27cfc 100644 --- a/source4/libcli/swig/libcli_nbt_wrap.c +++ b/source4/libcli/swig/libcli_nbt_wrap.c @@ -4065,7 +4065,7 @@ SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyO arg3 = (struct nbt_name_query *)(argp3); result = do_nbt_name_query(arg1,arg2,arg3); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { -- cgit From 9a1bec08013dda77597369387da0193081a7a6e2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 20 Mar 2008 12:12:10 +1100 Subject: More kludge ACLs! Rather than killing off the nasty 'kludge ACLs' stuff, this patch extends it, to ensure that LSA secrets and the registry are also protected. Andrew Bartlett (This used to be commit 2f2b110fb870132099bad1d4c16ed8962affb3ce) --- source4/libcli/security/security.h | 8 ++++++++ source4/libcli/security/security_token.c | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h index d9485c825f..c7f2a09311 100644 --- a/source4/libcli/security/security.h +++ b/source4/libcli/security/security.h @@ -18,4 +18,12 @@ */ #include "librpc/gen_ndr/security.h" + +enum security_user_level { + SECURITY_ANONYMOUS, + SECURITY_USER, + SECURITY_ADMINISTRATOR, + SECURITY_SYSTEM +}; + #include "libcli/security/proto.h" diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index e126340c46..0680c54258 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -23,6 +23,7 @@ #include "includes.h" #include "dsdb/samdb/samdb.h" #include "libcli/security/security.h" +#include "auth/session.h" /* return a blank security token @@ -141,3 +142,29 @@ bool security_token_has_nt_authenticated_users(const struct security_token *toke { return security_token_has_sid_string(token, SID_NT_AUTHENTICATED_USERS); } + +enum security_user_level security_session_user_level(struct auth_session_info *session_info) +{ + if (!session_info) { + return SECURITY_ANONYMOUS; + } + + if (security_token_is_system(session_info->security_token)) { + return SECURITY_SYSTEM; + } + + if (security_token_is_anonymous(session_info->security_token)) { + return SECURITY_ANONYMOUS; + } + + if (security_token_has_builtin_administrators(session_info->security_token)) { + return SECURITY_ADMINISTRATOR; + } + + if (security_token_has_nt_authenticated_users(session_info->security_token)) { + return SECURITY_USER; + } + + return SECURITY_ANONYMOUS; +} + -- cgit From 482f33077b965bab7f6ccb82cee03b66d70c57b7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 21 Mar 2008 10:35:54 +0100 Subject: Add my copyright If I remember it right and when I look at the git log, then this way to do the async functions was designed by me. (This used to be commit 8d44f997c88b97fc40a88eebd50b6df720c0c10f) --- source4/libcli/composite/composite.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index aab7487a42..26169e7838 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -1,6 +1,7 @@ /* Unix SMB/CIFS implementation. + Copyright (C) Volker Lendecke 2005 Copyright (C) Andrew Tridgell 2005 This program is free software; you can redistribute it and/or modify -- cgit From 341c6b46b33268e58b08d6d2eddb109dd079539e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Mar 2008 09:39:32 +0100 Subject: libcli/security: fix compiler warnings metze (This used to be commit 91dd223bd432f0461c5c85259b4e48a1b7f83af1) --- source4/libcli/security/security.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h index c7f2a09311..46ef6186b8 100644 --- a/source4/libcli/security/security.h +++ b/source4/libcli/security/security.h @@ -26,4 +26,6 @@ enum security_user_level { SECURITY_SYSTEM }; +struct auth_session_info; + #include "libcli/security/proto.h" -- cgit From f41b9a9dde0dcad17e3a137537548f9bd9ab3901 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Apr 2008 15:08:30 +0200 Subject: Rename libsamba-config to libsamba-hostconfig. (This used to be commit c46b7e90e347da76156ddcae4866adb88e9fec21) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 61d3fe8c94..f786c71469 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -8,7 +8,7 @@ OBJ_FILES = credentials.o \ smbdes.o PUBLIC_DEPENDENCIES = \ MSRPC_PARSE \ - LIBSAMBA-CONFIG + LIBSAMBA-HOSTCONFIG # End SUBSYSTEM LIBCLI_AUTH ################################# diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index d3a3beaaa9..0aa67f35db 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -53,11 +53,11 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i -PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-CONFIG +PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG [PYTHON::python_libcli_smb] SWIG_FILE = swig/libcli_smb.i -PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-CONFIG +PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG [SUBSYSTEM::LIBCLI_DGRAM] OBJ_FILES = \ @@ -96,7 +96,7 @@ OBJ_FILES = \ resolve/wins.o \ resolve/host.o \ resolve/resolve_lp.o -PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-CONFIG LIBNETIF +PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF [SUBSYSTEM::LIBCLI_FINDDCS] PRIVATE_PROTO_HEADER = finddcs.h -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/libcli/auth/smbencrypt.c | 4 +- source4/libcli/cliconnect.c | 1 + source4/libcli/clilist.c | 1 + source4/libcli/climessage.c | 1 + source4/libcli/clireadwrite.c | 1 + source4/libcli/composite/composite.h | 37 +++++++++++++++- source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 5 ++- source4/libcli/ldap/ldap.h | 4 +- source4/libcli/ldap/ldap_bind.c | 7 +-- source4/libcli/ldap/ldap_client.c | 23 +++++----- source4/libcli/ldap/ldap_client.h | 44 ++++++++++++++++++ source4/libcli/ldap/ldap_ildap.c | 6 +-- source4/libcli/ldap/ldap_msg.c | 2 +- source4/libcli/nbt/libnbt.h | 75 ++++++++++++++++++++++++++++++- source4/libcli/nbt/namequery.c | 1 + source4/libcli/nbt/namerefresh.c | 11 ++--- source4/libcli/nbt/nameregister.c | 15 ++++--- source4/libcli/nbt/namerelease.c | 7 +-- source4/libcli/nbt/nbtname.c | 2 +- source4/libcli/nbt/nbtsocket.c | 6 +-- source4/libcli/raw/clierror.c | 4 +- source4/libcli/raw/clioplock.c | 1 + source4/libcli/raw/clisession.c | 3 +- source4/libcli/raw/clisocket.c | 4 +- source4/libcli/raw/clitransport.c | 8 ++-- source4/libcli/raw/clitree.c | 7 +-- source4/libcli/raw/libcliraw.h | 76 +++++++++++++++++++++++++++++++- source4/libcli/raw/rawacl.c | 1 + source4/libcli/raw/rawfile.c | 25 ++++++----- source4/libcli/raw/rawfileinfo.c | 9 ++-- source4/libcli/raw/rawfsinfo.c | 3 +- source4/libcli/raw/rawioctl.c | 3 +- source4/libcli/raw/rawnegotiate.c | 1 + source4/libcli/raw/rawnotify.c | 5 ++- source4/libcli/raw/rawreadwrite.c | 11 ++--- source4/libcli/raw/rawrequest.c | 7 ++- source4/libcli/raw/rawsearch.c | 3 +- source4/libcli/raw/rawsetfileinfo.c | 7 +-- source4/libcli/raw/rawshadow.c | 1 + source4/libcli/raw/rawtrans.c | 9 ++-- source4/libcli/raw/smb_signing.c | 1 + source4/libcli/smb2/close.c | 1 + source4/libcli/smb2/connect.c | 1 + source4/libcli/smb2/create.c | 1 + source4/libcli/smb2/find.c | 1 + source4/libcli/smb2/getinfo.c | 1 + source4/libcli/smb2/negprot.c | 2 + source4/libcli/smb2/notify.c | 1 + source4/libcli/smb2/setinfo.c | 1 + source4/libcli/smb2/transport.c | 1 + source4/libcli/smb_composite/appendacl.c | 1 + source4/libcli/smb_composite/connect.c | 1 + source4/libcli/smb_composite/fsinfo.c | 1 + source4/libcli/smb_composite/savefile.c | 1 + source4/libcli/smb_composite/sesssetup.c | 2 + source4/libcli/util/error.h | 3 +- source4/libcli/util/errormap.c | 1 + 58 files changed, 371 insertions(+), 94 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index cefb55e205..7de9627302 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -63,7 +63,7 @@ bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -_PUBLIC_ bool E_md4hash(const char *passwd, uint8_t p16[16]) +bool E_md4hash(const char *passwd, uint8_t p16[16]) { int len; void *wpwd; @@ -91,7 +91,7 @@ _PUBLIC_ bool E_md4hash(const char *passwd, uint8_t p16[16]) * @note p16 is filled in regardless */ -_PUBLIC_ bool E_deshash(const char *passwd, uint8_t p16[16]) +bool E_deshash(const char *passwd, uint8_t p16[16]) { bool ret = true; fstring dospwd; diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 666dfe8446..4858a96110 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/auth/libcli_auth.h" #include "libcli/smb_composite/smb_composite.h" #include "param/param.h" diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index 07393a3491..5d43606c61 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/libcli.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" struct search_private { struct clilist_file_info *dirlist; diff --git a/source4/libcli/climessage.c b/source4/libcli/climessage.c index 6002ccfc59..5ed0e8e3cd 100644 --- a/source4/libcli/climessage.c +++ b/source4/libcli/climessage.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/libcli.h" diff --git a/source4/libcli/clireadwrite.c b/source4/libcli/clireadwrite.c index f5ba799bbc..ae2367918c 100644 --- a/source4/libcli/clireadwrite.c +++ b/source4/libcli/clireadwrite.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/libcli.h" /**************************************************************************** diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index db0ecf9af6..f1bed20361 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -19,6 +19,9 @@ along with this program. If not, see . */ +#ifndef __COMPOSITE_H__ +#define __COMPOSITE_H__ + #include "libcli/raw/interfaces.h" /* @@ -68,4 +71,36 @@ struct smb2_request; struct rpc_request; struct nbt_name_request; -#include "libcli/composite/proto.h" +struct composite_context *composite_create(TALLOC_CTX *mem_ctx, struct event_context *ev); +bool composite_nomem(const void *p, struct composite_context *ctx); +void composite_continue(struct composite_context *ctx, + struct composite_context *new_ctx, + void (*continuation)(struct composite_context *), + void *private_data); +void composite_continue_rpc(struct composite_context *ctx, + struct rpc_request *new_req, + void (*continuation)(struct rpc_request *), + void *private_data); +void composite_continue_irpc(struct composite_context *ctx, + struct irpc_request *new_req, + void (*continuation)(struct irpc_request *), + void *private_data); +void composite_continue_smb(struct composite_context *ctx, + struct smbcli_request *new_req, + void (*continuation)(struct smbcli_request *), + void *private_data); +void composite_continue_smb2(struct composite_context *ctx, + struct smb2_request *new_req, + void (*continuation)(struct smb2_request *), + void *private_data); +void composite_continue_nbt(struct composite_context *ctx, + struct nbt_name_request *new_req, + void (*continuation)(struct nbt_name_request *), + void *private_data); +bool composite_is_ok(struct composite_context *ctx); +void composite_done(struct composite_context *ctx); +void composite_error(struct composite_context *ctx, NTSTATUS status); +NTSTATUS composite_wait(struct composite_context *c); + + +#endif /* __COMPOSITE_H__ */ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index bcdedd3440..0c5236c138 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,9 +10,8 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec -PUBLIC_HEADERS += libcli/ldap/ldap.h +PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h [SUBSYSTEM::LDAP_ENCODE] -PRIVATE_PROTO_HEADER = ldap_ndr.h OBJ_FILES = ldap_ndr.o # FIXME PRIVATE_DEPENDENCIES = LIBLDB diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 00a0631753..fc6de7993e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,6 +25,7 @@ #include "includes.h" #include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) @@ -187,7 +188,7 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data *data = asn1_init(mem_ctx); int i, j; @@ -927,7 +928,7 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* This routine returns LDAP status codes */ -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) { uint8_t tag; diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 6f5e86744e..a336a7ad85 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -254,6 +254,8 @@ struct cli_credentials; struct dom_sid; struct asn1_data; -#include "libcli/ldap/ldap_proto.h" +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); #endif diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index fd15ff2fc7..2c04edf950 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" @@ -35,7 +36,7 @@ struct ldap_simple_creds { const char *pw; }; -NTSTATUS ldap_rebind(struct ldap_connection *conn) +_PUBLIC_ NTSTATUS ldap_rebind(struct ldap_connection *conn) { NTSTATUS status; struct ldap_simple_creds *creds; @@ -88,7 +89,7 @@ static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *con /* perform a simple username/password bind */ -NTSTATUS ldap_bind_simple(struct ldap_connection *conn, +_PUBLIC_ NTSTATUS ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) { struct ldap_request *req; @@ -199,7 +200,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, /* perform a sasl bind using the given credentials */ -NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, +_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds, struct loadparm_context *lp_ctx) { diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index d99851ee15..296a7b11f2 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -28,6 +28,7 @@ #include "lib/events/events.h" #include "lib/socket/socket.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" @@ -41,7 +42,7 @@ /** create a new ldap_connection stucture. The event context is optional */ -struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, +_PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct event_context *ev) { @@ -293,7 +294,7 @@ struct ldap_connect_state { static void ldap_connect_recv_unix_conn(struct composite_context *ctx); static void ldap_connect_recv_tcp_conn(struct composite_context *ctx); -struct composite_context *ldap_connect_send(struct ldap_connection *conn, +_PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *conn, const char *url) { struct composite_context *result, *ctx; @@ -476,7 +477,7 @@ _PUBLIC_ NTSTATUS ldap_connect_recv(struct composite_context *ctx) return status; } -NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) +_PUBLIC_ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) { struct composite_context *ctx = ldap_connect_send(conn, url); return ldap_connect_recv(ctx); @@ -484,7 +485,7 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) /* set reconnect parameters */ -void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries) +_PUBLIC_ void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries) { if (conn) { conn->reconnect.max_retries = max_retries; @@ -569,7 +570,7 @@ static void ldap_request_complete(struct event_context *ev, struct timed_event * /* send a ldap message - async interface */ -struct ldap_request *ldap_request_send(struct ldap_connection *conn, +_PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; @@ -645,7 +646,7 @@ failed: wait for a request to complete note that this does not destroy the request */ -NTSTATUS ldap_request_wait(struct ldap_request *req) +_PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req) { while (req->state < LDAP_REQUEST_DONE) { if (event_loop_once(req->conn->event.event_ctx) != 0) { @@ -709,7 +710,7 @@ static const struct { /* used to setup the status code from a ldap response */ -NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) +_PUBLIC_ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) { int i; const char *codename = "unknown"; @@ -742,7 +743,7 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r /* return error string representing the last error */ -const char *ldap_errstr(struct ldap_connection *conn, +_PUBLIC_ const char *ldap_errstr(struct ldap_connection *conn, TALLOC_CTX *mem_ctx, NTSTATUS status) { @@ -756,7 +757,7 @@ const char *ldap_errstr(struct ldap_connection *conn, /* return the Nth result message, waiting if necessary */ -NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg) +_PUBLIC_ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg) { *msg = NULL; @@ -784,7 +785,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms /* return a single result message, checking if it is of the expected LDAP type */ -NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type) +_PUBLIC_ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type) { NTSTATUS status; status = ldap_result_n(req, 0, msg); @@ -802,7 +803,7 @@ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, in a simple ldap transaction, for single result requests that only need a status code this relies on single valued requests having the response type == request type + 1 */ -NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg) +_PUBLIC_ NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req = ldap_request_send(conn, msg); struct ldap_message *res; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index d5ff441aff..13b0bf725c 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -94,3 +94,47 @@ struct ldap_connection { struct packet_context *packet; }; + +struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct event_context *ev); + +NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url); +struct composite_context *ldap_connect_send(struct ldap_connection *conn, + const char *url); + +NTSTATUS ldap_rebind(struct ldap_connection *conn); +NTSTATUS ldap_bind_simple(struct ldap_connection *conn, + const char *userdn, const char *password); +NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, + struct cli_credentials *creds, + struct loadparm_context *lp_ctx); +struct ldap_request *ldap_request_send(struct ldap_connection *conn, + struct ldap_message *msg); +NTSTATUS ldap_request_wait(struct ldap_request *req); +struct composite_context; +NTSTATUS ldap_connect_recv(struct composite_context *ctx); +NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg); +NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type); +NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg); +const char *ldap_errstr(struct ldap_connection *conn, + TALLOC_CTX *mem_ctx, + NTSTATUS status); +NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r); +void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries); +int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res); +NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, + int scope, struct ldb_parse_tree *tree, + const char * const *attrs, bool attributesonly, + struct ldb_control **control_req, + struct ldb_control ***control_res, + struct ldap_message ***results); +NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, + int scope, const char *expression, + const char * const *attrs, bool attributesonly, + struct ldb_control **control_req, + struct ldb_control ***control_res, + struct ldap_message ***results); + + + diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 7b592c65ae..8f21af0690 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -28,7 +28,7 @@ /* count the returned search entries */ -int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) +_PUBLIC_ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) { int i; for (i=0;res && res[i];i++) /* noop */ ; @@ -39,7 +39,7 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) /* perform a synchronous ldap search */ -NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, +_PUBLIC_ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, int scope, struct ldb_parse_tree *tree, const char * const *attrs, bool attributesonly, struct ldb_control **control_req, @@ -112,7 +112,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, /* perform a ldap search */ -NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, +_PUBLIC_ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, int scope, const char *expression, const char * const *attrs, bool attributesonly, struct ldb_control **control_req, diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 12832b8ec4..c712e1e654 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -26,7 +26,7 @@ #include "libcli/ldap/ldap_client.h" -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { return talloc_zero(mem_ctx, struct ldap_message); } diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index bc85d87b89..14cec3a024 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -23,6 +23,7 @@ #define __LIBNBT_H__ #include "librpc/gen_ndr/nbt.h" +#include "librpc/ndr/libndr.h" /* possible states for pending requests @@ -273,6 +274,78 @@ struct nbt_name_release { } out; }; -#include "libcli/nbt/nbt_proto.h" +struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct smb_iconv_convenience *iconv_convenience); +struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, + struct nbt_name_query *io); +NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io); +NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_query *io); +struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, + struct nbt_name_status *io); +NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_status *io); +NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_status *io); + +NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname); +NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name); +NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name); +void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type); +char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name); +NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_register *io); +NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); +NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, struct nbt_name_release *io); +NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, + struct nbt_name_register_wins *io); +NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, + TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io); +NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_register *io); +struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, + struct nbt_name_register *io); +NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_release *io); + +struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, + struct nbt_name_release *io); + +NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, + TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); + +NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, + void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, + struct socket_address *), + void *private); +NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, + struct socket_address *dest, + struct nbt_name_packet *request); + + +NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *) +NDR_SCALAR_PROTO(nbt_string, const char *); +NDR_BUFFER_PROTO(nbt_name, struct nbt_name) +NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode); + +struct composite_context; +struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, + struct nbt_name_register_bcast *io); +NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c); +struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, + struct nbt_name_register_wins *io); +NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io); +struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, + struct nbt_name_refresh_wins *io); +NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct nbt_name_register_wins *io); + #endif /* __LIBNBT_H__ */ diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index e3432bfda1..2e1bcd818b 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "libcli/nbt/nbt_proto.h" #include "lib/socket/socket.h" #include "param/param.h" diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index 1157c110a1..b372e4a3f3 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "libcli/nbt/nbt_proto.h" #include "libcli/composite/composite.h" #include "lib/socket/socket.h" #include "param/param.h" @@ -86,7 +87,7 @@ failed: /* wait for a refresh reply */ -NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, +_PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) { NTSTATUS status; @@ -128,7 +129,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, /* synchronous name refresh request */ -NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) { struct nbt_name_request *req = nbt_name_refresh_send(nbtsock, io); @@ -217,7 +218,7 @@ done: /** the async send call for a multi-server WINS refresh */ -struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, struct nbt_name_refresh_wins *io) { struct composite_context *c; @@ -274,7 +275,7 @@ failed: /* multi-homed WINS name refresh - recv side */ -NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, +_PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct nbt_name_refresh_wins *io) { NTSTATUS status; @@ -292,7 +293,7 @@ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem /* multi-homed WINS refresh - sync interface */ -NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_refresh_wins *io) { diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 6667564664..9c5ae43d40 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "libcli/nbt/nbt_proto.h" #include "libcli/composite/composite.h" #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_nbt.h" @@ -94,7 +95,7 @@ failed: /* wait for a registration reply */ -NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, +_PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_register *io) { NTSTATUS status; @@ -136,7 +137,7 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, /* synchronous name registration request */ -NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_register *io) { struct nbt_name_request *req = nbt_name_register_send(nbtsock, io); @@ -207,7 +208,7 @@ done: /* the async send call for a 4 stage name registration */ -struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, struct nbt_name_register_bcast *io) { struct composite_context *c; @@ -256,7 +257,7 @@ failed: /* broadcast 4 part name register - recv */ -NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c) +_PUBLIC_ NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c) { NTSTATUS status; status = composite_wait(c); @@ -355,7 +356,7 @@ done: /* the async send call for a multi-server WINS register */ -struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, struct nbt_name_register_wins *io) { struct composite_context *c; @@ -414,7 +415,7 @@ failed: /* multi-homed WINS name register - recv side */ -NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, +_PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct nbt_name_register_wins *io) { NTSTATUS status; @@ -432,7 +433,7 @@ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *me /* multi-homed WINS register - sync interface */ -NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_register_wins *io) { diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index d735892516..ba3af41752 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -21,13 +21,14 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "libcli/nbt/nbt_proto.h" #include "lib/socket/socket.h" #include "param/param.h" /* send a nbt name release request */ -struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, struct nbt_name_release *io) { struct nbt_name_request *req; @@ -84,7 +85,7 @@ failed: /* wait for a release reply */ -NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, +_PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, TALLOC_CTX *mem_ctx, struct nbt_name_release *io) { NTSTATUS status; @@ -126,7 +127,7 @@ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, /* synchronous name release request */ -NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, TALLOC_CTX *mem_ctx, struct nbt_name_release *io) { struct nbt_name_request *req = nbt_name_release_send(nbtsock, io); diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index ae9f3f6b05..0d9073ccbb 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -500,7 +500,7 @@ _PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) /** pull a nbt name, WINS Replication uses another on wire format for nbt name */ -_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name **_r) +_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r) { struct nbt_name *r; uint8_t *namebuf; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 95a1643efc..747127980a 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -423,7 +423,7 @@ failed: /* send off a nbt name reply */ -NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, struct socket_address *dest, struct nbt_name_packet *request) { @@ -486,7 +486,7 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) /* setup a handler for incoming requests */ -NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, +_PUBLIC_ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, struct socket_address *), void *private) @@ -501,7 +501,7 @@ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, /* turn a NBT rcode into a NTSTATUS */ -NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode) +_PUBLIC_ NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode) { int i; struct { diff --git a/source4/libcli/raw/clierror.c b/source4/libcli/raw/clierror.c index c515259ee7..157bd847d4 100644 --- a/source4/libcli/raw/clierror.c +++ b/source4/libcli/raw/clierror.c @@ -25,7 +25,7 @@ /*************************************************************************** Return an error message from the last response ****************************************************************************/ -const char *smbcli_errstr(struct smbcli_tree *tree) +_PUBLIC_ const char *smbcli_errstr(struct smbcli_tree *tree) { switch (tree->session->transport->error.etype) { case ETYPE_SMB: @@ -45,7 +45,7 @@ const char *smbcli_errstr(struct smbcli_tree *tree) /* Return the 32-bit NT status code from the last packet */ -NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) +_PUBLIC_ NTSTATUS smbcli_nt_error(struct smbcli_tree *tree) { switch (tree->session->transport->error.etype) { case ETYPE_SMB: diff --git a/source4/libcli/raw/clioplock.c b/source4/libcli/raw/clioplock.c index ae4e58ae01..47ffb6dd31 100644 --- a/source4/libcli/raw/clioplock.c +++ b/source4/libcli/raw/clioplock.c @@ -19,6 +19,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" /**************************************************************************** send an ack for an oplock break request diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index 5a33d9cffc..ad4ca7b471 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "system/filesys.h" #include "param/param.h" @@ -291,7 +292,7 @@ struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session) /**************************************************************************** Send a exit (sync interface) *****************************************************************************/ -NTSTATUS smb_raw_exit(struct smbcli_session *session) +_PUBLIC_ NTSTATUS smb_raw_exit(struct smbcli_session *session) { struct smbcli_request *req = smb_raw_exit_send(session); return smbcli_request_simple_recv(req); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index eaa02e1047..1dcf2d1c53 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -170,7 +170,7 @@ NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx, /**************************************************************************** mark the socket as dead ****************************************************************************/ -void smbcli_sock_dead(struct smbcli_socket *sock) +_PUBLIC_ void smbcli_sock_dead(struct smbcli_socket *sock) { talloc_free(sock->event.fde); sock->event.fde = NULL; @@ -189,7 +189,7 @@ void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options) /**************************************************************************** resolve a hostname and connect ****************************************************************************/ -struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, +_PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, TALLOC_CTX *mem_ctx, struct resolve_context *resolve_ctx, struct event_context *event_ctx) diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 5c14e9f9b8..34fb96230d 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -21,12 +21,14 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "lib/socket/socket.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/stream/packet.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" +#include "libcli/nbt/libnbt.h" /* @@ -322,7 +324,7 @@ static void idle_handler(struct event_context *ev, setup the idle handler for a transport the period is in microseconds */ -void smbcli_transport_idle_handler(struct smbcli_transport *transport, +_PUBLIC_ void smbcli_transport_idle_handler(struct smbcli_transport *transport, void (*idle_func)(struct smbcli_transport *, void *), uint64_t period, void *private) @@ -502,7 +504,7 @@ error: process some read/write requests that are pending return false if the socket is dead */ -bool smbcli_transport_process(struct smbcli_transport *transport) +_PUBLIC_ bool smbcli_transport_process(struct smbcli_transport *transport) { NTSTATUS status; size_t npending; @@ -599,7 +601,7 @@ void smbcli_transport_send(struct smbcli_request *req) /**************************************************************************** Send an SMBecho (async send) *****************************************************************************/ -struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, +_PUBLIC_ struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, struct smb_echo *p) { struct smbcli_request *req; diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 507bde999a..d5075f9271 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb_composite/smb_composite.h" #include "param/param.h" @@ -33,7 +34,7 @@ /**************************************************************************** Initialize the tree context ****************************************************************************/ -struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session, +_PUBLIC_ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session, TALLOC_CTX *parent_ctx, bool primary) { struct smbcli_tree *tree; @@ -141,7 +142,7 @@ failed: /**************************************************************************** Send a tconX (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, +_PUBLIC_ NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_tcon *parms) { struct smbcli_request *req = smb_raw_tcon_send(tree, parms); @@ -152,7 +153,7 @@ NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, /**************************************************************************** Send a tree disconnect. ****************************************************************************/ -NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) +_PUBLIC_ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree) { struct smbcli_request *req; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 0578a9eab1..16a98ad66e 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -286,6 +286,80 @@ struct smbcli_request { } #include "libcli/raw/interfaces.h" -#include "libcli/raw/raw_proto.h" + +NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms); +struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms); +NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, + TALLOC_CTX *mem_ctx, + struct smb_trans2 *parms); +size_t smb_raw_max_trans_data(struct smbcli_tree *tree, size_t param_size); +struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, struct smb_trans2 *parms); +NTSTATUS smbcli_request_destroy(struct smbcli_request *req); +struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms); +struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms); +NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms); +struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms); + +bool smbcli_transport_process(struct smbcli_transport *transport); +const char *smbcli_errstr(struct smbcli_tree *tree); +NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo); +NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms); +NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_shadow_copy *info); +NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms); +struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session, TALLOC_CTX *parent_ctx, bool primary); +NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_tcon *parms); +void smbcli_oplock_handler(struct smbcli_transport *transport, + bool (*handler)(struct smbcli_transport *, uint16_t, uint16_t, uint8_t, void *), + void *private); +void smbcli_transport_idle_handler(struct smbcli_transport *transport, + void (*idle_func)(struct smbcli_transport *, void *), + uint64_t period, + void *private); +NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req); +bool smbcli_oplock_ack(struct smbcli_tree *tree, uint16_t fnum, uint16_t ack_level); +NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms); +NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms); +NTSTATUS smb_raw_unlink(struct smbcli_tree *tree, union smb_unlink *parms); +NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms); +NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree, union smb_mkdir *parms); +NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree, struct smb_rmdir *parms); +NTSTATUS smb_raw_rename(struct smbcli_tree *tree, union smb_rename *parms); +NTSTATUS smb_raw_seek(struct smbcli_tree *tree, union smb_seek *parms); +NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms); +NTSTATUS smb_raw_write(struct smbcli_tree *tree, union smb_write *parms); +NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms); +NTSTATUS smb_raw_setpathinfo(struct smbcli_tree *tree, union smb_setfileinfo *parms); +NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree, union smb_setfileinfo *parms); + +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms); +NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_notify *parms); + +NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree); +NTSTATUS smbcli_nt_error(struct smbcli_tree *tree); +NTSTATUS smb_raw_exit(struct smbcli_session *session); +NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req, + TALLOC_CTX *mem_ctx, + union smb_fileinfo *parms); +struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, + union smb_fileinfo *parms); +struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, + union smb_setfileinfo *parms); +struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, + struct smb_echo *p); +NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_search_first *io, void *private, + smbcli_search_callback callback); +NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms); + +NTSTATUS smb_raw_trans(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + struct smb_trans2 *parms); + +struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, + TALLOC_CTX *mem_ctx, + struct resolve_context *resolve_ctx, + struct event_context *event_ctx); +void smbcli_sock_dead(struct smbcli_socket *sock); #endif /* __LIBCLI_RAW__H__ */ diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c index 847d133173..466b94f4a9 100644 --- a/source4/libcli/raw/rawacl.c +++ b/source4/libcli/raw/rawacl.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "librpc/gen_ndr/ndr_security.h" #include "param/param.h" diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 725034c3a9..3c5c1b742b 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -22,6 +22,7 @@ #include "includes.h" #include "smb.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "librpc/gen_ndr/ndr_security.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ @@ -92,7 +93,7 @@ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree, /**************************************************************************** Rename a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_rename(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_rename(struct smbcli_tree *tree, union smb_rename *parms) { struct smbcli_request *req = smb_raw_rename_send(tree, parms); @@ -123,7 +124,7 @@ struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree, /* delete a file - sync interface */ -NTSTATUS smb_raw_unlink(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_unlink(struct smbcli_tree *tree, union smb_unlink *parms) { struct smbcli_request *req = smb_raw_unlink_send(tree, parms); @@ -201,7 +202,7 @@ struct smbcli_request *smb_raw_mkdir_send(struct smbcli_tree *tree, /**************************************************************************** Create a directory - sync interface ****************************************************************************/ -NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree, union smb_mkdir *parms) { struct smbcli_request *req = smb_raw_mkdir_send(tree, parms); @@ -231,7 +232,7 @@ struct smbcli_request *smb_raw_rmdir_send(struct smbcli_tree *tree, /**************************************************************************** Remove a directory - sync interface ****************************************************************************/ -NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree, struct smb_rmdir *parms) { struct smbcli_request *req = smb_raw_rmdir_send(tree, parms); @@ -448,7 +449,7 @@ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ /**************************************************************************** Open a file - async send ****************************************************************************/ -struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms) +_PUBLIC_ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms) { int len; struct smbcli_request *req = NULL; @@ -585,7 +586,7 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope /**************************************************************************** Open a file - async recv ****************************************************************************/ -NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) +_PUBLIC_ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms) { NTSTATUS status; @@ -720,7 +721,7 @@ failed: /**************************************************************************** Open a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms) +_PUBLIC_ NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms) { struct smbcli_request *req = smb_raw_open_send(tree, parms); return smb_raw_open_recv(req, mem_ctx, parms); @@ -730,7 +731,7 @@ NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_o /**************************************************************************** Close a file - async send ****************************************************************************/ -struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms) +_PUBLIC_ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms) { struct smbcli_request *req = NULL; @@ -766,7 +767,7 @@ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_cl /**************************************************************************** Close a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms) +_PUBLIC_ NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms) { struct smbcli_request *req = smb_raw_close_send(tree, parms); return smbcli_request_simple_recv(req); @@ -843,7 +844,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc /**************************************************************************** Locking calls - sync interface ****************************************************************************/ -NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms) +_PUBLIC_ NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms) { struct smbcli_request *req = smb_raw_lock_send(tree, parms); return smbcli_request_simple_recv(req); @@ -913,7 +914,7 @@ struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_fl /**************************************************************************** flush a file - sync interface ****************************************************************************/ -NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms) +_PUBLIC_ NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms) { struct smbcli_request *req = smb_raw_flush_send(tree, parms); return smbcli_request_simple_recv(req); @@ -962,7 +963,7 @@ failed: /* seek a file - sync interface */ -NTSTATUS smb_raw_seek(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_seek(struct smbcli_tree *tree, union smb_seek *parms) { struct smbcli_request *req = smb_raw_seek_send(tree, parms); diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index ed5475e926..71900be49c 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "librpc/gen_ndr/ndr_security.h" #include "param/param.h" @@ -711,7 +712,7 @@ NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req, /**************************************************************************** Query file info (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { @@ -722,7 +723,7 @@ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree, /**************************************************************************** Query path info (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, +_PUBLIC_ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, union smb_fileinfo *parms) { DATA_BLOB data; @@ -756,7 +757,7 @@ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree, /**************************************************************************** Query path info (async recv) ****************************************************************************/ -NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req, +_PUBLIC_ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { @@ -767,7 +768,7 @@ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req, /**************************************************************************** Query path info (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms) { diff --git a/source4/libcli/raw/rawfsinfo.c b/source4/libcli/raw/rawfsinfo.c index bfb5db828e..43a0919e38 100644 --- a/source4/libcli/raw/rawfsinfo.c +++ b/source4/libcli/raw/rawfsinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "librpc/gen_ndr/ndr_misc.h" /**************************************************************************** @@ -326,7 +327,7 @@ failed: /**************************************************************************** Query FSInfo raw interface (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo) { diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c index 957e554c6b..77c7b03f15 100644 --- a/source4/libcli/raw/rawioctl.c +++ b/source4/libcli/raw/rawioctl.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ @@ -163,7 +164,7 @@ NTSTATUS smb_raw_ioctl_recv(struct smbcli_request *req, /* send a raw ioctl - sync interface */ -_PUBLIC_ NTSTATUS smb_raw_ioctl(struct smbcli_tree *tree, +NTSTATUS smb_raw_ioctl(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_ioctl *parms) { struct smbcli_request *req; diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 6c16935f21..f0de4b48bd 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "system/time.h" #include "param/param.h" diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index 91a12a8618..bf7578d7fc 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -19,12 +19,13 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "lib/util/dlinklist.h" /**************************************************************************** change notify (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) +_PUBLIC_ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) { struct smb_nttrans nt; uint8_t setup[8]; @@ -51,7 +52,7 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union /**************************************************************************** change notify (async recv) ****************************************************************************/ -NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, +_PUBLIC_ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_notify *parms) { struct smb_nttrans nt; diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c index 9e4edaf99c..a8c7996310 100644 --- a/source4/libcli/raw/rawreadwrite.c +++ b/source4/libcli/raw/rawreadwrite.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #define SETUP_REQUEST(cmd, wct, buflen) do { \ req = smbcli_request_setup(tree, cmd, wct, buflen); \ @@ -29,7 +30,7 @@ /**************************************************************************** low level read operation (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms) +_PUBLIC_ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms) { bool bigoffset = false; struct smbcli_request *req = NULL; @@ -115,7 +116,7 @@ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_rea /**************************************************************************** low level read operation (async recv) ****************************************************************************/ -NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) +_PUBLIC_ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms) { if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { @@ -197,7 +198,7 @@ failed: /**************************************************************************** low level read operation (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms) +_PUBLIC_ NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms) { struct smbcli_request *req = smb_raw_read_send(tree, parms); return smb_raw_read_recv(req, parms); @@ -207,7 +208,7 @@ NTSTATUS smb_raw_read(struct smbcli_tree *tree, union smb_read *parms) /**************************************************************************** raw write interface (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms) +_PUBLIC_ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms) { bool bigoffset = false; struct smbcli_request *req = NULL; @@ -341,7 +342,7 @@ failed: /**************************************************************************** raw write interface (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_write(struct smbcli_tree *tree, union smb_write *parms) +_PUBLIC_ NTSTATUS smb_raw_write(struct smbcli_tree *tree, union smb_write *parms) { struct smbcli_request *req = smb_raw_write_send(tree, parms); return smb_raw_write_recv(req, parms); diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 355d092583..a42c710547 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -24,9 +24,12 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "param/param.h" +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/ndr_misc.h" /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 0 @@ -49,7 +52,7 @@ void smb_setup_bufinfo(struct smbcli_request *req) /* destroy a request structure and return final status */ -NTSTATUS smbcli_request_destroy(struct smbcli_request *req) +_PUBLIC_ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) { NTSTATUS status; @@ -405,7 +408,7 @@ bool smbcli_handle_oplock_break(struct smbcli_transport *transport, uint_t len, wait for a reply to be received for a packet that just returns an error code and nothing more */ -NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req) +_PUBLIC_ NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req) { (void) smbcli_request_receive(req); return smbcli_request_destroy(req); diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index fb2b09467c..99141574e2 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -20,6 +20,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" /**************************************************************************** Old style search backend - process output. @@ -718,7 +719,7 @@ static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, /* Implements trans2findfirst2 and old search */ -NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, smbcli_search_callback callback) diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index f1e4ee3686..16052e8708 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "librpc/gen_ndr/ndr_security.h" @@ -409,7 +410,7 @@ struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree, /**************************************************************************** Set file info (async send) ****************************************************************************/ -NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree, union smb_setfileinfo *parms) { struct smbcli_request *req = smb_raw_setfileinfo_send(tree, parms); @@ -420,7 +421,7 @@ NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree, /**************************************************************************** Set path info (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, +_PUBLIC_ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, union smb_setfileinfo *parms) { DATA_BLOB blob; @@ -456,7 +457,7 @@ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree, /**************************************************************************** Set path info (sync interface) ****************************************************************************/ -NTSTATUS smb_raw_setpathinfo(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_setpathinfo(struct smbcli_tree *tree, union smb_setfileinfo *parms) { struct smbcli_request *req = smb_raw_setpathinfo_send(tree, parms); diff --git a/source4/libcli/raw/rawshadow.c b/source4/libcli/raw/rawshadow.c index 4c58c91383..b318c3e025 100644 --- a/source4/libcli/raw/rawshadow.c +++ b/source4/libcli/raw/rawshadow.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/raw/ioctl.h" /* diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 53670d22a3..29881afd2b 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/util/dlinklist.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #define TORTURE_TRANS_DATA 0 @@ -192,7 +193,7 @@ failed: return smbcli_request_destroy(req); } -NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, +_PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { @@ -365,7 +366,7 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, trans/trans2 raw async interface - only BLOBs used in this interface. note that this doesn't yet support multi-part requests */ -struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, +_PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, struct smb_trans2 *parms) { return smb_raw_trans_send_backend(tree, parms, SMBtrans); @@ -394,7 +395,7 @@ NTSTATUS smb_raw_trans2(struct smbcli_tree *tree, /* trans synchronous blob interface */ -NTSTATUS smb_raw_trans(struct smbcli_tree *tree, +_PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { @@ -631,7 +632,7 @@ NTSTATUS smb_raw_nttrans(struct smbcli_tree *tree, TODO: we only need to avoid multi-part replies because the multi-part trans receive code is broken. */ -size_t smb_raw_max_trans_data(struct smbcli_tree *tree, size_t param_size) +_PUBLIC_ size_t smb_raw_max_trans_data(struct smbcli_tree *tree, size_t param_size) { return tree->session->transport->negotiate.max_xmit - (70 + param_size); } diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 4acfb9d16d..97bb688d1a 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -22,6 +22,7 @@ #include "includes.h" #include "smb.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "lib/crypto/crypto.h" #include "param/param.h" diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 04c0c85499..4e6f33095f 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 85ddafc031..d68b85ad54 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" #include "libcli/composite/composite.h" diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index cca83a040c..999c10ab08 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 6d0a9c8072..6b4902a026 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index e9f47140f5..b462bab1de 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 6b879e2add..c1f0cf0b24 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -21,8 +21,10 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "librpc/ndr/libndr.h" /* send a negprot request diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index e7c38a27f9..096d790a31 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c index a6e22d9a68..69c0f45b63 100644 --- a/source4/libcli/smb2/setinfo.c +++ b/source4/libcli/smb2/setinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 1d601fdbfe..af19fcb0a9 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/smb_composite/appendacl.c b/source4/libcli/smb_composite/appendacl.c index 0fda8c4d65..1f06b96e75 100644 --- a/source4/libcli/smb_composite/appendacl.c +++ b/source4/libcli/smb_composite/appendacl.c @@ -1,5 +1,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" #include "libcli/security/security.h" #include "libcli/smb_composite/smb_composite.h" diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 22573442a2..c44c62f868 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "lib/events/events.h" diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index e4dd4436ba..2ec13df9b6 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -4,6 +4,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "param/param.h" diff --git a/source4/libcli/smb_composite/savefile.c b/source4/libcli/smb_composite/savefile.c index b94be9e9b1..f02ca46f06 100644 --- a/source4/libcli/smb_composite/savefile.c +++ b/source4/libcli/smb_composite/savefile.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 75a2a579a2..1427fe525b 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -22,8 +22,10 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" +#include "libcli/smb_composite/proto.h" #include "libcli/auth/libcli_auth.h" #include "auth/auth.h" #include "auth/gensec/gensec.h" diff --git a/source4/libcli/util/error.h b/source4/libcli/util/error.h index e054948fbe..84255448a0 100644 --- a/source4/libcli/util/error.h +++ b/source4/libcli/util/error.h @@ -22,7 +22,6 @@ #include "libcli/util/werror.h" #include "libcli/util/doserr.h" #include "libcli/util/ntstatus.h" -#include "librpc/ndr/libndr.h" /** NT error on DOS connection! (NT_STATUS_OK) */ bool ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2); @@ -47,6 +46,8 @@ WERROR ntstatus_to_werror(NTSTATUS error); *********************************************************************/ NTSTATUS map_nt_error_from_unix(int unix_error); +enum ndr_err_code; + /********************************************************************* Map an NT error code from a NDR error code. *********************************************************************/ diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index b8458d4bf3..2257955c76 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -21,6 +21,7 @@ #include "includes.h" #include "param/param.h" +#include "librpc/ndr/libndr.h" /* This map was extracted by the ERRMAPEXTRACT smbtorture command. The setup was a Samba HEAD (2002-01-03) PDC and an Win2k member -- cgit From 236fc02913adafd80921d4e30aa6ee1e414bef44 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 13:41:10 +0200 Subject: Reduce the number of installed headers. (This used to be commit 2243e24024f09ff9c9c7d0eb735c3b39c9d84424) --- source4/libcli/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0aa67f35db..b85fbe7066 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -73,7 +73,7 @@ OBJ_FILES = cldap/cldap.o PUBLIC_DEPENDENCIES = LIBCLI_LDAP PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB -PUBLIC_HEADERS += libcli/cldap/cldap.h +# PUBLIC_HEADERS += libcli/cldap/cldap.h [SUBSYSTEM::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h @@ -118,7 +118,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket -PUBLIC_HEADERS += libcli/libcli.h +# PUBLIC_HEADERS += libcli/libcli.h [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h -- cgit From 4e5e7a7c688d8a065994cb16fb1da7581bab081a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 16:47:17 +0200 Subject: Reintroduce header previously autogenerated but ignored by git. Also fixed extra include in regpatch. (This used to be commit 0e371cf169e9a607fcbb3e65437ab9413935dd52) --- source4/libcli/ldap/ldap_ndr.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 source4/libcli/ldap/ldap_ndr.h (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h new file mode 100644 index 0000000000..dfbb723c36 --- /dev/null +++ b/source4/libcli/ldap/ldap_ndr.h @@ -0,0 +1,10 @@ +#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ +#define __LIBCLI_LDAP_LDAP_NDR_H__ + +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); + +#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ + -- cgit From 6ce078141326a41278bbb8c6854c4cacc7cefd99 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 29 Mar 2008 01:42:06 +0100 Subject: wbclient: Add an async winbind client library. (This used to be commit 3e3563f2840e7cd795f5fc157003af3c932cb4d1) --- source4/libcli/config.mk | 1 + source4/libcli/wbclient/config.mk | 6 ++ source4/libcli/wbclient/wbclient.c | 210 +++++++++++++++++++++++++++++++++++++ source4/libcli/wbclient/wbclient.h | 50 +++++++++ 4 files changed, 267 insertions(+) create mode 100644 source4/libcli/wbclient/config.mk create mode 100644 source4/libcli/wbclient/wbclient.c create mode 100644 source4/libcli/wbclient/wbclient.h (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index b85fbe7066..0c00fa2740 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -1,6 +1,7 @@ mkinclude auth/config.mk mkinclude ldap/config.mk mkinclude security/config.mk +mkinclude wbclient/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] OBJ_FILES = util/doserr.o \ diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk new file mode 100644 index 0000000000..32f2f5aeed --- /dev/null +++ b/source4/libcli/wbclient/config.mk @@ -0,0 +1,6 @@ +[SUBSYSTEM::LIBWBCLIENT] +OBJ_FILES = wbclient.o +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS +PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING + +PUBLIC_HEADERS += libcli/wbclient/wbclient.h diff --git a/source4/libcli/wbclient/wbclient.c b/source4/libcli/wbclient/wbclient.c new file mode 100644 index 0000000000..1b2d314824 --- /dev/null +++ b/source4/libcli/wbclient/wbclient.c @@ -0,0 +1,210 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client library. + + Copyright (C) 2008 Kai Blin + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/wbclient/wbclient.h" + +/** + * Get the server_id of the winbind task. + * + * \param[in] msg_ctx message context to use + * \param[in] mem_ctx talloc context to use + * \param[out] ids array of server_id structs containing the winbind id + * \return NT_STATUS_OK on success, NT_STATUS_INTERNAL_ERROR on failure + */ +static NTSTATUS get_server_id(struct messaging_context *msg_ctx, + TALLOC_CTX *mem_ctx, struct server_id **ids) +{ + *ids = irpc_servers_byname(msg_ctx, mem_ctx, "winbind_server"); + if (*ids == NULL || (*ids)[0].id == 0) { + DEBUG(0, ("Geting the winbind server ID failed.\n")); + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} + +/** + * Initialize the wbclient context, talloc_free() when done. + * + * \param mem_ctx talloc context to allocate memory from + * \param msg_ctx message context to use + * \param + */ +struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, + struct event_context *event_ctx) +{ + struct wbc_context *ctx; + NTSTATUS status; + + ctx = talloc(mem_ctx, struct wbc_context); + if (ctx == NULL) return NULL; + + status = get_server_id(msg_ctx, mem_ctx, &ctx->ids); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return NULL; + } + + ctx->msg_ctx = msg_ctx; + ctx->event_ctx = event_ctx; + + return ctx; +} + +struct wbc_idmap_state { + struct composite_context *ctx; + struct winbind_get_idmap *req; + struct irpc_request *irpc_req; + struct id_mapping *ids; +}; + +static void sids_to_xids_recv_ids(struct irpc_request *req); + +struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, + TALLOC_CTX *mem_ctx, + uint32_t count, + struct id_mapping *ids) +{ + struct composite_context *ctx; + struct wbc_idmap_state *state; + + DEBUG(5, ("wbc_sids_to_xids called\n")); + + ctx = composite_create(mem_ctx, wbc_ctx->event_ctx); + if (ctx == NULL) return NULL; + + state = talloc(ctx, struct wbc_idmap_state); + if (composite_nomem(state, ctx)) return ctx; + ctx->private_data = state; + + state->req = talloc(state, struct winbind_get_idmap); + if (composite_nomem(state->req, ctx)) return ctx; + + state->req->in.count = count; + state->req->in.level = WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS; + state->req->in.ids = ids; + state->ctx = ctx; + + state->irpc_req = IRPC_CALL_SEND(wbc_ctx->msg_ctx, wbc_ctx->ids[0], + winbind, WINBIND_GET_IDMAP, state->req, + state); + if (composite_nomem(state->irpc_req, ctx)) return ctx; + + composite_continue_irpc(ctx, state->irpc_req, sids_to_xids_recv_ids, + state); + return ctx; +} + +static void sids_to_xids_recv_ids(struct irpc_request *req) +{ + struct wbc_idmap_state *state = talloc_get_type_abort( + req->async.private, + struct wbc_idmap_state); + + state->ctx->status = irpc_call_recv(state->irpc_req); + if (!composite_is_ok(state->ctx)) return; + + state->ids = state->req->out.ids; + composite_done(state->ctx); +} + +NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx, + struct id_mapping **ids) +{ + NTSTATUS status = composite_wait(ctx); + DEBUG(5, ("wbc_sids_to_xids_recv called\n")); + if (NT_STATUS_IS_OK(status)) { + struct wbc_idmap_state *state = talloc_get_type_abort( + ctx->private_data, + struct wbc_idmap_state); + *ids = state->ids; + } + + return status; +} + +static void xids_to_sids_recv_ids(struct irpc_request *req); + +struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx, + TALLOC_CTX *mem_ctx, + uint32_t count, + struct id_mapping *ids) +{ + struct composite_context *ctx; + struct wbc_idmap_state *state; + + DEBUG(5, ("wbc_xids_to_sids called\n")); + + ctx = composite_create(mem_ctx, wbc_ctx->event_ctx); + if (ctx == NULL) return NULL; + + state = talloc(ctx, struct wbc_idmap_state); + if (composite_nomem(state, ctx)) return ctx; + ctx->private_data = state; + + state->req = talloc(state, struct winbind_get_idmap); + if (composite_nomem(state->req, ctx)) return ctx; + + state->req->in.count = count; + state->req->in.level = WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS; + state->req->in.ids = ids; + state->ctx = ctx; + + state->irpc_req = IRPC_CALL_SEND(wbc_ctx->msg_ctx, wbc_ctx->ids[0], + winbind, WINBIND_GET_IDMAP, state->req, + state); + if (composite_nomem(state->irpc_req, ctx)) return ctx; + + composite_continue_irpc(ctx, state->irpc_req, xids_to_sids_recv_ids, + state); + + return ctx; +} + +static void xids_to_sids_recv_ids(struct irpc_request *req) +{ + struct wbc_idmap_state *state = talloc_get_type_abort( + req->async.private, + struct wbc_idmap_state); + + state->ctx->status = irpc_call_recv(state->irpc_req); + if (!composite_is_ok(state->ctx)) return; + + state->ids = state->req->out.ids; + composite_done(state->ctx); +} + +NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx, + struct id_mapping **ids) +{ + NTSTATUS status = composite_wait(ctx); + DEBUG(5, ("wbc_xids_to_sids_recv called\n")); + if (NT_STATUS_IS_OK(status)) { + struct wbc_idmap_state *state = talloc_get_type_abort( + ctx->private_data, + struct wbc_idmap_state); + *ids = state->ids; + } + + return status; +} + diff --git a/source4/libcli/wbclient/wbclient.h b/source4/libcli/wbclient/wbclient.h new file mode 100644 index 0000000000..099abaa511 --- /dev/null +++ b/source4/libcli/wbclient/wbclient.h @@ -0,0 +1,50 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client library. + + Copyright (C) 2008 Kai Blin + + 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 3 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, see . +*/ +#include "lib/messaging/irpc.h" +#include "libcli/composite/composite.h" +#include "librpc/gen_ndr/ndr_winbind.h" + +struct wbc_context { + struct messaging_context *msg_ctx; + struct event_context *event_ctx; + struct server_id *ids; +}; + +struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, + struct event_context *event_ctx); + +struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, + TALLOC_CTX *mem_ctx, + uint32_t count, + struct id_mapping *ids); + +NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx, + struct id_mapping **ids); + +struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx, + TALLOC_CTX *mem_ctx, + uint32_t count, + struct id_mapping *ids); + +NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx, + struct id_mapping **ids); + -- cgit From faa3dec34a67b59fc7e733a2ce3a9d9f2cb34b2d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 4 Apr 2008 16:03:54 +0200 Subject: Install pidl by default if ExtUtils::MakeMaker is available. This should make the build process for openchange users easier. (This used to be commit 7fccd85cc673c139bc1d57915e0fccd22316998c) --- source4/libcli/wbclient/config.mk | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk index 32f2f5aeed..9384a172ff 100644 --- a/source4/libcli/wbclient/config.mk +++ b/source4/libcli/wbclient/config.mk @@ -2,5 +2,3 @@ OBJ_FILES = wbclient.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING - -PUBLIC_HEADERS += libcli/wbclient/wbclient.h -- cgit From 55809f5029788892919bd7f6ec305ae9df858038 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 9 Apr 2008 17:11:57 -0400 Subject: Make sure we do not reference req after it has been freed (This used to be commit a13f64bf54afc22516d1f6a786dfec67389cb754) --- source4/libcli/cldap/cldap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index d10eeb8ffd..d9910285d9 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -601,8 +601,11 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, NTSTATUS status; enum ndr_err_code ndr_err; struct cldap_search search; + struct cldap_socket *cldap; DATA_BLOB *data; + cldap = req->cldap; + status = cldap_search_recv(req, mem_ctx, &search); if (!NT_STATUS_IS_OK(status)) { return status; @@ -620,7 +623,7 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, data = search.out.response->attributes[0].values; ndr_err = ndr_pull_union_blob_all(data, mem_ctx, - req->cldap->iconv_convenience, + cldap->iconv_convenience, &io->out.netlogon, io->in.version & 0xF, (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); -- cgit From 275f32ae2df333c089343dd20fc4efee1bed2b7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 11:31:17 +0200 Subject: fill in unknown fields in SMB2 READ call (This used to be commit 9b686c138037f613da15168d0722786e00f023e5) --- source4/libcli/raw/interfaces.h | 18 +++++++++++++----- source4/libcli/smb2/read.c | 13 +++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 3965c58204..61441b2cdc 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1706,19 +1706,27 @@ union smb_read { /* static body buffer 48 (0x30) bytes */ /* uint16_t buffer_code; 0x31 = 0x30 + 1 */ - uint16_t _pad; + uint8_t _pad; + uint8_t reserved; uint32_t length; uint64_t offset; /* struct smb2_handle handle; */ - uint64_t unknown1; /* 0x0000000000000000 */ - uint64_t unknown2; /* 0x0000000000000000 */ + uint32_t min_count; + uint32_t channel; + uint32_t remaining; + /* the docs give no indication of what + these channel variables are for */ + uint16_t channel_offset; + uint16_t channel_length; } in; struct { /* static body buffer 16 (0x10) bytes */ /* uint16_t buffer_code; 0x11 = 0x10 + 1 */ - /* uint16_t data_ofs; */ + /* uint8_t data_ofs; */ + /* uint8_t reserved; */ /* uint32_t data_size; */ - uint64_t unknown1; /* 0x0000000000000000 */ + uint32_t remaining; + uint32_t reserved; /* dynamic body */ DATA_BLOB data; diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c index b61f918481..9d40e32a4d 100644 --- a/source4/libcli/smb2/read.c +++ b/source4/libcli/smb2/read.c @@ -33,12 +33,16 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x30, true, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, 0); /* pad */ + SCVAL(req->out.body, 0x02, 0); /* pad */ + SCVAL(req->out.body, 0x03, 0); /* reserved */ SIVAL(req->out.body, 0x04, io->in.length); SBVAL(req->out.body, 0x08, io->in.offset); smb2_push_handle(req->out.body+0x10, &io->in.file.handle); - SBVAL(req->out.body, 0x20, io->in.unknown1); - SBVAL(req->out.body, 0x28, io->in.unknown2); + SIVAL(req->out.body, 0x20, io->in.min_count); + SIVAL(req->out.body, 0x24, io->in.channel); + SIVAL(req->out.body, 0x28, io->in.remaining); + SSVAL(req->out.body, 0x2C, io->in.channel_offset); + SSVAL(req->out.body, 0x2E, io->in.channel_length); smb2_transport_send(req); @@ -67,7 +71,8 @@ NTSTATUS smb2_read_recv(struct smb2_request *req, return status; } - io->out.unknown1 = BVAL(req->in.body, 0x08); + io->out.remaining = IVAL(req->in.body, 0x08); + io->out.reserved = IVAL(req->in.body, 0x0C); return smb2_request_destroy(req); } -- cgit From e9017ba418202b4b191c5a9ad4a96857558ce606 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 17:22:58 +0200 Subject: Use _OBJ_FILES variables in a couple more places. (This used to be commit 92856d5054106894b65cd1a1b5119c0facfc4cff) --- source4/libcli/auth/config.mk | 9 +-- source4/libcli/config.mk | 128 ++++++++++++++++++-------------------- source4/libcli/ldap/config.mk | 14 ++--- source4/libcli/security/config.mk | 13 ++-- source4/libcli/smb2/config.mk | 29 +++------ source4/libcli/wbclient/config.mk | 3 +- 6 files changed, 87 insertions(+), 109 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index f786c71469..85fc4ab527 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -2,15 +2,16 @@ # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] PRIVATE_PROTO_HEADER = proto.h -OBJ_FILES = credentials.o \ - session.o \ - smbencrypt.o \ - smbdes.o PUBLIC_DEPENDENCIES = \ MSRPC_PARSE \ LIBSAMBA-HOSTCONFIG # End SUBSYSTEM LIBCLI_AUTH ################################# +LIBCLI_AUTH_OBJ_FILES = $(addprefix libcli/auth/, \ + credentials.o \ + session.o \ + smbencrypt.o \ + smbdes.o) PUBLIC_HEADERS += libcli/auth/credentials.h diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0c00fa2740..1ed52ca9d3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -4,120 +4,127 @@ mkinclude security/config.mk mkinclude wbclient/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] -OBJ_FILES = util/doserr.o \ - util/errormap.o \ - util/nterr.o \ +LIBSAMBA-ERRORS_OBJ_FILES = $(addprefix libcli/util/, doserr.o errormap.o nterr.o) PUBLIC_HEADERS += $(addprefix libcli/, util/error.h util/ntstatus.h util/doserr.h util/werror.h) [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h -OBJ_FILES = util/clilsa.o PUBLIC_DEPENDENCIES = RPC_NDR_LSA PRIVATE_DEPENDENCIES = LIBSECURITY +LIBCLI_LSA_OBJ_FILES = libcli/util/clilsa.o + [SUBSYSTEM::LIBCLI_COMPOSITE] PRIVATE_PROTO_HEADER = composite/proto.h -OBJ_FILES = \ - composite/composite.o PUBLIC_DEPENDENCIES = LIBEVENTS +LIBCLI_COMPOSITE_OBJ_FILES = libcli/composite/composite.o + [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] PRIVATE_PROTO_HEADER = smb_composite/proto.h -OBJ_FILES = \ - smb_composite/loadfile.o \ - smb_composite/savefile.o \ - smb_composite/connect.o \ - smb_composite/sesssetup.o \ - smb_composite/fetchfile.o \ - smb_composite/appendacl.o \ - smb_composite/fsinfo.o PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec LIBCLI_RESOLVE +LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix libcli/smb_composite/, \ + loadfile.o \ + savefile.o \ + connect.o \ + sesssetup.o \ + fetchfile.o \ + appendacl.o \ + fsinfo.o) + + [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h -OBJ_FILES = nbt/nbtname.o + +NDR_NBT_BUF_OBJ_FILES = libcli/nbt/nbtname.o [SUBSYSTEM::LIBCLI_NBT] #VERSION = 0.0.1 #SO_VERSION = 0 PRIVATE_PROTO_HEADER = nbt/nbt_proto.h -OBJ_FILES = \ - nbt/nbtsocket.o \ - nbt/namequery.o \ - nbt/nameregister.o \ - nbt/namerefresh.o \ - nbt/namerelease.o PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL +LIBCLI_NBT_OBJ_FILES = $(addprefix libcli/nbt/, \ + nbtsocket.o \ + namequery.o \ + nameregister.o \ + namerefresh.o \ + namerelease.o) + [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG +python_libcli_nbt_OBJ_FILES = libcli/swig/libcli_nbt_wrap.o + [PYTHON::python_libcli_smb] SWIG_FILE = swig/libcli_smb.i PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG +python_libcli_smb_OBJ_FILES = libcli/swig/libcli_smb_wrap.o + [SUBSYSTEM::LIBCLI_DGRAM] -OBJ_FILES = \ - dgram/dgramsocket.o \ - dgram/mailslot.o \ - dgram/netlogon.o \ - dgram/ntlogon.o \ - dgram/browse.o PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE +LIBCLI_DGRAM_OBJ_FILES = $(addprefix libcli/dgram/, \ + dgramsocket.o \ + mailslot.o \ + netlogon.o \ + ntlogon.o \ + browse.o) + [SUBSYSTEM::LIBCLI_CLDAP] -OBJ_FILES = cldap/cldap.o PUBLIC_DEPENDENCIES = LIBCLI_LDAP PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB +LIBCLI_CLDAP_OBJ_FILES = libcli/cldap/cldap.o # PUBLIC_HEADERS += libcli/cldap/cldap.h [SUBSYSTEM::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h -OBJ_FILES = \ - wrepl/winsrepl.o PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \ LIBPACKET LIBNDR +LIBCLI_WREPL_OBJ_FILES = libcli/wrepl/winsrepl.o + [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h -OBJ_FILES = \ - resolve/resolve.o PUBLIC_DEPENDENCIES = NDR_NBT +LIBCLI_RESOLVE_OBJ_FILES = libcli/resolve/resolve.o + [SUBSYSTEM::LP_RESOLVE] PRIVATE_PROTO_HEADER = resolve/lp_proto.h -OBJ_FILES = \ - resolve/bcast.o \ - resolve/nbtlist.o \ - resolve/wins.o \ - resolve/host.o \ - resolve/resolve_lp.o PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF +LP_RESOLVE_OBJ_FILES = $(addprefix libcli/resolve/, \ + bcast.o nbtlist.o wins.o \ + host.o resolve_lp.o) + [SUBSYSTEM::LIBCLI_FINDDCS] PRIVATE_PROTO_HEADER = finddcs.h -OBJ_FILES = \ - finddcs.o PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING +LIBCLI_FINDDCS_OBJ_FILES = libcli/finddcs.o + [SUBSYSTEM::LIBCLI_SMB] PRIVATE_PROTO_HEADER = libcli_proto.h -OBJ_FILES = clireadwrite.o \ +PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ + LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ + LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket + +LIBCLI_SMB_OBJ_FILES = $(addprefix libcli/, \ + clireadwrite.o \ cliconnect.o \ clifile.o \ clilist.o \ clitrans2.o \ climessage.o \ - clideltree.o -PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ - LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ - LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket - + clideltree.o) # PUBLIC_HEADERS += libcli/libcli.h @@ -126,28 +133,11 @@ PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR #LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS -OBJ_FILES = raw/rawfile.o \ - raw/smb_signing.o \ - raw/clisocket.o \ - raw/clitransport.o \ - raw/clisession.o \ - raw/clitree.o \ - raw/clierror.o \ - raw/rawrequest.o \ - raw/rawreadwrite.o \ - raw/rawsearch.o \ - raw/rawsetfileinfo.o \ - raw/raweas.o \ - raw/rawtrans.o \ - raw/clioplock.o \ - raw/rawnegotiate.o \ - raw/rawfsinfo.o \ - raw/rawfileinfo.o \ - raw/rawnotify.o \ - raw/rawioctl.o \ - raw/rawacl.o \ - raw/rawdate.o \ - raw/rawlpq.o \ - raw/rawshadow.o + +LIBCLI_RAW_OBJ_FILES = $(addprefix libcli/raw/, rawfile.o smb_signing.o clisocket.o \ + clitransport.o clisession.o clitree.o clierror.o rawrequest.o \ + rawreadwrite.o rawsearch.o rawsetfileinfo.o raweas.o rawtrans.o \ + clioplock.o rawnegotiate.o rawfsinfo.o rawfileinfo.o rawnotify.o \ + rawioctl.o rawacl.o rawdate.o rawlpq.o rawshadow.o) mkinclude smb2/config.mk diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 0c5236c138..33e32c7417 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,17 +1,17 @@ [SUBSYSTEM::LIBCLI_LDAP] PRIVATE_PROTO_HEADER = ldap_proto.h -OBJ_FILES = ldap.o \ - ldap_client.o \ - ldap_bind.o \ - ldap_msg.o \ - ldap_ildap.o \ - ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec +LIBCLI_LDAP_OBJ_FILES = $(addprefix libcli/ldap/, \ + ldap.o ldap_client.o ldap_bind.o \ + ldap_msg.o ldap_ildap.o ldap_controls.o) + + PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h [SUBSYSTEM::LDAP_ENCODE] -OBJ_FILES = ldap_ndr.o # FIXME PRIVATE_DEPENDENCIES = LIBLDB + +LDAP_ENCODE_OBJ_FILES = libcli/ldap/ldap_ndr.o diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 8c66df0325..fde065aa34 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,13 +1,14 @@ [SUBSYSTEM::LIBSECURITY] PRIVATE_PROTO_HEADER = proto.h -OBJ_FILES = security_token.o \ - security_descriptor.o \ - dom_sid.o \ - access_check.o \ - privilege.o \ - sddl.o PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR +LIBSECURITY_OBJ_FILES = $(addprefix libcli/security/, \ + security_token.o security_descriptor.o \ + dom_sid.o access_check.o privilege.o sddl.o) + + [PYTHON::swig_security] SWIG_FILE = security.i PRIVATE_DEPENDENCIES = LIBSECURITY + +swig_security_OBJ_FILES = libcli/security/security_wrap.o diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index ab079fefde..e95997db54 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -1,25 +1,10 @@ [SUBSYSTEM::LIBCLI_SMB2] PRIVATE_PROTO_HEADER = smb2_proto.h -OBJ_FILES = \ - transport.o \ - request.o \ - negprot.o \ - session.o \ - tcon.o \ - create.o \ - close.o \ - connect.o \ - getinfo.o \ - write.o \ - read.o \ - setinfo.o \ - find.o \ - ioctl.o \ - logoff.o \ - tdis.o \ - flush.o \ - lock.o \ - notify.o \ - cancel.o \ - keepalive.o PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec + +LIBCLI_SMB2_OBJ_FILES = $(addprefix libcli/smb2/, \ + transport.o request.o negprot.o session.o tcon.o \ + create.o close.o connect.o getinfo.o write.o read.o \ + setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ + lock.o notify.o cancel.o keepalive.o) + diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk index 9384a172ff..94e30d44f1 100644 --- a/source4/libcli/wbclient/config.mk +++ b/source4/libcli/wbclient/config.mk @@ -1,4 +1,5 @@ [SUBSYSTEM::LIBWBCLIENT] -OBJ_FILES = wbclient.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING + +LIBWBCLIENT_OBJ_FILES = libcli/wbclient/wbclient.o -- cgit From 08baea013b73607df0c86f24506912c7e6af6f7e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 02:25:16 +0200 Subject: Move SOVERSION, VERSION and PC_FILE out of smb_build but use make variables directly instead. (This used to be commit 9d0ae012b0b463278cd054d06788aa998acc2da2) --- source4/libcli/config.mk | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 1ed52ca9d3..95b45003be 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -42,8 +42,6 @@ PRIVATE_PROTO_HEADER = nbt/nbtname.h NDR_NBT_BUF_OBJ_FILES = libcli/nbt/nbtname.o [SUBSYSTEM::LIBCLI_NBT] -#VERSION = 0.0.1 -#SO_VERSION = 0 PRIVATE_PROTO_HEADER = nbt/nbt_proto.h PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL -- cgit From 1a8bfba5452f7b72d9f0b2a178f7e8a66557c463 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 12:15:43 +0200 Subject: Fix warnings. (This used to be commit 88013ca9775a6ff5e5a393f9d8238dbcd197f26f) --- source4/libcli/ldap/ldap_ndr.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h index dfbb723c36..ee1f702c78 100644 --- a/source4/libcli/ldap/ldap_ndr.h +++ b/source4/libcli/ldap/ldap_ndr.h @@ -1,6 +1,8 @@ #ifndef __LIBCLI_LDAP_LDAP_NDR_H__ #define __LIBCLI_LDAP_LDAP_NDR_H__ +#include "librpc/gen_ndr/ndr_misc.h" + char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -- cgit From b0f34bc8ca072c06b89934fbef516a2f3da0e269 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Apr 2008 10:05:53 +0200 Subject: libcli/smb2: also offer the SMB2 dialect that what used in longhorn beta3 With this smbtorture works against longhorn beta3 again, hopefully it still works with new versions... metze (This used to be commit 874924a85a862e38b7d1a6199276e998cf3697d8) --- source4/libcli/smb2/connect.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index d68b85ad54..59d4e6ea2d 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -121,7 +121,7 @@ static void continue_socket(struct composite_context *creq) struct smbcli_socket *sock; struct smb2_transport *transport; struct smb2_request *req; - uint16_t dialects[1]; + uint16_t dialects[2]; c->status = smbcli_sock_connect_recv(creq, state, &sock); if (!composite_is_ok(c)) return; @@ -130,11 +130,12 @@ static void continue_socket(struct composite_context *creq) if (composite_nomem(transport, c)) return; ZERO_STRUCT(state->negprot); - state->negprot.in.dialect_count = 1; + state->negprot.in.dialect_count = 2; state->negprot.in.security_mode = 0; state->negprot.in.capabilities = 0; unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); - dialects[0] = SMB2_DIALECT_REVISION; + dialects[0] = 0; + dialects[1] = SMB2_DIALECT_REVISION; state->negprot.in.dialects = dialects; req = smb2_negprot_send(transport, &state->negprot); -- cgit From 578539216fcb275e5ec013b3ed1c81e4baced80e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Apr 2008 10:03:08 +0200 Subject: libcli/smb2: make it possible to pass additional extra blobs in smb2_create() This also fixes the alignment from 8 to 4 byte bounderies. metze (This used to be commit e0a0d8e36acd735b587cd7870625af52c5dc3431) --- source4/libcli/raw/interfaces.h | 8 ++++ source4/libcli/smb2/create.c | 94 +++++++++++++++++++++++++++++++---------- 2 files changed, 79 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 61441b2cdc..cf5a3aa25e 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1587,6 +1587,14 @@ union smb_open { /* optional list of extended attributes */ struct smb_ea_list eas; + + struct smb2_create_blobs { + uint32_t num_blobs; + struct smb2_create_blob { + const char *tag; + DATA_BLOB data; + } *blobs; + } blobs; } in; struct { union smb_handle file; diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 999c10ab08..6ac32a494f 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -28,30 +28,59 @@ /* add a blob to a smb2_create attribute blob */ -NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - const char *tag, - DATA_BLOB add, bool last) +static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer, + const struct smb2_create_blob *blob, + bool last) { - uint32_t ofs = blob->length; - size_t tag_length = strlen(tag); - uint8_t pad = smb2_padding_size(add.length+tag_length, 8); - if (!data_blob_realloc(mem_ctx, blob, - blob->length + 0x14 + tag_length + add.length + pad)) + uint32_t ofs = buffer->length; + size_t tag_length = strlen(blob->tag); + uint8_t pad = smb2_padding_size(blob->data.length+tag_length, 4); + + if (!data_blob_realloc(mem_ctx, buffer, + buffer->length + 0x14 + tag_length + blob->data.length + pad)) return NT_STATUS_NO_MEMORY; - + if (last) { - SIVAL(blob->data, ofs+0x00, 0); + SIVAL(buffer->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad); + SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad); } - SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ - SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */ - SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ - SIVAL(blob->data, ofs+0x0C, add.length); - memcpy(blob->data+ofs+0x10, tag, tag_length); - SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */ - memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length); - memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad); + SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */ + SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */ + SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ + SIVAL(buffer->data, ofs+0x0C, blob->data.length); + memcpy(buffer->data+ofs+0x10, blob->tag, tag_length); + SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */ + memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length); + memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad); + + return NT_STATUS_OK; +} + +NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b, + const char *tag, DATA_BLOB data) +{ + struct smb2_create_blob *array; + + array = talloc_realloc(mem_ctx, b->blobs, + struct smb2_create_blob, + b->num_blobs + 1); + NT_STATUS_HAVE_NO_MEMORY(array); + b->blobs = array; + + b->blobs[b->num_blobs].tag = talloc_strdup(b->blobs, tag); + NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].tag); + + if (data.data) { + b->blobs[b->num_blobs].data = data_blob_talloc(b->blobs, + data.data, + data.length); + NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].data.data); + } else { + b->blobs[b->num_blobs].data = data_blob(NULL, 0); + } + + b->num_blobs += 1; return NT_STATUS_OK; } @@ -64,6 +93,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create struct smb2_request *req; NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); + uint32_t i; req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; @@ -89,7 +119,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false); + status = smb2_create_blob_add(req, &io->in.blobs, + SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -99,13 +130,30 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC, - data_blob(NULL, 0), true); - + status = smb2_create_blob_add(req, &io->in.blobs, + SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } + + for (i=0; i < io->in.blobs.num_blobs; i++) { + bool last = false; + const struct smb2_create_blob *c; + + if ((i + 1) == io->in.blobs.num_blobs) { + last = true; + } + + c = &io->in.blobs.blobs[i]; + status = smb2_create_blob_push_one(req, &blob, + c, last); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + status = smb2_push_o32s32_blob(&req->out, 0x30, blob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); -- cgit From 11703b298685c9984a6a3c3a64eddb8a1a516b90 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Apr 2008 15:20:39 +0200 Subject: fix the overflow/wrap checks in Samba4 for new gcc optimisation behavior The approach I have used is as set out in https://www.securecoding.cert.org/confluence/display/seccode/ARR38-C.+Do+not+add+or+subtract+an+integer+to+a+pointer+if+the+resulting+value+does+not+refer+to+an+element+within+the+array (This used to be commit 92d5fb531db39be655f0cbd2d75b5f675a0a4cfa) --- source4/libcli/raw/rawrequest.c | 6 +++--- source4/libcli/raw/rawtrans.c | 6 +++--- source4/libcli/smb2/request.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index a42c710547..ef856c6ea1 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -700,10 +700,10 @@ DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count) { /* be careful with wraparound! */ - if (ptr < bufinfo->data || - ptr >= bufinfo->data + bufinfo->data_size || + if ((uintptr_t)ptr < (uintptr_t)bufinfo->data || + (uintptr_t)ptr >= (uintptr_t)bufinfo->data + bufinfo->data_size || count > bufinfo->data_size || - ptr + count > bufinfo->data + bufinfo->data_size) { + (uintptr_t)ptr + count > (uintptr_t)bufinfo->data + bufinfo->data_size) { return true; } return false; diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 29881afd2b..0f15b2151b 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -40,10 +40,10 @@ static bool raw_trans_oob(struct smbcli_request *req, ptr = req->in.hdr + offset; /* be careful with wraparound! */ - if (ptr < req->in.data || - ptr >= req->in.data + req->in.data_size || + if ((uintptr_t)ptr < (uintptr_t)req->in.data || + (uintptr_t)ptr >= (uintptr_t)req->in.data + req->in.data_size || count > req->in.data_size || - ptr + count > req->in.data + req->in.data_size) { + (uintptr_t)ptr + count > (uintptr_t)req->in.data + req->in.data_size) { return true; } return false; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2471fcaa4d..f52b0ceef2 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -211,10 +211,10 @@ bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) return false; } /* be careful with wraparound! */ - if (ptr < buf->body || - ptr >= buf->body + buf->body_size || + if ((uintptr_t)ptr < (uintptr_t)buf->body || + (uintptr_t)ptr >= (uintptr_t)buf->body + buf->body_size || size > buf->body_size || - ptr + size > buf->body + buf->body_size) { + (uintptr_t)ptr + size > (uintptr_t)buf->body + buf->body_size) { return true; } return false; @@ -669,7 +669,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, } if (*str == 0) { - blob.data = str; + blob.data = discard_const(str); blob.length = 0; return smb2_push_o16s16_blob(buf, ofs, blob); } -- cgit From 670b7dcae3d50e62902fce45d6bb1eeef8530f7c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Apr 2008 22:19:08 +0200 Subject: libcli: define structure for SMB2 Break metze (This used to be commit 5ffea702c3a1c92a797afab1a3cadf2f2a18729f) --- source4/libcli/raw/interfaces.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index cf5a3aa25e..bad3743721 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1862,7 +1862,8 @@ enum smb_lock_level { RAW_LOCK_LOCK, RAW_LOCK_UNLOCK, RAW_LOCK_LOCKX, - RAW_LOCK_SMB2 + RAW_LOCK_SMB2, + RAW_LOCK_SMB2_BREAK }; /* the generic interface is defined to be equal to the lockingX interface */ @@ -1925,6 +1926,20 @@ union smb_lock { uint16_t unknown1; } out; } smb2; + + /* SMB2 Break */ + struct smb2_break { + enum smb_lock_level level; + struct { + union smb_handle file; + + /* static body buffer 24 (0x18) bytes */ + uint8_t oplock_level; + uint8_t reserved; + uint32_t reserved2; + /* struct smb2_handle handle; */ + } in, out; + } smb2_break; }; -- cgit From 0f4a60ff24b2bdb7e2bd73e787613264ec73265c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Apr 2008 22:24:21 +0200 Subject: libcli/smb2: add smb2_break() calls metze (This used to be commit 7f545dbbf0186fe552e4c49a3f618862cb4771e7) --- source4/libcli/smb2/break.c | 74 +++++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/config.mk | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/break.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/break.c b/source4/libcli/smb2/break.c new file mode 100644 index 0000000000..fe0cceb829 --- /dev/null +++ b/source4/libcli/smb2/break.c @@ -0,0 +1,74 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client oplock break handling + + Copyright (C) Stefan Metzmacher 2008 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" + +/* + send a break request +*/ +struct smb2_request *smb2_break_send(struct smb2_tree *tree, struct smb2_break *io) +{ + struct smb2_request *req; + + req = smb2_request_init_tree(tree, SMB2_OP_BREAK, 0x18, false, 0); + if (req == NULL) return NULL; + + SCVAL(req->out.body, 0x02, io->in.oplock_level); + SCVAL(req->out.body, 0x03, io->in.reserved); + SIVAL(req->out.body, 0x04, io->in.reserved2); + smb2_push_handle(req->out.body+0x08, &io->in.file.handle); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a break reply +*/ +NTSTATUS smb2_break_recv(struct smb2_request *req, struct smb2_break *io) +{ + if (!smb2_request_receive(req) || + !smb2_request_is_ok(req)) { + return smb2_request_destroy(req); + } + + SMB2_CHECK_PACKET_RECV(req, 0x18, false); + + io->out.oplock_level = CVAL(req->in.body, 0x02); + io->out.reserved = CVAL(req->in.body, 0x03); + io->out.reserved2 = IVAL(req->in.body, 0x04); + smb2_pull_handle(req->in.body+0x08, &io->out.file.handle); + + return smb2_request_destroy(req); +} + +/* + sync flush request +*/ +NTSTATUS smb2_break(struct smb2_tree *tree, struct smb2_break *io) +{ + struct smb2_request *req = smb2_break_send(tree, io); + return smb2_break_recv(req, io); +} diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index e95997db54..18f6245a3e 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -6,5 +6,5 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix libcli/smb2/, \ transport.o request.o negprot.o session.o tcon.o \ create.o close.o connect.o getinfo.o write.o read.o \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ - lock.o notify.o cancel.o keepalive.o) + lock.o notify.o cancel.o keepalive.o break.o) -- cgit From 132852f44ac24824d2247d3d873f217c5b8207a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Apr 2008 22:27:24 +0200 Subject: libcli/smb2: make it possible to handle incoming oplock requests metze (This used to be commit 58189b87eade62b717c2c17c679e482786bf2098) --- source4/libcli/smb2/smb2.h | 11 +++++++++++ source4/libcli/smb2/transport.c | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 726df64090..ae66a6e0d3 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -21,6 +21,8 @@ #include "libcli/raw/request.h" +struct smb2_handle; + struct smb2_options { uint32_t timeout; }; @@ -58,6 +60,15 @@ struct smb2_transport { void *private; uint_t period; } idle; + + struct { + /* a oplock break request handler */ + bool (*handler)(struct smb2_transport *transport, + const struct smb2_handle *handle, + uint8_t level, void *private_data); + /* private data passed to the oplock handler */ + void *private_data; + } oplock; }; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index af19fcb0a9..8eb60a06f1 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -140,6 +140,44 @@ void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status) } } +static bool smb2_handle_oplock_break(struct smb2_transport *transport, + const DATA_BLOB *blob) +{ + uint8_t *hdr; + uint16_t opcode; + uint64_t seqnum; + + hdr = blob->data+NBT_HDR_SIZE; + + if (blob->length < (SMB2_MIN_SIZE+0x18)) { + DEBUG(1,("Discarding smb2 oplock reply of size %u\n", + blob->length)); + return false; + } + + opcode = SVAL(hdr, SMB2_HDR_OPCODE); + seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); + + if ((opcode != SMB2_OP_BREAK) || + (seqnum != UINT64_MAX)) { + return false; + } + + if (transport->oplock.handler) { + uint8_t *body = hdr+SMB2_HDR_BODY; + struct smb2_handle h; + uint8_t level; + + level = CVAL(body, 0x02); + smb2_pull_handle(body+0x08, &h); + + transport->oplock.handler(transport, &h, level, + transport->oplock.private_data); + } + + return true; +} + /* we have a full request in our receive buffer - match it to a pending request and process @@ -167,6 +205,11 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) goto error; } + if (smb2_handle_oplock_break(transport, &blob)) { + talloc_free(buffer); + return NT_STATUS_OK; + } + flags = IVAL(hdr, SMB2_HDR_FLAGS); seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); -- cgit From 4e83011f72ba3df387512755a17760b42a7bf2f2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 21 Apr 2008 17:58:23 -0400 Subject: Remove more event_context_init() uses from function calls within deep down the code. Make sure we pass around the event_context where we need it instead. All test but a few python ones fail. Jelmer promised to fix them. (This used to be commit 3045d391626fba169aa26be52174883e18d323e9) --- source4/libcli/cldap/cldap.c | 6 +----- source4/libcli/cliconnect.c | 5 +++-- source4/libcli/composite/composite.c | 6 +++++- source4/libcli/dgram/dgramsocket.c | 6 +----- source4/libcli/ldap/ldap_bind.c | 5 +++-- source4/libcli/ldap/ldap_client.c | 12 ++++-------- source4/libcli/nbt/nbtsocket.c | 6 +----- source4/libcli/raw/clisocket.c | 22 ++++++---------------- source4/libcli/resolve/host.c | 1 - source4/libcli/resolve/nbtlist.c | 3 +-- source4/libcli/resolve/resolve.c | 13 ++++--------- source4/libcli/smb_composite/connect.c | 8 +++----- source4/libcli/smb_composite/fetchfile.c | 2 -- source4/libcli/smb_composite/fsinfo.c | 2 -- source4/libcli/wrepl/winsrepl.c | 6 +----- 15 files changed, 33 insertions(+), 70 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index d9910285d9..614bd51d2a 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -250,11 +250,7 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, cldap = talloc(mem_ctx, struct cldap_socket); if (cldap == NULL) goto failed; - if (event_ctx == NULL) { - cldap->event_ctx = event_context_init(cldap); - } else { - cldap->event_ctx = talloc_reference(cldap, event_ctx); - } + cldap->event_ctx = talloc_reference(cldap, event_ctx); if (cldap->event_ctx == NULL) goto failed; cldap->idr = idr_init(cldap); diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 4858a96110..c20a7fd935 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -33,13 +33,14 @@ */ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, const char **ports, + struct event_context *ev_ctx, struct resolve_context *resolve_ctx, struct smbcli_options *options) { struct smbcli_socket *sock; - sock = smbcli_sock_connect_byname(server, ports, NULL, resolve_ctx, - NULL); + sock = smbcli_sock_connect_byname(server, ports, NULL, + resolve_ctx, ev_ctx); if (sock == NULL) return false; diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 26169e7838..966f56cba8 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -42,7 +42,11 @@ _PUBLIC_ struct composite_context *composite_create(TALLOC_CTX *mem_ctx, c = talloc_zero(mem_ctx, struct composite_context); if (!c) return NULL; c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = ev; + c->event_ctx = talloc_reference(c, ev); + if (!c->event_ctx) { + talloc_free(c); + return NULL; + } return c; } diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 130d8ae870..06b7bd5771 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -167,11 +167,7 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, dgmsock = talloc(mem_ctx, struct nbt_dgram_socket); if (dgmsock == NULL) goto failed; - if (event_ctx == NULL) { - dgmsock->event_ctx = event_context_init(dgmsock); - } else { - dgmsock->event_ctx = talloc_reference(dgmsock, event_ctx); - } + dgmsock->event_ctx = talloc_reference(dgmsock, event_ctx); if (dgmsock->event_ctx == NULL) goto failed; status = socket_create("ip", SOCKET_TYPE_DGRAM, &dgmsock->sock, 0); diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2c04edf950..e1569e7296 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -200,7 +200,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, /* perform a sasl bind using the given credentials */ -_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, +_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds, struct loadparm_context *lp_ctx) { @@ -223,7 +223,8 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, gensec_init(lp_ctx); - status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx); + status = gensec_client_start(conn, &conn->gensec, + conn->event.event_ctx, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 296a7b11f2..bca867b033 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -48,17 +48,13 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, { struct ldap_connection *conn; - conn = talloc_zero(mem_ctx, struct ldap_connection); - if (conn == NULL) { + if (ev == NULL) { return NULL; } - if (ev == NULL) { - ev = event_context_init(conn); - if (ev == NULL) { - talloc_free(conn); - return NULL; - } + conn = talloc_zero(mem_ctx, struct ldap_connection); + if (conn == NULL) { + return NULL; } conn->next_messageid = 1; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 747127980a..5d4611e2d9 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -318,11 +318,7 @@ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, nbtsock = talloc(mem_ctx, struct nbt_name_socket); if (nbtsock == NULL) goto failed; - if (event_ctx == NULL) { - nbtsock->event_ctx = event_context_init(nbtsock); - } else { - nbtsock->event_ctx = talloc_reference(nbtsock, event_ctx); - } + nbtsock->event_ctx = talloc_reference(nbtsock, event_ctx); if (nbtsock->event_ctx == NULL) goto failed; status = socket_create("ip", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0); diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 1dcf2d1c53..49838e8a1c 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -59,12 +59,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; - if (event_ctx != NULL) { - result->event_ctx = talloc_reference(result, event_ctx); - } else { - result->event_ctx = event_context_init(result); - } - + result->event_ctx = talloc_reference(result, event_ctx); if (result->event_ctx == NULL) goto failed; state = talloc(result, struct sock_connect_state); @@ -202,6 +197,11 @@ _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, cons TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); struct smbcli_socket *result; + if (event_ctx == NULL) { + DEBUG(0, ("Invalid NULL event context passed in as parameter\n")); + return NULL; + } + if (tmp_ctx == NULL) { DEBUG(0, ("talloc_new failed\n")); return NULL; @@ -214,16 +214,6 @@ _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, cons return NULL; } - if (event_ctx == NULL) { - event_ctx = event_context_init(mem_ctx); - } - - if (event_ctx == NULL) { - DEBUG(0, ("event_context_init failed\n")); - talloc_free(tmp_ctx); - return NULL; - } - /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(name, '#'))) { name_type = strtol(p+1, NULL, 16); diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 4b8f3f9553..1a695432ee 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -135,7 +135,6 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx, c = composite_create(mem_ctx, event_ctx); if (c == NULL) return NULL; - c->event_ctx = talloc_reference(c, event_ctx); if (composite_nomem(c->event_ctx, c)) return c; state = talloc(c, struct host_state); diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 887bdd7ecf..8f085c5404 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -110,10 +110,9 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, struct nbtlist_state *state; int i; - c = composite_create(event_ctx, event_ctx); + c = composite_create(mem_ctx, event_ctx); if (c == NULL) return NULL; - c->event_ctx = talloc_reference(c, event_ctx); if (composite_nomem(c->event_ctx, c)) return c; state = talloc(c, struct nbtlist_state); diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 33ace09443..aaf9ff1f8d 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -136,19 +136,14 @@ struct composite_context *resolve_name_send(struct resolve_context *ctx, struct composite_context *c; struct resolve_state *state; - c = composite_create(event_ctx, event_ctx); - if (c == NULL) return NULL; - - if (ctx == NULL) { + if (ctx == NULL || event_ctx == NULL) { composite_error(c, NT_STATUS_INVALID_PARAMETER); return c; } - if (event_ctx == NULL) { - c->event_ctx = event_context_init(c); - } else { - c->event_ctx = talloc_reference(c, event_ctx); - } + c = composite_create(ctx, event_ctx); + if (c == NULL) return NULL; + if (composite_nomem(c->event_ctx, c)) return c; state = talloc(c, struct resolve_state); diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index c44c62f868..c4abfa5e37 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -451,17 +451,15 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) goto failed; + c->event_ctx = talloc_reference(c, event_ctx); + if (c->event_ctx == NULL) goto failed; + state = talloc_zero(c, struct connect_state); if (state == NULL) goto failed; - if (event_ctx == NULL) { - event_ctx = event_context_init(mem_ctx); - } - state->io = io; c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = talloc_reference(c, event_ctx); c->private_data = state; state->stage = CONNECT_RESOLVE; diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index d8d7481270..9cd02a51f4 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -62,7 +62,6 @@ static NTSTATUS fetchfile_connect(struct composite_context *c, state->creq->async.fn = fetchfile_composite_handler; state->stage = FETCHFILE_READ; - c->event_ctx = talloc_reference(c, state->creq->event_ctx); return NT_STATUS_OK; } @@ -158,7 +157,6 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FETCHFILE_CONNECT; - c->event_ctx = talloc_reference(c, state->creq->event_ctx); c->private_data = state; return c; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index 2ec13df9b6..270d71f518 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -52,7 +52,6 @@ static NTSTATUS fsinfo_connect(struct composite_context *c, state->req->async.fn = fsinfo_raw_handler; state->stage = FSINFO_QUERY; - c->event_ctx = talloc_reference(c, state->req->session->transport->socket->event.ctx); return NT_STATUS_OK; } @@ -158,7 +157,6 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; - c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx); c->private_data = state; state->creq = smb_composite_connect_send(state->connect, state, diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 3e7793c0c7..0a4e52bd7b 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -172,11 +172,7 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx, wrepl_socket = talloc_zero(mem_ctx, struct wrepl_socket); if (!wrepl_socket) return NULL; - if (event_ctx == NULL) { - wrepl_socket->event.ctx = event_context_init(wrepl_socket); - } else { - wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx); - } + wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx); if (!wrepl_socket->event.ctx) goto failed; wrepl_socket->iconv_convenience = iconv_convenience; -- cgit From 996d1bc09063fc42c2ac4907d5d9cdf106aec38c Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Fri, 18 Apr 2008 17:09:09 +0200 Subject: fix an extrasemi compile warning (This used to be commit 47e8ef4f6aa91ed0b069a1890cb1f853b4e9b879) --- source4/libcli/nbt/libnbt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 14cec3a024..0b01365510 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -330,7 +330,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *) -NDR_SCALAR_PROTO(nbt_string, const char *); +NDR_SCALAR_PROTO(nbt_string, const char *) NDR_BUFFER_PROTO(nbt_name, struct nbt_name) NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode); -- cgit From d67e47e5cd11c928299dc03ce2ff521e2d3cca83 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Apr 2008 16:27:36 +0100 Subject: Add comment explaining why io.in.workgroup isn't important. This protocol feild isn't used by servers (apparently), so we might be able to get rid of it. Andrew Bartlett (This used to be commit 58935acc7c8e97323d5d5979234ef26ef8a100a4) --- source4/libcli/raw/clitree.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index d5075f9271..15cd70833c 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -193,6 +193,11 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.service_type = service_type; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; + + /* This workgroup gets sent out by the SPNEGO session setup. + * I don't know of any servers that look at it, so we might + * hardcode it to "" some day, when the war on global_loadparm + * is complete -- abartlet 2008-04-28 */ io.in.workgroup = lp_workgroup(global_loadparm); io.in.options = *options; -- cgit From c4219fd8030494986c5fa418c46defb1a9c05c7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Apr 2008 15:08:52 +0100 Subject: Make the composite 'connect to server' code useful for security=server The ability to short-circuit the connection code to only do a negprot allows us to do the rest once we have the user's password. We return the 8 byte challenge so we can pass it to the client. Andrew Bartlett (This used to be commit 40fe386b0374df8b390b995c332d048dbbc08f1b) --- source4/libcli/smb_composite/connect.c | 42 ++++++++++++++++++++-------- source4/libcli/smb_composite/sesssetup.c | 2 +- source4/libcli/smb_composite/smb_composite.h | 5 ++-- 3 files changed, 35 insertions(+), 14 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index c4abfa5e37..4400c61a81 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -38,7 +38,9 @@ enum connect_stage {CONNECT_RESOLVE, CONNECT_NEGPROT, CONNECT_SESSION_SETUP, CONNECT_SESSION_SETUP_ANON, - CONNECT_TCON}; + CONNECT_TCON, + CONNECT_DONE +}; struct connect_state { enum connect_stage stage; @@ -97,8 +99,7 @@ static NTSTATUS connect_tcon(struct composite_context *c, state->io_tcon->tconx.out.fs_type); } - /* all done! */ - c->state = COMPOSITE_STATE_DONE; + state->stage = CONNECT_DONE; return NT_STATUS_OK; } @@ -203,6 +204,13 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->session->vuid = state->io_setup->out.vuid; + /* If we don't have a remote share name then this indicates that + * we don't want to do a tree connect */ + if (!io->in.service) { + state->stage = CONNECT_DONE; + return NT_STATUS_OK; + } + /* setup for a tconx */ io->out.tree = smbcli_tree_init(state->session, state, true); NT_STATUS_HAVE_NO_MEMORY(io->out.tree); @@ -251,10 +259,23 @@ static NTSTATUS connect_negprot(struct composite_context *c, status = smb_raw_negotiate_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); + if (!(state->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY)) { + io->out.negprot_challenge = state->transport->negotiate.secblob; + } else { + io->out.negprot_challenge = data_blob(NULL, 0); + } + + /* If we don't have any credentials then this indicates that + * we don't want to do a session setup */ + if (!io->in.credentials) { + state->stage = CONNECT_DONE; + return NT_STATUS_OK; + } + /* next step is a session setup */ state->session = smbcli_session_init(state->transport, state, true); NT_STATUS_HAVE_NO_MEMORY(state->session); - + state->io_setup = talloc(c, struct smb_composite_sesssetup); NT_STATUS_HAVE_NO_MEMORY(state->io_setup); @@ -272,6 +293,7 @@ static NTSTATUS connect_negprot(struct composite_context *c, state->creq->async.fn = composite_handler; state->creq->async.private_data = c; + state->stage = CONNECT_SESSION_SETUP; return NT_STATUS_OK; @@ -405,13 +427,11 @@ static void state_handler(struct composite_context *c) break; } - if (!NT_STATUS_IS_OK(c->status)) { - c->state = COMPOSITE_STATE_ERROR; - } - - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); + if (state->stage == CONNECT_DONE) { + /* all done! */ + composite_done(c); + } else { + composite_is_ok(c); } } diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 1427fe525b..11ac37e257 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -224,7 +224,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, { NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); - const char *password = cli_credentials_get_password(io->in.credentials); DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = CLI_CRED_NTLM_AUTH; @@ -266,6 +265,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, data_blob_free(&session_key); } else if (session->options.plaintext_auth) { + const char *password = cli_credentials_get_password(io->in.credentials); state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); } else { diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index e7e131869c..80746f2732 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -83,8 +83,8 @@ struct smb_composite_savefile { - socket establishment - session request - negprot - - session setup - - tree connect + - session setup (if credentials are not NULL) + - tree connect (if service is not NULL) */ struct smb_composite_connect { struct { @@ -101,6 +101,7 @@ struct smb_composite_connect { struct { struct smbcli_tree *tree; bool anonymous_fallback_done; + DATA_BLOB negprot_challenge; } out; }; -- cgit From 35e45534c64930a0f22c5975c64be41d96265a00 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Apr 2008 15:59:22 +0100 Subject: Revert to using the old CIFS connection API. Rather than add a new 'out' member to the API, simply fill in the 'tree' early enough that we can access the server challenge there. Andrew Bartlett (This used to be commit 6dbbcf8aaf9b93af970d1701dfb185460d4dc788) --- source4/libcli/smb_composite/connect.c | 24 ++++++++---------------- source4/libcli/smb_composite/smb_composite.h | 1 - 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 4400c61a81..39c614f042 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -122,9 +122,6 @@ static NTSTATUS connect_session_setup_anon(struct composite_context *c, state->session->vuid = state->io_setup->out.vuid; /* setup for a tconx */ - io->out.tree = smbcli_tree_init(state->session, state, true); - NT_STATUS_HAVE_NO_MEMORY(io->out.tree); - state->io_tcon = talloc(c, union smb_tcon); NT_STATUS_HAVE_NO_MEMORY(state->io_tcon); @@ -211,10 +208,6 @@ static NTSTATUS connect_session_setup(struct composite_context *c, return NT_STATUS_OK; } - /* setup for a tconx */ - io->out.tree = smbcli_tree_init(state->session, state, true); - NT_STATUS_HAVE_NO_MEMORY(io->out.tree); - state->io_tcon = talloc(c, union smb_tcon); NT_STATUS_HAVE_NO_MEMORY(state->io_tcon); @@ -259,11 +252,14 @@ static NTSTATUS connect_negprot(struct composite_context *c, status = smb_raw_negotiate_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); - if (!(state->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY)) { - io->out.negprot_challenge = state->transport->negotiate.secblob; - } else { - io->out.negprot_challenge = data_blob(NULL, 0); - } + /* next step is a session setup */ + state->session = smbcli_session_init(state->transport, state, true); + NT_STATUS_HAVE_NO_MEMORY(state->session); + + /* setup for a tconx (or at least have the structure ready to + * return, if we won't go that far) */ + io->out.tree = smbcli_tree_init(state->session, state, true); + NT_STATUS_HAVE_NO_MEMORY(io->out.tree); /* If we don't have any credentials then this indicates that * we don't want to do a session setup */ @@ -272,10 +268,6 @@ static NTSTATUS connect_negprot(struct composite_context *c, return NT_STATUS_OK; } - /* next step is a session setup */ - state->session = smbcli_session_init(state->transport, state, true); - NT_STATUS_HAVE_NO_MEMORY(state->session); - state->io_setup = talloc(c, struct smb_composite_sesssetup); NT_STATUS_HAVE_NO_MEMORY(state->io_setup); diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 80746f2732..afee11ce3b 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -101,7 +101,6 @@ struct smb_composite_connect { struct { struct smbcli_tree *tree; bool anonymous_fallback_done; - DATA_BLOB negprot_challenge; } out; }; -- cgit From f8fb5d8c4da11cdb8ac79649fd74047d4cc42c68 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 May 2008 12:57:23 +1000 Subject: Reorder this function in the file, so it reads bottom-up. The rest of this file reads bottom-up, but this function (connect_send_negprot()) was out of place. Andrew Bartlett (This used to be commit f0c95cd74fb6fea57cef89b59e5d2f10ea25c138) --- source4/libcli/smb_composite/connect.c | 37 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 39c614f042..e56339f96b 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -58,25 +58,6 @@ struct connect_state { static void request_handler(struct smbcli_request *); static void composite_handler(struct composite_context *); -/* - setup a negprot send -*/ -static NTSTATUS connect_send_negprot(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - - state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - state->req->async.fn = request_handler; - state->req->async.private = c; - state->stage = CONNECT_NEGPROT; - - return NT_STATUS_OK; -} - - /* a tree connect request has completed */ @@ -291,6 +272,24 @@ static NTSTATUS connect_negprot(struct composite_context *c, return NT_STATUS_OK; } +/* + setup a negprot send +*/ +static NTSTATUS connect_send_negprot(struct composite_context *c, + struct smb_composite_connect *io) +{ + struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); + + state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol); + NT_STATUS_HAVE_NO_MEMORY(state->req); + + state->req->async.fn = request_handler; + state->req->async.private = c; + state->stage = CONNECT_NEGPROT; + + return NT_STATUS_OK; +} + /* a session request operation has completed -- cgit From 8113bb07a8eaee2bce1290bff1f06856bc7c76e6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 14 May 2008 19:49:38 +0200 Subject: Fix an uninitialized variable introduced by 3045d391 Simo, please check! Volker (This used to be commit 0c09d28acf42400d26cc27675e37226060de26d3) --- source4/libcli/resolve/resolve.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index aaf9ff1f8d..d89b50e430 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -137,8 +137,7 @@ struct composite_context *resolve_name_send(struct resolve_context *ctx, struct resolve_state *state; if (ctx == NULL || event_ctx == NULL) { - composite_error(c, NT_STATUS_INVALID_PARAMETER); - return c; + return NULL; } c = composite_create(ctx, event_ctx); -- cgit From 0abc2e2020f40d018587eb265f2a1467fdba4c89 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 May 2008 20:45:30 +1000 Subject: use a newer fsinfo level in smbclient, to support larger disks (This used to be commit 1acc8077fb86c1e78724b010d149db166d98238d) --- source4/libcli/clifile.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index e59b7f9af3..2cf174060b 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -650,7 +650,8 @@ NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path) /**************************************************************************** Query disk space. ****************************************************************************/ -NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, int *bsize, int *total, int *avail) +NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, uint32_t *bsize, + uint64_t *total, uint64_t *avail) { union smb_fsinfo fsinfo_parms; TALLOC_CTX *mem_ctx; @@ -658,12 +659,12 @@ NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, int *bsize, int *total, int *a mem_ctx = talloc_init("smbcli_dskattr"); - fsinfo_parms.dskattr.level = RAW_QFS_DSKATTR; + fsinfo_parms.dskattr.level = RAW_QFS_SIZE_INFO; status = smb_raw_fsinfo(tree, mem_ctx, &fsinfo_parms); if (NT_STATUS_IS_OK(status)) { - *bsize = fsinfo_parms.dskattr.out.block_size; - *total = fsinfo_parms.dskattr.out.units_total; - *avail = fsinfo_parms.dskattr.out.units_free; + *bsize = fsinfo_parms.size_info.out.bytes_per_sector * fsinfo_parms.size_info.out.sectors_per_unit; + *total = fsinfo_parms.size_info.out.total_alloc_units; + *avail = fsinfo_parms.size_info.out.avail_alloc_units; } talloc_free(mem_ctx); -- cgit From 8846981807a08e86c19b585be135b738eb9edf61 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 May 2008 20:46:10 +1000 Subject: update some SMB2 find flags (This used to be commit b7560afd4bab984c0083e9687b69bc42970ad932) --- source4/libcli/raw/interfaces.h | 7 ++++--- source4/libcli/smb2/find.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index bad3743721..871bab01db 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2354,10 +2354,11 @@ union smb_search_first { #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26 -/* flags for RAW_FILEINFO_SMB2_ALL_EAS */ +/* flags for SMB2 find */ #define SMB2_CONTINUE_FLAG_RESTART 0x01 #define SMB2_CONTINUE_FLAG_SINGLE 0x02 -#define SMB2_CONTINUE_FLAG_NEW 0x10 +#define SMB2_CONTINUE_FLAG_INDEX 0x04 +#define SMB2_CONTINUE_FLAG_REOPEN 0x10 /* SMB2 Find */ struct smb2_find { @@ -2370,7 +2371,7 @@ union smb_search_first { /* uint16_t buffer_code; 0x21 = 0x20 + 1 */ uint8_t level; uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */ - uint32_t unknown; /* perhaps a continue token? */ + uint32_t file_index; /* struct smb2_handle handle; */ /* uint16_t pattern_ofs; */ /* uint16_t pattern_size; */ diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 6b4902a026..8ebfd81bcd 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -38,7 +38,7 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io SCVAL(req->out.body, 0x02, io->in.level); SCVAL(req->out.body, 0x03, io->in.continue_flags); - SIVAL(req->out.body, 0x04, io->in.unknown); + SIVAL(req->out.body, 0x04, io->in.file_index); smb2_push_handle(req->out.body+0x08, &io->in.file.handle); status = smb2_push_o16s16_string(&req->out, 0x18, io->in.pattern); -- cgit From 58e7f253eafecca6934162034e88ee19b103c6ee Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 16 May 2008 13:03:01 +1000 Subject: Rework the CLDAP and NBT netlogon requests and responses. This now matches section 7.3.3 of the MS-ATDS specification, and all our current tests pass against windows. There is still more testing to do, and the server implementation to complete. Andrew Bartlett (This used to be commit 431d0c03965cbee85691cd0dc1e2a509c1a2b717) --- source4/libcli/cldap/cldap.c | 35 ++++------- source4/libcli/cldap/cldap.h | 7 ++- source4/libcli/config.mk | 13 +++- source4/libcli/dgram/libdgram.h | 21 +------ source4/libcli/dgram/netlogon.c | 22 +++---- source4/libcli/dgram/ntlogon.c | 128 ---------------------------------------- 6 files changed, 39 insertions(+), 187 deletions(-) delete mode 100644 source4/libcli/dgram/ntlogon.c (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 614bd51d2a..3867f3d3fd 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -595,7 +595,6 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, struct cldap_netlogon *io) { NTSTATUS status; - enum ndr_err_code ndr_err; struct cldap_search search; struct cldap_socket *cldap; DATA_BLOB *data; @@ -618,18 +617,15 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - ndr_err = ndr_pull_union_blob_all(data, mem_ctx, - cldap->iconv_convenience, - &io->out.netlogon, - io->in.version & 0xF, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", - SVAL(data->data, 0))); - dump_data(10, data->data, data->length); - return ndr_map_error2ntstatus(ndr_err); + status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience, + &io->out.netlogon); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (io->in.map_response) { + map_netlogon_samlogon_response(&io->out.netlogon); } - return NT_STATUS_OK; } @@ -704,25 +700,20 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, uint32_t version, - union nbt_cldap_netlogon *netlogon) + struct netlogon_samlogon_response *netlogon) { NTSTATUS status; - enum ndr_err_code ndr_err; struct cldap_reply reply; struct ldap_SearchResEntry response; struct ldap_Result result; TALLOC_CTX *tmp_ctx = talloc_new(cldap); DATA_BLOB blob; - ndr_err = ndr_push_union_blob(&blob, tmp_ctx, - cldap->iconv_convenience, - netlogon, version & 0xF, - (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } + status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience, + netlogon); + if (!NT_STATUS_IS_OK(status)) { + } reply.messageid = message_id; reply.dest = src; reply.response = &response; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index eb0191d0f4..7c2daf0ca2 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -20,7 +20,7 @@ */ #include "lib/util/asn1.h" -#include "librpc/gen_ndr/nbt.h" +#include "libcli/netlogon.h" struct ldap_message; @@ -161,9 +161,10 @@ struct cldap_netlogon { const char *domain_sid; int acct_control; uint32_t version; + bool map_response; } in; struct { - union nbt_cldap_netlogon netlogon; + struct netlogon_samlogon_response netlogon; } out; }; @@ -178,4 +179,4 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, uint32_t version, - union nbt_cldap_netlogon *netlogon); + struct netlogon_samlogon_response *netlogon); diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 95b45003be..08c08043a6 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -53,6 +53,14 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix libcli/nbt/, \ namerefresh.o \ namerelease.o) +[SUBSYSTEM::LIBCLI_NETLOGON] +PRIVATE_PROTO_HEADER = netlogon_proto.h +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ + NDR_SECURITY LIBSAMBA-UTIL + +LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ + netlogon.o) + [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG @@ -66,18 +74,17 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_smb_OBJ_FILES = libcli/swig/libcli_smb_wrap.o [SUBSYSTEM::LIBCLI_DGRAM] -PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE +PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON LIBCLI_DGRAM_OBJ_FILES = $(addprefix libcli/dgram/, \ dgramsocket.o \ mailslot.o \ netlogon.o \ - ntlogon.o \ browse.o) [SUBSYSTEM::LIBCLI_CLDAP] PUBLIC_DEPENDENCIES = LIBCLI_LDAP -PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON LIBCLI_CLDAP_OBJ_FILES = libcli/cldap/cldap.o # PUBLIC_HEADERS += libcli/cldap/cldap.h diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 707cca8cc5..3eac78f5e8 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -19,7 +19,7 @@ along with this program. If not, see . */ -#include "librpc/gen_ndr/nbt.h" +#include "libcli/netlogon.h" /* a datagram name request @@ -121,6 +121,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, struct socket_address *dest, + const char *mailslot_name, struct nbt_name *src_name, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, @@ -131,23 +132,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, - struct nbt_netlogon_packet *netlogon); - -NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - struct socket_address *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request); -NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, - const char *my_netbios_name, - const char *mailslot_name, - struct nbt_ntlogon_packet *reply); -NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_ntlogon_packet *ntlogon); + struct nbt_netlogon_response *netlogon); NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 5c7dedc7bb..c097127083 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -32,6 +32,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, struct socket_address *dest, + const char *mailslot, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -51,7 +52,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - NBT_MAILSLOT_NETLOGON, + mailslot, dest_name, dest, src_name, &blob); talloc_free(tmp_ctx); @@ -109,21 +110,16 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, - struct nbt_netlogon_packet *netlogon) + struct nbt_netlogon_response *netlogon) { + NTSTATUS status; DATA_BLOB data = dgram_mailslot_data(dgram); - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon, - (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - NTSTATUS status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", - (int)data.length, nt_errstr(status))); - if (DEBUGLVL(10)) { - file_save("netlogon.dat", data.data, data.length); - } + + status = pull_nbt_netlogon_response(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon); + if (!NT_STATUS_IS_OK(status)) { return status; } + return NT_STATUS_OK; } + diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c deleted file mode 100644 index 7b26ed7c00..0000000000 --- a/source4/libcli/dgram/ntlogon.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - handling for ntlogon dgram requests - - Copyright (C) Andrew Tridgell 2005 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "libcli/dgram/libdgram.h" -#include "lib/socket/socket.h" -#include "libcli/resolve/resolve.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -/* - send a ntlogon mailslot request -*/ -NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - struct socket_address *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request) -{ - NTSTATUS status; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - - status = dgram_mailslot_send(dgmsock, msg_type, - NBT_MAILSLOT_NTLOGON, - dest_name, dest, - src_name, &blob); - talloc_free(tmp_ctx); - return status; -} - - -/* - send a ntlogon mailslot reply -*/ -NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, - const char *my_netbios_name, - const char *mailslot_name, - struct nbt_ntlogon_packet *reply) -{ - NTSTATUS status; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - struct nbt_name myname; - struct socket_address *dest; - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply, - (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - make_nbt_name_client(&myname, my_netbios_name); - - dest = socket_address_from_strings(tmp_ctx, - dgmsock->sock->backend_name, - request->src_addr, request->src_port); - if (!dest) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - - status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - mailslot_name, - &request->data.msg.source_name, - dest, - &myname, &blob); - talloc_free(tmp_ctx); - return status; -} - - -/* - parse a ntlogon response. The packet must be a valid mailslot packet -*/ -NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_ntlogon_packet *ntlogon) -{ - DATA_BLOB data = dgram_mailslot_data(dgram); - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, ntlogon, - (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - NTSTATUS status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("Failed to parse ntlogon packet of length %d: %s\n", - (int)data.length, nt_errstr(status))); - if (DEBUGLVL(10)) { - file_save("ntlogon.dat", data.data, data.length); - } - return status; - } - return NT_STATUS_OK; -} -- cgit From de99db1084c73007f1d6f66fe7efb7a1a9271dfc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:02:14 +1000 Subject: started adding SMB2 composite functions that emulate common SMB calls (such as unlink) (This used to be commit 433038f3fea60087bdca07dcc856d0be4a4753f3) --- source4/libcli/smb_composite/smb2.c | 122 ++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 source4/libcli/smb_composite/smb2.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c new file mode 100644 index 0000000000..7bce65fb27 --- /dev/null +++ b/source4/libcli/smb_composite/smb2.c @@ -0,0 +1,122 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2008 + + 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 3 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, see . +*/ +/* + a composite API for making SMB-like calls using SMB2. This is useful + as SMB2 often requires more than one requests where a single SMB + request would do. In converting code that uses SMB to use SMB2, + these routines make life a lot easier +*/ + + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" +#include "param/param.h" +#include "libcli/smb2/smb2_calls.h" + +/* + continue after a SMB2 close + */ +static void continue_close(struct smb2_request *req) +{ + struct composite_context *ctx = talloc_get_type(req->async.private_data, + struct composite_context); + NTSTATUS status; + struct smb2_close close_parm; + + status = smb2_close_recv(req, &close_parm); + composite_error(ctx, status); +} + +/* + continue after the create in a composite unlink + */ +static void continue_unlink(struct smb2_request *req) +{ + struct composite_context *ctx = talloc_get_type(req->async.private_data, + struct composite_context); + struct smb2_tree *tree = req->tree; + struct smb2_create create_parm; + struct smb2_close close_parm; + NTSTATUS status; + + status = smb2_create_recv(req, ctx, &create_parm); + if (!NT_STATUS_IS_OK(status)) { + composite_error(ctx, status); + return; + } + + ZERO_STRUCT(close_parm); + close_parm.in.file.handle = create_parm.out.file.handle; + + req = smb2_close_send(tree, &close_parm); + composite_continue_smb2(ctx, req, continue_close, ctx); +} + +/* + composite SMB2 unlink call +*/ +struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree, + union smb_unlink *io) +{ + struct composite_context *ctx; + struct smb2_create create_parm; + struct smb2_request *req; + + ctx = composite_create(tree, tree->session->transport->socket->event.ctx); + if (ctx == NULL) return NULL; + + /* check for wildcards - we could support these with a + search, but for now they aren't necessary */ + if (strpbrk(io->unlink.in.pattern, "*?<>") != NULL) { + composite_error(ctx, NT_STATUS_NOT_SUPPORTED); + return ctx; + } + + ZERO_STRUCT(create_parm); + create_parm.in.desired_access = SEC_STD_DELETE; + create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; + create_parm.in.share_access = + NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + create_parm.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + create_parm.in.fname = io->unlink.in.pattern; + if (create_parm.in.fname[0] == '\\') { + create_parm.in.fname++; + } + + req = smb2_create_send(tree, &create_parm); + + composite_continue_smb2(ctx, req, continue_unlink, ctx); + return ctx; +} + + +/* + composite unlink call - sync interface +*/ +NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io) +{ + struct composite_context *c = smb2_composite_unlink_send(tree, io); + return composite_wait_free(c); +} + -- cgit From 14ca2b5b5db4abb1e6ab624365fdebfd9ec422e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:02:58 +1000 Subject: - added a composite_wait_free() call - allow composite_error() to take NT_STATUS_OK (This used to be commit 5240e1e25655af1f9b92da99e85d845bf30c4e9e) --- source4/libcli/composite/composite.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 966f56cba8..3e3f224f47 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -69,6 +69,17 @@ _PUBLIC_ NTSTATUS composite_wait(struct composite_context *c) return c->status; } +/* + block until a composite function has completed, then return the status. + Free the composite context before returning +*/ +_PUBLIC_ NTSTATUS composite_wait_free(struct composite_context *c) +{ + NTSTATUS status = composite_wait(c); + talloc_free(c); + return status; +} + /* callback from composite_done() and composite_error() @@ -94,6 +105,12 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te, _PUBLIC_ void composite_error(struct composite_context *ctx, NTSTATUS status) { + /* you are allowed to pass NT_STATUS_OK to composite_error(), in which + case it is equivalent to composite_done() */ + if (NT_STATUS_IS_OK(status)) { + composite_done(ctx); + return; + } if (!ctx->used_wait && !ctx->async.fn) { event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); } @@ -187,7 +204,7 @@ _PUBLIC_ void composite_continue_smb2(struct composite_context *ctx, { if (composite_nomem(new_req, ctx)) return; new_req->async.fn = continuation; - new_req->async.private = private_data; + new_req->async.private_data = private_data; } _PUBLIC_ void composite_continue_nbt(struct composite_context *ctx, -- cgit From c02b0f47a0c85250715a1c511415a6cb4fe7a082 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:03:12 +1000 Subject: declare composite_wait_free() (This used to be commit 5b6f80aba30fc8ade26f73b0a1336c22e40b66a9) --- source4/libcli/composite/composite.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h index f1bed20361..28cd6a88dc 100644 --- a/source4/libcli/composite/composite.h +++ b/source4/libcli/composite/composite.h @@ -101,6 +101,7 @@ bool composite_is_ok(struct composite_context *ctx); void composite_done(struct composite_context *ctx); void composite_error(struct composite_context *ctx, NTSTATUS status); NTSTATUS composite_wait(struct composite_context *c); +NTSTATUS composite_wait_free(struct composite_context *c); #endif /* __COMPOSITE_H__ */ -- cgit From 9bfafcfc213477a4f117ab07ce8f37bc18e74293 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:03:24 +1000 Subject: build the smb2 composite calls (This used to be commit ac10e3ad15dd17b96424987d1a2b7a0e4dc67cd0) --- source4/libcli/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 95b45003be..4350cd7b04 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -33,7 +33,8 @@ LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix libcli/smb_composite/, \ sesssetup.o \ fetchfile.o \ appendacl.o \ - fsinfo.o) + fsinfo.o \ + smb2.o) [SUBSYSTEM::NDR_NBT_BUF] -- cgit From c7d7577fb978dfa822b4aab238440816188099c6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:03:58 +1000 Subject: private -> private_data for struct smb2_request (This used to be commit 67290e0ad69df2f2fe651249c6550b8e32dd641b) --- source4/libcli/smb2/connect.c | 8 ++++---- source4/libcli/smb2/request.c | 25 +++++++++++++++++-------- source4/libcli/smb2/session.c | 4 ++-- source4/libcli/smb2/smb2.h | 7 ++++++- source4/libcli/smb_composite/smb_composite.h | 1 + 5 files changed, 30 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 59d4e6ea2d..867af14c92 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -44,7 +44,7 @@ struct smb2_connect_state { */ static void continue_tcon(struct smb2_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct smb2_connect_state *state = talloc_get_type(c->private_data, struct smb2_connect_state); @@ -83,7 +83,7 @@ static void continue_session(struct composite_context *creq) if (composite_nomem(req, c)) return; req->async.fn = continue_tcon; - req->async.private = c; + req->async.private_data = c; } /* @@ -91,7 +91,7 @@ static void continue_session(struct composite_context *creq) */ static void continue_negprot(struct smb2_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct smb2_connect_state *state = talloc_get_type(c->private_data, struct smb2_connect_state); @@ -142,7 +142,7 @@ static void continue_socket(struct composite_context *creq) if (composite_nomem(req, c)) return; req->async.fn = continue_negprot; - req->async.private = c; + req->async.private_data = c; } diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index f52b0ceef2..64d427f889 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -43,6 +43,18 @@ void smb2_setup_bufinfo(struct smb2_request *req) } } + +/* destroy a request structure */ +static int smb2_request_destructor(struct smb2_request *req) +{ + if (req->transport) { + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_recv, req); + } + return 0; +} + /* initialise a smb2 request */ @@ -122,6 +134,8 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SCVAL(req->out.dynamic, 0, 0); } + talloc_set_destructor(req, smb2_request_destructor); + return req; } @@ -154,18 +168,13 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req) _send() call fails completely */ if (!req) return NT_STATUS_UNSUCCESSFUL; - if (req->transport) { - /* remove it from the list of pending requests (a null op if - its not in the list) */ - DLIST_REMOVE(req->transport->pending_recv, req); - } - if (req->state == SMB2_REQUEST_ERROR && NT_STATUS_IS_OK(req->status)) { - req->status = NT_STATUS_INTERNAL_ERROR; + status = NT_STATUS_INTERNAL_ERROR; + } else { + status = req->status; } - status = req->status; talloc_free(req); return status; } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 18fe3486a4..29af6652f2 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -145,7 +145,7 @@ struct smb2_session_state { */ static void session_request_handler(struct smb2_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct smb2_session_state *state = talloc_get_type(c->private_data, struct smb2_session_state); @@ -178,7 +178,7 @@ static void session_request_handler(struct smb2_request *req) } state->req->async.fn = session_request_handler; - state->req->async.private = c; + state->req->async.private_data = c; return; } diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index ae66a6e0d3..964dcf320c 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -19,6 +19,9 @@ along with this program. If not, see . */ +#ifndef __LIBCLI_SMB2_SMB2_H__ +#define __LIBCLI_SMB2_SMB2_H__ + #include "libcli/raw/request.h" struct smb2_handle; @@ -165,7 +168,7 @@ struct smb2_request { */ struct { void (*fn)(struct smb2_request *); - void *private; + void *private_data; } async; }; @@ -282,3 +285,5 @@ struct smb2_request { return NT_STATUS_INVALID_PARAMETER; \ } \ } while (0) + +#endif diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index afee11ce3b..7f4b9d73e4 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -29,6 +29,7 @@ #include "libcli/raw/signing.h" #include "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" /* -- cgit From 7c0eea48f35dfb4cbc06fbaabf767612b30121eb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 12:38:58 +1000 Subject: Put back the old netlogn parsing code - for the request only This gives us seperate parsing functions for requests and replies. Andrew Bartlett (This used to be commit d2d3d15a8edd58cda7543feebdeb52178400615b) --- source4/libcli/dgram/libdgram.h | 15 ++++++++++----- source4/libcli/dgram/netlogon.c | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 3eac78f5e8..e1209e7a54 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -128,11 +128,16 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *my_netbios_name, const char *mailslot_name, - struct nbt_netlogon_packet *reply); -NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_netlogon_response *netlogon); + struct nbt_netlogon_response *reply); +NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon); + +NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_response *netlogon); NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index c097127083..b37d4a2ee6 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -67,22 +67,18 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *my_netbios_name, const char *mailslot_name, - struct nbt_netlogon_packet *reply) + struct nbt_netlogon_response *reply) { NTSTATUS status; - enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, - dgmsock->iconv_convenience, - reply, - (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); + status = push_nbt_netlogon_response(&blob, tmp_ctx, dgmsock->iconv_convenience, + reply); + if (!NT_STATUS_IS_OK(status)) { + return status; } make_nbt_name_client(&myname, my_netbios_name); @@ -107,7 +103,32 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, /* parse a netlogon response. The packet must be a valid mailslot packet */ -NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, +NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon) +{ + DATA_BLOB data = dgram_mailslot_data(dgram); + enum ndr_err_code ndr_err; + + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data.length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data.data, data.length); + } + return status; + } + return NT_STATUS_OK; +} + +/* + parse a netlogon response. The packet must be a valid mailslot packet +*/ +NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, struct nbt_netlogon_response *netlogon) -- cgit From 4f557d7954eb80e566a91b2fe22f7b7e30e0b456 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 13:24:29 +1000 Subject: Show that the NTLOGON and NETLOGON mailslots are *very* similar. Rework the mailslot infrustructure to cope, passing down the mailslot name so that we can implement both in the same callback function. Andrew Bartlett (This used to be commit 89fdd77891529aa74bb920994b8b5959aae8ac2d) --- source4/libcli/dgram/dgramsocket.c | 2 +- source4/libcli/dgram/libdgram.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 06b7bd5771..2cdda654ef 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -88,7 +88,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, src); + dgmslot->handler(dgmslot, packet, mailslot_name, src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index e1209e7a54..51408d029e 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -70,6 +70,7 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, + const char *mailslot_name, struct socket_address *src); struct dgram_mailslot_handler { -- cgit From 38c68f1d5bf972f2473a41bf15c4a54efdc38b7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 21:30:36 +1000 Subject: Ensure we don't send a reply if we couldn't push the CLDAP blob Andrew Bartlett (This used to be commit a8ec36eba79f96940f314520f97d23181bc9cfc5) --- source4/libcli/cldap/cldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 3867f3d3fd..860bd358d5 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -712,7 +712,7 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience, netlogon); if (!NT_STATUS_IS_OK(status)) { - + return status; } reply.messageid = message_id; reply.dest = src; -- cgit From 03643aec88244d976da394521adbd29a31339569 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 19:54:27 +0200 Subject: Use variables for source directory in a couple more places. (This used to be commit c41bd3005f5f0b9cfd3709fc9217b4a401d265b4) --- source4/libcli/auth/config.mk | 4 ++-- source4/libcli/config.mk | 38 +++++++++++++++++++------------------- source4/libcli/ldap/config.mk | 6 +++--- source4/libcli/security/config.mk | 4 ++-- source4/libcli/smb2/config.mk | 2 +- source4/libcli/wbclient/config.mk | 2 +- 6 files changed, 28 insertions(+), 28 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 85fc4ab527..6bd6bdc241 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -8,10 +8,10 @@ PUBLIC_DEPENDENCIES = \ # End SUBSYSTEM LIBCLI_AUTH ################################# -LIBCLI_AUTH_OBJ_FILES = $(addprefix libcli/auth/, \ +LIBCLI_AUTH_OBJ_FILES = $(addprefix $(libclisrcdir)/auth/, \ credentials.o \ session.o \ smbencrypt.o \ smbdes.o) -PUBLIC_HEADERS += libcli/auth/credentials.h +PUBLIC_HEADERS += $(libclisrcdir)/auth/credentials.h diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 95b45003be..6c7238200e 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -5,28 +5,28 @@ mkinclude wbclient/config.mk [SUBSYSTEM::LIBSAMBA-ERRORS] -LIBSAMBA-ERRORS_OBJ_FILES = $(addprefix libcli/util/, doserr.o errormap.o nterr.o) +LIBSAMBA-ERRORS_OBJ_FILES = $(addprefix $(libclisrcdir)/util/, doserr.o errormap.o nterr.o) -PUBLIC_HEADERS += $(addprefix libcli/, util/error.h util/ntstatus.h util/doserr.h util/werror.h) +PUBLIC_HEADERS += $(addprefix $(libclisrcdir)/, util/error.h util/ntstatus.h util/doserr.h util/werror.h) [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h PUBLIC_DEPENDENCIES = RPC_NDR_LSA PRIVATE_DEPENDENCIES = LIBSECURITY -LIBCLI_LSA_OBJ_FILES = libcli/util/clilsa.o +LIBCLI_LSA_OBJ_FILES = $(libclisrcdir)/util/clilsa.o [SUBSYSTEM::LIBCLI_COMPOSITE] PRIVATE_PROTO_HEADER = composite/proto.h PUBLIC_DEPENDENCIES = LIBEVENTS -LIBCLI_COMPOSITE_OBJ_FILES = libcli/composite/composite.o +LIBCLI_COMPOSITE_OBJ_FILES = $(libclisrcdir)/composite/composite.o [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] PRIVATE_PROTO_HEADER = smb_composite/proto.h PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec LIBCLI_RESOLVE -LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix libcli/smb_composite/, \ +LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix $(libclisrcdir)/smb_composite/, \ loadfile.o \ savefile.o \ connect.o \ @@ -39,14 +39,14 @@ LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix libcli/smb_composite/, \ [SUBSYSTEM::NDR_NBT_BUF] PRIVATE_PROTO_HEADER = nbt/nbtname.h -NDR_NBT_BUF_OBJ_FILES = libcli/nbt/nbtname.o +NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o [SUBSYSTEM::LIBCLI_NBT] PRIVATE_PROTO_HEADER = nbt/nbt_proto.h PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL -LIBCLI_NBT_OBJ_FILES = $(addprefix libcli/nbt/, \ +LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ nbtsocket.o \ namequery.o \ nameregister.o \ @@ -57,18 +57,18 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix libcli/nbt/, \ SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG -python_libcli_nbt_OBJ_FILES = libcli/swig/libcli_nbt_wrap.o +python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o [PYTHON::python_libcli_smb] SWIG_FILE = swig/libcli_smb.i PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG -python_libcli_smb_OBJ_FILES = libcli/swig/libcli_smb_wrap.o +python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o [SUBSYSTEM::LIBCLI_DGRAM] PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE -LIBCLI_DGRAM_OBJ_FILES = $(addprefix libcli/dgram/, \ +LIBCLI_DGRAM_OBJ_FILES = $(addprefix $(libclisrcdir)/dgram/, \ dgramsocket.o \ mailslot.o \ netlogon.o \ @@ -79,27 +79,27 @@ LIBCLI_DGRAM_OBJ_FILES = $(addprefix libcli/dgram/, \ PUBLIC_DEPENDENCIES = LIBCLI_LDAP PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB -LIBCLI_CLDAP_OBJ_FILES = libcli/cldap/cldap.o -# PUBLIC_HEADERS += libcli/cldap/cldap.h +LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o +# PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h [SUBSYSTEM::LIBCLI_WREPL] PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \ LIBPACKET LIBNDR -LIBCLI_WREPL_OBJ_FILES = libcli/wrepl/winsrepl.o +LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o [SUBSYSTEM::LIBCLI_RESOLVE] PRIVATE_PROTO_HEADER = resolve/proto.h PUBLIC_DEPENDENCIES = NDR_NBT -LIBCLI_RESOLVE_OBJ_FILES = libcli/resolve/resolve.o +LIBCLI_RESOLVE_OBJ_FILES = $(libclisrcdir)/resolve/resolve.o [SUBSYSTEM::LP_RESOLVE] PRIVATE_PROTO_HEADER = resolve/lp_proto.h PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF -LP_RESOLVE_OBJ_FILES = $(addprefix libcli/resolve/, \ +LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \ bcast.o nbtlist.o wins.o \ host.o resolve_lp.o) @@ -107,7 +107,7 @@ LP_RESOLVE_OBJ_FILES = $(addprefix libcli/resolve/, \ PRIVATE_PROTO_HEADER = finddcs.h PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING -LIBCLI_FINDDCS_OBJ_FILES = libcli/finddcs.o +LIBCLI_FINDDCS_OBJ_FILES = $(libclisrcdir)/finddcs.o [SUBSYSTEM::LIBCLI_SMB] PRIVATE_PROTO_HEADER = libcli_proto.h @@ -115,7 +115,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket -LIBCLI_SMB_OBJ_FILES = $(addprefix libcli/, \ +LIBCLI_SMB_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ clireadwrite.o \ cliconnect.o \ clifile.o \ @@ -124,7 +124,7 @@ LIBCLI_SMB_OBJ_FILES = $(addprefix libcli/, \ climessage.o \ clideltree.o) -# PUBLIC_HEADERS += libcli/libcli.h +# PUBLIC_HEADERS += $(libclisrcdir)/libcli.h [SUBSYSTEM::LIBCLI_RAW] PRIVATE_PROTO_HEADER = raw/raw_proto.h @@ -132,7 +132,7 @@ PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECU #LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS -LIBCLI_RAW_OBJ_FILES = $(addprefix libcli/raw/, rawfile.o smb_signing.o clisocket.o \ +LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o clisocket.o \ clitransport.o clisession.o clitree.o clierror.o rawrequest.o \ rawreadwrite.o rawsearch.o rawsetfileinfo.o raweas.o rawtrans.o \ clioplock.o rawnegotiate.o rawfsinfo.o rawfileinfo.o rawnotify.o \ diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 33e32c7417..d5b7c5d2b5 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -4,14 +4,14 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec -LIBCLI_LDAP_OBJ_FILES = $(addprefix libcli/ldap/, \ +LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ ldap.o ldap_client.o ldap_bind.o \ ldap_msg.o ldap_ildap.o ldap_controls.o) -PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h [SUBSYSTEM::LDAP_ENCODE] # FIXME PRIVATE_DEPENDENCIES = LIBLDB -LDAP_ENCODE_OBJ_FILES = libcli/ldap/ldap_ndr.o +LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index fde065aa34..8f1b88c64e 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -2,7 +2,7 @@ PRIVATE_PROTO_HEADER = proto.h PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR -LIBSECURITY_OBJ_FILES = $(addprefix libcli/security/, \ +LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ security_token.o security_descriptor.o \ dom_sid.o access_check.o privilege.o sddl.o) @@ -11,4 +11,4 @@ LIBSECURITY_OBJ_FILES = $(addprefix libcli/security/, \ SWIG_FILE = security.i PRIVATE_DEPENDENCIES = LIBSECURITY -swig_security_OBJ_FILES = libcli/security/security_wrap.o +swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 18f6245a3e..d00ef6e03b 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -2,7 +2,7 @@ PRIVATE_PROTO_HEADER = smb2_proto.h PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec -LIBCLI_SMB2_OBJ_FILES = $(addprefix libcli/smb2/, \ +LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ transport.o request.o negprot.o session.o tcon.o \ create.o close.o connect.o getinfo.o write.o read.o \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk index 94e30d44f1..00df5dbb22 100644 --- a/source4/libcli/wbclient/config.mk +++ b/source4/libcli/wbclient/config.mk @@ -2,4 +2,4 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING -LIBWBCLIENT_OBJ_FILES = libcli/wbclient/wbclient.o +LIBWBCLIENT_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o -- cgit From 4c8756f147f8b9a2806fd76e4cb06bb99d391516 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 22:30:08 +0200 Subject: Create prototype headers from Makefile directory, without smb_build in the middle. (This used to be commit f4a77b96f9c17d853348b70794026e5b9e384942) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 32 +++++++++++++++++++++----------- source4/libcli/ldap/config.mk | 3 ++- source4/libcli/security/config.mk | 2 +- source4/libcli/smb2/config.mk | 2 +- 5 files changed, 26 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 6bd6bdc241..8e3b21672b 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -1,7 +1,6 @@ ################################# # Start SUBSYSTEM LIBCLI_AUTH [SUBSYSTEM::LIBCLI_AUTH] -PRIVATE_PROTO_HEADER = proto.h PUBLIC_DEPENDENCIES = \ MSRPC_PARSE \ LIBSAMBA-HOSTCONFIG @@ -15,3 +14,4 @@ LIBCLI_AUTH_OBJ_FILES = $(addprefix $(libclisrcdir)/auth/, \ smbdes.o) PUBLIC_HEADERS += $(libclisrcdir)/auth/credentials.h +$(call proto_header_template,$(libclisrcdir)/auth/proto.h,$(LIBCLI_AUTH_OBJ_FILES:.o=.c)) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 6c7238200e..b9d90868d3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -10,20 +10,20 @@ LIBSAMBA-ERRORS_OBJ_FILES = $(addprefix $(libclisrcdir)/util/, doserr.o errormap PUBLIC_HEADERS += $(addprefix $(libclisrcdir)/, util/error.h util/ntstatus.h util/doserr.h util/werror.h) [SUBSYSTEM::LIBCLI_LSA] -PRIVATE_PROTO_HEADER = util/clilsa.h PUBLIC_DEPENDENCIES = RPC_NDR_LSA PRIVATE_DEPENDENCIES = LIBSECURITY LIBCLI_LSA_OBJ_FILES = $(libclisrcdir)/util/clilsa.o +$(call proto_header_template,$(libclisrcdir)/util/clilsa.h,$(LIBCLI_LSA_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LIBCLI_COMPOSITE] -PRIVATE_PROTO_HEADER = composite/proto.h PUBLIC_DEPENDENCIES = LIBEVENTS LIBCLI_COMPOSITE_OBJ_FILES = $(libclisrcdir)/composite/composite.o +$(call proto_header_template,$(libclisrcdir)/composite/proto.h,$(LIBCLI_COMPOSITE_OBJ_FILES:.o=.c)) [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] -PRIVATE_PROTO_HEADER = smb_composite/proto.h PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec LIBCLI_RESOLVE LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix $(libclisrcdir)/smb_composite/, \ @@ -35,14 +35,15 @@ LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix $(libclisrcdir)/smb_composite/, \ appendacl.o \ fsinfo.o) +$(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBCLI_SMB_COMPOSITE_OBJ_FILES:.o=.c)) [SUBSYSTEM::NDR_NBT_BUF] -PRIVATE_PROTO_HEADER = nbt/nbtname.h NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o +$(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LIBCLI_NBT] -PRIVATE_PROTO_HEADER = nbt/nbt_proto.h PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL @@ -53,6 +54,8 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ namerefresh.o \ namerelease.o) +$(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c)) + [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG @@ -83,34 +86,37 @@ LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o # PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h [SUBSYSTEM::LIBCLI_WREPL] -PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \ LIBPACKET LIBNDR LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o +$(call proto_header_template,$(libclisrcdir)/wrepl/winsrepl_proto.h,$(LIBCLI_WREPL_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LIBCLI_RESOLVE] -PRIVATE_PROTO_HEADER = resolve/proto.h PUBLIC_DEPENDENCIES = NDR_NBT LIBCLI_RESOLVE_OBJ_FILES = $(libclisrcdir)/resolve/resolve.o +$(call proto_header_template,$(libclisrcdir)/resolve/proto.h,$(LIBCLI_RESOLVE_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LP_RESOLVE] -PRIVATE_PROTO_HEADER = resolve/lp_proto.h PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \ bcast.o nbtlist.o wins.o \ host.o resolve_lp.o) +$(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES)) + [SUBSYSTEM::LIBCLI_FINDDCS] -PRIVATE_PROTO_HEADER = finddcs.h PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING LIBCLI_FINDDCS_OBJ_FILES = $(libclisrcdir)/finddcs.o +$(call proto_header_template,$(libclisrcdir)/finddcs.h,$(LIBCLI_FINDDCS_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LIBCLI_SMB] -PRIVATE_PROTO_HEADER = libcli_proto.h PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket @@ -124,10 +130,11 @@ LIBCLI_SMB_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ climessage.o \ clideltree.o) +$(call proto_header_template,$(libclisrcdir)/libcli_proto.h,$(LIBCLI_SMB_OBJ_FILES:.o=.c)) + # PUBLIC_HEADERS += $(libclisrcdir)/libcli.h [SUBSYSTEM::LIBCLI_RAW] -PRIVATE_PROTO_HEADER = raw/raw_proto.h PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR #LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT) PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS @@ -138,4 +145,7 @@ LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o clioplock.o rawnegotiate.o rawfsinfo.o rawfileinfo.o rawnotify.o \ rawioctl.o rawacl.o rawdate.o rawlpq.o rawshadow.o) + +$(call proto_header_template,$(libclisrcdir)/raw/raw_proto.h,$(LIBCLI_RAW_OBJ_FILES:.o=.c)) + mkinclude smb2/config.mk diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index d5b7c5d2b5..e761b80024 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,5 +1,4 @@ [SUBSYSTEM::LIBCLI_LDAP] -PRIVATE_PROTO_HEADER = ldap_proto.h PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec @@ -11,6 +10,8 @@ LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h +$(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LDAP_ENCODE] # FIXME PRIVATE_DEPENDENCIES = LIBLDB diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 8f1b88c64e..2bea795c02 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,11 +1,11 @@ [SUBSYSTEM::LIBSECURITY] -PRIVATE_PROTO_HEADER = proto.h PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ security_token.o security_descriptor.o \ dom_sid.o access_check.o privilege.o sddl.o) +$(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c)) [PYTHON::swig_security] SWIG_FILE = security.i diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index d00ef6e03b..1d0126dca8 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -1,5 +1,4 @@ [SUBSYSTEM::LIBCLI_SMB2] -PRIVATE_PROTO_HEADER = smb2_proto.h PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ @@ -8,3 +7,4 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ lock.o notify.o cancel.o keepalive.o break.o) +$(call proto_header_template,$(libclisrcdir)/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c)) -- cgit From 4c70cda986c86fe536327321d04c29eca81b6409 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:02:47 +0200 Subject: Fix a couple (well, little more than that..) of typos. (This used to be commit a6b52119940a900fb0de3864b8bca94e2965cc24) --- source4/libcli/auth/config.mk | 2 +- source4/libcli/config.mk | 22 +++++++++++----------- source4/libcli/ldap/config.mk | 2 +- source4/libcli/security/config.mk | 2 +- source4/libcli/smb2/config.mk | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk index 8e3b21672b..498c2af258 100644 --- a/source4/libcli/auth/config.mk +++ b/source4/libcli/auth/config.mk @@ -14,4 +14,4 @@ LIBCLI_AUTH_OBJ_FILES = $(addprefix $(libclisrcdir)/auth/, \ smbdes.o) PUBLIC_HEADERS += $(libclisrcdir)/auth/credentials.h -$(call proto_header_template,$(libclisrcdir)/auth/proto.h,$(LIBCLI_AUTH_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/auth/proto.h,$(LIBCLI_AUTH_OBJ_FILES:.o=.c))) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index b9d90868d3..0b493de1ea 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -15,13 +15,13 @@ PRIVATE_DEPENDENCIES = LIBSECURITY LIBCLI_LSA_OBJ_FILES = $(libclisrcdir)/util/clilsa.o -$(call proto_header_template,$(libclisrcdir)/util/clilsa.h,$(LIBCLI_LSA_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/util/clilsa.h,$(LIBCLI_LSA_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_COMPOSITE] PUBLIC_DEPENDENCIES = LIBEVENTS LIBCLI_COMPOSITE_OBJ_FILES = $(libclisrcdir)/composite/composite.o -$(call proto_header_template,$(libclisrcdir)/composite/proto.h,$(LIBCLI_COMPOSITE_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/composite/proto.h,$(LIBCLI_COMPOSITE_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_SMB_COMPOSITE] PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec LIBCLI_RESOLVE @@ -35,13 +35,13 @@ LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix $(libclisrcdir)/smb_composite/, \ appendacl.o \ fsinfo.o) -$(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBCLI_SMB_COMPOSITE_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBCLI_SMB_COMPOSITE_OBJ_FILES:.o=.c))) [SUBSYSTEM::NDR_NBT_BUF] NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o -$(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_NBT] PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ @@ -54,7 +54,7 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ namerefresh.o \ namerelease.o) -$(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c))) [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i @@ -91,14 +91,14 @@ PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \ LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o -$(call proto_header_template,$(libclisrcdir)/wrepl/winsrepl_proto.h,$(LIBCLI_WREPL_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/wrepl/winsrepl_proto.h,$(LIBCLI_WREPL_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_RESOLVE] PUBLIC_DEPENDENCIES = NDR_NBT LIBCLI_RESOLVE_OBJ_FILES = $(libclisrcdir)/resolve/resolve.o -$(call proto_header_template,$(libclisrcdir)/resolve/proto.h,$(LIBCLI_RESOLVE_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/resolve/proto.h,$(LIBCLI_RESOLVE_OBJ_FILES:.o=.c))) [SUBSYSTEM::LP_RESOLVE] PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF @@ -107,14 +107,14 @@ LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \ bcast.o nbtlist.o wins.o \ host.o resolve_lp.o) -$(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES)) +$(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES))) [SUBSYSTEM::LIBCLI_FINDDCS] PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING LIBCLI_FINDDCS_OBJ_FILES = $(libclisrcdir)/finddcs.o -$(call proto_header_template,$(libclisrcdir)/finddcs.h,$(LIBCLI_FINDDCS_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/finddcs.h,$(LIBCLI_FINDDCS_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_SMB] PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \ @@ -130,7 +130,7 @@ LIBCLI_SMB_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ climessage.o \ clideltree.o) -$(call proto_header_template,$(libclisrcdir)/libcli_proto.h,$(LIBCLI_SMB_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/libcli_proto.h,$(LIBCLI_SMB_OBJ_FILES:.o=.c))) # PUBLIC_HEADERS += $(libclisrcdir)/libcli.h @@ -146,6 +146,6 @@ LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o rawioctl.o rawacl.o rawdate.o rawlpq.o rawshadow.o) -$(call proto_header_template,$(libclisrcdir)/raw/raw_proto.h,$(LIBCLI_RAW_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/raw/raw_proto.h,$(LIBCLI_RAW_OBJ_FILES:.o=.c))) mkinclude smb2/config.mk diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index e761b80024..02678eed7a 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,7 @@ LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h -$(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) [SUBSYSTEM::LDAP_ENCODE] # FIXME PRIVATE_DEPENDENCIES = LIBLDB diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 2bea795c02..63e54fac8a 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -5,7 +5,7 @@ LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ security_token.o security_descriptor.o \ dom_sid.o access_check.o privilege.o sddl.o) -$(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c))) [PYTHON::swig_security] SWIG_FILE = security.i diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 1d0126dca8..ea41d5924e 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -7,4 +7,4 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ lock.o notify.o cancel.o keepalive.o break.o) -$(call proto_header_template,$(libclisrcdir)/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c))) -- cgit From 60ae8f06574c74261643f469e6be2a945fd90880 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:40:23 +0200 Subject: Fix a bunch of dependencies. (This used to be commit a63f458462d207d215a6e4ef8e480b0c8daedf6a) --- source4/libcli/config.mk | 2 +- source4/libcli/smb2/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 0b493de1ea..dbd05b57bc 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -107,7 +107,7 @@ LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \ bcast.o nbtlist.o wins.o \ host.o resolve_lp.o) -$(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES))) +$(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_FINDDCS] PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index ea41d5924e..e653fbac1c 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -7,4 +7,4 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ lock.o notify.o cancel.o keepalive.o break.o) -$(eval $(call proto_header_template,$(libclisrcdir)/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,$(libclisrcdir)/smb2/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c))) -- cgit From 66cbf7eb59ab4a29dca1d30850c9aeb35a598b3d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 May 2008 11:39:16 +1000 Subject: added mkdir to SMB2 proxy (This used to be commit 1323aab11fbf346e19c4cef227d727ddfcaa7d60) --- source4/libcli/smb_composite/smb2.c | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c index 7bce65fb27..7fccbe3a3c 100644 --- a/source4/libcli/smb_composite/smb2.c +++ b/source4/libcli/smb_composite/smb2.c @@ -120,3 +120,75 @@ NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io) return composite_wait_free(c); } + + + +/* + continue after the create in a composite mkdir + */ +static void continue_mkdir(struct smb2_request *req) +{ + struct composite_context *ctx = talloc_get_type(req->async.private_data, + struct composite_context); + struct smb2_tree *tree = req->tree; + struct smb2_create create_parm; + struct smb2_close close_parm; + NTSTATUS status; + + status = smb2_create_recv(req, ctx, &create_parm); + if (!NT_STATUS_IS_OK(status)) { + composite_error(ctx, status); + return; + } + + ZERO_STRUCT(close_parm); + close_parm.in.file.handle = create_parm.out.file.handle; + + req = smb2_close_send(tree, &close_parm); + composite_continue_smb2(ctx, req, continue_close, ctx); +} + +/* + composite SMB2 mkdir call +*/ +struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree, + union smb_mkdir *io) +{ + struct composite_context *ctx; + struct smb2_create create_parm; + struct smb2_request *req; + + ctx = composite_create(tree, tree->session->transport->socket->event.ctx); + if (ctx == NULL) return NULL; + + ZERO_STRUCT(create_parm); + + create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + create_parm.in.share_access = + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + create_parm.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + create_parm.in.create_disposition = NTCREATEX_DISP_CREATE; + create_parm.in.fname = io->mkdir.in.path; + if (create_parm.in.fname[0] == '\\') { + create_parm.in.fname++; + } + + req = smb2_create_send(tree, &create_parm); + + composite_continue_smb2(ctx, req, continue_mkdir, ctx); + + return ctx; +} + + +/* + composite mkdir call - sync interface +*/ +NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io) +{ + struct composite_context *c = smb2_composite_mkdir_send(tree, io); + return composite_wait_free(c); +} + -- cgit From e7d993b8b26e121ff37640825b4d2f2c4d6332bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 May 2008 13:05:08 +1000 Subject: added SMB2 proxying of rmdir (This used to be commit 1e0c24b2760f2a632333b51710cd9581f0cee851) --- source4/libcli/smb_composite/smb2.c | 74 ++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c index 7fccbe3a3c..84b4f66b61 100644 --- a/source4/libcli/smb_composite/smb2.c +++ b/source4/libcli/smb_composite/smb2.c @@ -98,7 +98,9 @@ struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree, NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| NTCREATEX_SHARE_ACCESS_WRITE; - create_parm.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + create_parm.in.create_options = + NTCREATEX_OPTIONS_DELETE_ON_CLOSE | + NTCREATEX_OPTIONS_NON_DIRECTORY_FILE; create_parm.in.fname = io->unlink.in.pattern; if (create_parm.in.fname[0] == '\\') { create_parm.in.fname++; @@ -192,3 +194,73 @@ NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io) return composite_wait_free(c); } + + +/* + continue after the create in a composite rmdir + */ +static void continue_rmdir(struct smb2_request *req) +{ + struct composite_context *ctx = talloc_get_type(req->async.private_data, + struct composite_context); + struct smb2_tree *tree = req->tree; + struct smb2_create create_parm; + struct smb2_close close_parm; + NTSTATUS status; + + status = smb2_create_recv(req, ctx, &create_parm); + if (!NT_STATUS_IS_OK(status)) { + composite_error(ctx, status); + return; + } + + ZERO_STRUCT(close_parm); + close_parm.in.file.handle = create_parm.out.file.handle; + + req = smb2_close_send(tree, &close_parm); + composite_continue_smb2(ctx, req, continue_close, ctx); +} + +/* + composite SMB2 rmdir call +*/ +struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree, + struct smb_rmdir *io) +{ + struct composite_context *ctx; + struct smb2_create create_parm; + struct smb2_request *req; + + ctx = composite_create(tree, tree->session->transport->socket->event.ctx); + if (ctx == NULL) return NULL; + + ZERO_STRUCT(create_parm); + create_parm.in.desired_access = SEC_STD_DELETE; + create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; + create_parm.in.share_access = + NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + create_parm.in.create_options = + NTCREATEX_OPTIONS_DIRECTORY | + NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + create_parm.in.fname = io->in.path; + if (create_parm.in.fname[0] == '\\') { + create_parm.in.fname++; + } + + req = smb2_create_send(tree, &create_parm); + + composite_continue_smb2(ctx, req, continue_rmdir, ctx); + return ctx; +} + + +/* + composite rmdir call - sync interface +*/ +NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io) +{ + struct composite_context *c = smb2_composite_rmdir_send(tree, io); + return composite_wait_free(c); +} -- cgit From 8052309d5a4d0d4b7c63806cfdba5e6dcc161461 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 May 2008 10:58:43 +1000 Subject: Add the core of the new CLDAP/NBT 'netlogon' parsing library. This uses some hand-adjusted PIDL output to cope with some 'oddities' in the parsing of the _EX varient of the netlogon packet. Andrew Bartlett (This used to be commit 6e357d00474de65395ca51524d3b85d00691baf2) --- source4/libcli/netlogon.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++ source4/libcli/netlogon.h | 53 ++++++++ 2 files changed, 364 insertions(+) create mode 100644 source4/libcli/netlogon.c create mode 100644 source4/libcli/netlogon.h (limited to 'source4/libcli') diff --git a/source4/libcli/netlogon.c b/source4/libcli/netlogon.c new file mode 100644 index 0000000000..3ef7cf6335 --- /dev/null +++ b/source4/libcli/netlogon.c @@ -0,0 +1,311 @@ +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +#include "includes.h" +#include "libcli/netlogon.h" + +_PUBLIC_ enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz)); + NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site)); + if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) { + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + { + struct ndr_push *_ndr_sockaddr; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + } + } + if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site)); + } + NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r, + uint32_t nt_version_flags) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ZERO_STRUCTP(r); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz)); + NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site)); + if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) { + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size)); + { + struct ndr_pull *_ndr_sockaddr; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size)); + NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size)); + } + } + if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site)); + } + NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version)); + if (r->nt_version != nt_version_flags) { + return NDR_ERR_VALIDATE; + } + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct netlogon_samlogon_response *response) +{ + enum ndr_err_code ndr_err; + if (response->ntver == NETLOGON_NT_VERSION_1) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt4, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40); + } else if (response->ntver & NETLOGON_NT_VERSION_5EX) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt5_ex, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags); + } else if (response->ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt5, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE); + } else { + DEBUG(0, ("Asked to push unknown netlogon response type 0x%02x\n", response->ntver)); + return NT_STATUS_INVALID_PARAMETER; + } + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(2,("failed to push netlogon response of type 0x%02x\n", + response->ntver)); + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} + +NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct netlogon_samlogon_response *response) +{ + uint32_t ntver; + enum ndr_err_code ndr_err; + + if (data->length < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* lmnttoken */ + if (SVAL(data->data, data->length - 4) != 0xffff) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + /* lm20token */ + if (SVAL(data->data, data->length - 2) != 0xffff) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + ntver = IVAL(data->data, data->length - 8); + + if (ntver == NETLOGON_NT_VERSION_1) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + iconv_convenience, + &response->nt4, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40); + response->ntver = NETLOGON_NT_VERSION_1; + } else if (ntver & NETLOGON_NT_VERSION_5EX) { + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(data, mem_ctx, iconv_convenience); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(ndr, NDR_SCALARS|NDR_BUFFERS, &response->nt5_ex, ntver); + if (ndr->offset < ndr->data_size) { + ndr_err = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES, + "not all bytes consumed ofs[%u] size[%u]", + ndr->offset, ndr->data_size); + } + response->ntver = NETLOGON_NT_VERSION_5EX; + + } else if (ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + iconv_convenience, + &response->nt5, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE); + response->ntver = NETLOGON_NT_VERSION_5; + } else { + DEBUG(2,("failed to parse netlogon response of type 0x%02x - unknown response type\n", + ntver)); + dump_data(10, data->data, data->length); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(2,("failed to parse netlogon response of type 0x%02x\n", + ntver)); + dump_data(10, data->data, data->length); + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} + +void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response) +{ + struct NETLOGON_SAM_LOGON_RESPONSE_EX response_5_ex; + switch (response->ntver) { + case NETLOGON_NT_VERSION_5EX: + break; + case NETLOGON_NT_VERSION_5: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->nt5.command; + response_5_ex.pdc_name = response->nt5.pdc_name; + response_5_ex.user_name = response->nt5.user_name; + response_5_ex.domain = response->nt5.domain_name; + response_5_ex.domain_uuid = response->nt5.domain_uuid; + response_5_ex.forest = response->nt5.forest; + response_5_ex.dns_domain = response->nt5.dns_domain; + response_5_ex.pdc_dns_name = response->nt5.pdc_dns_name; + response_5_ex.sockaddr.pdc_ip = response->nt5.pdc_ip; + response_5_ex.server_type = response->nt5.server_type; + response_5_ex.nt_version = response->nt5.nt_version; + response_5_ex.lmnt_token = response->nt5.lmnt_token; + response_5_ex.lm20_token = response->nt5.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->nt5_ex = response_5_ex; + break; + + case NETLOGON_NT_VERSION_1: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->nt4.command; + response_5_ex.pdc_name = response->nt4.server; + response_5_ex.user_name = response->nt4.user_name; + response_5_ex.domain = response->nt4.domain; + response_5_ex.nt_version = response->nt4.nt_version; + response_5_ex.lmnt_token = response->nt4.lmnt_token; + response_5_ex.lm20_token = response->nt4.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->nt5_ex = response_5_ex; + break; + } + return; +} + +NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct nbt_netlogon_response *response) +{ + NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE; + enum ndr_err_code ndr_err; + switch (response->response_type) { + case NETLOGON_GET_PDC: + ndr_err = ndr_push_struct_blob(data, mem_ctx, iconv_convenience, &response->get_pdc, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response_from_pdc); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data->length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data->data, data->length); + } + return status; + } + status = NT_STATUS_OK; + break; + case NETLOGON_SAMLOGON: + status = push_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon); + break; + } + return status; +} + + +NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct nbt_netlogon_response *response) +{ + NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE; + enum netlogon_command command; + enum ndr_err_code ndr_err; + if (data->length < 4) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + command = SVAL(data->data, 0); + + switch (command) { + case NETLOGON_RESPONSE_FROM_PDC: + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, iconv_convenience, &response->get_pdc, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response_from_pdc); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data->length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data->data, data->length); + } + return status; + } + status = NT_STATUS_OK; + response->response_type = NETLOGON_GET_PDC; + break; + case LOGON_SAM_LOGON_RESPONSE: + case LOGON_SAM_LOGON_PAUSE_RESPONSE: + case LOGON_SAM_LOGON_USER_UNKNOWN: + case LOGON_SAM_LOGON_RESPONSE_EX: + case LOGON_SAM_LOGON_PAUSE_RESPONSE_EX: + case LOGON_SAM_LOGON_USER_UNKNOWN_EX: + status = pull_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon); + response->response_type = NETLOGON_SAMLOGON; + break; + + /* These levels are queries, not responses */ + case LOGON_PRIMARY_QUERY: + case NETLOGON_ANNOUNCE_UAS: + case LOGON_SAM_LOGON_REQUEST: + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + return status; + +} diff --git a/source4/libcli/netlogon.h b/source4/libcli/netlogon.h new file mode 100644 index 0000000000..b8615b55a5 --- /dev/null +++ b/source4/libcli/netlogon.h @@ -0,0 +1,53 @@ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 2008 + + 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 3 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, see . +*/ + +#ifndef __LIBCLI_NETLOGON_H__ +#define __LIBCLI_NETLOGON_H__ + +#include "librpc/gen_ndr/ndr_nbt.h" + +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_svcctl.h" +#include "librpc/gen_ndr/ndr_samr.h" + +struct netlogon_samlogon_response +{ + uint32_t ntver; + union { + struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4; + struct NETLOGON_SAM_LOGON_RESPONSE nt5; + struct NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex; + }; + +}; + +struct nbt_netlogon_response +{ + enum {NETLOGON_GET_PDC, NETLOGON_SAMLOGON} response_type; + union { + struct nbt_netlogon_response_from_pdc get_pdc; + struct netlogon_samlogon_response samlogon; + }; +}; + +#include "libcli/netlogon_proto.h" +#endif /* __CLDAP_SERVER_PROTO_H__ */ -- cgit From e533e7a7ebc8b3029cf604e63cdc6d1cf8570ccd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 May 2008 11:24:38 +1000 Subject: Fix prototype generation in new syntax for netlogon.c Andrew Bartlett (This used to be commit b6f91ce75ae401bed515012fa3019a6241e7ff6d) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c8056dbe63..0cc97c058a 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -63,7 +63,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ netlogon.o) -$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i -- cgit From aa90730e0c2617c3d2ab477c3f08c26adb582b21 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 May 2008 11:54:50 +1000 Subject: Revert addition of 'mailslot' parameter. It turns out that the mailslot name (and a useful private prointer) is provided in the struct dgram_mailslot_handler. Andrew Bartlett (This used to be commit e17804b8857fdb3c182c5e886323b9d6c194c2ff) --- source4/libcli/dgram/dgramsocket.c | 2 +- source4/libcli/dgram/libdgram.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 2cdda654ef..06b7bd5771 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -88,7 +88,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, mailslot_name, src); + dgmslot->handler(dgmslot, packet, src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 51408d029e..e1209e7a54 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -70,7 +70,6 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, - const char *mailslot_name, struct socket_address *src); struct dgram_mailslot_handler { -- cgit From 9c6a35ad9ba9458fe9d3a73ba1f785a61305e2aa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 May 2008 11:57:43 +1000 Subject: remember the server time fields on negotiate. Needed for gentest (This used to be commit 7989ca861dcc700b52be3a47ea5ae8b03fbb9330) --- source4/libcli/smb2/connect.c | 3 +++ source4/libcli/smb2/smb2.h | 2 ++ 2 files changed, 5 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 867af14c92..eabfa410ad 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -101,6 +101,9 @@ static void continue_negprot(struct smb2_request *req) c->status = smb2_negprot_recv(req, c, &state->negprot); if (!composite_is_ok(c)) return; + transport->negotiate.system_time = state->negprot.out.system_time; + transport->negotiate.server_start_time = state->negprot.out.server_start_time; + state->session = smb2_session_init(transport, global_loadparm, state, true); if (composite_nomem(state->session, c)) return; diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 964dcf320c..b55da05e21 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -35,6 +35,8 @@ struct smb2_options { */ struct smb2_negotiate { DATA_BLOB secblob; + NTTIME system_time; + NTTIME server_start_time; }; /* this is the context for the smb2 transport layer */ -- cgit From 803c076450da4075c71faaba3f0882f0b8e6208a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 May 2008 11:58:04 +1000 Subject: added some SMB2 utility functions (This used to be commit 6a3b1cd6698faa460c6258bb41b4936e363f4387) --- source4/libcli/smb2/config.mk | 2 +- source4/libcli/smb2/util.c | 178 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/smb2/util.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index e653fbac1c..00b6305def 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -5,6 +5,6 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ transport.o request.o negprot.o session.o tcon.o \ create.o close.o connect.o getinfo.o write.o read.o \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ - lock.o notify.o cancel.o keepalive.o break.o) + lock.o notify.o cancel.o keepalive.o break.o util.o) $(eval $(call proto_header_template,$(libclisrcdir)/smb2/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c))) diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c new file mode 100644 index 0000000000..0fc03b48c5 --- /dev/null +++ b/source4/libcli/smb2/util.c @@ -0,0 +1,178 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client utility functions + + Copyright (C) Andrew Tridgell 2005 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" +#include "libcli/smb_composite/smb_composite.h" + +/* + simple close wrapper with SMB2 +*/ +NTSTATUS smb2_util_close(struct smb2_tree *tree, struct smb2_handle h) +{ + struct smb2_close c; + + ZERO_STRUCT(c); + c.in.file.handle = h; + + return smb2_close(tree, &c); +} + +/* + unlink a file with SMB2 +*/ +NTSTATUS smb2_util_unlink(struct smb2_tree *tree, const char *fname) +{ + union smb_unlink io; + + ZERO_STRUCT(io); + io.unlink.in.pattern = fname; + + return smb2_composite_unlink(tree, &io); +} + + +/* + rmdir with SMB2 +*/ +NTSTATUS smb2_util_rmdir(struct smb2_tree *tree, const char *dname) +{ + struct smb_rmdir io; + + ZERO_STRUCT(io); + io.in.path = dname; + + return smb2_composite_rmdir(tree, &io); +} + + +/* + mkdir with SMB2 +*/ +NTSTATUS smb2_util_mkdir(struct smb2_tree *tree, const char *dname) +{ + union smb_mkdir io; + + ZERO_STRUCT(io); + io.mkdir.level = RAW_MKDIR_MKDIR; + io.mkdir.in.path = dname; + + return smb2_composite_mkdir(tree, &io); +} + + + + +/* + recursively descend a tree deleting all files + returns the number of files deleted, or -1 on error +*/ +int smb2_deltree(struct smb2_tree *tree, const char *dname) +{ + NTSTATUS status; + uint32_t total_deleted = 0; + uint_t count, i; + union smb_search_data *list; + TALLOC_CTX *tmp_ctx = talloc_new(tree); + struct smb2_find f; + struct smb2_create create_parm; + + /* it might be a file */ + status = smb2_util_unlink(tree, dname); + if (NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return 1; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) || + NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) || + NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE)) { + talloc_free(tmp_ctx); + return 0; + } + + ZERO_STRUCT(create_parm); + create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + create_parm.in.share_access = + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; + create_parm.in.fname = dname; + + status = smb2_create(tree, tmp_ctx, &create_parm); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(2,("Failed to open %s - %s\n", dname, nt_errstr(status))); + talloc_free(tmp_ctx); + return -1; + } + + + ZERO_STRUCT(f); + f.in.file.handle = create_parm.out.file.handle; + f.in.max_response_size = 0x10000; + f.in.level = SMB2_FIND_NAME_INFO; + f.in.pattern = "*"; + + status = smb2_find_level(tree, tmp_ctx, &f, &count, &list); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(2,("Failed to list %s - %s\n", + dname, nt_errstr(status))); + smb2_util_close(tree, create_parm.out.file.handle); + talloc_free(tmp_ctx); + return -1; + } + + for (i=0;i 0) total_deleted += ret; + } + talloc_free(name); + if (NT_STATUS_IS_OK(status)) { + total_deleted++; + } + } + + smb2_util_close(tree, create_parm.out.file.handle); + + status = smb2_util_rmdir(tree, dname); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(2,("Failed to delete %s - %s\n", + dname, nt_errstr(status))); + talloc_free(tmp_ctx); + return -1; + } + + talloc_free(tmp_ctx); + + return total_deleted; +} -- cgit From d6f1dd1a422cc2b5d443e82693021e93dc98fe75 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 May 2008 13:37:27 +1000 Subject: added SMB2 setpathinfo composite wrapper (This used to be commit e90c7587385598a1dd976c2420798f9bd682b43d) --- source4/libcli/smb_composite/smb2.c | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c index 84b4f66b61..6e005e03c0 100644 --- a/source4/libcli/smb_composite/smb2.c +++ b/source4/libcli/smb_composite/smb2.c @@ -264,3 +264,108 @@ NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io) struct composite_context *c = smb2_composite_rmdir_send(tree, io); return composite_wait_free(c); } + + +/* + continue after the setfileinfo in a composite setpathinfo + */ +static void continue_setpathinfo_close(struct smb2_request *req) +{ + struct composite_context *ctx = talloc_get_type(req->async.private_data, + struct composite_context); + struct smb2_tree *tree = req->tree; + struct smb2_close close_parm; + NTSTATUS status; + union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, + union smb_setfileinfo); + + status = smb2_setinfo_recv(req); + if (!NT_STATUS_IS_OK(status)) { + composite_error(ctx, status); + return; + } + + ZERO_STRUCT(close_parm); + close_parm.in.file.handle = io2->generic.in.file.handle; + + req = smb2_close_send(tree, &close_parm); + composite_continue_smb2(ctx, req, continue_close, ctx); +} + + +/* + continue after the create in a composite setpathinfo + */ +static void continue_setpathinfo(struct smb2_request *req) +{ + struct composite_context *ctx = talloc_get_type(req->async.private_data, + struct composite_context); + struct smb2_tree *tree = req->tree; + struct smb2_create create_parm; + NTSTATUS status; + union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, + union smb_setfileinfo); + + status = smb2_create_recv(req, ctx, &create_parm); + if (!NT_STATUS_IS_OK(status)) { + composite_error(ctx, status); + return; + } + + io2->generic.in.file.handle = create_parm.out.file.handle; + + req = smb2_setinfo_file_send(tree, io2); + composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx); +} + + +/* + composite SMB2 setpathinfo call +*/ +struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree, + union smb_setfileinfo *io) +{ + struct composite_context *ctx; + struct smb2_create create_parm; + struct smb2_request *req; + union smb_setfileinfo *io2; + + ctx = composite_create(tree, tree->session->transport->socket->event.ctx); + if (ctx == NULL) return NULL; + + ZERO_STRUCT(create_parm); + create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; + create_parm.in.share_access = + NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + create_parm.in.create_options = 0; + create_parm.in.fname = io->generic.in.file.path; + if (create_parm.in.fname[0] == '\\') { + create_parm.in.fname++; + } + + req = smb2_create_send(tree, &create_parm); + + io2 = talloc(ctx, union smb_setfileinfo); + if (composite_nomem(io2, ctx)) { + return ctx; + } + *io2 = *io; + + ctx->private_data = io2; + + composite_continue_smb2(ctx, req, continue_setpathinfo, ctx); + return ctx; +} + + +/* + composite setpathinfo call + */ +NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io) +{ + struct composite_context *c = smb2_composite_setpathinfo_send(tree, io); + return composite_wait_free(c); +} -- cgit From 2214e6d9bfdc52db0558e831691b4500405ab9ae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 May 2008 13:37:51 +1000 Subject: added smb2_util_setatr (This used to be commit d4f41db964ce82c8889017d0f932d60100b3cd32) --- source4/libcli/smb2/util.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c index 0fc03b48c5..9eb344e83f 100644 --- a/source4/libcli/smb2/util.c +++ b/source4/libcli/smb2/util.c @@ -82,6 +82,22 @@ NTSTATUS smb2_util_mkdir(struct smb2_tree *tree, const char *dname) } +/* + set file attribute with SMB2 +*/ +NTSTATUS smb2_util_setatr(struct smb2_tree *tree, const char *name, uint32_t attrib) +{ + union smb_setfileinfo io; + + ZERO_STRUCT(io); + io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; + io.basic_info.in.file.path = name; + io.basic_info.in.attrib = attrib; + + return smb2_composite_setpathinfo(tree, &io); +} + + /* @@ -151,6 +167,12 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname) } name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s); status = smb2_util_unlink(tree, name); + if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { + /* it could be read-only */ + status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL); + status = smb2_util_unlink(tree, name); + } + if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { int ret; ret = smb2_deltree(tree, name); -- cgit From 2f5a1d2b1cfdbfc3d4c7c1e96d1ed061e7970f88 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 May 2008 14:26:38 +1000 Subject: Manually handle the NETLOGON_SAM_LOGON_REQUEST too. With the sid structure being both optional and aligned, it was too hard to do this in just IDL. This requried moving some things around, as otherwise we would have a dependency loop. Andrew Bartlett (This used to be commit e28790ba4884277f310be1b8bd3fba4fd47dbbdb) --- source4/libcli/config.mk | 12 ++- source4/libcli/ndr_netlogon.c | 209 ++++++++++++++++++++++++++++++++++++++++++ source4/libcli/netlogon.c | 112 ++++------------------ source4/libcli/netlogon.h | 1 + 4 files changed, 240 insertions(+), 94 deletions(-) create mode 100644 source4/libcli/ndr_netlogon.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index f502091b07..16e23430d7 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -57,9 +57,17 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ $(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c))) +[SUBSYSTEM::LIBCLI_NDR_NETLOGON] +PUBLIC_DEPENDENCIES = LIBNDR \ + NDR_SECURITY + +LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ + ndr_netlogon.o) + +$(eval $(call proto_header_template,$(libclisrcdir)/ndr_netlogon_proto.h,$(LIBCLI_NDR_NETLOGON_OBJ_FILES:.o=.c))) + [SUBSYSTEM::LIBCLI_NETLOGON] -PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ - NDR_SECURITY LIBSAMBA-UTIL +PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL LIBCLI_NDR_NETLOGON LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ netlogon.o) diff --git a/source4/libcli/ndr_netlogon.c b/source4/libcli/ndr_netlogon.c new file mode 100644 index 0000000000..504b3b02a7 --- /dev/null +++ b/source4/libcli/ndr_netlogon.c @@ -0,0 +1,209 @@ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 2008 + + 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 3 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, see . +*/ + +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +#include "includes.h" +#include "libcli/netlogon.h" +/* Manually modified to handle the dom_sid being optional based on if it is present or all zero */ +enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_REQUEST *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->request_count)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->computer_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->user_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->mailslot_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_samr_AcctFlags(ndr, NDR_SCALARS, r->acct_control)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_dom_sid0(&r->sid, ndr->flags))); + if (ndr_size_dom_sid0(&r->sid, ndr->flags)) { + struct ndr_push *_ndr_sid; + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags))); + NDR_CHECK(ndr_push_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags))); + } + NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +/* Manually modified to handle the dom_sid being optional based on if it is present (size is non-zero) or not */ +enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_REQUEST *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->request_count)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->computer_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->user_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->mailslot_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_samr_AcctFlags(ndr, NDR_SCALARS, &r->acct_control)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sid_size)); + if (r->sid_size) { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + struct ndr_pull *_ndr_sid; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sid, 0, r->sid_size)); + NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sid, 0, r->sid_size)); + } else { + ZERO_STRUCT(r->sid); + } + NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +/* Manually modified to only push some parts of the structure if certain flags are set */ +enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz)); + NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site)); + if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) { + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + { + struct ndr_push *_ndr_sockaddr; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + } + } + if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site)); + } + NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +/* Manually modified to only pull some parts of the structure if certain flags provided */ +enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r, + uint32_t nt_version_flags) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ZERO_STRUCTP(r); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz)); + NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site)); + if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) { + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size)); + { + struct ndr_pull *_ndr_sockaddr; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size)); + NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size)); + } + } + if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site)); + } + NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version)); + if (r->nt_version != nt_version_flags) { + return NDR_ERR_VALIDATE; + } + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} diff --git a/source4/libcli/netlogon.c b/source4/libcli/netlogon.c index 3ef7cf6335..052d7cbc1e 100644 --- a/source4/libcli/netlogon.c +++ b/source4/libcli/netlogon.c @@ -1,99 +1,27 @@ -/* parser auto-generated by pidl, then hand-modified by abartlet */ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 2008 + + 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 3 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, see . +*/ #include "includes.h" #include "libcli/netlogon.h" -_PUBLIC_ enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r) -{ - { - uint32_t _flags_save_STRUCT = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz)); - NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type)); - NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site)); - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site)); - if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) { - NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); - { - struct ndr_push *_ndr_sockaddr; - NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); - NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); - NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); - } - } - if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { - NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site)); - } - NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token)); - } - if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); - } - ndr->flags = _flags_save_STRUCT; - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r, - uint32_t nt_version_flags) -{ - { - uint32_t _flags_save_STRUCT = ndr->flags; - ZERO_STRUCTP(r); - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command)); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz)); - NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type)); - NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site)); - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site)); - if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) { - NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size)); - { - struct ndr_pull *_ndr_sockaddr; - NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size)); - NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); - NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size)); - } - } - if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { - NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site)); - } - NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version)); - if (r->nt_version != nt_version_flags) { - return NDR_ERR_VALIDATE; - } - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token)); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token)); - } - if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); - } - ndr->flags = _flags_save_STRUCT; - } - return NDR_ERR_SUCCESS; -} - NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, struct netlogon_samlogon_response *response) diff --git a/source4/libcli/netlogon.h b/source4/libcli/netlogon.h index b8615b55a5..177ed3a514 100644 --- a/source4/libcli/netlogon.h +++ b/source4/libcli/netlogon.h @@ -50,4 +50,5 @@ struct nbt_netlogon_response }; #include "libcli/netlogon_proto.h" +#include "libcli/ndr_netlogon_proto.h" #endif /* __CLDAP_SERVER_PROTO_H__ */ -- cgit From 4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 May 2008 22:12:20 +1000 Subject: fixed SMB2 locking - SMB2 locking is different in several ways from SMB locking. To fix it properly we will need a new generic mapping structure for locking, but for now do a best effort mapping - added locking to gentest_smb2 (This used to be commit ea6d9cf602302adafe0f9d5f5f90a9b26d1ead6f) --- source4/libcli/raw/interfaces.h | 28 +++++++++++++++------------- source4/libcli/smb2/lock.c | 24 ++++++++++++++++-------- 2 files changed, 31 insertions(+), 21 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 871bab01db..149b91916a 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1866,13 +1866,12 @@ enum smb_lock_level { RAW_LOCK_SMB2_BREAK }; -/* the generic interface is defined to be equal to the lockingX interface */ -#define RAW_LOCK_GENERIC RAW_LOCK_LOCKX +#define RAW_LOCK_GENERIC RAW_LOCK_LOCKX /* union for lock() backend call */ union smb_lock { - /* SMBlockingX (and generic) interface */ + /* SMBlockingX and generic interface */ struct { enum smb_lock_level level; struct { @@ -1887,7 +1886,7 @@ union smb_lock { uint64_t count; } *locks; /* unlocks are first in the arrray */ } in; - } lockx, generic; + } generic, lockx; /* SMBlock and SMBunlock interface */ struct { @@ -1907,23 +1906,26 @@ union smb_lock { /* static body buffer 48 (0x30) bytes */ /* uint16_t buffer_code; 0x30 */ - uint16_t unknown1; /* must be 0x0001 */ - uint32_t unknown2; + uint16_t lock_count; + uint32_t reserved; /* struct smb2_handle handle; */ - uint64_t offset; - uint64_t count; - uint32_t unknown5; + struct smb2_lock_element { + uint64_t offset; + uint64_t length; +/* these flags are the same as the SMB2 lock flags */ #define SMB2_LOCK_FLAG_NONE 0x00000000 #define SMB2_LOCK_FLAG_SHARED 0x00000001 -#define SMB2_LOCK_FLAG_EXCLUSIV 0x00000002 +#define SMB2_LOCK_FLAG_EXCLUSIVE 0x00000002 #define SMB2_LOCK_FLAG_UNLOCK 0x00000004 -#define SMB2_LOCK_FLAG_NO_PENDING 0x00000010 - uint32_t flags; +#define SMB2_LOCK_FLAG_FAIL_IMMEDIATELY 0x00000010 + uint32_t flags; + uint32_t reserved; + } *locks; } in; struct { /* static body buffer 4 (0x04) bytes */ /* uint16_t buffer_code; 0x04 */ - uint16_t unknown1; + uint16_t reserved; } out; } smb2; diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c index d71a337d56..62c6e5dba7 100644 --- a/source4/libcli/smb2/lock.c +++ b/source4/libcli/smb2/lock.c @@ -29,17 +29,25 @@ struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io) { struct smb2_request *req; + int i; - req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, false, 0); + req = smb2_request_init_tree(tree, SMB2_OP_LOCK, + 24 + io->in.lock_count*24, false, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, io->in.unknown1); - SIVAL(req->out.body, 0x04, io->in.unknown2); + /* this is quite bizarre - the spec says we must lie about the length! */ + SSVAL(req->out.body, 0, 0x30); + + SSVAL(req->out.body, 0x02, io->in.lock_count); + SIVAL(req->out.body, 0x04, io->in.reserved); smb2_push_handle(req->out.body+0x08, &io->in.file.handle); - SBVAL(req->out.body, 0x18, io->in.offset); - SBVAL(req->out.body, 0x20, io->in.count); - SIVAL(req->out.body, 0x24, io->in.unknown5); - SIVAL(req->out.body, 0x28, io->in.flags); + + for (i=0;iin.lock_count;i++) { + SBVAL(req->out.body, 0x18 + i*24, io->in.locks[i].offset); + SBVAL(req->out.body, 0x20 + i*24, io->in.locks[i].length); + SIVAL(req->out.body, 0x28 + i*24, io->in.locks[i].flags); + SIVAL(req->out.body, 0x2C + i*24, io->in.locks[i].reserved); + } smb2_transport_send(req); @@ -59,7 +67,7 @@ NTSTATUS smb2_lock_recv(struct smb2_request *req, struct smb2_lock *io) SMB2_CHECK_PACKET_RECV(req, 0x04, false); - io->out.unknown1 = SVAL(req->in.body, 0x02); + io->out.reserved = SVAL(req->in.body, 0x02); return smb2_request_destroy(req); } -- cgit From 721332411aac09b096f6add77c7c59c0a300ba1c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 14:29:05 +0200 Subject: Regenerate with newer version of swig. (This used to be commit 034c68bea934db87bce13a750c17fb1bd2bbe3b6) --- source4/libcli/swig/libcli_nbt.py | 2 +- source4/libcli/swig/libcli_nbt_wrap.c | 73 ++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/swig/libcli_nbt.py b/source4/libcli/swig/libcli_nbt.py index b49e240bc2..a26aa6092e 100644 --- a/source4/libcli/swig/libcli_nbt.py +++ b/source4/libcli/swig/libcli_nbt.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c index e0bdb27cfc..2deec98cb5 100644 --- a/source4/libcli/swig/libcli_nbt_wrap.c +++ b/source4/libcli/swig/libcli_nbt_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2507,7 +2525,7 @@ static swig_module_info swig_module = {swig_types, 18, 0, 0, 0, 0}; #define SWIG_name "_libcli_nbt" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -3134,7 +3152,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject struct nbt_name *result = 0 ; if (!SWIG_Python_UnpackTuple(args,"new_nbt_name",0,0,0)) SWIG_fail; - result = (struct nbt_name *)(struct nbt_name *) calloc(1, sizeof(struct nbt_name)); + result = (struct nbt_name *)calloc(1, sizeof(struct nbt_name)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, SWIG_POINTER_NEW | 0 ); return resultobj; fail: @@ -3227,7 +3245,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), Py struct nbt_name_query *result = 0 ; if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query",0,0,0)) SWIG_fail; - result = (struct nbt_name_query *)(struct nbt_name_query *) calloc(1, sizeof(struct nbt_name_query)); + result = (struct nbt_name_query *)calloc(1, sizeof(struct nbt_name_query)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query, SWIG_POINTER_NEW | 0 ); return resultobj; fail: @@ -3493,7 +3511,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self) nbt_name_query_out *result = 0 ; if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_out",0,0,0)) SWIG_fail; - result = (nbt_name_query_out *)(nbt_name_query_out *) calloc(1, sizeof(nbt_name_query_out)); + result = (nbt_name_query_out *)calloc(1, sizeof(nbt_name_query_out)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_NEW | 0 ); return resultobj; fail: @@ -3865,7 +3883,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self), nbt_name_query_in *result = 0 ; if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_in",0,0,0)) SWIG_fail; - result = (nbt_name_query_in *)(nbt_name_query_in *) calloc(1, sizeof(nbt_name_query_in)); + result = (nbt_name_query_in *)calloc(1, sizeof(nbt_name_query_in)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_NEW | 0 ); return resultobj; fail: @@ -4280,7 +4298,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -4290,6 +4308,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -4318,6 +4339,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); -- cgit From aed93a238e13247945073921d91408c91ae210c3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 May 2008 22:51:21 +1000 Subject: fixed SMB2 flush call, and added flush to gentest_smb2 (This used to be commit c52fe1fe1c77636d87355d3c4baa66e052fe9008) --- source4/libcli/raw/interfaces.h | 6 +++++- source4/libcli/smb2/flush.c | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 149b91916a..3370021d48 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2156,8 +2156,12 @@ union smb_flush { enum smb_flush_level level; struct { union smb_handle file; - uint32_t unknown; + uint16_t reserved1; + uint32_t reserved2; } in; + struct { + uint16_t reserved; + } out; } smb2; }; diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c index 116068ed6e..577d1ba1ba 100644 --- a/source4/libcli/smb2/flush.c +++ b/source4/libcli/smb2/flush.c @@ -33,8 +33,8 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush * req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, false, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, 0); /* pad? */ - SIVAL(req->out.body, 0x04, io->in.unknown); + SSVAL(req->out.body, 0x02, io->in.reserved1); + SIVAL(req->out.body, 0x04, io->in.reserved2); smb2_push_handle(req->out.body+0x08, &io->in.file.handle); smb2_transport_send(req); @@ -55,6 +55,8 @@ NTSTATUS smb2_flush_recv(struct smb2_request *req, struct smb2_flush *io) SMB2_CHECK_PACKET_RECV(req, 0x04, false); + io->out.reserved = SVAL(req->in.body, 0x02); + return smb2_request_destroy(req); } -- cgit From 2914b0ca04355f6f175b603a1de6030b20ce0830 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 21:24:48 +0200 Subject: Remove support for .py files from smb_build - deal with it only in the makefiles. (This used to be commit b865249efaa58d0fc87fa25491fda3b970af81c3) --- source4/libcli/config.mk | 4 ++++ source4/libcli/security/config.mk | 2 ++ 2 files changed, 6 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 16e23430d7..d7e4e143c0 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -80,12 +80,16 @@ PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o +$(eval $(call python_py_module_template,libcli_nbt.py,$(libclisrcdir)/swig/libcli_nbt.py)) + [PYTHON::python_libcli_smb] SWIG_FILE = swig/libcli_smb.i PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o +$(eval $(call python_py_module_template,libcli_smb.py,$(libclisrcdir)/swig/libcli_smb.py)) + [SUBSYSTEM::LIBCLI_DGRAM] PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 63e54fac8a..9f704e9592 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -12,3 +12,5 @@ SWIG_FILE = security.i PRIVATE_DEPENDENCIES = LIBSECURITY swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o + +$(eval $(call python_py_module_template,security.py,$(libclisrcdir)/security/security.py)) -- cgit From 82bcf967b79321706cd19c759ea54c4465fe0d96 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 21:32:53 +0200 Subject: Move CFLAGS overrides for SWIG modules to Makefile. (This used to be commit 58665a8a8e4b10435aebbf2c95b6a8e50db232d6) --- source4/libcli/config.mk | 5 +++++ source4/libcli/security/config.mk | 2 ++ 2 files changed, 7 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index d7e4e143c0..54a5e48e73 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -82,6 +82,8 @@ python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o $(eval $(call python_py_module_template,libcli_nbt.py,$(libclisrcdir)/swig/libcli_nbt.py)) +$(python_libcli_nbt_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" + [PYTHON::python_libcli_smb] SWIG_FILE = swig/libcli_smb.i PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG @@ -90,6 +92,9 @@ python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o $(eval $(call python_py_module_template,libcli_smb.py,$(libclisrcdir)/swig/libcli_smb.py)) +$(python_libcli_smb_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" + + [SUBSYSTEM::LIBCLI_DGRAM] PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 9f704e9592..4d46734059 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -14,3 +14,5 @@ PRIVATE_DEPENDENCIES = LIBSECURITY swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o $(eval $(call python_py_module_template,security.py,$(libclisrcdir)/security/security.py)) + +$(swig_security_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" -- cgit From b1fc7bab111fcef7f546e821f24c175bdec6865a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 21:50:56 +0200 Subject: Move some python files into the samba package. (This used to be commit ed38c668cdbe10966e46bad97301122eea8001d0) --- source4/libcli/config.mk | 4 ++-- source4/libcli/security/config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 54a5e48e73..e1955876a1 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -80,7 +80,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o -$(eval $(call python_py_module_template,libcli_nbt.py,$(libclisrcdir)/swig/libcli_nbt.py)) +$(eval $(call python_py_module_template,samba/nbt.py,$(libclisrcdir)/swig/libcli_nbt.py)) $(python_libcli_nbt_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" @@ -90,7 +90,7 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o -$(eval $(call python_py_module_template,libcli_smb.py,$(libclisrcdir)/swig/libcli_smb.py)) +$(eval $(call python_py_module_template,samba/smb.py,$(libclisrcdir)/swig/libcli_smb.py)) $(python_libcli_smb_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 4d46734059..2645f99bc6 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -13,6 +13,6 @@ PRIVATE_DEPENDENCIES = LIBSECURITY swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o -$(eval $(call python_py_module_template,security.py,$(libclisrcdir)/security/security.py)) +$(eval $(call python_py_module_template,samba/security.py,$(libclisrcdir)/security/security.py)) $(swig_security_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" -- cgit From 49706ab19bd3ffd6125639e6a7753b2350cf54e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 23:59:34 +0200 Subject: Move more modules inside of the samba package. (This used to be commit 9b39e99f48266a54ed0b8890c2efde218b4b118a) --- source4/libcli/config.mk | 4 ++-- source4/libcli/security/config.mk | 2 +- source4/libcli/security/tests/bindings.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index e1955876a1..ee8d6b27e2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -75,7 +75,7 @@ LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ $(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) [PYTHON::python_libcli_nbt] -SWIG_FILE = swig/libcli_nbt.i +LIBRARY_REALNAME = samba/_libcli_nbt.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o @@ -85,7 +85,7 @@ $(eval $(call python_py_module_template,samba/nbt.py,$(libclisrcdir)/swig/libcli $(python_libcli_nbt_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" [PYTHON::python_libcli_smb] -SWIG_FILE = swig/libcli_smb.i +LIBRARY_REALNAME = samba/_libcli_smb.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 2645f99bc6..82fe8f1278 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -8,7 +8,7 @@ LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ $(eval $(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c))) [PYTHON::swig_security] -SWIG_FILE = security.i +LIBRARY_REALNAME = samba/_security.$(SHLIBEXT) PRIVATE_DEPENDENCIES = LIBSECURITY swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o diff --git a/source4/libcli/security/tests/bindings.py b/source4/libcli/security/tests/bindings.py index 59a5e69640..82ce7aeba8 100644 --- a/source4/libcli/security/tests/bindings.py +++ b/source4/libcli/security/tests/bindings.py @@ -18,7 +18,7 @@ # import unittest -import security +from samba import security class SecurityTokenTests(unittest.TestCase): def setUp(self): -- cgit From 5ce59419a07c8e147daf51b77ffe2117f3d6a505 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 02:13:26 +0200 Subject: Fix CFLAGS for SWIG files. (This used to be commit 8ee4f075046e0b181ec8a4ac1eaf3ea5621a56bf) --- source4/libcli/config.mk | 4 ++-- source4/libcli/security/config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index ee8d6b27e2..b24f3eb4af 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -82,7 +82,7 @@ python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o $(eval $(call python_py_module_template,samba/nbt.py,$(libclisrcdir)/swig/libcli_nbt.py)) -$(python_libcli_nbt_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" +$(python_libcli_nbt_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) [PYTHON::python_libcli_smb] LIBRARY_REALNAME = samba/_libcli_smb.$(SHLIBEXT) @@ -92,7 +92,7 @@ python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o $(eval $(call python_py_module_template,samba/smb.py,$(libclisrcdir)/swig/libcli_smb.py)) -$(python_libcli_smb_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" +$(python_libcli_smb_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) [SUBSYSTEM::LIBCLI_DGRAM] diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index 82fe8f1278..f2883d1ede 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -15,4 +15,4 @@ swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o $(eval $(call python_py_module_template,samba/security.py,$(libclisrcdir)/security/security.py)) -$(swig_security_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" +$(swig_security_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) -- cgit From dec930448f957aca7e70e975221a2ac060819b2e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 14:49:21 +1000 Subject: fixed parsing of the SMB2 ALL_INFO qfileinfo level (This used to be commit a7be5ba22e0cf2c61501f5a05e64673f31ba145c) --- source4/libcli/raw/interfaces.h | 3 ++- source4/libcli/raw/rawfileinfo.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 3370021d48..bae0e67b02 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -684,7 +684,8 @@ union smb_fileinfo { uint32_t ea_size; uint32_t access_mask; uint64_t position; - uint64_t mode; + uint32_t mode; + uint32_t alignment_requirement; struct smb_wire_string fname; } out; } all_info2; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 71900be49c..0ea5a93606 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -243,7 +243,8 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->all_info2.out.ea_size = IVAL(blob->data, 0x48); parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C); parms->all_info2.out.position = BVAL(blob->data, 0x50); - parms->all_info2.out.mode = BVAL(blob->data, 0x58); + parms->all_info2.out.mode = IVAL(blob->data, 0x58); + parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C); smbcli_blob_pull_string(NULL, mem_ctx, blob, &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE); return NT_STATUS_OK; -- cgit From a6e5c70da75e62c84eff0911c279c6a9b0b00b45 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 17:54:06 +1000 Subject: added a define for all valid file attributes (This used to be commit 198ed9336756f973cebd7cc3df7f51e2c4575205) --- source4/libcli/raw/smb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index e054ed6522..74869e8a45 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -370,6 +370,7 @@ #define FILE_ATTRIBUTE_OFFLINE 0x1000 #define FILE_ATTRIBUTE_NONINDEXED 0x2000 #define FILE_ATTRIBUTE_ENCRYPTED 0x4000 +#define FILE_ATTRIBUTE_ALL_MASK 0x7FFF /* Flags - combined with attributes. */ #define FILE_FLAG_WRITE_THROUGH 0x80000000L -- cgit From d5def936fe67c1cde2c4ed00834c4ce325dfcb55 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 22:46:29 +1000 Subject: pass in the required alignment to the EA construction routines (This used to be commit af31030e0b78b6b220740529901ec8d2d9f5a3fe) --- source4/libcli/raw/raweas.c | 9 +++++---- source4/libcli/raw/rawfile.c | 4 ++-- source4/libcli/smb2/create.c | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 8ea8e621c9..07b517ade3 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -54,13 +54,13 @@ static uint_t ea_name_list_size(uint_t num_names, struct ea_name *eas) This assumes the names are strict ascii, which should be a reasonable assumption */ -size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas) +size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas, unsigned alignment) { uint_t total = 0; int i; for (i=0;intcreatex.in.ea_list) { uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas, - parms->ntcreatex.in.ea_list->eas); + parms->ntcreatex.in.ea_list->eas, 4); ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size); if (ea_blob.data == NULL) { return NULL; } ea_put_list_chained(ea_blob.data, parms->ntcreatex.in.ea_list->num_eas, - parms->ntcreatex.in.ea_list->eas); + parms->ntcreatex.in.ea_list->eas, 4); } nt.in.params = data_blob_talloc(mem_ctx, NULL, 53); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 6ac32a494f..9d28bbf8c4 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -117,8 +117,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create if (io->in.eas.num_eas != 0) { DATA_BLOB b = data_blob_talloc(req, NULL, - ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); - ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); + ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 8)); + ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 8); status = smb2_create_blob_add(req, &io->in.blobs, SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { -- cgit From ec7a6ee8ab25f4550a68b286d9eba32b955a73a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 May 2008 00:07:12 +1000 Subject: fix make test for EAs again - go back to 4 byte alignment until I work out the rules that Vista wants more exactly - add the zero sized EA handling for SMB2 more generically (This used to be commit 326b69bc8064cbea357864cecd6bd27b50c57184) --- source4/libcli/smb2/create.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 9d28bbf8c4..b1b8b0ccfa 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -117,8 +117,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create if (io->in.eas.num_eas != 0) { DATA_BLOB b = data_blob_talloc(req, NULL, - ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 8)); - ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 8); + ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4)); + ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4); status = smb2_create_blob_add(req, &io->in.blobs, SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { -- cgit From a46450810b7d41dc11b1d35807307d9b19e68682 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 03:22:56 +0200 Subject: Regenerate with SWIG 1.3.35. (This used to be commit ce063eca498036937f99161a1f12e076c2ab313f) --- source4/libcli/security/security.py | 2 +- source4/libcli/security/security_wrap.c | 65 +++++++++++++++++++++++---------- source4/libcli/swig/libcli_smb.py | 2 +- source4/libcli/swig/libcli_smb_wrap.c | 65 +++++++++++++++++++++++---------- 4 files changed, 94 insertions(+), 40 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py index 10b263b27b..7e56e22cef 100644 --- a/source4/libcli/security/security.py +++ b/source4/libcli/security/security.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index eb9e4c45d9..aabf6c27ee 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2503,7 +2521,7 @@ static swig_module_info swig_module = {swig_types, 14, 0, 0, 0, 0}; #define SWIG_name "_security" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -3674,7 +3692,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -3684,6 +3702,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -3712,6 +3733,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); diff --git a/source4/libcli/swig/libcli_smb.py b/source4/libcli/swig/libcli_smb.py index 80c4040237..6e4fe036c7 100644 --- a/source4/libcli/swig/libcli_smb.py +++ b/source4/libcli/swig/libcli_smb.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/libcli/swig/libcli_smb_wrap.c b/source4/libcli/swig/libcli_smb_wrap.c index 8b71f2c3be..de8e6ba1e4 100644 --- a/source4/libcli/swig/libcli_smb_wrap.c +++ b/source4/libcli/swig/libcli_smb_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2495,7 +2513,7 @@ static swig_module_info swig_module = {swig_types, 6, 0, 0, 0, 0}; #define SWIG_name "_libcli_smb" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -2769,7 +2787,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -2779,6 +2797,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -2807,6 +2828,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); -- cgit From 73b789b6d25698dba15c867c71d0cdd8c264f352 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 04:01:57 +0200 Subject: Add docstrings to a couple more python modules. (This used to be commit b4560c90e5e8d3a35367d3a21d361dc4c9c0de23) --- source4/libcli/security/security.i | 13 ++++++++++- source4/libcli/security/security.py | 40 ++++++++++++++++++++++++++++++++- source4/libcli/security/security_wrap.c | 25 ++++++++++++++++----- 3 files changed, 71 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i index 647c9aea09..1d964cc3d5 100644 --- a/source4/libcli/security/security.i +++ b/source4/libcli/security/security.i @@ -16,7 +16,7 @@ along with this program. If not, see . */ -%module(package="samba.security") security +%module(docstring="Security-related classes.",package="samba.security") security %{ #include "includes.h" @@ -65,8 +65,14 @@ enum sec_privilege { typedef struct security_token { %extend { security_token(TALLOC_CTX *mem_ctx) { return security_token_initialise(mem_ctx); } + %feature("docstring") is_sid "S.is_sid(sid) -> bool\n" \ + "Check whether this token is of the specified SID."; bool is_sid(const struct dom_sid *sid); + %feature("docstring") is_system "S.is_system() -> bool\n" \ + "Check whether this is a system token."; bool is_system(); + %feature("docstring") is_anonymous "S.is_anonymus() -> bool\n" \ + "Check whether this is an anonymous token."; bool is_anonymous(); bool has_sid(const struct dom_sid *sid); bool has_builtin_administrators(); @@ -81,6 +87,8 @@ typedef struct security_token { typedef struct security_descriptor { %extend { security_descriptor(TALLOC_CTX *mem_ctx) { return security_descriptor_initialise(mem_ctx); } + %feature("docstring") sacl_add "S.sacl_add(ace) -> None\n" \ + "Add a security ace to this security descriptor"; NTSTATUS sacl_add(const struct security_ace *ace); NTSTATUS dacl_add(const struct security_ace *ace); NTSTATUS dacl_del(const struct dom_sid *trustee); @@ -111,6 +119,9 @@ typedef struct dom_sid { } } dom_sid; +%feature("docstring") random_sid "random_sid() -> sid\n" \ + "Generate a random SID"; + %inline %{ static struct dom_sid *random_sid(TALLOC_CTX *mem_ctx) { diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py index 7e56e22cef..065c7a19e4 100644 --- a/source4/libcli/security/security.py +++ b/source4/libcli/security/security.py @@ -3,6 +3,10 @@ # # Don't modify this file, modify the SWIG interface instead. +""" +Security-related classes. +""" + import _security import new new_instancemethod = new.instancemethod @@ -86,6 +90,27 @@ class SecurityToken(object): __repr__ = _swig_repr def __init__(self, *args, **kwargs): _security.SecurityToken_swiginit(self,_security.new_SecurityToken(*args, **kwargs)) + def is_sid(*args, **kwargs): + """ + S.is_sid(sid) -> bool + Check whether this token is of the specified SID. + """ + return _security.SecurityToken_is_sid(*args, **kwargs) + + def is_system(*args, **kwargs): + """ + S.is_system() -> bool + Check whether this is a system token. + """ + return _security.SecurityToken_is_system(*args, **kwargs) + + def is_anonymous(*args, **kwargs): + """ + S.is_anonymus() -> bool + Check whether this is an anonymous token. + """ + return _security.SecurityToken_is_anonymous(*args, **kwargs) + __swig_destroy__ = _security.delete_SecurityToken SecurityToken.is_sid = new_instancemethod(_security.SecurityToken_is_sid,None,SecurityToken) SecurityToken.is_system = new_instancemethod(_security.SecurityToken_is_system,None,SecurityToken) @@ -103,6 +128,13 @@ class security_descriptor(object): __repr__ = _swig_repr def __init__(self, *args, **kwargs): _security.security_descriptor_swiginit(self,_security.new_security_descriptor(*args, **kwargs)) + def sacl_add(*args, **kwargs): + """ + S.sacl_add(ace) -> None + Add a security ace to this security descriptor + """ + return _security.security_descriptor_sacl_add(*args, **kwargs) + __swig_destroy__ = _security.delete_security_descriptor security_descriptor.sacl_add = new_instancemethod(_security.security_descriptor_sacl_add,None,security_descriptor) security_descriptor.dacl_add = new_instancemethod(_security.security_descriptor_dacl_add,None,security_descriptor) @@ -123,7 +155,13 @@ Sid.__eq__ = new_instancemethod(_security.Sid___eq__,None,Sid) Sid_swigregister = _security.Sid_swigregister Sid_swigregister(Sid) -random_sid = _security.random_sid + +def random_sid(*args): + """ + random_sid() -> sid + Generate a random SID + """ + return _security.random_sid(*args) privilege_name = _security.privilege_name privilege_id = _security.privilege_id diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index aabf6c27ee..a10626c043 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -3527,9 +3527,18 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"new_SecurityToken", (PyCFunction)_wrap_new_SecurityToken, METH_NOARGS, NULL}, - { (char *)"SecurityToken_is_sid", (PyCFunction) _wrap_SecurityToken_is_sid, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"SecurityToken_is_system", (PyCFunction)_wrap_SecurityToken_is_system, METH_O, NULL}, - { (char *)"SecurityToken_is_anonymous", (PyCFunction)_wrap_SecurityToken_is_anonymous, METH_O, NULL}, + { (char *)"SecurityToken_is_sid", (PyCFunction) _wrap_SecurityToken_is_sid, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.is_sid(sid) -> bool\n" + "Check whether this token is of the specified SID.\n" + ""}, + { (char *)"SecurityToken_is_system", (PyCFunction)_wrap_SecurityToken_is_system, METH_O, (char *)"\n" + "S.is_system() -> bool\n" + "Check whether this is a system token.\n" + ""}, + { (char *)"SecurityToken_is_anonymous", (PyCFunction)_wrap_SecurityToken_is_anonymous, METH_O, (char *)"\n" + "S.is_anonymus() -> bool\n" + "Check whether this is an anonymous token.\n" + ""}, { (char *)"SecurityToken_has_sid", (PyCFunction) _wrap_SecurityToken_has_sid, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"SecurityToken_has_builtin_administrators", (PyCFunction)_wrap_SecurityToken_has_builtin_administrators, METH_O, NULL}, { (char *)"SecurityToken_has_nt_authenticated_users", (PyCFunction)_wrap_SecurityToken_has_nt_authenticated_users, METH_O, NULL}, @@ -3539,7 +3548,10 @@ static PyMethodDef SwigMethods[] = { { (char *)"SecurityToken_swigregister", SecurityToken_swigregister, METH_VARARGS, NULL}, { (char *)"SecurityToken_swiginit", SecurityToken_swiginit, METH_VARARGS, NULL}, { (char *)"new_security_descriptor", (PyCFunction)_wrap_new_security_descriptor, METH_NOARGS, NULL}, - { (char *)"security_descriptor_sacl_add", (PyCFunction) _wrap_security_descriptor_sacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"security_descriptor_sacl_add", (PyCFunction) _wrap_security_descriptor_sacl_add, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.sacl_add(ace) -> None\n" + "Add a security ace to this security descriptor\n" + ""}, { (char *)"security_descriptor_dacl_add", (PyCFunction) _wrap_security_descriptor_dacl_add, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_dacl_del", (PyCFunction) _wrap_security_descriptor_dacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"security_descriptor_sacl_del", (PyCFunction) _wrap_security_descriptor_sacl_del, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -3553,7 +3565,10 @@ static PyMethodDef SwigMethods[] = { { (char *)"delete_Sid", (PyCFunction)_wrap_delete_Sid, METH_O, NULL}, { (char *)"Sid_swigregister", Sid_swigregister, METH_VARARGS, NULL}, { (char *)"Sid_swiginit", Sid_swiginit, METH_VARARGS, NULL}, - { (char *)"random_sid", (PyCFunction)_wrap_random_sid, METH_NOARGS, NULL}, + { (char *)"random_sid", (PyCFunction)_wrap_random_sid, METH_NOARGS, (char *)"\n" + "random_sid() -> sid\n" + "Generate a random SID\n" + ""}, { (char *)"privilege_name", (PyCFunction) _wrap_privilege_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"privilege_id", (PyCFunction) _wrap_privilege_id, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } -- cgit From f9c36fae757d197ee4de06f0ecf94ae13faad0de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 21:38:33 +0200 Subject: Export functions for setting NTSTATUS and WERRORs in python. (This used to be commit 4bcb92d2d49d90863b1e64b15d055517fbfd263c) --- source4/libcli/util/errors.i | 10 ++++++---- source4/libcli/util/pyerrors.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 source4/libcli/util/pyerrors.h (limited to 'source4/libcli') diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i index 17efcbf62a..1fcde04c85 100644 --- a/source4/libcli/util/errors.i +++ b/source4/libcli/util/errors.i @@ -18,10 +18,13 @@ */ #ifdef SWIGPYTHON +%{ +#include "libcli/util/pyerrors.h" +%} + %typemap(out,noblock=1) WERROR { if (!W_ERROR_IS_OK($1)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V($1), win_errstr($1)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR($1); SWIG_fail; } else if ($result == NULL) { $result = Py_None; @@ -30,8 +33,7 @@ %typemap(out,noblock=1) NTSTATUS { if (NT_STATUS_IS_ERR($1)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V($1), nt_errstr($1)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetNTSTATUS($1); SWIG_fail; } else if ($result == NULL) { $result = Py_None; diff --git a/source4/libcli/util/pyerrors.h b/source4/libcli/util/pyerrors.h new file mode 100644 index 0000000000..49d9923130 --- /dev/null +++ b/source4/libcli/util/pyerrors.h @@ -0,0 +1,29 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + + 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 3 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, see . +*/ + +#ifndef __PYERRORS_H__ +#define __PYERRORS_H__ + +#define PyErr_SetWERROR(err) \ + PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue((char *)"(i,s)", W_ERROR_V(err), discard_const_p(char, win_errstr(err)))) + +#define PyErr_SetNTSTATUS(status) \ + PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue((char *)"(i,s)", NT_STATUS_V(status), discard_const_p(char, nt_errstr(status)))) + +#endif /* __PYERRORS_H__ */ -- cgit From 75e7962d2efb1aa6e45ca999b1a93829406de540 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 22:13:32 +0200 Subject: Add convenience functions for setting Python objects from errors. (This used to be commit f1de723b89251cbc8140b838941f304a34871bf3) --- source4/libcli/util/pyerrors.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/pyerrors.h b/source4/libcli/util/pyerrors.h index 49d9923130..aaa35b4d26 100644 --- a/source4/libcli/util/pyerrors.h +++ b/source4/libcli/util/pyerrors.h @@ -20,10 +20,14 @@ #ifndef __PYERRORS_H__ #define __PYERRORS_H__ +#define PyErr_FromWERROR(err) Py_BuildValue("(i,s)", W_ERROR_V(err), discard_const_p(char, win_errstr(err))) + +#define PyErr_FromNTSTATUS(status) Py_BuildValue("(i,s)", NT_STATUS_V(status), discard_const_p(char, nt_errstr(status))) + #define PyErr_SetWERROR(err) \ - PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue((char *)"(i,s)", W_ERROR_V(err), discard_const_p(char, win_errstr(err)))) + PyErr_SetObject(PyExc_RuntimeError, PyErr_FromWERROR(err)) #define PyErr_SetNTSTATUS(status) \ - PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue((char *)"(i,s)", NT_STATUS_V(status), discard_const_p(char, nt_errstr(status)))) + PyErr_SetObject(PyExc_RuntimeError, PyErr_FromNTSTATUS(status)) #endif /* __PYERRORS_H__ */ -- cgit From 2ad2bdda89c07c0b8ce754c3b0cd4664eefc697d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 May 2008 15:02:43 +1000 Subject: stricter checks for valid inputs in SMB2 open and lock (This used to be commit a7b5689a73adde59de28770aa3949660441291ea) --- source4/libcli/raw/interfaces.h | 1 + source4/libcli/raw/smb.h | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index bae0e67b02..36d8c3abb0 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1919,6 +1919,7 @@ union smb_lock { #define SMB2_LOCK_FLAG_EXCLUSIVE 0x00000002 #define SMB2_LOCK_FLAG_UNLOCK 0x00000004 #define SMB2_LOCK_FLAG_FAIL_IMMEDIATELY 0x00000010 +#define SMB2_LOCK_FLAG_ALL_MASK 0x00000017 uint32_t flags; uint32_t reserved; } *locks; diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 74869e8a45..5a92b99757 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -133,6 +133,7 @@ #define NTCREATEX_SHARE_ACCESS_READ 1 #define NTCREATEX_SHARE_ACCESS_WRITE 2 #define NTCREATEX_SHARE_ACCESS_DELETE 4 +#define NTCREATEX_SHARE_ACCESS_MASK 7 /* ntcreatex open_disposition field */ #define NTCREATEX_DISP_SUPERSEDE 0 /* supersede existing file (if it exists) */ @@ -154,14 +155,18 @@ #define NTCREATEX_OPTIONS_RANDOM_ACCESS 0x0800 #define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000 #define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000 -#define NTCREATEX_OPTIONS_UNKNOWN_400000 0x400000 - +#define NTCREATEX_OPTIONS_BACKUP_INTENT 0x4000 +#define NTCREATEX_OPTIONS_REPARSE_POINT 0x200000 +#define NTCREATEX_OPTIONS_UNKNOWN_400000 0x400000 /* create options these bits are for private use by backends, they are not valid on the wire */ #define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000 #define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 #define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 +#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK 0x00DFA188 + + /* ntcreatex impersonation field */ #define NTCREATEX_IMPERSONATION_ANONYMOUS 0 -- cgit From dce310ef4ec2eedb496e814cf341ad7caab821af Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 May 2008 13:31:57 +0200 Subject: Remove evil hack which breaks Python bindings. (This used to be commit 1c179566cb39eb09e522dbce69230472a5d4e655) --- source4/libcli/nbt/nbtname.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 0d9073ccbb..97ae2e9d72 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -626,3 +626,24 @@ _PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, ndr_print_string(ndr, name, s); talloc_free(s); } + +_PUBLIC_ enum ndr_err_code ndr_push_nbt_res_rec(struct ndr_push *ndr, int ndr_flags, const struct nbt_res_rec *r) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_nbt_name(ndr, NDR_SCALARS, &r->name)); + NDR_CHECK(ndr_push_nbt_qtype(ndr, NDR_SCALARS, r->rr_type)); + NDR_CHECK(ndr_push_nbt_qclass(ndr, NDR_SCALARS, r->rr_class)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ttl)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->rdata, ((((r->rr_type) == NBT_QTYPE_NETBIOS) && ((r->rdata).data.length == 2))?0:r->rr_type))); + NDR_CHECK(ndr_push_nbt_rdata(ndr, NDR_SCALARS, &r->rdata)); + } + if (ndr_flags & NDR_BUFFERS) { + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} -- cgit From 2814868e93116bb967a7438d95b6fd407246acc1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 12:42:19 +1000 Subject: don't alter the in blobs in a SMB2 create, otherwise two calls in a row will fail (This used to be commit 3b811a52fe9a8356337ad149d01a3498c09d900a) --- source4/libcli/smb2/create.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index b1b8b0ccfa..1901cb4977 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -94,6 +94,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); uint32_t i; + struct smb2_create_blobs blobs = io->in.blobs; req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; @@ -119,7 +120,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4); - status = smb2_create_blob_add(req, &io->in.blobs, + status = smb2_create_blob_add(req, &blobs, SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -130,22 +131,22 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &io->in.blobs, + status = smb2_create_blob_add(req, &blobs, SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } - for (i=0; i < io->in.blobs.num_blobs; i++) { + for (i=0; i < blobs.num_blobs; i++) { bool last = false; const struct smb2_create_blob *c; - if ((i + 1) == io->in.blobs.num_blobs) { + if ((i + 1) == blobs.num_blobs) { last = true; } - c = &io->in.blobs.blobs[i]; + c = &blobs.blobs[i]; status = smb2_create_blob_push_one(req, &blob, c, last); if (!NT_STATUS_IS_OK(status)) { -- cgit From 9691856569e2fdbcbd8c05a2cf3155263b8fa410 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 14:06:27 +1000 Subject: cope better with read only files in smb2_deltree (This used to be commit 88a2c7b2f44f160836e477e460812df557204f51) --- source4/libcli/smb2/util.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c index 9eb344e83f..311cea94a0 100644 --- a/source4/libcli/smb2/util.c +++ b/source4/libcli/smb2/util.c @@ -127,6 +127,16 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname) return 0; } + if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { + /* it could be read-only */ + status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL); + status = smb2_util_unlink(tree, dname); + } + if (NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return 1; + } + ZERO_STRUCT(create_parm); create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; create_parm.in.share_access = -- cgit From cb36437db2d75e7facc91cf0089f2caa20bf0ca0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 16:43:36 +1000 Subject: added support for the output fields of SMB2 close (This used to be commit 2633bc749792c224acc73a2e4ca723404331c19c) --- source4/libcli/raw/interfaces.h | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 36d8c3abb0..68ebc19bdb 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1950,23 +1950,43 @@ union smb_lock { enum smb_close_level { RAW_CLOSE_CLOSE, RAW_CLOSE_SPLCLOSE, - RAW_CLOSE_SMB2 + RAW_CLOSE_SMB2, + RAW_CLOSE_GENERIC, }; -#define RAW_CLOSE_GENERIC RAW_CLOSE_CLOSE - /* union for close() backend call */ union smb_close { - /* SMBclose (and generic) interface */ + /* generic interface */ struct { enum smb_close_level level; struct { union smb_handle file; time_t write_time; +#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0) + uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ } in; - } close, generic; + struct { + uint16_t flags; + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint64_t alloc_size; + uint64_t size; + uint32_t file_attr; + } out; + } generic; + + /* SMBclose interface */ + struct { + enum smb_close_level level; + struct { + union smb_handle file; + time_t write_time; + } in; + } close; /* SMBsplclose interface - empty! */ struct { @@ -1984,7 +2004,6 @@ union smb_close { /* static body buffer 24 (0x18) bytes */ /* uint16_t buffer_code; 0x18 */ -#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0) uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ uint32_t _pad; } in; -- cgit From 8daeee5c5d7d5851677089cceaf26a0e32675a96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 18:20:23 +1000 Subject: ensure that we honor SMB2 read min_count properly (This used to be commit 318038d6f670efffa96d8b0db63f46b3752e1cd3) --- source4/libcli/raw/interfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 68ebc19bdb..17c85138ac 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1647,7 +1647,7 @@ union smb_read { struct { union smb_handle file; uint64_t offset; - uint16_t mincnt; + uint32_t mincnt; /* enforced on SMB2, 16 bit on SMB */ uint32_t maxcnt; uint16_t remaining; bool read_for_execute; -- cgit From 1284308a35f4983609fd77633b6137fdf8df6c75 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 May 2008 18:20:29 +0200 Subject: Use variable for ndr_netlogon.o path. (This used to be commit b5d9d7a0affb4dcd8b89830e6967e4a14b512619) --- source4/libcli/config.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index b24f3eb4af..02711eedb3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -61,15 +61,14 @@ $(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT PUBLIC_DEPENDENCIES = LIBNDR \ NDR_SECURITY -LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ - ndr_netlogon.o) +LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix $(libclisrcdir)/, ndr_netlogon.o) $(eval $(call proto_header_template,$(libclisrcdir)/ndr_netlogon_proto.h,$(LIBCLI_NDR_NETLOGON_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_NETLOGON] PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL LIBCLI_NDR_NETLOGON -LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ +LIBCLI_NETLOGON_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ netlogon.o) $(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) -- cgit From 2173169e191754887acddb669a937b872b7ce017 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 15:27:50 +1000 Subject: added support for all of the known SMB2 create tags in our client library (This used to be commit 597b38e97b01d2137e6ac96ca07cd56fadb2c09e) --- source4/libcli/raw/interfaces.h | 20 ++++- source4/libcli/smb2/create.c | 186 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 195 insertions(+), 11 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 17c85138ac..d170006d3b 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1586,9 +1586,17 @@ union smb_open { /* dynamic body */ const char *fname; - /* optional list of extended attributes */ + /* now some optional parameters - encoded as tagged blobs */ struct smb_ea_list eas; - + uint64_t alloc_size; + struct security_descriptor *sec_desc; + bool durable_open; + struct smb2_handle *durable_handle; + bool query_maximal_access; + NTTIME timewarp; + bool query_on_disk_id; + + /* and any additional blobs the caller wants */ struct smb2_create_blobs { uint32_t num_blobs; struct smb2_create_blob { @@ -1617,8 +1625,12 @@ union smb_open { /* uint32_t blob_ofs; */ /* uint32_t blob_size; */ - /* dynamic body */ - DATA_BLOB blob; + /* optional return values matching tagged values in the call */ + uint32_t maximal_access; + uint8_t on_disk_id[32]; + + /* tagged blobs in the reply */ + struct smb2_create_blobs blobs; } out; } smb2; }; diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 1901cb4977..4a97f8aafb 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -24,6 +24,74 @@ #include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "librpc/gen_ndr/ndr_security.h" + + +/* + parse a set of SMB2 create blobs +*/ +NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer, + struct smb2_create_blobs *blobs) +{ + const uint8_t *data = buffer.data; + uint32_t remaining = buffer.length; + + while (remaining > 0) { + uint32_t next; + uint32_t name_offset, name_length; + uint32_t reserved, data_offset; + uint32_t data_length; + char *tag; + DATA_BLOB b; + NTSTATUS status; + + if (remaining < 16) { + return NT_STATUS_INVALID_PARAMETER; + } + next = IVAL(data, 0); + name_offset = SVAL(data, 4); + name_length = SVAL(data, 6); + reserved = SVAL(data, 8); + data_offset = SVAL(data, 10); + data_length = IVAL(data, 12); + + if ((next & 0x7) != 0 || + next > remaining || + name_offset < 16 || + name_offset > remaining || + name_offset + name_length > remaining || + data_offset < name_offset + name_length || + data_offset > remaining || + data_offset + (uint64_t)data_length > remaining) { + return NT_STATUS_INVALID_PARAMETER; + } + + tag = talloc_strndup(mem_ctx, (const char *)data + name_offset, name_length); + if (tag == NULL) { + return NT_STATUS_NO_MEMORY; + } + + b = data_blob_const(data+data_offset, data_length); + status = smb2_create_blob_add(mem_ctx, blobs, tag, b); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + talloc_free(tag); + + if (next == 0) break; + + remaining -= next; + data += next; + + if (remaining < 16) { + return NT_STATUS_INVALID_PARAMETER; + } + } + + return NT_STATUS_OK; +} + /* add a blob to a smb2_create attribute blob @@ -116,6 +184,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create return NULL; } + /* now add all the optional blobs */ if (io->in.eas.num_eas != 0) { DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4)); @@ -131,13 +200,87 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blobs, - SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; + if (io->in.query_maximal_access) { + /* TODO: MS-SMB2 2.2.13.2.5 says this can contain a timestamp? What to do + with that if it doesn't match? */ + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.alloc_size != 0) { + uint8_t data[8]; + SBVAL(data, 0, io->in.alloc_size); + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_ALSI, data_blob_const(data, 8)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.durable_open) { + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_DHNQ, data_blob_talloc_zero(req, 16)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.durable_handle) { + uint8_t data[16]; + smb2_push_handle(data, io->in.durable_handle); + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_DHNC, data_blob_const(data, 16)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.timewarp) { + uint8_t data[8]; + SBVAL(data, 0, io->in.timewarp); + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_TWRP, data_blob_const(data, 8)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } } + if (io->in.sec_desc) { + enum ndr_err_code ndr_err; + DATA_BLOB sd_blob; + ndr_err = ndr_push_struct_blob(&sd_blob, req, NULL, + io->in.sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(req); + return NULL; + } + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_SECD, sd_blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.query_on_disk_id) { + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_QFID, data_blob(NULL, 0)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + /* and any custom blobs */ for (i=0; i < blobs.num_blobs; i++) { bool last = false; const struct smb2_create_blob *c; @@ -173,6 +316,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io) { NTSTATUS status; + DATA_BLOB blob; + int i; if (!smb2_request_receive(req) || !smb2_request_is_ok(req)) { @@ -180,7 +325,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct } SMB2_CHECK_PACKET_RECV(req, 0x58, true); - + ZERO_STRUCT(io->out); io->out.oplock_level = CVAL(req->in.body, 0x02); io->out.reserved = CVAL(req->in.body, 0x03); io->out.create_action = IVAL(req->in.body, 0x04); @@ -193,12 +338,39 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.file_attr = IVAL(req->in.body, 0x38); io->out.reserved2 = IVAL(req->in.body, 0x3C); smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); - status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &blob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); return status; } + status = smb2_create_blob_parse(mem_ctx, blob, &io->out.blobs); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + + /* pull out the parsed blobs */ + for (i=0;iout.blobs.num_blobs;i++) { + if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) { + /* why 8 bytes not 4?? */ + if (io->out.blobs.blobs[i].data.length != 8) { + smb2_request_destroy(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0); + } + if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) { + if (io->out.blobs.blobs[i].data.length != 32) { + smb2_request_destroy(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32); + } + } + + data_blob_free(&blob); + return smb2_request_destroy(req); } -- cgit From 773f5cce80322d8674ac0b99b0e0ea641991af1b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 16:27:38 +1000 Subject: expose a function for pushing all SMB2 create blobs (This used to be commit f5985a0490e4105a9b0208f6b7b19e635db324f9) --- source4/libcli/smb2/create.c | 53 ++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 4a97f8aafb..b976b528f1 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -125,6 +125,35 @@ static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer return NT_STATUS_OK; } + +/* + create a buffer of a set of create blobs +*/ +NTSTATUS smb2_create_blob_push(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer, + const struct smb2_create_blobs blobs) +{ + int i; + NTSTATUS status; + + *buffer = data_blob(NULL, 0); + for (i=0; i < blobs.num_blobs; i++) { + bool last = false; + const struct smb2_create_blob *c; + + if ((i + 1) == blobs.num_blobs) { + last = true; + } + + c = &blobs.blobs[i]; + status = smb2_create_blob_push_one(mem_ctx, buffer, c, last); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + return NT_STATUS_OK; +} + + NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b, const char *tag, DATA_BLOB data) { @@ -160,8 +189,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create { struct smb2_request *req; NTSTATUS status; - DATA_BLOB blob = data_blob(NULL, 0); - uint32_t i; + DATA_BLOB blob; struct smb2_create_blobs blobs = io->in.blobs; req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); @@ -281,21 +309,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create } /* and any custom blobs */ - for (i=0; i < blobs.num_blobs; i++) { - bool last = false; - const struct smb2_create_blob *c; - - if ((i + 1) == blobs.num_blobs) { - last = true; - } - - c = &blobs.blobs[i]; - status = smb2_create_blob_push_one(req, &blob, - c, last); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; - } + status = smb2_create_blob_push(req, &blob, blobs); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; } status = smb2_push_o32s32_blob(&req->out, 0x30, blob); @@ -304,6 +321,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create return NULL; } + data_blob_free(&blob); + smb2_transport_send(req); return req; -- cgit From 0be9746e1fc47aff93c1d77d256f4fb7942529d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 16:58:34 +1000 Subject: ensure we don't change the incoming blobs in a SMB2 create (This used to be commit a6cc89fffe8c149b540f2125cea57f31331d5460) --- source4/libcli/smb2/create.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index b976b528f1..bff0a1587d 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -59,6 +59,7 @@ NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer, next > remaining || name_offset < 16 || name_offset > remaining || + name_length != 4 || /* windows enforces this */ name_offset + name_length > remaining || data_offset < name_offset + name_length || data_offset > remaining || @@ -190,7 +191,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create struct smb2_request *req; NTSTATUS status; DATA_BLOB blob; - struct smb2_create_blobs blobs = io->in.blobs; + struct smb2_create_blobs blobs; + int i; + + ZERO_STRUCT(blobs); req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; @@ -309,6 +313,17 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create } /* and any custom blobs */ + for (i=0;iin.blobs.num_blobs;i++) { + status = smb2_create_blob_add(req, &blobs, + io->in.blobs.blobs[i].tag, + io->in.blobs.blobs[i].data); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + status = smb2_create_blob_push(req, &blob, blobs); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); -- cgit From f4077a05cbdb0a7bb0cc9baf120d26e026f86b9b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 21:48:26 +1000 Subject: updated comment based on MS-SMB2 docs (This used to be commit 5754cc13514a0f5fe4c47ce53521c256c9d96487) --- source4/libcli/smb2/create.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index bff0a1587d..342a519376 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -387,7 +387,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct /* pull out the parsed blobs */ for (i=0;iout.blobs.num_blobs;i++) { if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) { - /* why 8 bytes not 4?? */ + /* TODO: this also contains a status field in + first 4 bytes */ if (io->out.blobs.blobs[i].data.length != 8) { smb2_request_destroy(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; -- cgit From f6b678b57e14e23479530b64652efe8c51bb4929 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 18:23:00 +1000 Subject: fixed offset for maximal access response (This used to be commit ddd0bb32510d615c7b943fb4ce4c9c275b98ab89) --- source4/libcli/smb2/create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 342a519376..8a40e56a00 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -393,7 +393,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_request_destroy(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; } - io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0); + io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4); } if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) { if (io->out.blobs.blobs[i].data.length != 32) { -- cgit From c86dc11be6e626fa81f025d7ec78226fb4249cdc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 19:16:26 +1000 Subject: added support for returning the maximal access MXAC tag in SMB2 create (This used to be commit 4eb49335d5f0319f9aa47ded5215a2977d3336bf) --- source4/libcli/raw/interfaces.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d170006d3b..19d51893a6 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1354,7 +1354,7 @@ union smb_open { break; \ } \ } while (0) - /* SMBNTCreateX interface */ + /* SMBNTCreateX, nttrans and generic interface */ struct { enum smb_open_level level; struct { @@ -1377,6 +1377,9 @@ union smb_open { NTTRANS varient of the call */ struct security_descriptor *sec_desc; struct smb_ea_list *ea_list; + + /* some optional parameters from the SMB2 varient */ + bool query_maximal_access; } in; struct { union smb_handle file; @@ -1392,6 +1395,10 @@ union smb_open { uint16_t file_type; uint16_t ipc_state; uint8_t is_directory; + + /* optional return values matching SMB2 tagged + values in the call */ + uint32_t maximal_access; } out; } ntcreatex, nttrans, generic; -- cgit From beaa01e403dda7557a6acdf0181d79d58a33bbbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 May 2008 17:03:54 +1000 Subject: implemented client side SMB2 signing This doessn't work against Windows yet, and I've submitted a WSPP request for clarification of the docs to try and find out why. Meanwhile this is no worse than what we had, as it only gets used when the server demands signing, and we didn't work then anyway. (This used to be commit b788096add3586d7277efcd3bf5ca7f3a604cb7a) --- source4/libcli/smb2/cancel.c | 6 +- source4/libcli/smb2/config.mk | 2 +- source4/libcli/smb2/connect.c | 54 +++++++++++-- source4/libcli/smb2/notify.c | 6 +- source4/libcli/smb2/session.c | 17 ++++- source4/libcli/smb2/signing.c | 165 ++++++++++++++++++++++++++++++++++++++++ source4/libcli/smb2/smb2.h | 22 ++++-- source4/libcli/smb2/transport.c | 49 +++++++----- 8 files changed, 283 insertions(+), 38 deletions(-) create mode 100644 source4/libcli/smb2/signing.c (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/cancel.c b/source4/libcli/smb2/cancel.c index 80127feea5..65f02187c1 100644 --- a/source4/libcli/smb2/cancel.c +++ b/source4/libcli/smb2/cancel.c @@ -61,10 +61,10 @@ NTSTATUS smb2_cancel(struct smb2_request *r) SSVAL(c->out.body, 0x02, 0); - old_timeout = c->transport->options.timeout; - c->transport->options.timeout = 0; + old_timeout = c->transport->options.request_timeout; + c->transport->options.request_timeout = 0; smb2_transport_send(c); - c->transport->options.timeout = old_timeout; + c->transport->options.request_timeout = old_timeout; if (c->state == SMB2_REQUEST_ERROR) { status = c->status; diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk index 00b6305def..322bca1416 100644 --- a/source4/libcli/smb2/config.mk +++ b/source4/libcli/smb2/config.mk @@ -5,6 +5,6 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/smb2/, \ transport.o request.o negprot.o session.o tcon.o \ create.o close.o connect.o getinfo.o write.o read.o \ setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \ - lock.o notify.o cancel.o keepalive.o break.o util.o) + lock.o notify.o cancel.o keepalive.o break.o util.o signing.o) $(eval $(call proto_header_template,$(libclisrcdir)/smb2/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c))) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index eabfa410ad..cdb5e3b5d4 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -33,6 +33,7 @@ struct smb2_connect_state { struct resolve_context *resolve_ctx; const char *host; const char *share; + struct smbcli_options options; struct smb2_negprot negprot; struct smb2_tree_connect tcon; struct smb2_session *session; @@ -103,6 +104,34 @@ static void continue_negprot(struct smb2_request *req) transport->negotiate.system_time = state->negprot.out.system_time; transport->negotiate.server_start_time = state->negprot.out.server_start_time; + transport->negotiate.security_mode = state->negprot.out.security_mode; + + switch (transport->options.signing) { + case SMB_SIGNING_OFF: + if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { + composite_error(c, NT_STATUS_ACCESS_DENIED); + return; + } + transport->signing.doing_signing = false; + break; + case SMB_SIGNING_SUPPORTED: + case SMB_SIGNING_AUTO: + if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { + transport->signing.doing_signing = true; + } else { + transport->signing.doing_signing = false; + } + break; + case SMB_SIGNING_REQUIRED: + if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { + transport->signing.doing_signing = true; + } else { + composite_error(c, NT_STATUS_ACCESS_DENIED); + return; + } + break; + } + state->session = smb2_session_init(transport, global_loadparm, state, true); if (composite_nomem(state->session, c)) return; @@ -129,12 +158,24 @@ static void continue_socket(struct composite_context *creq) c->status = smbcli_sock_connect_recv(creq, state, &sock); if (!composite_is_ok(c)) return; - transport = smb2_transport_init(sock, state); + transport = smb2_transport_init(sock, state, &state->options); if (composite_nomem(transport, c)) return; ZERO_STRUCT(state->negprot); state->negprot.in.dialect_count = 2; - state->negprot.in.security_mode = 0; + switch (transport->options.signing) { + case SMB_SIGNING_OFF: + state->negprot.in.security_mode = 0; + break; + case SMB_SIGNING_SUPPORTED: + case SMB_SIGNING_AUTO: + state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; + break; + case SMB_SIGNING_REQUIRED: + state->negprot.in.security_mode = + SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; + break; + } state->negprot.in.capabilities = 0; unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); dialects[0] = 0; @@ -178,7 +219,8 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, const char *share, struct resolve_context *resolve_ctx, struct cli_credentials *credentials, - struct event_context *ev) + struct event_context *ev, + struct smbcli_options *options) { struct composite_context *c; struct smb2_connect_state *state; @@ -193,6 +235,7 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, c->private_data = state; state->credentials = credentials; + state->options = *options; state->host = talloc_strdup(c, host); if (composite_nomem(state->host, c)) return c; state->share = talloc_strdup(c, share); @@ -232,10 +275,11 @@ NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, struct resolve_context *resolve_ctx, struct cli_credentials *credentials, struct smb2_tree **tree, - struct event_context *ev) + struct event_context *ev, + struct smbcli_options *options) { struct composite_context *c = smb2_connect_send(mem_ctx, host, share, resolve_ctx, - credentials, ev); + credentials, ev, options); return smb2_connect_recv(c, mem_ctx, tree); } diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 096d790a31..ef7341cae8 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -44,10 +44,10 @@ struct smb2_request *smb2_notify_send(struct smb2_tree *tree, struct smb2_notify SIVAL(req->out.body, 0x18, io->in.completion_filter); SIVAL(req->out.body, 0x1C, io->in.unknown); - old_timeout = req->transport->options.timeout; - req->transport->options.timeout = 0; + old_timeout = req->transport->options.request_timeout; + req->transport->options.request_timeout = 0; smb2_transport_send(req); - req->transport->options.timeout = old_timeout; + req->transport->options.request_timeout = old_timeout; return req; } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 29af6652f2..54915d8535 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -164,8 +164,8 @@ static void session_request_handler(struct smb2_request *req) session_key_err = gensec_session_key(session->gensec, &session_key); if (NT_STATUS_IS_OK(session_key_err)) { - session->session_key = session_key; - } + session->transport->signing.session_key = session_key; + } } session->uid = state->io.out.uid; @@ -187,6 +187,14 @@ static void session_request_handler(struct smb2_request *req) return; } + if (session->transport->signing.doing_signing) { + c->status = smb2_start_signing(session->transport); + if (!NT_STATUS_IS_OK(c->status)) { + composite_error(c, c->status); + return; + } + } + composite_done(c); } @@ -208,7 +216,10 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se ZERO_STRUCT(state->io); state->io.in.vc_number = 0; - state->io.in.security_mode = 0; + if (session->transport->signing.doing_signing) { + state->io.in.security_mode = + SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; + } state->io.in.capabilities = 0; state->io.in.channel = 0; state->io.in.previous_sessionid = 0; diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c new file mode 100644 index 0000000000..01f7576134 --- /dev/null +++ b/source4/libcli/smb2/signing.c @@ -0,0 +1,165 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 Signing Code + + Copyright (C) Andrew Tridgell 2008 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" +#include "heimdal/lib/hcrypto/sha.h" + +/* + NOTE: this code does not yet interoperate with the windows SMB2 + implementation. We are waiting on feedback on the docs to find out + why + */ + + +/* + setup signing on a transport + */ +NTSTATUS smb2_start_signing(struct smb2_transport *transport) +{ + if (transport->signing.session_key.length != 16) { + DEBUG(2,("Wrong session key length %u for SMB2 signing\n", + (unsigned)transport->signing.session_key.length)); + return NT_STATUS_ACCESS_DENIED; + } + + transport->signing.signing_started = true; + return NT_STATUS_OK; +} + +/* + sign an outgoing message + */ +NTSTATUS smb2_sign_message(struct smb2_request *req) +{ + struct smb2_request_buffer *buf = &req->out; + uint64_t session_id; + SHA256_CTX m; + uint8_t res[32]; + + if (!req->transport->signing.doing_signing || + !req->transport->signing.signing_started) { + return NT_STATUS_OK; + } + + if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) { + /* can't sign non-SMB2 messages */ + return NT_STATUS_OK; + } + + session_id = BVAL(buf->hdr, SMB2_HDR_SESSION_ID); + if (session_id == 0) { + /* we don't sign messages with a zero session_id. See + MS-SMB2 3.2.4.1.1 */ + return NT_STATUS_OK; + } + + if (req->transport->signing.session_key.length != 16) { + DEBUG(2,("Wrong session key length %u for SMB2 signing\n", + (unsigned)req->transport->signing.session_key.length)); + return NT_STATUS_ACCESS_DENIED; + } + + memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16); + + SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED); + + ZERO_STRUCT(m); + SHA256_Init(&m); + SHA256_Update(&m, req->transport->signing.session_key.data, + req->transport->signing.session_key.length); + SHA256_Update(&m, buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE); + SHA256_Final(res, &m); + + DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE)); + + memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16); + + if (DEBUGLVL(5)) { + /* check our own signature */ + smb2_check_signature(req->transport, buf->buffer, buf->size); + } + + return NT_STATUS_OK; +} + +/* + check an incoming signature + */ +NTSTATUS smb2_check_signature(struct smb2_transport *transport, + uint8_t *buffer, uint_t length) +{ + uint64_t session_id; + SHA256_CTX m; + uint8_t res[SHA256_DIGEST_LENGTH]; + uint8_t sig[16]; + + if (!transport->signing.signing_started || + !transport->signing.doing_signing) { + return NT_STATUS_OK; + } + + if (length < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) { + /* can't check non-SMB2 messages */ + return NT_STATUS_OK; + } + + session_id = BVAL(buffer+NBT_HDR_SIZE, SMB2_HDR_SESSION_ID); + if (session_id == 0) { + /* don't sign messages with a zero session_id. See + MS-SMB2 3.2.4.1.1 */ + return NT_STATUS_OK; + } + + if (transport->signing.session_key.length == 0) { + /* we don't have the session key yet */ + return NT_STATUS_OK; + } + + if (transport->signing.session_key.length != 16) { + DEBUG(2,("Wrong session key length %u for SMB2 signing\n", + (unsigned)transport->signing.session_key.length)); + return NT_STATUS_ACCESS_DENIED; + } + + memcpy(sig, buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, 16); + + memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16); + + ZERO_STRUCT(m); + SHA256_Init(&m); + SHA256_Update(&m, transport->signing.session_key.data, 16); + SHA256_Update(&m, buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE); + SHA256_Final(res, &m); + + memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16); + + if (memcmp(res, sig, 16) != 0) { + DEBUG(0,("Bad SMB2 signature for message of size %u\n", length)); + dump_data(0, sig, 16); + dump_data(0, res, 16); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index b55da05e21..0903509528 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -23,20 +23,24 @@ #define __LIBCLI_SMB2_SMB2_H__ #include "libcli/raw/request.h" +#include "libcli/raw/libcliraw.h" struct smb2_handle; -struct smb2_options { - uint32_t timeout; +struct smb2_signing_context { + bool doing_signing; + bool signing_started; + DATA_BLOB session_key; }; /* - information returned from the negotiate response + information returned from the negotiate process */ struct smb2_negotiate { DATA_BLOB secblob; NTTIME system_time; NTTIME server_start_time; + uint16_t security_mode; }; /* this is the context for the smb2 transport layer */ @@ -44,7 +48,6 @@ struct smb2_transport { /* socket level info */ struct smbcli_socket *socket; - struct smb2_options options; struct smb2_negotiate negotiate; /* next seqnum to allocate */ @@ -74,6 +77,9 @@ struct smb2_transport { /* private data passed to the oplock handler */ void *private_data; } oplock; + + struct smbcli_options options; + struct smb2_signing_context signing; }; @@ -92,7 +98,6 @@ struct smb2_session { struct smb2_transport *transport; struct gensec_security *gensec; uint64_t uid; - DATA_BLOB session_key; }; @@ -193,6 +198,13 @@ struct smb2_request { #define SMB2_HDR_SIGNATURE 0x30 /* 16 bytes */ #define SMB2_HDR_BODY 0x40 +/* header flags */ +#define SMB2_HDR_FLAG_REDIRECT 0x01 +#define SMB2_HDR_FLAG_ASYNC 0x02 +#define SMB2_HDR_FLAG_CHAINED 0x04 +#define SMB2_HDR_FLAG_SIGNED 0x08 +#define SMB2_HDR_FLAG_DFS 0x10000000 + /* SMB2 opcodes */ #define SMB2_OP_NEGPROT 0x00 #define SMB2_OP_SESSSETUP 0x01 diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 8eb60a06f1..561b6e528e 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -74,7 +74,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob); create a transport structure based on an established socket */ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, - TALLOC_CTX *parent_ctx) + TALLOC_CTX *parent_ctx, + struct smbcli_options *options) { struct smb2_transport *transport; @@ -82,6 +83,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, if (!transport) return NULL; transport->socket = talloc_steal(transport, sock); + transport->options = *options; /* setup the stream -> packet parser */ transport->packet = packet_init(transport); @@ -112,8 +114,6 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, talloc_set_destructor(transport, transport_destructor); - transport->options.timeout = 30; - return transport; } @@ -140,27 +140,24 @@ void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status) } } -static bool smb2_handle_oplock_break(struct smb2_transport *transport, - const DATA_BLOB *blob) +static NTSTATUS smb2_handle_oplock_break(struct smb2_transport *transport, + const DATA_BLOB *blob) { uint8_t *hdr; uint16_t opcode; - uint64_t seqnum; hdr = blob->data+NBT_HDR_SIZE; if (blob->length < (SMB2_MIN_SIZE+0x18)) { DEBUG(1,("Discarding smb2 oplock reply of size %u\n", - blob->length)); - return false; + (unsigned)blob->length)); + return NT_STATUS_INVALID_NETWORK_RESPONSE; } opcode = SVAL(hdr, SMB2_HDR_OPCODE); - seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); - if ((opcode != SMB2_OP_BREAK) || - (seqnum != UINT64_MAX)) { - return false; + if (opcode != SMB2_OP_BREAK) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; } if (transport->oplock.handler) { @@ -173,9 +170,11 @@ static bool smb2_handle_oplock_break(struct smb2_transport *transport, transport->oplock.handler(transport, &h, level, transport->oplock.private_data); + } else { + DEBUG(5,("Got SMB2 oplock break with no handler\n")); } - return true; + return NT_STATUS_OK; } /* @@ -194,6 +193,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) uint16_t buffer_code; uint32_t dynamic_size; uint32_t i; + NTSTATUS status; buffer = blob.data; len = blob.length; @@ -205,14 +205,20 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) goto error; } - if (smb2_handle_oplock_break(transport, &blob)) { + status = smb2_check_signature(transport, buffer, len); + if (!NT_STATUS_IS_OK(status)) { talloc_free(buffer); - return NT_STATUS_OK; + return status; } - + flags = IVAL(hdr, SMB2_HDR_FLAGS); seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); + /* see MS-SMB2 3.2.5.19 */ + if (seqnum == UINT64_MAX) { + return smb2_handle_oplock_break(transport, &blob); + } + /* match the incoming request against the list of pending requests */ for (req=transport->pending_recv; req; req=req->next) { if (req->seqnum == seqnum) break; @@ -340,6 +346,13 @@ void smb2_transport_send(struct smb2_request *req) return; } + status = smb2_sign_message(req); + if (!NT_STATUS_IS_OK(status)) { + req->state = SMB2_REQUEST_ERROR; + req->status = status; + return; + } + blob = data_blob_const(req->out.buffer, req->out.size); status = packet_send(req->transport->packet, blob); if (!NT_STATUS_IS_OK(status)) { @@ -352,9 +365,9 @@ void smb2_transport_send(struct smb2_request *req) DLIST_ADD(req->transport->pending_recv, req); /* add a timeout */ - if (req->transport->options.timeout) { + if (req->transport->options.request_timeout) { event_add_timed(req->transport->socket->event.ctx, req, - timeval_current_ofs(req->transport->options.timeout, 0), + timeval_current_ofs(req->transport->options.request_timeout, 0), smb2_timeout_handler, req); } -- cgit From 3850d47fef103c4118f1baff4b91b403ab4dde71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Jun 2008 11:02:57 +1000 Subject: updated some info levels based on WSPP docs (This used to be commit f84620324a8cebcd2fd19388d910928ca1ad1334) --- source4/libcli/raw/interfaces.h | 17 +++++++++++++---- source4/libcli/raw/rawsetfileinfo.c | 29 +++++++++++++++++++++++------ source4/libcli/raw/trans2.h | 27 ++++++++++++++++----------- 3 files changed, 52 insertions(+), 21 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 19d51893a6..8e23510f06 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -906,15 +906,24 @@ enum smb_setfileinfo_level { RAW_SFILEINFO_RENAME_INFORMATION = SMB_SFILEINFO_RENAME_INFORMATION, RAW_SFILEINFO_DISPOSITION_INFORMATION = SMB_SFILEINFO_DISPOSITION_INFORMATION, RAW_SFILEINFO_POSITION_INFORMATION = SMB_SFILEINFO_POSITION_INFORMATION, + RAW_SFILEINFO_FULL_EA_INFORMATION = SMB_SFILEINFO_FULL_EA_INFORMATION, RAW_SFILEINFO_MODE_INFORMATION = SMB_SFILEINFO_MODE_INFORMATION, RAW_SFILEINFO_ALLOCATION_INFORMATION = SMB_SFILEINFO_ALLOCATION_INFORMATION, RAW_SFILEINFO_END_OF_FILE_INFORMATION = SMB_SFILEINFO_END_OF_FILE_INFORMATION, - RAW_SFILEINFO_1023 = SMB_SFILEINFO_1023, + RAW_SFILEINFO_PIPE_INFORMATION = SMB_SFILEINFO_PIPE_INFORMATION, + RAW_SFILEINFO_VALID_DATA_INFORMATION = SMB_SFILEINFO_VALID_DATA_INFORMATION, + RAW_SFILEINFO_SHORT_NAME_INFORMATION = SMB_SFILEINFO_SHORT_NAME_INFORMATION, RAW_SFILEINFO_1025 = SMB_SFILEINFO_1025, + RAW_SFILEINFO_1027 = SMB_SFILEINFO_1027, RAW_SFILEINFO_1029 = SMB_SFILEINFO_1029, + RAW_SFILEINFO_1030 = SMB_SFILEINFO_1030, + RAW_SFILEINFO_1031 = SMB_SFILEINFO_1031, RAW_SFILEINFO_1032 = SMB_SFILEINFO_1032, - RAW_SFILEINFO_1039 = SMB_SFILEINFO_1039, - RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040, + RAW_SFILEINFO_1036 = SMB_SFILEINFO_1036, + RAW_SFILEINFO_1041 = SMB_SFILEINFO_1041, + RAW_SFILEINFO_1042 = SMB_SFILEINFO_1042, + RAW_SFILEINFO_1043 = SMB_SFILEINFO_1043, + RAW_SFILEINFO_1044 = SMB_SFILEINFO_1044, /* cope with breakage in SMB2 */ RAW_SFILEINFO_RENAME_INFORMATION_SMB2 = SMB_SFILEINFO_RENAME_INFORMATION|0x80000000, @@ -1901,7 +1910,7 @@ union smb_lock { uint16_t ulock_cnt; uint16_t lock_cnt; struct smb_lock_entry { - uint16_t pid; + uint32_t pid; /* 16 bits in SMB1 */ uint64_t offset; uint64_t count; } *locks; /* unlocks are first in the arrray */ diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 16052e8708..5a4706778a 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -110,12 +110,20 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, } /* Unhandled levels */ - case RAW_SFILEINFO_1023: + case RAW_SFILEINFO_PIPE_INFORMATION: + case RAW_SFILEINFO_VALID_DATA_INFORMATION: + case RAW_SFILEINFO_SHORT_NAME_INFORMATION: case RAW_SFILEINFO_1025: + case RAW_SFILEINFO_1027: case RAW_SFILEINFO_1029: + case RAW_SFILEINFO_1030: + case RAW_SFILEINFO_1031: case RAW_SFILEINFO_1032: - case RAW_SFILEINFO_1039: - case RAW_SFILEINFO_1040: + case RAW_SFILEINFO_1036: + case RAW_SFILEINFO_1041: + case RAW_SFILEINFO_1042: + case RAW_SFILEINFO_1043: + case RAW_SFILEINFO_1044: break; default: @@ -227,12 +235,21 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree, parms, blob); /* Unhandled passthru levels */ - case RAW_SFILEINFO_1023: + case RAW_SFILEINFO_PIPE_INFORMATION: + case RAW_SFILEINFO_VALID_DATA_INFORMATION: + case RAW_SFILEINFO_SHORT_NAME_INFORMATION: + case RAW_SFILEINFO_FULL_EA_INFORMATION: case RAW_SFILEINFO_1025: + case RAW_SFILEINFO_1027: case RAW_SFILEINFO_1029: + case RAW_SFILEINFO_1030: + case RAW_SFILEINFO_1031: case RAW_SFILEINFO_1032: - case RAW_SFILEINFO_1039: - case RAW_SFILEINFO_1040: + case RAW_SFILEINFO_1036: + case RAW_SFILEINFO_1041: + case RAW_SFILEINFO_1042: + case RAW_SFILEINFO_1043: + case RAW_SFILEINFO_1044: return smb_raw_setfileinfo_passthru(mem_ctx, parms->generic.level, parms, blob); diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index 5b7987aa8c..63632eb5ed 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -217,32 +217,37 @@ Found 13 valid levels #define SMB_SFILEINFO_UNIX_INFO2 0x20b #define SMB_SFILEINFO_BASIC_INFORMATION 1004 #define SMB_SFILEINFO_RENAME_INFORMATION 1010 +#define SMB_SFILEINFO_LINK_INFORMATION 1011 #define SMB_SFILEINFO_DISPOSITION_INFORMATION 1013 #define SMB_SFILEINFO_POSITION_INFORMATION 1014 +#define SMB_SFILEINFO_FULL_EA_INFORMATION 1015 #define SMB_SFILEINFO_MODE_INFORMATION 1016 #define SMB_SFILEINFO_ALLOCATION_INFORMATION 1019 #define SMB_SFILEINFO_END_OF_FILE_INFORMATION 1020 - -/* filemon shows FilePipeInformation */ -#define SMB_SFILEINFO_1023 1023 +#define SMB_SFILEINFO_PIPE_INFORMATION 1023 +#define SMB_SFILEINFO_VALID_DATA_INFORMATION 1039 +#define SMB_SFILEINFO_SHORT_NAME_INFORMATION 1040 /* filemon shows FilePipeRemoteInformation */ #define SMB_SFILEINFO_1025 1025 +/* vista scan responds */ +#define SMB_SFILEINFO_1027 1027 + /* filemon shows CopyOnWriteInformation */ #define SMB_SFILEINFO_1029 1029 /* filemon shows OleClassIdInformation */ #define SMB_SFILEINFO_1032 1032 -/* seems to be the file size - perhaps valid data size? - filemon shows 'InheritContentIndexInfo' -*/ -#define SMB_SFILEINFO_1039 1039 - -/* OLE_INFORMATION? */ -#define SMB_SFILEINFO_1040 1040 - +/* vista scan responds to these */ +#define SMB_SFILEINFO_1030 1030 +#define SMB_SFILEINFO_1031 1031 +#define SMB_SFILEINFO_1036 1036 +#define SMB_SFILEINFO_1041 1041 +#define SMB_SFILEINFO_1042 1042 +#define SMB_SFILEINFO_1043 1043 +#define SMB_SFILEINFO_1044 1044 /* trans2 findfirst levels */ /* -- cgit From 7c926ff1150133127c73b9b46d82524f57b3c616 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Jun 2008 14:29:27 +1000 Subject: SMB2 signing now works. The spec was wrong (and will be fixed in the next version) (This used to be commit 436cb17b869e2d6cc57936ccc5e81680fb992341) --- source4/libcli/smb2/signing.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c index 01f7576134..16c0ff99c1 100644 --- a/source4/libcli/smb2/signing.c +++ b/source4/libcli/smb2/signing.c @@ -23,7 +23,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#include "heimdal/lib/hcrypto/sha.h" +#include "lib/crypto/crypto.h" /* NOTE: this code does not yet interoperate with the windows SMB2 @@ -54,7 +54,7 @@ NTSTATUS smb2_sign_message(struct smb2_request *req) { struct smb2_request_buffer *buf = &req->out; uint64_t session_id; - SHA256_CTX m; + struct HMACSHA256Context m; uint8_t res[32]; if (!req->transport->signing.doing_signing || @@ -85,11 +85,9 @@ NTSTATUS smb2_sign_message(struct smb2_request *req) SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED); ZERO_STRUCT(m); - SHA256_Init(&m); - SHA256_Update(&m, req->transport->signing.session_key.data, - req->transport->signing.session_key.length); - SHA256_Update(&m, buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE); - SHA256_Final(res, &m); + hmac_sha256_init(req->transport->signing.session_key.data, 16, &m); + hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m); + hmac_sha256_final(res, &m); DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE)); @@ -110,7 +108,7 @@ NTSTATUS smb2_check_signature(struct smb2_transport *transport, uint8_t *buffer, uint_t length) { uint64_t session_id; - SHA256_CTX m; + struct HMACSHA256Context m; uint8_t res[SHA256_DIGEST_LENGTH]; uint8_t sig[16]; @@ -147,10 +145,9 @@ NTSTATUS smb2_check_signature(struct smb2_transport *transport, memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16); ZERO_STRUCT(m); - SHA256_Init(&m); - SHA256_Update(&m, transport->signing.session_key.data, 16); - SHA256_Update(&m, buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE); - SHA256_Final(res, &m); + hmac_sha256_init(transport->signing.session_key.data, 16, &m); + hmac_sha256_update(buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE, &m); + hmac_sha256_final(res, &m); memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16); -- cgit From 3df3bf577d5510f30aceca13b6be29267c1c6380 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 6 Jun 2008 10:53:00 -0700 Subject: ensure we don't end up with a partially initialised EA structure (This used to be commit 388f4fde3655146bf57b4c51c59c39f475aa7fe8) --- source4/libcli/raw/raweas.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c index 07b517ade3..6317c49fd7 100644 --- a/source4/libcli/raw/raweas.c +++ b/source4/libcli/raw/raweas.c @@ -131,6 +131,8 @@ uint_t ea_pull_struct(const DATA_BLOB *blob, uint8_t nlen; uint16_t vlen; + ZERO_STRUCTP(ea); + if (blob->length < 6) { return 0; } -- cgit From e97cf207fac5e4101376d2a10dd95a93a9a1e0fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 6 Jun 2008 22:10:30 -0700 Subject: added server side SMB2 signing (This used to be commit 8e919dcb0826a5b25d037ee6144af5f7cb21f3ae) --- source4/libcli/smb2/session.c | 8 +++-- source4/libcli/smb2/signing.c | 74 ++++++++++------------------------------- source4/libcli/smb2/transport.c | 32 ++++++++++++------ 3 files changed, 44 insertions(+), 70 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 54915d8535..42fd4840a1 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -188,11 +188,13 @@ static void session_request_handler(struct smb2_request *req) } if (session->transport->signing.doing_signing) { - c->status = smb2_start_signing(session->transport); - if (!NT_STATUS_IS_OK(c->status)) { - composite_error(c, c->status); + if (session->transport->signing.session_key.length != 16) { + DEBUG(2,("Wrong session key length %u for SMB2 signing\n", + (unsigned)session->transport->signing.session_key.length)); + composite_error(c, NT_STATUS_ACCESS_DENIED); return; } + session->transport->signing.signing_started = true; } composite_done(c); diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c index 16c0ff99c1..fb2c22db4e 100644 --- a/source4/libcli/smb2/signing.c +++ b/source4/libcli/smb2/signing.c @@ -25,42 +25,14 @@ #include "libcli/smb2/smb2_calls.h" #include "lib/crypto/crypto.h" -/* - NOTE: this code does not yet interoperate with the windows SMB2 - implementation. We are waiting on feedback on the docs to find out - why - */ - - -/* - setup signing on a transport - */ -NTSTATUS smb2_start_signing(struct smb2_transport *transport) -{ - if (transport->signing.session_key.length != 16) { - DEBUG(2,("Wrong session key length %u for SMB2 signing\n", - (unsigned)transport->signing.session_key.length)); - return NT_STATUS_ACCESS_DENIED; - } - - transport->signing.signing_started = true; - return NT_STATUS_OK; -} - /* sign an outgoing message */ -NTSTATUS smb2_sign_message(struct smb2_request *req) +NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_key) { - struct smb2_request_buffer *buf = &req->out; - uint64_t session_id; struct HMACSHA256Context m; uint8_t res[32]; - - if (!req->transport->signing.doing_signing || - !req->transport->signing.signing_started) { - return NT_STATUS_OK; - } + uint64_t session_id; if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) { /* can't sign non-SMB2 messages */ @@ -74,9 +46,9 @@ NTSTATUS smb2_sign_message(struct smb2_request *req) return NT_STATUS_OK; } - if (req->transport->signing.session_key.length != 16) { + if (session_key.length != 16) { DEBUG(2,("Wrong session key length %u for SMB2 signing\n", - (unsigned)req->transport->signing.session_key.length)); + (unsigned)session_key.length)); return NT_STATUS_ACCESS_DENIED; } @@ -85,7 +57,7 @@ NTSTATUS smb2_sign_message(struct smb2_request *req) SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED); ZERO_STRUCT(m); - hmac_sha256_init(req->transport->signing.session_key.data, 16, &m); + hmac_sha256_init(session_key.data, 16, &m); hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m); hmac_sha256_final(res, &m); @@ -93,66 +65,56 @@ NTSTATUS smb2_sign_message(struct smb2_request *req) memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16); - if (DEBUGLVL(5)) { - /* check our own signature */ - smb2_check_signature(req->transport, buf->buffer, buf->size); - } - return NT_STATUS_OK; } /* check an incoming signature */ -NTSTATUS smb2_check_signature(struct smb2_transport *transport, - uint8_t *buffer, uint_t length) +NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session_key) { uint64_t session_id; struct HMACSHA256Context m; uint8_t res[SHA256_DIGEST_LENGTH]; uint8_t sig[16]; - if (!transport->signing.signing_started || - !transport->signing.doing_signing) { - return NT_STATUS_OK; - } - - if (length < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) { + if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) { /* can't check non-SMB2 messages */ return NT_STATUS_OK; } - session_id = BVAL(buffer+NBT_HDR_SIZE, SMB2_HDR_SESSION_ID); + session_id = BVAL(buf->hdr, SMB2_HDR_SESSION_ID); if (session_id == 0) { /* don't sign messages with a zero session_id. See MS-SMB2 3.2.4.1.1 */ return NT_STATUS_OK; } - if (transport->signing.session_key.length == 0) { + if (session_key.length == 0) { /* we don't have the session key yet */ return NT_STATUS_OK; } - if (transport->signing.session_key.length != 16) { + if (session_key.length != 16) { DEBUG(2,("Wrong session key length %u for SMB2 signing\n", - (unsigned)transport->signing.session_key.length)); + (unsigned)session_key.length)); return NT_STATUS_ACCESS_DENIED; } - memcpy(sig, buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, 16); + memcpy(sig, buf->hdr+SMB2_HDR_SIGNATURE, 16); - memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16); + memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16); ZERO_STRUCT(m); - hmac_sha256_init(transport->signing.session_key.data, 16, &m); - hmac_sha256_update(buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE, &m); + hmac_sha256_init(session_key.data, 16, &m); + hmac_sha256_update(buf->hdr, buf->size-NBT_HDR_SIZE, &m); hmac_sha256_final(res, &m); - memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16); + memcpy(buf->hdr+SMB2_HDR_SIGNATURE, sig, 16); if (memcmp(res, sig, 16) != 0) { - DEBUG(0,("Bad SMB2 signature for message of size %u\n", length)); + DEBUG(0,("Bad SMB2 signature for message of size %u\n", + (unsigned)buf->size-NBT_HDR_SIZE)); dump_data(0, sig, 16); dump_data(0, res, 16); return NT_STATUS_ACCESS_DENIED; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 561b6e528e..a9a9efb3aa 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -205,12 +205,6 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) goto error; } - status = smb2_check_signature(transport, buffer, len); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(buffer); - return status; - } - flags = IVAL(hdr, SMB2_HDR_FLAGS); seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); @@ -241,6 +235,18 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); + if (transport->signing.signing_started && + transport->signing.doing_signing) { + status = smb2_check_signature(&req->in, + transport->signing.session_key); + if (!NT_STATUS_IS_OK(status)) { + /* the spec says to ignore packets with a bad signature */ + talloc_free(buffer); + return status; + } + } + + if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { if (flags & 0x00000002) { req->cancel.can_cancel = true; @@ -346,11 +352,15 @@ void smb2_transport_send(struct smb2_request *req) return; } - status = smb2_sign_message(req); - if (!NT_STATUS_IS_OK(status)) { - req->state = SMB2_REQUEST_ERROR; - req->status = status; - return; + /* possibly sign the message */ + if (req->transport->signing.doing_signing && + req->transport->signing.signing_started) { + status = smb2_sign_message(&req->out, req->transport->signing.session_key); + if (!NT_STATUS_IS_OK(status)) { + req->state = SMB2_REQUEST_ERROR; + req->status = status; + return; + } } blob = data_blob_const(req->out.buffer, req->out.size); -- cgit From 1c33953ae21384f04de11539afaf9ead5e413b96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 7 Jun 2008 08:30:51 -0700 Subject: make signing per session in the SMB2 client library Thanks to Metze for spotting this (This used to be commit e9fd9b821c04d1cb7b574f539dd8169611e662aa) --- source4/libcli/smb2/session.c | 6 +++--- source4/libcli/smb2/smb2.h | 2 +- source4/libcli/smb2/tcon.c | 1 + source4/libcli/smb2/transport.c | 12 ++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 42fd4840a1..91616319d5 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -164,7 +164,7 @@ static void session_request_handler(struct smb2_request *req) session_key_err = gensec_session_key(session->gensec, &session_key); if (NT_STATUS_IS_OK(session_key_err)) { - session->transport->signing.session_key = session_key; + session->session_key = session_key; } } @@ -188,9 +188,9 @@ static void session_request_handler(struct smb2_request *req) } if (session->transport->signing.doing_signing) { - if (session->transport->signing.session_key.length != 16) { + if (session->session_key.length != 16) { DEBUG(2,("Wrong session key length %u for SMB2 signing\n", - (unsigned)session->transport->signing.session_key.length)); + (unsigned)session->session_key.length)); composite_error(c, NT_STATUS_ACCESS_DENIED); return; } diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 0903509528..2b468d3dc9 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -30,7 +30,6 @@ struct smb2_handle; struct smb2_signing_context { bool doing_signing; bool signing_started; - DATA_BLOB session_key; }; /* @@ -98,6 +97,7 @@ struct smb2_session { struct smb2_transport *transport; struct gensec_security *gensec; uint64_t uid; + DATA_BLOB session_key; }; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index db35669d41..ec7152b264 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -57,6 +57,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid); + req->session = tree->session; SSVAL(req->out.body, 0x02, io->in.reserved); status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path); diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index a9a9efb3aa..6e0d523e21 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -235,10 +235,9 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); - if (transport->signing.signing_started && - transport->signing.doing_signing) { + if (req->session && transport->signing.doing_signing) { status = smb2_check_signature(&req->in, - transport->signing.session_key); + req->session->session_key); if (!NT_STATUS_IS_OK(status)) { /* the spec says to ignore packets with a bad signature */ talloc_free(buffer); @@ -353,9 +352,10 @@ void smb2_transport_send(struct smb2_request *req) } /* possibly sign the message */ - if (req->transport->signing.doing_signing && - req->transport->signing.signing_started) { - status = smb2_sign_message(&req->out, req->transport->signing.session_key); + if (req->transport->signing.doing_signing && + req->transport->signing.signing_started && + req->session) { + status = smb2_sign_message(&req->out, req->session->session_key); if (!NT_STATUS_IS_OK(status)) { req->state = SMB2_REQUEST_ERROR; req->status = status; -- cgit From 230503ad847f9514e95b57c48eeacbd619a1c9f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 11 Jun 2008 00:05:58 +0200 Subject: Add working Python bindings for NBT. (This used to be commit 9c88f5e1de9db34751f16c2247fa91ae2445c5f7) --- source4/libcli/config.mk | 8 +- source4/libcli/nbt/pynbt.c | 408 +++ source4/libcli/swig/libcli_nbt.i | 101 - source4/libcli/swig/libcli_nbt.py | 127 - source4/libcli/swig/libcli_nbt_wrap.c | 4771 --------------------------------- 5 files changed, 411 insertions(+), 5004 deletions(-) create mode 100644 source4/libcli/nbt/pynbt.c delete mode 100644 source4/libcli/swig/libcli_nbt.i delete mode 100644 source4/libcli/swig/libcli_nbt.py delete mode 100644 source4/libcli/swig/libcli_nbt_wrap.c (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 02711eedb3..affd8e277d 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -73,13 +73,11 @@ LIBCLI_NETLOGON_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ $(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) -[PYTHON::python_libcli_nbt] -LIBRARY_REALNAME = samba/_libcli_nbt.$(SHLIBEXT) +[PYTHON::python_netbios] +LIBRARY_REALNAME = samba/netbios.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG -python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o - -$(eval $(call python_py_module_template,samba/nbt.py,$(libclisrcdir)/swig/libcli_nbt.py)) +python_netbios_OBJ_FILES = $(libclisrcdir)/nbt/pynbt.o $(python_libcli_nbt_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) diff --git a/source4/libcli/nbt/pynbt.c b/source4/libcli/nbt/pynbt.c new file mode 100644 index 0000000000..626a63ac48 --- /dev/null +++ b/source4/libcli/nbt/pynbt.c @@ -0,0 +1,408 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright © Jelmer Vernooij 2008 + + 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 3 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, see . +*/ + +#include "includes.h" +#include +#include "libcli/util/pyerrors.h" +#include "libcli/nbt/libnbt.h" +#include "lib/events/events.h" +#include "param/param.h" + +PyAPI_DATA(PyTypeObject) nbt_node_Type; + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct nbt_name_socket *socket; +} nbt_node_Object; + +static void py_nbt_node_dealloc(PyObject *obj) +{ + talloc_free(((nbt_node_Object *)obj)->mem_ctx); + PyObject_Del(obj); +} + +static PyObject *py_nbt_node_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + struct event_context *ev; + nbt_node_Object *ret = PyObject_New(nbt_node_Object, &nbt_node_Type); + + ret->mem_ctx = talloc_new(NULL); + if (ret->mem_ctx == NULL) + return NULL; + + ev = event_context_init(ret->mem_ctx); + ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, lp_iconv_convenience(global_loadparm)); + return (PyObject *)ret; +} + +static bool PyObject_AsDestinationTuple(PyObject *obj, const char **dest_addr, uint16_t *dest_port) +{ + if (PyString_Check(obj)) { + *dest_addr = PyString_AsString(obj); + *dest_port = NBT_NAME_SERVICE_PORT; + return true; + } + + if (PyTuple_Check(obj)) { + if (PyTuple_Size(obj) < 1) { + PyErr_SetString(PyExc_TypeError, "Destination tuple size invalid"); + return false; + } + + if (!PyString_Check(PyTuple_GetItem(obj, 0))) { + PyErr_SetString(PyExc_TypeError, "Destination tuple first element not string"); + return false; + } + + *dest_addr = PyString_AsString(obj); + + if (PyTuple_Size(obj) == 1) { + *dest_port = NBT_NAME_SERVICE_PORT; + return true; + } else if (PyInt_Check(PyTuple_GetItem(obj, 1))) { + *dest_port = PyInt_AsLong(PyTuple_GetItem(obj, 1)); + return true; + } else { + PyErr_SetString(PyExc_TypeError, "Destination tuple second element not a port"); + return false; + } + } + + PyErr_SetString(PyExc_TypeError, "Destination tuple second element not a port"); + return false; +} + +static bool PyObject_AsNBTName(PyObject *obj, struct nbt_name_socket *socket, struct nbt_name *name) +{ + if (PyTuple_Check(obj)) { + if (PyTuple_Size(obj) == 2) { + name->name = PyString_AsString(PyTuple_GetItem(obj, 0)); + name->type = PyInt_AsLong(PyTuple_GetItem(obj, 1)); + name->scope = NULL; + return true; + } else if (PyTuple_Size(obj) == 3) { + name->name = PyString_AsString(PyTuple_GetItem(obj, 0)); + name->scope = PyString_AsString(PyTuple_GetItem(obj, 1)); + name->type = PyInt_AsLong(PyTuple_GetItem(obj, 2)); + return true; + } else { + PyErr_SetString(PyExc_TypeError, "Invalid tuple size"); + return false; + } + } + + if (PyString_Check(obj)) { + /* FIXME: Parse string to be able to interpret things like RHONWYN<02> ? */ + name->name = PyString_AsString(obj); + name->scope = NULL; + name->type = 0; + return true; + } + + PyErr_SetString(PyExc_TypeError, "Invalid type for object"); + return false; +} + +static PyObject *PyObject_FromNBTName(struct nbt_name_socket *socket, struct smb_iconv_convenience *ic, + struct nbt_name *name) +{ + if (name->scope) { + return Py_BuildValue("(ssi)", name->name, name->scope, name->type); + } else { + return Py_BuildValue("(si)", name->name, name->type); + } +} + +static PyObject *py_nbt_name_query(PyObject *self, PyObject *args, PyObject *kwargs) +{ + nbt_node_Object *node = (nbt_node_Object *)self; + PyObject *ret, *reply_addrs, *py_dest, *py_name; + struct nbt_name_query io; + NTSTATUS status; + int i; + + const char *kwnames[] = { "name", "dest", "broadcast", "wins", "timeout", + "retries", NULL }; + io.in.broadcast = true; + io.in.wins_lookup = false; + io.in.timeout = 0; + io.in.retries = 3; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bbii:query_name", + discard_const_p(char *, kwnames), + &py_name, &py_dest, + &io.in.broadcast, &io.in.wins_lookup, + &io.in.timeout, &io.in.retries)) { + return NULL; + } + + if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) + return NULL; + + if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) + return NULL; + + status = nbt_name_query(node->socket, NULL, &io); + + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetNTSTATUS(status); + return NULL; + } + + ret = PyTuple_New(3); + if (ret == NULL) + return NULL; + PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); + + py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); + if (py_name == NULL) + return NULL; + + PyTuple_SetItem(ret, 1, py_name); + + reply_addrs = PyList_New(io.out.num_addrs); + if (reply_addrs == NULL) { + Py_DECREF(ret); + return NULL; + } + + for (i = 0; i < io.out.num_addrs; i++) { + PyList_SetItem(reply_addrs, i, PyString_FromString(io.out.reply_addrs[i])); + } + + PyTuple_SetItem(ret, 2, reply_addrs); + return ret; +} + +static PyObject *py_nbt_name_status(PyObject *self, PyObject *args, PyObject *kwargs) +{ + nbt_node_Object *node = (nbt_node_Object *)self; + PyObject *ret, *py_dest, *py_name, *py_names; + struct nbt_name_status io; + int i; + NTSTATUS status; + + const char *kwnames[] = { "name", "dest", "timeout", "retries", NULL }; + + io.in.timeout = 0; + io.in.retries = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ii:name_status", + discard_const_p(char *, kwnames), + &py_name, &py_dest, + &io.in.timeout, &io.in.retries)) { + return NULL; + } + + if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) + return NULL; + + if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) + return NULL; + + status = nbt_name_status(node->socket, NULL, &io); + + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetNTSTATUS(status); + return NULL; + } + + ret = PyTuple_New(3); + if (ret == NULL) + return NULL; + PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); + + py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); + if (py_name == NULL) + return NULL; + + PyTuple_SetItem(ret, 1, py_name); + + py_names = PyList_New(io.out.status.num_names); + + for (i = 0; i < io.out.status.num_names; i++) { + PyList_SetItem(py_names, i, Py_BuildValue("(sii)", + io.out.status.names[i].name, + io.out.status.names[i].nb_flags, + io.out.status.names[i].type)); + } + + PyTuple_SetItem(ret, 2, py_names); + + return ret; +} + +static PyObject *py_nbt_name_register(PyObject *self, PyObject *args, PyObject *kwargs) +{ + nbt_node_Object *node = (nbt_node_Object *)self; + PyObject *ret, *py_dest, *py_name; + struct nbt_name_register io; + NTSTATUS status; + + const char *kwnames[] = { "name", "address", "dest", "register_demand", "broadcast", + "multi_homed", "ttl", "timeout", "retries", NULL }; + + io.in.broadcast = true; + io.in.multi_homed = true; + io.in.register_demand = true; + io.in.timeout = 0; + io.in.retries = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|bbbiii:query_name", + discard_const_p(char *, kwnames), + &py_name, &io.in.address, &py_dest, + &io.in.register_demand, + &io.in.broadcast, &io.in.multi_homed, + &io.in.ttl, &io.in.timeout, &io.in.retries)) { + return NULL; + } + + if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) + return NULL; + + if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) + return NULL; + + status = nbt_name_register(node->socket, NULL, &io); + + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetNTSTATUS(status); + return NULL; + } + + ret = PyTuple_New(3); + if (ret == NULL) + return NULL; + PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); + + py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); + if (py_name == NULL) + return NULL; + + PyTuple_SetItem(ret, 1, py_name); + + PyTuple_SetItem(ret, 2, PyString_FromString(io.out.reply_addr)); + + PyTuple_SetItem(ret, 3, PyInt_FromLong(io.out.rcode)); + + return ret; +} + +static PyObject *py_nbt_name_refresh(PyObject *self, PyObject *args, PyObject *kwargs) +{ + nbt_node_Object *node = (nbt_node_Object *)self; + PyObject *ret, *py_dest, *py_name; + struct nbt_name_refresh io; + NTSTATUS status; + + const char *kwnames[] = { "name", "address", "dest", "nb_flags", "broadcast", + "ttl", "timeout", "retries", NULL }; + + io.in.broadcast = true; + io.in.nb_flags = 0; + io.in.timeout = 0; + io.in.retries = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|ibiii:query_name", + discard_const_p(char *, kwnames), + &py_name, &io.in.address, &py_dest, + &io.in.nb_flags, + &io.in.broadcast, + &io.in.ttl, &io.in.timeout, &io.in.retries)) { + return NULL; + } + + if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) + return NULL; + + if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) + return NULL; + + status = nbt_name_refresh(node->socket, NULL, &io); + + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetNTSTATUS(status); + return NULL; + } + + ret = PyTuple_New(3); + if (ret == NULL) + return NULL; + PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); + + py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); + if (py_name == NULL) + return NULL; + + PyTuple_SetItem(ret, 1, py_name); + + PyTuple_SetItem(ret, 2, PyString_FromString(io.out.reply_addr)); + + PyTuple_SetItem(ret, 3, PyInt_FromLong(io.out.rcode)); + + return ret; +} + +static PyObject *py_nbt_name_release(PyObject *self, PyObject *args, PyObject *kwargs) +{ + return Py_None; /* FIXME */ +} + +static PyMethodDef py_nbt_methods[] = { + { "query_name", (PyCFunction)py_nbt_name_query, METH_VARARGS|METH_KEYWORDS, + "S.query_name(name, dest, broadcast=True, wins=False, timeout=0, retries=3) -> (reply_from, name, reply_addr)\n" + "Query for a NetBIOS name" }, + { "register_name", (PyCFunction)py_nbt_name_register, METH_VARARGS|METH_KEYWORDS, + "S.register_name(name, address, dest, register_demand=True, broadcast=True, multi_homed=True, ttl=0, timeout=0, retries=0) -> (reply_from, name, reply_addr, rcode)\n" + "Register a new name" }, + { "release_name", (PyCFunction)py_nbt_name_release, METH_VARARGS|METH_KEYWORDS, "S.release_name(name, address, dest, nb_flags=0, broadcast=true, timeout=0, retries=3) -> (reply_from, name, reply_addr, rcode)\n" + "release a previously registered name" }, + { "refresh_name", (PyCFunction)py_nbt_name_refresh, METH_VARARGS|METH_KEYWORDS, "S.refresh_name(name, address, dest, nb_flags=0, broadcast=True, ttl=0, timeout=0, retries=0) -> (reply_from, name, reply_addr, rcode)\n" + "release a previously registered name" }, + { "name_status", (PyCFunction)py_nbt_name_status, METH_VARARGS|METH_KEYWORDS, + "S.name_status(name, dest, timeout=0, retries=0) -> (reply_from, name, status)\n" + "Find the status of a name" }, + + { NULL } +}; + +PyTypeObject nbt_node_Type = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "netbios.Node", + .tp_basicsize = sizeof(nbt_node_Object), + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_new = py_nbt_node_init, + .tp_dealloc = py_nbt_node_dealloc, + .tp_methods = py_nbt_methods, + .tp_doc = "Node()\n" + "Create a new NetBIOS node\n" +}; + +void initnetbios(void) +{ + PyObject *mod; + if (PyType_Ready(&nbt_node_Type) < 0) + return; + + mod = Py_InitModule3("netbios", NULL, "NetBIOS over TCP/IP support"); + + Py_INCREF((PyObject *)&nbt_node_Type); + PyModule_AddObject(mod, "Node", (PyObject *)&nbt_node_Type); +} diff --git a/source4/libcli/swig/libcli_nbt.i b/source4/libcli/swig/libcli_nbt.i deleted file mode 100644 index e4e366873f..0000000000 --- a/source4/libcli/swig/libcli_nbt.i +++ /dev/null @@ -1,101 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Swig interface to libcli_nbt library. - - Copyright (C) 2006 Tim Potter - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -%module libcli_nbt - -%{ - -#include "includes.h" -#include "lib/talloc/talloc.h" -#include "libcli/nbt/libnbt.h" -#include "param/param.h" -#include "lib/events/events.h" - -/* Undo strcpy safety macro as it's used by swig )-: */ - -#undef strcpy - -%} - -%import "stdint.i" -%import "../util/errors.i" -%import "../../lib/talloc/talloc.i" -%import "../../lib/events/events.i" - -/* Function prototypes */ -struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct smb_iconv_convenience *iconv_convenience); - -enum nbt_name_type { - NBT_NAME_CLIENT=0x00, - NBT_NAME_MS=0x01, - NBT_NAME_USER=0x03, - NBT_NAME_SERVER=0x20, - NBT_NAME_PDC=0x1B, - NBT_NAME_LOGON=0x1C, - NBT_NAME_MASTER=0x1D, - NBT_NAME_BROWSER=0x1E -}; - -struct nbt_name { - const char *name; - const char *scope; - enum nbt_name_type type; -}; - -%rename(data_in) in; -%rename(data_out) out; - -struct nbt_name_query { - struct { - struct nbt_name name; - const char *dest_addr; - bool broadcast; - bool wins_lookup; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - int16_t num_addrs; - const char **reply_addrs; - } out; -}; - -%include "carrays.i" -%array_functions(char *, char_ptr_array); - -NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); - -%{ -NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io) -{ - return nbt_name_query(nbtsock, mem_ctx, io); -} -%} diff --git a/source4/libcli/swig/libcli_nbt.py b/source4/libcli/swig/libcli_nbt.py deleted file mode 100644 index a26aa6092e..0000000000 --- a/source4/libcli/swig/libcli_nbt.py +++ /dev/null @@ -1,127 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.35 -# -# Don't modify this file, modify the SWIG interface instead. - -import _libcli_nbt -import new -new_instancemethod = new.instancemethod -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. -def _swig_setattr_nondynamic(self,class_type,name,value,static=1): - if (name == "thisown"): return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'PySwigObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - if (not static) or hasattr(self,name): - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - -def _swig_setattr(self,class_type,name,value): - return _swig_setattr_nondynamic(self,class_type,name,value,0) - -def _swig_getattr(self,class_type,name): - if (name == "thisown"): return self.this.own() - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError,name - -def _swig_repr(self): - try: strthis = "proxy of " + self.this.__repr__() - except: strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -import types -try: - _object = types.ObjectType - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 -del types - - -def _swig_setattr_nondynamic_method(set): - def set_attr(self,name,value): - if (name == "thisown"): return self.this.own(value) - if hasattr(self,name) or (name == "this"): - set(self,name,value) - else: - raise AttributeError("You cannot add attributes to %s" % self) - return set_attr - - -import events -nbt_name_socket_init = _libcli_nbt.nbt_name_socket_init -NBT_NAME_CLIENT = _libcli_nbt.NBT_NAME_CLIENT -NBT_NAME_MS = _libcli_nbt.NBT_NAME_MS -NBT_NAME_USER = _libcli_nbt.NBT_NAME_USER -NBT_NAME_SERVER = _libcli_nbt.NBT_NAME_SERVER -NBT_NAME_PDC = _libcli_nbt.NBT_NAME_PDC -NBT_NAME_LOGON = _libcli_nbt.NBT_NAME_LOGON -NBT_NAME_MASTER = _libcli_nbt.NBT_NAME_MASTER -NBT_NAME_BROWSER = _libcli_nbt.NBT_NAME_BROWSER -class nbt_name(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - name = _swig_property(_libcli_nbt.nbt_name_name_get, _libcli_nbt.nbt_name_name_set) - scope = _swig_property(_libcli_nbt.nbt_name_scope_get, _libcli_nbt.nbt_name_scope_set) - type = _swig_property(_libcli_nbt.nbt_name_type_get, _libcli_nbt.nbt_name_type_set) - def __init__(self, *args, **kwargs): - _libcli_nbt.nbt_name_swiginit(self,_libcli_nbt.new_nbt_name(*args, **kwargs)) - __swig_destroy__ = _libcli_nbt.delete_nbt_name -nbt_name_swigregister = _libcli_nbt.nbt_name_swigregister -nbt_name_swigregister(nbt_name) - -class nbt_name_query(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - data_out = _swig_property(_libcli_nbt.nbt_name_query_data_out_get) - data_in = _swig_property(_libcli_nbt.nbt_name_query_data_in_get) - def __init__(self, *args, **kwargs): - _libcli_nbt.nbt_name_query_swiginit(self,_libcli_nbt.new_nbt_name_query(*args, **kwargs)) - __swig_destroy__ = _libcli_nbt.delete_nbt_name_query -nbt_name_query_swigregister = _libcli_nbt.nbt_name_query_swigregister -nbt_name_query_swigregister(nbt_name_query) - -class nbt_name_query_out(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - reply_from = _swig_property(_libcli_nbt.nbt_name_query_out_reply_from_get, _libcli_nbt.nbt_name_query_out_reply_from_set) - name = _swig_property(_libcli_nbt.nbt_name_query_out_name_get, _libcli_nbt.nbt_name_query_out_name_set) - num_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_num_addrs_get, _libcli_nbt.nbt_name_query_out_num_addrs_set) - reply_addrs = _swig_property(_libcli_nbt.nbt_name_query_out_reply_addrs_get, _libcli_nbt.nbt_name_query_out_reply_addrs_set) - def __init__(self, *args, **kwargs): - _libcli_nbt.nbt_name_query_out_swiginit(self,_libcli_nbt.new_nbt_name_query_out(*args, **kwargs)) - __swig_destroy__ = _libcli_nbt.delete_nbt_name_query_out -nbt_name_query_out_swigregister = _libcli_nbt.nbt_name_query_out_swigregister -nbt_name_query_out_swigregister(nbt_name_query_out) - -class nbt_name_query_in(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - name = _swig_property(_libcli_nbt.nbt_name_query_in_name_get, _libcli_nbt.nbt_name_query_in_name_set) - dest_addr = _swig_property(_libcli_nbt.nbt_name_query_in_dest_addr_get, _libcli_nbt.nbt_name_query_in_dest_addr_set) - broadcast = _swig_property(_libcli_nbt.nbt_name_query_in_broadcast_get, _libcli_nbt.nbt_name_query_in_broadcast_set) - wins_lookup = _swig_property(_libcli_nbt.nbt_name_query_in_wins_lookup_get, _libcli_nbt.nbt_name_query_in_wins_lookup_set) - timeout = _swig_property(_libcli_nbt.nbt_name_query_in_timeout_get, _libcli_nbt.nbt_name_query_in_timeout_set) - retries = _swig_property(_libcli_nbt.nbt_name_query_in_retries_get, _libcli_nbt.nbt_name_query_in_retries_set) - def __init__(self, *args, **kwargs): - _libcli_nbt.nbt_name_query_in_swiginit(self,_libcli_nbt.new_nbt_name_query_in(*args, **kwargs)) - __swig_destroy__ = _libcli_nbt.delete_nbt_name_query_in -nbt_name_query_in_swigregister = _libcli_nbt.nbt_name_query_in_swigregister -nbt_name_query_in_swigregister(nbt_name_query_in) - -new_char_ptr_array = _libcli_nbt.new_char_ptr_array -delete_char_ptr_array = _libcli_nbt.delete_char_ptr_array -char_ptr_array_getitem = _libcli_nbt.char_ptr_array_getitem -char_ptr_array_setitem = _libcli_nbt.char_ptr_array_setitem -do_nbt_name_query = _libcli_nbt.do_nbt_name_query - - diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c deleted file mode 100644 index 2deec98cb5..0000000000 --- a/source4/libcli/swig/libcli_nbt_wrap.c +++ /dev/null @@ -1,4771 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.35 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -#define SWIGPYTHON -#define SWIG_PYTHON_NO_BUILD_NONE -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - - - -/* Python.h has to appear first */ -#include - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic CAPI SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the swig runtime code. - In 99.9% of the cases, swig just needs to declare them as 'static'. - - But only do this if is strictly necessary, ie, if you have problems - with your compiler or so. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The swig conversion methods, as ConvertPtr, return and integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old swig versions, you usually write code as: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit as: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - that seems to be the same, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - requires also to SWIG_ConvertPtr to return new result values, as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - swig errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() - - - */ -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* think of this as a c++ template<> or a scheme macro */ -#define SWIG_TypeCheck_Template(comparison, ty) \ - if (ty) { \ - swig_cast_info *iter = ty->cast; \ - while (iter) { \ - if (comparison) { \ - if (iter == ty->cast) return iter; \ - /* Move iter to the top of the linked list */ \ - iter->prev->next = iter->next; \ - if (iter->next) \ - iter->next->prev = iter->prev; \ - iter->next = ty->cast; \ - iter->prev = 0; \ - if (ty->cast) ty->cast->prev = iter; \ - ty->cast = iter; \ - return iter; \ - } \ - iter = iter->next; \ - } \ - } \ - return 0 - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); -} - -/* Same as previous function, except strcmp is replaced with a pointer comparison */ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { - SWIG_TypeCheck_Template(iter->type == from, into); -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - register size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -/* Add PyOS_snprintf for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# define PyOS_snprintf _snprintf -# else -# define PyOS_snprintf snprintf -# endif -#endif - -/* A crude PyString_FromFormat implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 - -#ifndef SWIG_PYBUFFER_SIZE -# define SWIG_PYBUFFER_SIZE 1024 -#endif - -static PyObject * -PyString_FromFormat(const char *fmt, ...) { - va_list ap; - char buf[SWIG_PYBUFFER_SIZE * 2]; - int res; - va_start(ap, fmt); - res = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); -} -#endif - -/* Add PyObject_Del for old Pythons */ -#if PY_VERSION_HEX < 0x01060000 -# define PyObject_Del(op) PyMem_DEL((op)) -#endif -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* A crude PyExc_StopIteration exception for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# ifndef PyExc_StopIteration -# define PyExc_StopIteration PyExc_RuntimeError -# endif -# ifndef PyObject_GenericGetAttr -# define PyObject_GenericGetAttr 0 -# endif -#endif -/* Py_NotImplemented is defined in 2.1 and up. */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef Py_NotImplemented -# define Py_NotImplemented PyExc_RuntimeError -# endif -#endif - - -/* A crude PyString_AsStringAndSize implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef PyString_AsStringAndSize -# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} -# endif -#endif - -/* PySequence_Size for old Pythons */ -#if PY_VERSION_HEX < 0x02000000 -# ifndef PySequence_Size -# define PySequence_Size PySequence_Length -# endif -#endif - - -/* PyBool_FromLong for old Pythons */ -#if PY_VERSION_HEX < 0x02030000 -static -PyObject *PyBool_FromLong(long ok) -{ - PyObject *result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; -} -#endif - -/* Py_ssize_t for old Pythons */ -/* This code is as recommended by: */ -/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -# define PY_SSIZE_T_MIN INT_MIN -#endif - -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - PyErr_Clear(); - Py_XINCREF(type); - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_SetString(PyExc_RuntimeError, mesg); - } -} - - - -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ -# define SWIG_PYTHON_USE_GIL -# endif -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# ifndef SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif - -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) PySwigClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, (char *) msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { - PyDict_SetItemString(d, (char*) name, obj); - Py_DECREF(obj); -} - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { -#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -#else - PyObject* o2; - PyObject* o3; - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyTuple_Check(result)) { - o2 = result; - result = PyTuple_New(1); - PyTuple_SET_ITEM(result, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SET_ITEM(o3, 0, obj); - o2 = result; - result = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return result; -#endif -} - -/* Unpack the argument tuple */ - -SWIGINTERN int -SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), (int)min); - return 0; - } - } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - register Py_ssize_t l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), (int)min, (int)l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), (int)max, (int)l); - return 0; - } else { - register int i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* How to access Py_None */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_BUILD_NONE -# ifndef SWIG_PYTHON_BUILD_NONE -# define SWIG_PYTHON_BUILD_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_BUILD_NONE -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue((char*)""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* PySwigClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; -} PySwigClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - PySwigClientData *data = (PySwigClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME PySwigClientData * -PySwigClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; -#else - data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); -#endif - if (data->newraw) { - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - } else { - data->newargs = obj; - } - Py_INCREF(data->newargs); - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - int flags; - Py_INCREF(data->destroy); - flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - return data; - } -} - -SWIGRUNTIME void -PySwigClientData_Del(PySwigClientData* data) -{ - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); -} - -/* =============== PySwigObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -} PySwigObject; - -SWIGRUNTIME PyObject * -PySwigObject_long(PySwigObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -PySwigObject_format(const char* fmt, PySwigObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { - PyObject *ofmt = PyString_FromString(fmt); - if (ofmt) { - res = PyString_Format(ofmt,args); - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -PySwigObject_oct(PySwigObject *v) -{ - return PySwigObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -PySwigObject_hex(PySwigObject *v) -{ - return PySwigObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -#ifdef METH_NOARGS -PySwigObject_repr(PySwigObject *v) -#else -PySwigObject_repr(PySwigObject *v, PyObject *args) -#endif -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *hex = PySwigObject_hex(v); - PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); - Py_DECREF(hex); - if (v->next) { -#ifdef METH_NOARGS - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); -#else - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); -#endif - PyString_ConcatAndDel(&repr,nrep); - } - return repr; -} - -SWIGRUNTIME int -PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ -#ifdef METH_NOARGS - PyObject *repr = PySwigObject_repr(v); -#else - PyObject *repr = PySwigObject_repr(v, NULL); -#endif - if (repr) { - fputs(PyString_AsString(repr), fp); - Py_DECREF(repr); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -PySwigObject_str(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? - PyString_FromString(result) : 0; -} - -SWIGRUNTIME int -PySwigObject_compare(PySwigObject *v, PySwigObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigObject_Check(PyObject *op) { - return ((op)->ob_type == PySwigObject_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -PySwigObject_dealloc(PyObject *v) -{ - PySwigObject *sobj = (PySwigObject *) v; - PyObject *next = sobj->next; - if (sobj->own == SWIG_POINTER_OWN) { - swig_type_info *ty = sobj->ty; - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - if (data->delargs) { - /* we need to create a temporal object to carry the destroy operation */ - PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - Py_XDECREF(res); - } -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - else { - const char *name = SWIG_TypePrettyName(ty); - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); - } -#endif - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -PySwigObject_append(PyObject* v, PyObject* next) -{ - PySwigObject *sobj = (PySwigObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!PySwigObject_Check(next)) { - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -PySwigObject_next(PyObject* v) -#else -PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_disown(PyObject *v) -#else -PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_acquire(PyObject *v) -#else -PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -PySwigObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) -#else - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - PySwigObject *sobj = (PySwigObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v); - } else { - PySwigObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v,args); - } else { - PySwigObject_disown(v,args); - } -#endif - } - return obj; - } -} - -#ifdef METH_O -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#else -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#endif - -#if PY_VERSION_HEX < 0x02020000 -SWIGINTERN PyObject * -PySwigObject_getattr(PySwigObject *sobj,char *name) -{ - return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); -} -#endif - -SWIGRUNTIME PyTypeObject* -_PySwigObject_type(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods PySwigObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)PySwigObject_long, /*nb_int*/ - (unaryfunc)PySwigObject_long, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)PySwigObject_oct, /*nb_oct*/ - (unaryfunc)PySwigObject_hex, /*nb_hex*/ -#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ -#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject pyswigobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigObject", /* tp_name */ - sizeof(PySwigObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigObject_dealloc, /* tp_dealloc */ - (printfunc)PySwigObject_print, /* tp_print */ -#if PY_VERSION_HEX < 0x02020000 - (getattrfunc)PySwigObject_getattr, /* tp_getattr */ -#else - (getattrfunc)0, /* tp_getattr */ -#endif - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigObject_compare, /* tp_compare */ - (reprfunc)PySwigObject_repr, /* tp_repr */ - &PySwigObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigObject_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigobject_type = tmp; - pyswigobject_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigobject_type; -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own) -{ - PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} PySwigPacked; - -SWIGRUNTIME int -PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -PySwigPacked_repr(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return PyString_FromFormat("", result, v->ty->name); - } else { - return PyString_FromFormat("", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -PySwigPacked_str(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return PyString_FromFormat("%s%s", result, v->ty->name); - } else { - return PyString_FromString(v->ty->name); - } -} - -SWIGRUNTIME int -PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigPacked_Check(PyObject *op) { - return ((op)->ob_type == _PySwigPacked_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); -} - -SWIGRUNTIME void -PySwigPacked_dealloc(PyObject *v) -{ - if (PySwigPacked_Check(v)) { - PySwigPacked *sobj = (PySwigPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -_PySwigPacked_type(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject pyswigpacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigPacked", /* tp_name */ - sizeof(PySwigPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigPacked_dealloc, /* tp_dealloc */ - (printfunc)PySwigPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigPacked_compare, /* tp_compare */ - (reprfunc)PySwigPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigpacked_type = tmp; - pyswigpacked_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigpacked_type; -} - -SWIGRUNTIME PyObject * -PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (PySwigPacked_Check(obj)) { - PySwigPacked *sobj = (PySwigPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIMEINLINE PyObject * -_SWIG_This(void) -{ - return PyString_FromString("this"); -} - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -SWIGRUNTIME PySwigObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - if (PySwigObject_Check(pyobj)) { - return (PySwigObject *) pyobj; - } else { - PyObject *obj = 0; -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !PySwigObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - PySwigObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (PySwigObject *)obj; - } -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own == SWIG_POINTER_OWN) { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - if (ptr) *ptr = 0; - return SWIG_OK; - } else { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (own) - *own = 0; - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (PySwigObject *)sobj->next; - } else { - if (ptr) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); - if (own) - *own = *own | SWIG_CAST_NEW_MEMORY; - } - } - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) - *own = *own | sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - return SWIG_OK; - } else { - int res = SWIG_ERROR; - if (flags & SWIG_POINTER_IMPLICIT_CONV) { - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - return res; - } - } -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) { - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) return SWIG_ERROR; - } - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, whitout calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } - return inst; -#else -#if (PY_VERSION_HEX >= 0x02010000) - PyObject *inst; - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - return (PyObject *) inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } -#ifdef Py_TPFLAGS_HAVE_WEAKREFS - inst->in_weakreflist = NULL; -#endif -#ifdef Py_TPFLAGS_GC - PyObject_GC_Init(inst); -#endif - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -#endif -} - -SWIGRUNTIME void -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ - PyObject *dict; -#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - PyDict_SetItem(dict, SWIG_This(), swig_this); - return; - } -#endif - dict = PyObject_GetAttrString(inst, (char*)"__dict__"); - PyDict_SetItem(dict, SWIG_This(), swig_this); - Py_DECREF(dict); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { - return NULL; - } else { - PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - PySwigObject_append((PyObject*) sthis, obj[1]); - } else { - SWIG_Python_SetSwigThis(obj[0], obj[1]); - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - if (!ptr) { - return SWIG_Py_Void(); - } else { - int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - PyObject *robj = PySwigObject_New(ptr, type, own); - PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; - if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - if (inst) { - Py_DECREF(robj); - robj = inst; - } - } - return robj; - } -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -SWIG_Python_DestroyModule(void *vptr) -{ - swig_module_info *swig_module = (swig_module_info *) vptr; - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - PySwigClientData *data = (PySwigClientData *) ty->clientdata; - if (data) PySwigClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ - - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - swig_empty_runtime_method_table); - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -} - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); - return cache; -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = PyString_FromString(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { - descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); - } else { - swig_module_info *swig_module = SWIG_Python_GetModule(); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { - obj = PyCObject_FromVoidPtr(descriptor, NULL); - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); - } else { - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - } - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -PySwigObject_GetDesc(PyObject *self) -{ - PySwigObject *v = (PySwigObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : (char*)""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && PySwigObject_Check(obj)) { - const char *otype = (const char *) PySwigObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? PyString_AsString(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } - } - return result; -} - - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_TALLOC_CTX swig_types[0] -#define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_event_context swig_types[2] -#define SWIGTYPE_p_int swig_types[3] -#define SWIGTYPE_p_long_long swig_types[4] -#define SWIGTYPE_p_nbt_name swig_types[5] -#define SWIGTYPE_p_nbt_name_query swig_types[6] -#define SWIGTYPE_p_nbt_name_query_in swig_types[7] -#define SWIGTYPE_p_nbt_name_query_out swig_types[8] -#define SWIGTYPE_p_nbt_name_socket swig_types[9] -#define SWIGTYPE_p_p_char swig_types[10] -#define SWIGTYPE_p_short swig_types[11] -#define SWIGTYPE_p_signed_char swig_types[12] -#define SWIGTYPE_p_smb_iconv_convenience swig_types[13] -#define SWIGTYPE_p_unsigned_char swig_types[14] -#define SWIGTYPE_p_unsigned_int swig_types[15] -#define SWIGTYPE_p_unsigned_long_long swig_types[16] -#define SWIGTYPE_p_unsigned_short swig_types[17] -static swig_type_info *swig_types[19]; -static swig_module_info swig_module = {swig_types, 18, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - -#if (PY_VERSION_HEX <= 0x02000000) -# if !defined(SWIG_PYTHON_CLASSIC) -# error "This python version requires swig to be run with the '-classic' option" -# endif -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodern' option" -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodernargs' option" -#endif -#ifndef METH_O -# error "This python version requires swig to be run with the '-nofastunpack' option" -#endif -#ifdef SWIG_TypeQuery -# undef SWIG_TypeQuery -#endif -#define SWIG_TypeQuery SWIG_Python_TypeQuery - -/*----------------------------------------------- - @(target):= _libcli_nbt.so - ------------------------------------------------*/ -#define SWIG_init init_libcli_nbt - -#define SWIG_name "_libcli_nbt" - -#define SWIGVERSION 0x010335 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - - -#include "includes.h" -#include "lib/talloc/talloc.h" -#include "libcli/nbt/libnbt.h" -#include "param/param.h" -#include "lib/events/events.h" - -/* Undo strcpy safety macro as it's used by swig )-: */ - -#undef strcpy - - - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject * -SWIG_From_int (int value) -{ - return SWIG_From_long (value); -} - - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ - if (PyString_Check(obj)) { - char *cstr; Py_ssize_t len; - PyString_AsStringAndSize(obj, &cstr, &len); - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation. To warranty that, if you define - SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string - buffer is always returned. - - The default behavior is just to return the pointer value, - so, be careful. - */ -#if defined(SWIG_PYTHON_SAFE_CSTRINGS) - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); - *alloc = SWIG_NEWOBJ; - } - else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { - *cptr = PyString_AsString(obj); - } - } - if (psize) *psize = len + 1; - return SWIG_OK; - } else { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} - - - - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - if (carray) { - if (size > INT_MAX) { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - return pchar_descriptor ? - SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); - } else { - return PyString_FromStringAndSize(carray, (int)(size)); - } - } else { - return SWIG_Py_Void(); - } -} - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtr(const char *cptr) -{ - return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); -} - - -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; - } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (int)(v); - } - } - return res; -} - - -typedef struct { - const char *reply_from; - struct nbt_name name; - int16_t num_addrs; - const char **reply_addrs; - } nbt_name_query_out; - - - -typedef struct { - struct nbt_name name; - const char *dest_addr; - bool broadcast; - bool wins_lookup; - int timeout; /* in seconds */ - int retries; - } nbt_name_query_in; - - - -SWIGINTERN int -SWIG_AsVal_short (PyObject * obj, short *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < SHRT_MIN || v > SHRT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (short)(v); - } - } - return res; -} - - -SWIGINTERNINLINE PyObject * -SWIG_From_short (short value) -{ - return SWIG_From_long (value); -} - - -SWIGINTERN int -SWIG_AsVal_bool (PyObject *obj, bool *val) -{ - int r = PyObject_IsTrue(obj); - if (r == -1) - return SWIG_ERROR; - if (val) *val = r ? true : false; - return SWIG_OK; -} - - -SWIGINTERNINLINE PyObject* - SWIG_From_bool (bool value) -{ - return PyBool_FromLong(value ? 1 : 0); -} - - - static char * *new_char_ptr_array(size_t nelements) { - return (char * *)malloc((nelements)*sizeof(char *)); - } - - static void delete_char_ptr_array(char * *ary) { - free((char*)ary); - } - - static char * char_ptr_array_getitem(char * *ary, size_t index) { - return ary[index]; - } - static void char_ptr_array_setitem(char * *ary, size_t index, char * value) { - ary[index] = value; - } - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) -{ - if (PyInt_Check(obj)) { - long v = PyInt_AsLong(obj); - if (v >= 0) { - if (val) *val = v; - return SWIG_OK; - } else { - return SWIG_OverflowError; - } - } else if (PyLong_Check(obj)) { - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { - if (val) *val = (unsigned long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERNINLINE int -SWIG_AsVal_size_t (PyObject * obj, size_t *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = (size_t)(v); - return res; -} - - -NTSTATUS do_nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io) -{ - return nbt_name_query(nbtsock, mem_ctx, io); -} - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_nbt_name_socket_init(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - struct event_context *arg2 = (struct event_context *) 0 ; - struct smb_iconv_convenience *arg3 = (struct smb_iconv_convenience *) 0 ; - struct nbt_name_socket *result = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "event_ctx",(char *) "iconv_convenience", NULL - }; - - arg2 = event_context_init(NULL); - arg1 = NULL; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:nbt_name_socket_init",kwnames,&obj0,&obj1)) SWIG_fail; - if (obj0) { - res2 = SWIG_ConvertPtr(obj0, &argp2,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_socket_init" "', argument " "2"" of type '" "struct event_context *""'"); - } - arg2 = (struct event_context *)(argp2); - } - if (obj1) { - res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_smb_iconv_convenience, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "nbt_name_socket_init" "', argument " "3"" of type '" "struct smb_iconv_convenience *""'"); - } - arg3 = (struct smb_iconv_convenience *)(argp3); - } - result = (struct nbt_name_socket *)nbt_name_socket_init(arg1,arg2,arg3); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_socket, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - char *arg2 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_name_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_name_set" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_name_set" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - if (arg2) { - size_t size = strlen((const char *)((const char *)(arg2))) + 1; - arg1->name = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); - } else { - arg1->name = 0; - } - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_name_get" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - result = (char *) ((arg1)->name); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_scope_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - char *arg2 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_scope_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_scope_set" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_scope_set" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - if (arg2) { - size_t size = strlen((const char *)((const char *)(arg2))) + 1; - arg1->scope = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); - } else { - arg1->scope = 0; - } - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_scope_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_scope_get" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - result = (char *) ((arg1)->scope); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_type_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - enum nbt_name_type arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_type_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_type_set" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_type_set" "', argument " "2"" of type '" "enum nbt_name_type""'"); - } - arg2 = (enum nbt_name_type)(val2); - if (arg1) (arg1)->type = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_type_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - enum nbt_name_type result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_type_get" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - result = (enum nbt_name_type) ((arg1)->type); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_nbt_name",0,0,0)) SWIG_fail; - result = (struct nbt_name *)calloc(1, sizeof(struct nbt_name)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name *arg1 = (struct nbt_name *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name" "', argument " "1"" of type '" "struct nbt_name *""'"); - } - arg1 = (struct nbt_name *)(argp1); - free((char *) arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *nbt_name_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *nbt_name_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -SWIGINTERN PyObject *_wrap_nbt_name_query_data_out_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; - nbt_name_query_out *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_data_out_get" "', argument " "1"" of type '" "struct nbt_name_query *""'"); - } - arg1 = (struct nbt_name_query *)(argp1); - result = (nbt_name_query_out *)& ((arg1)->out); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_data_in_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; - nbt_name_query_in *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_data_in_get" "', argument " "1"" of type '" "struct nbt_name_query *""'"); - } - arg1 = (struct nbt_name_query *)(argp1); - result = (nbt_name_query_in *)& ((arg1)->in); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name_query *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query",0,0,0)) SWIG_fail; - result = (struct nbt_name_query *)calloc(1, sizeof(struct nbt_name_query)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - struct nbt_name_query *arg1 = (struct nbt_name_query *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query" "', argument " "1"" of type '" "struct nbt_name_query *""'"); - } - arg1 = (struct nbt_name_query *)(argp1); - free((char *) arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *nbt_name_query_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *nbt_name_query_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - char *arg2 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_reply_from_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_from_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_reply_from_set" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - if (arg2) { - size_t size = strlen((const char *)((const char *)(arg2))) + 1; - arg1->reply_from = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); - } else { - arg1->reply_from = 0; - } - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_from_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_from_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - result = (char *) ((arg1)->reply_from); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - struct nbt_name *arg2 = (struct nbt_name *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_name_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_name_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_name_set" "', argument " "2"" of type '" "struct nbt_name *""'"); - } - arg2 = (struct nbt_name *)(argp2); - if (arg1) (arg1)->name = *arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - struct nbt_name *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_name_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - result = (struct nbt_name *)& ((arg1)->name); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_num_addrs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - int16_t arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - short val2 ; - int ecode2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_num_addrs_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_num_addrs_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - ecode2 = SWIG_AsVal_short(swig_obj[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_out_num_addrs_set" "', argument " "2"" of type '" "int16_t""'"); - } - arg2 = (int16_t)(val2); - if (arg1) (arg1)->num_addrs = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_num_addrs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - int16_t result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_num_addrs_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - result = (int16_t) ((arg1)->num_addrs); - resultobj = SWIG_From_short((short)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_addrs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - char **arg2 = (char **) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_out_reply_addrs_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_addrs_set" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_p_char, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_out_reply_addrs_set" "', argument " "2"" of type '" "char const **""'"); - } - arg2 = (char **)(argp2); - if (arg1) (arg1)->reply_addrs = (char const **)arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_out_reply_addrs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - char **result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_out_reply_addrs_get" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - result = (char **) ((arg1)->reply_addrs); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_out",0,0,0)) SWIG_fail; - result = (nbt_name_query_out *)calloc(1, sizeof(nbt_name_query_out)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_out *arg1 = (nbt_name_query_out *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query_out" "', argument " "1"" of type '" "nbt_name_query_out *""'"); - } - arg1 = (nbt_name_query_out *)(argp1); - free((char *) arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *nbt_name_query_out_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query_out, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *nbt_name_query_out_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - struct nbt_name *arg2 = (struct nbt_name *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_name_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_name_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_nbt_name, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_in_name_set" "', argument " "2"" of type '" "struct nbt_name *""'"); - } - arg2 = (struct nbt_name *)(argp2); - if (arg1) (arg1)->name = *arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - struct nbt_name *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_name_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - result = (struct nbt_name *)& ((arg1)->name); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_dest_addr_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - char *arg2 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_dest_addr_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_dest_addr_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "nbt_name_query_in_dest_addr_set" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - if (arg2) { - size_t size = strlen((const char *)((const char *)(arg2))) + 1; - arg1->dest_addr = (char const *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg2, sizeof(char)*(size)); - } else { - arg1->dest_addr = 0; - } - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_dest_addr_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_dest_addr_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - result = (char *) ((arg1)->dest_addr); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_broadcast_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - bool arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_broadcast_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_broadcast_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_broadcast_set" "', argument " "2"" of type '" "bool""'"); - } - arg2 = (bool)(val2); - if (arg1) (arg1)->broadcast = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_broadcast_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - bool result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_broadcast_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - result = (bool) ((arg1)->broadcast); - resultobj = SWIG_From_bool((bool)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_wins_lookup_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - bool arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_wins_lookup_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_wins_lookup_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_wins_lookup_set" "', argument " "2"" of type '" "bool""'"); - } - arg2 = (bool)(val2); - if (arg1) (arg1)->wins_lookup = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_wins_lookup_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - bool result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_wins_lookup_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - result = (bool) ((arg1)->wins_lookup); - resultobj = SWIG_From_bool((bool)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_timeout_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_timeout_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_timeout_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_timeout_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - if (arg1) (arg1)->timeout = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_timeout_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_timeout_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - result = (int) ((arg1)->timeout); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_retries_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject *swig_obj[2] ; - - if (!SWIG_Python_UnpackTuple(args,"nbt_name_query_in_retries_set",2,2,swig_obj)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_retries_set" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "nbt_name_query_in_retries_set" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - if (arg1) (arg1)->retries = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_nbt_name_query_in_retries_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "nbt_name_query_in_retries_get" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - result = (int) ((arg1)->retries); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_in",0,0,0)) SWIG_fail; - result = (nbt_name_query_in *)calloc(1, sizeof(nbt_name_query_in)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - nbt_name_query_in *arg1 = (nbt_name_query_in *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_nbt_name_query_in" "', argument " "1"" of type '" "nbt_name_query_in *""'"); - } - arg1 = (nbt_name_query_in *)(argp1); - free((char *) arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *nbt_name_query_in_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_nbt_name_query_in, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *nbt_name_query_in_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -SWIGINTERN PyObject *_wrap_new_char_ptr_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - size_t arg1 ; - char **result = 0 ; - size_t val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "nelements", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:new_char_ptr_array",kwnames,&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_size_t(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_char_ptr_array" "', argument " "1"" of type '" "size_t""'"); - } - arg1 = (size_t)(val1); - result = (char **)new_char_ptr_array(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_char_ptr_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - char **arg1 = (char **) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "ary", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:delete_char_ptr_array",kwnames,&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_char, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_char_ptr_array" "', argument " "1"" of type '" "char **""'"); - } - arg1 = (char **)(argp1); - delete_char_ptr_array(arg1); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_char_ptr_array_getitem(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - char **arg1 = (char **) 0 ; - size_t arg2 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - size_t val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "ary",(char *) "index", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:char_ptr_array_getitem",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_char, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "char_ptr_array_getitem" "', argument " "1"" of type '" "char **""'"); - } - arg1 = (char **)(argp1); - ecode2 = SWIG_AsVal_size_t(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "char_ptr_array_getitem" "', argument " "2"" of type '" "size_t""'"); - } - arg2 = (size_t)(val2); - result = (char *)char_ptr_array_getitem(arg1,arg2); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_char_ptr_array_setitem(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - char **arg1 = (char **) 0 ; - size_t arg2 ; - char *arg3 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - size_t val2 ; - int ecode2 = 0 ; - int res3 ; - char *buf3 = 0 ; - int alloc3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "ary",(char *) "index",(char *) "value", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:char_ptr_array_setitem",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_char, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "char_ptr_array_setitem" "', argument " "1"" of type '" "char **""'"); - } - arg1 = (char **)(argp1); - ecode2 = SWIG_AsVal_size_t(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "char_ptr_array_setitem" "', argument " "2"" of type '" "size_t""'"); - } - arg2 = (size_t)(val2); - res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "char_ptr_array_setitem" "', argument " "3"" of type '" "char *""'"); - } - arg3 = (char *)(buf3); - char_ptr_array_setitem(arg1,arg2,arg3); - resultobj = SWIG_Py_Void(); - if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); - return resultobj; -fail: - if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - struct nbt_name_socket *arg1 = (struct nbt_name_socket *) 0 ; - TALLOC_CTX *arg2 = (TALLOC_CTX *) 0 ; - struct nbt_name_query *arg3 = (struct nbt_name_query *) 0 ; - NTSTATUS result; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "nbtsock",(char *) "io", NULL - }; - - arg2 = NULL; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:do_nbt_name_query",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_nbt_name_socket, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "do_nbt_name_query" "', argument " "1"" of type '" "struct nbt_name_socket *""'"); - } - arg1 = (struct nbt_name_socket *)(argp1); - res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_nbt_name_query, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "do_nbt_name_query" "', argument " "3"" of type '" "struct nbt_name_query *""'"); - } - arg3 = (struct nbt_name_query *)(argp3); - result = do_nbt_name_query(arg1,arg2,arg3); - if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - return resultobj; -fail: - return NULL; -} - - -static PyMethodDef SwigMethods[] = { - { (char *)"nbt_name_socket_init", (PyCFunction) _wrap_nbt_name_socket_init, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"nbt_name_name_set", _wrap_nbt_name_name_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_name_get", (PyCFunction)_wrap_nbt_name_name_get, METH_O, NULL}, - { (char *)"nbt_name_scope_set", _wrap_nbt_name_scope_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_scope_get", (PyCFunction)_wrap_nbt_name_scope_get, METH_O, NULL}, - { (char *)"nbt_name_type_set", _wrap_nbt_name_type_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_type_get", (PyCFunction)_wrap_nbt_name_type_get, METH_O, NULL}, - { (char *)"new_nbt_name", (PyCFunction)_wrap_new_nbt_name, METH_NOARGS, NULL}, - { (char *)"delete_nbt_name", (PyCFunction)_wrap_delete_nbt_name, METH_O, NULL}, - { (char *)"nbt_name_swigregister", nbt_name_swigregister, METH_VARARGS, NULL}, - { (char *)"nbt_name_swiginit", nbt_name_swiginit, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_data_out_get", (PyCFunction)_wrap_nbt_name_query_data_out_get, METH_O, NULL}, - { (char *)"nbt_name_query_data_in_get", (PyCFunction)_wrap_nbt_name_query_data_in_get, METH_O, NULL}, - { (char *)"new_nbt_name_query", (PyCFunction)_wrap_new_nbt_name_query, METH_NOARGS, NULL}, - { (char *)"delete_nbt_name_query", (PyCFunction)_wrap_delete_nbt_name_query, METH_O, NULL}, - { (char *)"nbt_name_query_swigregister", nbt_name_query_swigregister, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_swiginit", nbt_name_query_swiginit, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_reply_from_set", _wrap_nbt_name_query_out_reply_from_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_reply_from_get", (PyCFunction)_wrap_nbt_name_query_out_reply_from_get, METH_O, NULL}, - { (char *)"nbt_name_query_out_name_set", _wrap_nbt_name_query_out_name_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_name_get", (PyCFunction)_wrap_nbt_name_query_out_name_get, METH_O, NULL}, - { (char *)"nbt_name_query_out_num_addrs_set", _wrap_nbt_name_query_out_num_addrs_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_num_addrs_get", (PyCFunction)_wrap_nbt_name_query_out_num_addrs_get, METH_O, NULL}, - { (char *)"nbt_name_query_out_reply_addrs_set", _wrap_nbt_name_query_out_reply_addrs_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_reply_addrs_get", (PyCFunction)_wrap_nbt_name_query_out_reply_addrs_get, METH_O, NULL}, - { (char *)"new_nbt_name_query_out", (PyCFunction)_wrap_new_nbt_name_query_out, METH_NOARGS, NULL}, - { (char *)"delete_nbt_name_query_out", (PyCFunction)_wrap_delete_nbt_name_query_out, METH_O, NULL}, - { (char *)"nbt_name_query_out_swigregister", nbt_name_query_out_swigregister, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_out_swiginit", nbt_name_query_out_swiginit, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_name_set", _wrap_nbt_name_query_in_name_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_name_get", (PyCFunction)_wrap_nbt_name_query_in_name_get, METH_O, NULL}, - { (char *)"nbt_name_query_in_dest_addr_set", _wrap_nbt_name_query_in_dest_addr_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_dest_addr_get", (PyCFunction)_wrap_nbt_name_query_in_dest_addr_get, METH_O, NULL}, - { (char *)"nbt_name_query_in_broadcast_set", _wrap_nbt_name_query_in_broadcast_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_broadcast_get", (PyCFunction)_wrap_nbt_name_query_in_broadcast_get, METH_O, NULL}, - { (char *)"nbt_name_query_in_wins_lookup_set", _wrap_nbt_name_query_in_wins_lookup_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_wins_lookup_get", (PyCFunction)_wrap_nbt_name_query_in_wins_lookup_get, METH_O, NULL}, - { (char *)"nbt_name_query_in_timeout_set", _wrap_nbt_name_query_in_timeout_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_timeout_get", (PyCFunction)_wrap_nbt_name_query_in_timeout_get, METH_O, NULL}, - { (char *)"nbt_name_query_in_retries_set", _wrap_nbt_name_query_in_retries_set, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_retries_get", (PyCFunction)_wrap_nbt_name_query_in_retries_get, METH_O, NULL}, - { (char *)"new_nbt_name_query_in", (PyCFunction)_wrap_new_nbt_name_query_in, METH_NOARGS, NULL}, - { (char *)"delete_nbt_name_query_in", (PyCFunction)_wrap_delete_nbt_name_query_in, METH_O, NULL}, - { (char *)"nbt_name_query_in_swigregister", nbt_name_query_in_swigregister, METH_VARARGS, NULL}, - { (char *)"nbt_name_query_in_swiginit", nbt_name_query_in_swiginit, METH_VARARGS, NULL}, - { (char *)"new_char_ptr_array", (PyCFunction) _wrap_new_char_ptr_array, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_char_ptr_array", (PyCFunction) _wrap_delete_char_ptr_array, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"char_ptr_array_getitem", (PyCFunction) _wrap_char_ptr_array_getitem, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"char_ptr_array_setitem", (PyCFunction) _wrap_char_ptr_array_setitem, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"do_nbt_name_query", (PyCFunction) _wrap_do_nbt_name_query, METH_VARARGS | METH_KEYWORDS, NULL}, - { NULL, NULL, 0, NULL } -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *|event *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_nbt_name = {"_p_nbt_name", "struct nbt_name *|nbt_name *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_nbt_name_query = {"_p_nbt_name_query", "struct nbt_name_query *|nbt_name_query *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_nbt_name_query_in = {"_p_nbt_name_query_in", "nbt_name_query_in *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_nbt_name_query_out = {"_p_nbt_name_query_out", "nbt_name_query_out *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_nbt_name_socket = {"_p_nbt_name_socket", "struct nbt_name_socket *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_smb_iconv_convenience = {"_p_smb_iconv_convenience", "struct smb_iconv_convenience *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_TALLOC_CTX, - &_swigt__p_char, - &_swigt__p_event_context, - &_swigt__p_int, - &_swigt__p_long_long, - &_swigt__p_nbt_name, - &_swigt__p_nbt_name_query, - &_swigt__p_nbt_name_query_in, - &_swigt__p_nbt_name_query_out, - &_swigt__p_nbt_name_socket, - &_swigt__p_p_char, - &_swigt__p_short, - &_swigt__p_signed_char, - &_swigt__p_smb_iconv_convenience, - &_swigt__p_unsigned_char, - &_swigt__p_unsigned_int, - &_swigt__p_unsigned_long_long, - &_swigt__p_unsigned_short, -}; - -static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_nbt_name[] = { {&_swigt__p_nbt_name, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_nbt_name_query[] = { {&_swigt__p_nbt_name_query, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_nbt_name_query_in[] = { {&_swigt__p_nbt_name_query_in, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_nbt_name_query_out[] = { {&_swigt__p_nbt_name_query_out, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_nbt_name_socket[] = { {&_swigt__p_nbt_name_socket, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_smb_iconv_convenience[] = { {&_swigt__p_smb_iconv_convenience, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_TALLOC_CTX, - _swigc__p_char, - _swigc__p_event_context, - _swigc__p_int, - _swigc__p_long_long, - _swigc__p_nbt_name, - _swigc__p_nbt_name_query, - _swigc__p_nbt_name_query_in, - _swigc__p_nbt_name_query_out, - _swigc__p_nbt_name_socket, - _swigc__p_p_char, - _swigc__p_short, - _swigc__p_signed_char, - _swigc__p_smb_iconv_convenience, - _swigc__p_unsigned_char, - _swigc__p_unsigned_int, - _swigc__p_unsigned_long_long, - _swigc__p_unsigned_short, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { -{0, 0, 0, 0.0, 0, 0}}; - -#ifdef __cplusplus -} -#endif -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned staticly to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int found, init; - - clientdata = clientdata; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - module_head = &swig_module; - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - found=0; - iter=module_head; - do { - if (iter==&swig_module) { - found=1; - break; - } - iter=iter->next; - } while (iter!= module_head); - - /* if the is found in the list, then all is done and we may leave */ - if (found) return; - /* otherwise we must add out module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpeters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ - /* c-mode */ -#endif -} -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - /* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - - /* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - - typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; - } swig_globalvar; - - typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; - } swig_varlinkobject; - - SWIGINTERN PyObject * - swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { - return PyString_FromString(""); - } - - SWIGINTERN PyObject * - swig_varlink_str(swig_varlinkobject *v) { - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); - return str; - } - - SWIGINTERN int - swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { - PyObject *str = swig_varlink_str(v); - fprintf(fp,"Swig global variables "); - fprintf(fp,"%s\n", PyString_AsString(str)); - Py_DECREF(str); - return 0; - } - - SWIGINTERN void - swig_varlink_dealloc(swig_varlinkobject *v) { - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } - } - - SWIGINTERN PyObject * - swig_varlink_getattr(swig_varlinkobject *v, char *n) { - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN int - swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN PyTypeObject* - swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* Number of items in variable part (ob_size) */ - (char *)"swigvarlink", /* Type name (tp_name) */ - sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ - 0, /* Itemsize (tp_itemsize) */ - (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ - (printfunc) swig_varlink_print, /* Print (tp_print) */ - (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ - (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - varlink_type = tmp; - varlink_type.ob_type = &PyType_Type; - type_init = 1; - } - return &varlink_type; - } - - /* Create a variable linking object for use later */ - SWIGINTERN PyObject * - SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); - } - - SWIGINTERN void - SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - strncpy(gv->name,name,size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; - } - - SWIGINTERN PyObject * - SWIG_globals(void) { - static PyObject *_SWIG_globals = 0; - if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); - return _SWIG_globals; - } - - /* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - - /* Install Constants */ - SWIGINTERN void - SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } - } - - /* -----------------------------------------------------------------------------*/ - /* Fix SwigMethods to carry the callback ptrs when needed */ - /* -----------------------------------------------------------------------------*/ - - SWIGINTERN void - SWIG_Python_FixMethods(PyMethodDef *methods, - swig_const_info *const_table, - swig_type_info **types, - swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (c && (c = strstr(c, "swig_ptr: "))) { - int j; - swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - strncpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } - } - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif -SWIGEXPORT void SWIG_init(void) { - PyObject *m, *d; - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - - m = Py_InitModule((char *) SWIG_name, SwigMethods); - d = PyModule_GetDict(m); - - SWIG_InitializeModule(0); - SWIG_InstallConstants(d,swig_const_table); - - - SWIG_Python_SetConstant(d, "NBT_NAME_CLIENT",SWIG_From_int((int)(NBT_NAME_CLIENT))); - SWIG_Python_SetConstant(d, "NBT_NAME_MS",SWIG_From_int((int)(NBT_NAME_MS))); - SWIG_Python_SetConstant(d, "NBT_NAME_USER",SWIG_From_int((int)(NBT_NAME_USER))); - SWIG_Python_SetConstant(d, "NBT_NAME_SERVER",SWIG_From_int((int)(NBT_NAME_SERVER))); - SWIG_Python_SetConstant(d, "NBT_NAME_PDC",SWIG_From_int((int)(NBT_NAME_PDC))); - SWIG_Python_SetConstant(d, "NBT_NAME_LOGON",SWIG_From_int((int)(NBT_NAME_LOGON))); - SWIG_Python_SetConstant(d, "NBT_NAME_MASTER",SWIG_From_int((int)(NBT_NAME_MASTER))); - SWIG_Python_SetConstant(d, "NBT_NAME_BROWSER",SWIG_From_int((int)(NBT_NAME_BROWSER))); -} - -- cgit From 929adc9efa5cf985f0585214d30d18521aa1a821 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jun 2008 11:24:17 -0400 Subject: Make up the right dependencies now that ldb depends on libevents (This used to be commit 3b8eec7ca334528cad3cdcd5e3fc5ee555d8d0e0) --- source4/libcli/ldap/ldap_ndr.c | 1 + source4/libcli/util/nterr.c | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 3f7cb8f538..a10f80ae2c 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "lib/events/events.h" #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index b1f345016d..7629a14106 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -20,6 +20,7 @@ /* NT error codes. please read nterr.h */ #include "includes.h" +#include "lib/events/events.h" #include "libcli/ldap/ldap.h" typedef struct -- cgit From 2daf2897d5c70c0efbeba9b827c62700b9a9537c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jun 2008 13:00:53 -0400 Subject: Use a custom init function for samba4 that sets a samba4 specific debug function. By default do not debug, this is the most appropriate action for a library as we cannot assume what stderr is use for in the main app. The main app is responsible to set ev_debug_stderr if they so desire. (This used to be commit e566a2f308ac6fb4b526a744f7059b565670aea5) --- source4/libcli/nbt/pynbt.c | 2 +- source4/libcli/swig/libcli_smb_wrap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/pynbt.c b/source4/libcli/nbt/pynbt.c index 626a63ac48..7978bfef90 100644 --- a/source4/libcli/nbt/pynbt.c +++ b/source4/libcli/nbt/pynbt.c @@ -47,7 +47,7 @@ static PyObject *py_nbt_node_init(PyObject *self, PyObject *args, PyObject *kwar if (ret->mem_ctx == NULL) return NULL; - ev = event_context_init(ret->mem_ctx); + ev = s4_event_context_init(ret->mem_ctx); ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, lp_iconv_convenience(global_loadparm)); return (PyObject *)ret; } diff --git a/source4/libcli/swig/libcli_smb_wrap.c b/source4/libcli/swig/libcli_smb_wrap.c index de8e6ba1e4..a3ea079b83 100644 --- a/source4/libcli/swig/libcli_smb_wrap.c +++ b/source4/libcli/swig/libcli_smb_wrap.c @@ -2621,7 +2621,7 @@ SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(s (char *) "host",(char *) "ports",(char *) "resolve_ctx",(char *) "event_ctx", NULL }; - arg5 = event_context_init(NULL); + arg5 = s4_event_context_init(NULL); arg3 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); -- cgit From cceabcd2a4a4282aee8562852de32b29038e12a3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 17 Jun 2008 14:21:02 +0200 Subject: Use friendly NTSTATUS message in python code when possible. (This used to be commit 09cf8c7dd82bb95e2f8782782286869654d96375) --- source4/libcli/util/pyerrors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/util/pyerrors.h b/source4/libcli/util/pyerrors.h index aaa35b4d26..47e6f58b5d 100644 --- a/source4/libcli/util/pyerrors.h +++ b/source4/libcli/util/pyerrors.h @@ -22,7 +22,7 @@ #define PyErr_FromWERROR(err) Py_BuildValue("(i,s)", W_ERROR_V(err), discard_const_p(char, win_errstr(err))) -#define PyErr_FromNTSTATUS(status) Py_BuildValue("(i,s)", NT_STATUS_V(status), discard_const_p(char, nt_errstr(status))) +#define PyErr_FromNTSTATUS(status) Py_BuildValue("(i,s)", NT_STATUS_V(status), discard_const_p(char, get_friendly_nt_error_msg(status))) #define PyErr_SetWERROR(err) \ PyErr_SetObject(PyExc_RuntimeError, PyErr_FromWERROR(err)) -- cgit From 4cd722b912b6ef0dc428cdfb1a7ec14a8e5fd8d1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 27 Jun 2008 09:12:57 +0200 Subject: pynbt: eliminate "initialization from incompatible pointer type" warning by fixing the signature of py_nbt_node_init(). Jelmer - please check! Michael (This used to be commit a7ee17a10f330297dc4d9d15499276b3985c7a51) --- source4/libcli/nbt/pynbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/pynbt.c b/source4/libcli/nbt/pynbt.c index 7978bfef90..e91096630a 100644 --- a/source4/libcli/nbt/pynbt.c +++ b/source4/libcli/nbt/pynbt.c @@ -38,7 +38,7 @@ static void py_nbt_node_dealloc(PyObject *obj) PyObject_Del(obj); } -static PyObject *py_nbt_node_init(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject *py_nbt_node_init(PyTypeObject *self, PyObject *args, PyObject *kwargs) { struct event_context *ev; nbt_node_Object *ret = PyObject_New(nbt_node_Object, &nbt_node_Type); -- cgit From 70ccb7e7ce0154c98b3bb26c4a85b52b4929ecf1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jul 2008 20:16:36 +0200 Subject: libcli/raw: the nttrans setup count is only 8-bit metze (This used to be commit a65599cc83a12ec61e5a6ba6ad9628619a0dc8a3) --- source4/libcli/raw/interfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 8e23510f06..537041c137 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2258,7 +2258,7 @@ struct smb_nttrans { uint8_t max_setup; uint32_t max_param; uint32_t max_data; - uint32_t setup_count; + uint8_t setup_count; uint16_t function; uint8_t *setup; DATA_BLOB params; -- cgit From 7718a89222549d3d38f58193374d7b5d6b0e79fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jul 2008 19:52:23 +0200 Subject: libcli/raw: add a recv_helper hook infrastructure The recv helper will be called when a response comes and the recv helper can decide to let the request on the SMBCLI_REQUEST_RECV when more reponse packets are expected. It's up to the helper function to keep a reference to the in buffers, each incoming response overwrites req->in. metze (This used to be commit 6d84af89ba96627abe142ba7080c24ae2421ed6c) --- source4/libcli/raw/clitransport.c | 16 +++++++++++++++- source4/libcli/raw/libcliraw.h | 8 ++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 34fb96230d..e95ae3271e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -480,8 +480,22 @@ async: /* if this request has an async handler then call that to notify that the reply has been received. This might destroy the request so it must happen last */ - DLIST_REMOVE(transport->pending_recv, req); + req->state = SMBCLI_REQUEST_DONE; + + if (req->recv_helper.fn) { + /* + * let the recv helper decide in + * what state the request really is + */ + req->state = req->recv_helper.fn(req); + + /* if more parts are needed, wait for them */ + if (req->state <= SMBCLI_REQUEST_RECV) { + return NT_STATUS_OK; + } + } + DLIST_REMOVE(transport->pending_recv, req); if (req->async.fn) { req->async.fn(req); } diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 16a98ad66e..d55b4cc42c 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -231,6 +231,14 @@ struct smbcli_request { struct smbcli_session *session; struct smbcli_tree *tree; + /* a receive helper, smbcli_transport_finish_recv will not call + req->async.fn callback handler unless the recv_helper returns + a value > SMBCLI_REQUEST_RECV. */ + struct { + enum smbcli_request_state (*fn)(struct smbcli_request *); + void *private_data; + } recv_helper; + /* the flags2 from the SMB request, in raw form (host byte order). Used to parse strings */ uint16_t flags2; -- cgit From b4726d48e517b38733a3fcc6e3d3cd23993c4f3d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jul 2008 20:07:52 +0200 Subject: libcli/raw: use the new recv_helper infrastructure for nttrans replies metze (This used to be commit 5bf136e233e26b4372155f494bae5118ef777a76) --- source4/libcli/raw/rawtrans.c | 247 +++++++++++++++++++++++++----------------- 1 file changed, 145 insertions(+), 102 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 0f15b2151b..9fa52eedae 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -405,146 +405,177 @@ _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, return smb_raw_trans_recv(req, mem_ctx, parms); } +struct smb_raw_nttrans_recv_state { + bool got_first; + uint32_t recvd_data; + uint32_t recvd_param; + struct smb_nttrans io; +}; -/**************************************************************************** - receive a SMB nttrans response allocating the necessary memory - ****************************************************************************/ NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_nttrans *parms) { - uint32_t total_data, recvd_data=0; - uint32_t total_param, recvd_param=0; + struct smb_raw_nttrans_recv_state *state; if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { - return smbcli_request_destroy(req); + goto failed; + } + + state = talloc_get_type(req->recv_helper.private_data, + struct smb_raw_nttrans_recv_state); + + parms->out = state->io.out; + talloc_steal(mem_ctx, parms->out.setup); + talloc_steal(mem_ctx, parms->out.params.data); + talloc_steal(mem_ctx, parms->out.data.data); + talloc_free(state); + + ZERO_STRUCT(req->recv_helper); + +failed: + return smbcli_request_destroy(req); +} + +/* + * This helper returns SMBCLI_REQUEST_RECV until all data has arrived + */ +static enum smbcli_request_state smb_raw_nttrans_recv_helper(struct smbcli_request *req) +{ + struct smb_raw_nttrans_recv_state *state = talloc_get_type(req->recv_helper.private_data, + struct smb_raw_nttrans_recv_state); + uint32_t param_count, param_ofs, param_disp; + uint32_t data_count, data_ofs, data_disp; + uint32_t total_data, total_param; + uint8_t setup_count; + + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + if (smbcli_request_is_error(req)) { + goto failed; } /* sanity check */ if (CVAL(req->in.hdr, HDR_COM) != SMBnttrans) { - DEBUG(0,("smb_raw_receive_nttrans: Expected %s response, got command 0x%02x\n", + DEBUG(0,("smb_raw_nttrans_recv_helper: Expected %s response, got command 0x%02x\n", "SMBnttrans", CVAL(req->in.hdr,HDR_COM))); - req->status = NT_STATUS_UNSUCCESSFUL; - return smbcli_request_destroy(req); + req->status = NT_STATUS_INVALID_NETWORK_RESPONSE; + goto failed; } + /* this is the first packet of the response */ SMBCLI_CHECK_MIN_WCT(req, 18); - /* parse out the lengths */ total_param = IVAL(req->in.vwv, 3); total_data = IVAL(req->in.vwv, 7); + setup_count = CVAL(req->in.vwv, 35); + + param_count = IVAL(req->in.vwv, 11); + param_ofs = IVAL(req->in.vwv, 15); + param_disp = IVAL(req->in.vwv, 19); + + data_count = IVAL(req->in.vwv, 23); + data_ofs = IVAL(req->in.vwv, 27); + data_disp = IVAL(req->in.vwv, 31); + + if (!state->got_first) { + if (total_param > 0) { + state->io.out.params = data_blob_talloc(state, NULL, total_param); + if (!state->io.out.params.data) { + goto nomem; + } + } - parms->out.data = data_blob_talloc(mem_ctx, NULL, total_data); - parms->out.params = data_blob_talloc(mem_ctx, NULL, total_param); - - if (parms->out.data.length != total_data || - parms->out.params.length != total_param) { - req->status = NT_STATUS_NO_MEMORY; - return smbcli_request_destroy(req); - } - - parms->out.setup_count = CVAL(req->in.vwv, 35); - SMBCLI_CHECK_WCT(req, 18 + parms->out.setup_count); + if (total_data > 0) { + state->io.out.data = data_blob_talloc(state, NULL, total_data); + if (!state->io.out.data.data) { + goto nomem; + } + } - if (parms->out.setup_count > 0) { - parms->out.setup = talloc_array(mem_ctx, uint8_t, - parms->out.setup_count*2); - if (!parms->out.setup) { - req->status = NT_STATUS_NO_MEMORY; - return smbcli_request_destroy(req); + if (setup_count > 0) { + SMBCLI_CHECK_WCT(req, 18 + setup_count); + + state->io.out.setup_count = setup_count; + state->io.out.setup = talloc_array(state, uint8_t, + setup_count * VWV(1)); + if (!state->io.out.setup) { + goto nomem; + } + memcpy(state->io.out.setup, (uint8_t *)req->out.vwv + VWV(18), + setup_count * VWV(1)); } - memcpy(parms->out.setup, VWV(18) + (uint8_t *)req->out.vwv, - sizeof(uint16_t) * parms->out.setup_count); + + state->got_first = true; } - - while (recvd_data < total_data || - recvd_param < total_param) { - uint32_t param_count, param_ofs, param_disp; - uint32_t data_count, data_ofs, data_disp; - uint32_t total_data2, total_param2; - /* parse out the total lengths again - they can shrink! */ - total_param2 = IVAL(req->in.vwv, 3); - total_data2 = IVAL(req->in.vwv, 7); + if (total_data > state->io.out.data.length || + total_param > state->io.out.params.length) { + /* they must *only* shrink */ + DEBUG(1,("smb_raw_nttrans_recv_helper: data/params expanded!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } - if (total_data2 > total_data || - total_param2 > total_param) { - /* they must *only* shrink */ - DEBUG(1,("smb_raw_receive_nttrans: data/params expanded!\n")); - req->status = NT_STATUS_BUFFER_TOO_SMALL; - return smbcli_request_destroy(req); - } + state->io.out.data.length = total_data; + state->io.out.params.length = total_param; - total_data = total_data2; - total_param = total_param2; - parms->out.data.length = total_data; - parms->out.params.length = total_param; + if (data_count + data_disp > total_data || + param_count + param_disp > total_param) { + DEBUG(1,("smb_raw_nttrans_recv_helper: Buffer overflow\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } - /* parse params for this lump */ - param_count = IVAL(req->in.vwv, 11); - param_ofs = IVAL(req->in.vwv, 15); - param_disp = IVAL(req->in.vwv, 19); + /* check the server isn't being nasty */ + if (raw_trans_oob(req, param_ofs, param_count) || + raw_trans_oob(req, data_ofs, data_count)) { + DEBUG(1,("smb_raw_nttrans_recv_helper: out of bounds parameters!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } - data_count = IVAL(req->in.vwv, 23); - data_ofs = IVAL(req->in.vwv, 27); - data_disp = IVAL(req->in.vwv, 31); + if (data_count) { + memcpy(state->io.out.data.data + data_disp, + req->in.hdr + data_ofs, + data_count); + } - if (data_count + data_disp > total_data || - param_count + param_disp > total_param) { - DEBUG(1,("smb_raw_receive_nttrans: Buffer overflow\n")); - req->status = NT_STATUS_BUFFER_TOO_SMALL; - return smbcli_request_destroy(req); - } - - /* check the server isn't being nasty */ - if (raw_trans_oob(req, param_ofs, param_count) || - raw_trans_oob(req, data_ofs, data_count)) { - DEBUG(1,("smb_raw_receive_nttrans: out of bounds parameters!\n")); - req->status = NT_STATUS_BUFFER_TOO_SMALL; - return smbcli_request_destroy(req); - } + if (param_count) { + memcpy(state->io.out.params.data + param_disp, + req->in.hdr + param_ofs, + param_count); + } - if (data_count) { - memcpy(parms->out.data.data + data_disp, - req->in.hdr + data_ofs, - data_count); - } + state->recvd_param += param_count; + state->recvd_data += data_count; - if (param_count) { - memcpy(parms->out.params.data + param_disp, - req->in.hdr + param_ofs, - param_count); - } + if (state->recvd_data < total_data || + state->recvd_param < total_param) { - recvd_param += param_count; - recvd_data += data_count; + /* we don't need the in buffer any more */ + talloc_free(req->in.buffer); + ZERO_STRUCT(req->in); - if (recvd_data >= total_data && - recvd_param >= total_param) { - break; - } - - if (!smbcli_request_receive(req) || - smbcli_request_is_error(req)) { - return smbcli_request_destroy(req); - } - - /* sanity check */ - if (CVAL(req->in.hdr, HDR_COM) != SMBnttrans) { - DEBUG(0,("smb_raw_receive_nttrans: Expected nttranss, got command 0x%02x\n", - CVAL(req->in.hdr, HDR_COM))); - req->status = NT_STATUS_UNSUCCESSFUL; - return smbcli_request_destroy(req); - } + /* we still wait for more data */ + DEBUG(10,("smb_raw_nttrans_recv_helper: more data needed\n")); + return SMBCLI_REQUEST_RECV; } + DEBUG(10,("smb_raw_nttrans_recv_helper: done\n")); + return SMBCLI_REQUEST_DONE; + +nomem: + req->status = NT_STATUS_NO_MEMORY; failed: - return smbcli_request_destroy(req); + return SMBCLI_REQUEST_ERROR; } - /**************************************************************************** nttrans raw - only BLOBs used in this interface. at the moment we only handle a single primary request @@ -553,6 +584,7 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, struct smb_nttrans *parms) { struct smbcli_request *req; + struct smb_raw_nttrans_recv_state *state; uint8_t *outdata, *outparam; int align = 0; @@ -569,7 +601,13 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, if (!req) { return NULL; } - + + state = talloc_zero(req, struct smb_raw_nttrans_recv_state); + if (!state) { + talloc_free(req); + return NULL; + } + /* fill in SMB parameters */ outparam = req->out.data + align; outdata = outparam + parms->in.params.length; @@ -599,6 +637,11 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, memcpy(outdata, parms->in.data.data, parms->in.data.length); } + /* add the helper which will check that all multi-part replies are + in before an async client callack will be issued */ + req->recv_helper.fn = smb_raw_nttrans_recv_helper; + req->recv_helper.private_data = state; + if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; -- cgit From 177773424057668339af993f7a0df610dd9b6ae2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jul 2008 20:46:10 +0200 Subject: libcli/raw: use the new recv_helper infrastructure for trans/trans2 replies metze (This used to be commit ec67c61b6a82e4f39a15f37a98ae3fe93bb81316) --- source4/libcli/raw/rawtrans.c | 497 ++++++++++++++++++++++++++---------------- 1 file changed, 313 insertions(+), 184 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 9fa52eedae..9f5e1da293 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -49,148 +49,188 @@ static bool raw_trans_oob(struct smbcli_request *req, return false; } -/**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ +static size_t raw_trans_space_left(struct smbcli_request *req) +{ + if (req->transport->negotiate.max_xmit <= req->out.size) { + return 0; + } + + return req->transport->negotiate.max_xmit - req->out.size; +} + +struct smb_raw_trans2_recv_state { + uint8_t command; + uint32_t params_total; + uint32_t data_total; + uint32_t params_left; + uint32_t data_left; + bool got_first; + uint32_t recvd_data; + uint32_t recvd_param; + struct smb_trans2 io; +}; + NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, struct smb_trans2 *parms) { - int total_data=0; - int total_param=0; - uint8_t *tdata; - uint8_t *tparam; + struct smb_raw_trans2_recv_state *state; - parms->out.data.length = 0; - parms->out.data.data = NULL; - parms->out.params.length = 0; - parms->out.params.data = NULL; - - if (!smbcli_request_receive(req)) { - return smbcli_request_destroy(req); + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + goto failed; } - + + state = talloc_get_type(req->recv_helper.private_data, + struct smb_raw_trans2_recv_state); + + parms->out = state->io.out; + talloc_steal(mem_ctx, parms->out.setup); + talloc_steal(mem_ctx, parms->out.params.data); + talloc_steal(mem_ctx, parms->out.data.data); + talloc_free(state); + + ZERO_STRUCT(req->recv_helper); + +failed: + return smbcli_request_destroy(req); +} + +static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req, + struct smb_raw_trans2_recv_state *state); + +/* + * This helper returns SMBCLI_REQUEST_RECV until all data has arrived + */ +static enum smbcli_request_state smb_raw_trans2_recv_helper(struct smbcli_request *req) +{ + struct smb_raw_trans2_recv_state *state = talloc_get_type(req->recv_helper.private_data, + struct smb_raw_trans2_recv_state); + uint16_t param_count, param_ofs, param_disp; + uint16_t data_count, data_ofs, data_disp; + uint16_t total_data, total_param; + uint16_t setup_count; + /* * An NT RPC pipe call can return ERRDOS, ERRmoredata * to a trans call. This is not an error and should not * be treated as such. */ - if (NT_STATUS_IS_ERR(req->status)) { - return smbcli_request_destroy(req); + if (smbcli_request_is_error(req)) { + goto failed; + } + + if (state->params_left > 0 || state->data_left > 0) { + return smb_raw_trans2_ship_rest(req, state); } SMBCLI_CHECK_MIN_WCT(req, 10); - /* parse out the lengths */ total_data = SVAL(req->in.vwv, VWV(1)); total_param = SVAL(req->in.vwv, VWV(0)); + setup_count = SVAL(req->in.vwv, VWV(9)); - /* allocate it */ - if (total_data != 0) { - tdata = talloc_array(mem_ctx, uint8_t, total_data); - if (!tdata) { - DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data)); - req->status = NT_STATUS_NO_MEMORY; - return smbcli_request_destroy(req); + param_count = SVAL(req->in.vwv, VWV(3)); + param_ofs = SVAL(req->in.vwv, VWV(4)); + param_disp = SVAL(req->in.vwv, VWV(5)); + + data_count = SVAL(req->in.vwv, VWV(6)); + data_ofs = SVAL(req->in.vwv, VWV(7)); + data_disp = SVAL(req->in.vwv, VWV(8)); + + if (!state->got_first) { + if (total_param > 0) { + state->io.out.params = data_blob_talloc(state, NULL, total_param); + if (!state->io.out.params.data) { + goto nomem; + } } - parms->out.data.data = tdata; - } - if (total_param != 0) { - tparam = talloc_array(mem_ctx, uint8_t, total_param); - if (!tparam) { - DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param)); - req->status = NT_STATUS_NO_MEMORY; - return smbcli_request_destroy(req); + if (total_data > 0) { + state->io.out.data = data_blob_talloc(state, NULL, total_data); + if (!state->io.out.data.data) { + goto nomem; + } } - parms->out.params.data = tparam; - } - parms->out.setup_count = SVAL(req->in.vwv, VWV(9)); - SMBCLI_CHECK_WCT(req, 10 + parms->out.setup_count); + if (setup_count > 0) { + uint16_t i; - if (parms->out.setup_count > 0) { - int i; - parms->out.setup = talloc_array(mem_ctx, uint16_t, parms->out.setup_count); - if (!parms->out.setup) { - req->status = NT_STATUS_NO_MEMORY; - return smbcli_request_destroy(req); - } - for (i=0;iout.setup_count;i++) { - parms->out.setup[i] = SVAL(req->in.vwv, VWV(10+i)); + SMBCLI_CHECK_WCT(req, 10 + setup_count); + + state->io.out.setup_count = setup_count; + state->io.out.setup = talloc_array(state, uint16_t, setup_count); + if (!state->io.out.setup) { + goto nomem; + } + for (i=0; i < setup_count; i++) { + state->io.out.setup[i] = SVAL(req->in.vwv, VWV(10+i)); + } } - } - while (1) { - uint16_t param_count, param_ofs, param_disp; - uint16_t data_count, data_ofs, data_disp; - uint16_t total_data2, total_param2; + state->got_first = true; + } - /* parse out the total lengths again - they can shrink! */ - total_data2 = SVAL(req->in.vwv, VWV(1)); - total_param2 = SVAL(req->in.vwv, VWV(0)); + if (total_data > state->io.out.data.length || + total_param > state->io.out.params.length) { + /* they must *only* shrink */ + DEBUG(1,("smb_raw_trans2_recv_helper: data/params expanded!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } - if (total_data2 > total_data || - total_param2 > total_param) { - /* they must *only* shrink */ - DEBUG(1,("smb_raw_receive_trans: data/params expanded!\n")); - req->status = NT_STATUS_BUFFER_TOO_SMALL; - return smbcli_request_destroy(req); - } + state->io.out.data.length = total_data; + state->io.out.params.length = total_param; - total_data = total_data2; - total_param = total_param2; + if (data_count + data_disp > total_data || + param_count + param_disp > total_param) { + DEBUG(1,("smb_raw_trans2_recv_helper: Buffer overflow\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } - /* parse params for this lump */ - param_count = SVAL(req->in.vwv, VWV(3)); - param_ofs = SVAL(req->in.vwv, VWV(4)); - param_disp = SVAL(req->in.vwv, VWV(5)); + /* check the server isn't being nasty */ + if (raw_trans_oob(req, param_ofs, param_count) || + raw_trans_oob(req, data_ofs, data_count)) { + DEBUG(1,("smb_raw_trans2_recv_helper: out of bounds parameters!\n")); + req->status = NT_STATUS_BUFFER_TOO_SMALL; + goto failed; + } - data_count = SVAL(req->in.vwv, VWV(6)); - data_ofs = SVAL(req->in.vwv, VWV(7)); - data_disp = SVAL(req->in.vwv, VWV(8)); + if (data_count) { + memcpy(state->io.out.data.data + data_disp, + req->in.hdr + data_ofs, + data_count); + } - if (data_count + data_disp > total_data || - param_count + param_disp > total_param) { - DEBUG(1,("smb_raw_receive_trans: Buffer overflow\n")); - req->status = NT_STATUS_BUFFER_TOO_SMALL; - return smbcli_request_destroy(req); - } - - /* check the server isn't being nasty */ - if (raw_trans_oob(req, param_ofs, param_count) || - raw_trans_oob(req, data_ofs, data_count)) { - DEBUG(1,("smb_raw_receive_trans: out of bounds parameters!\n")); - req->status = NT_STATUS_BUFFER_TOO_SMALL; - return smbcli_request_destroy(req); - } + if (param_count) { + memcpy(state->io.out.params.data + param_disp, + req->in.hdr + param_ofs, + param_count); + } - if (data_count) { - memcpy(parms->out.data.data + data_disp, - req->in.hdr + data_ofs, - data_count); - } + state->recvd_param += param_count; + state->recvd_data += data_count; - if (param_count) { - memcpy(parms->out.params.data + param_disp, - req->in.hdr + param_ofs, - param_count); - } + if (state->recvd_data < total_data || + state->recvd_param < total_param) { - parms->out.data.length += data_count; - parms->out.params.length += param_count; + /* we don't need the in buffer any more */ + talloc_free(req->in.buffer); + ZERO_STRUCT(req->in); - if (total_data <= parms->out.data.length && total_param <= parms->out.params.length) - break; - - if (!smbcli_request_receive_more(req)) { - req->status = NT_STATUS_UNSUCCESSFUL; - return smbcli_request_destroy(req); - } + /* we still wait for more data */ + DEBUG(10,("smb_raw_trans2_recv_helper: more data needed\n")); + return SMBCLI_REQUEST_RECV; } + DEBUG(10,("smb_raw_trans2_recv_helper: done\n")); + return SMBCLI_REQUEST_DONE; + +nomem: + req->status = NT_STATUS_NO_MEMORY; failed: - return smbcli_request_destroy(req); + return SMBCLI_REQUEST_ERROR; } _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, @@ -208,13 +248,17 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, struct smb_trans2 *parms, uint8_t command) { - int wct = 14 + parms->in.setup_count; - struct smbcli_request *req, *req2; - uint8_t *outdata,*outparam; + struct smb_raw_trans2_recv_state *state; + struct smbcli_request *req; int i; int padding; + size_t space_left; size_t namelen = 0; - uint16_t data_disp, data_length, max_data; + DATA_BLOB params_chunk; + uint16_t ofs; + uint16_t params_ofs = 0; + DATA_BLOB data_chunk; + uint16_t data_ofs = 0; if (parms->in.params.length > UINT16_MAX || parms->in.data.length > UINT16_MAX) { @@ -229,37 +273,83 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, else padding = 3; - req = smbcli_request_setup(tree, command, wct, padding); + req = smbcli_request_setup(tree, command, + 14 + parms->in.setup_count, + padding); if (!req) { return NULL; } + state = talloc_zero(req, struct smb_raw_trans2_recv_state); + if (!state) { + smbcli_request_destroy(req); + return NULL; + } + + state->command = command; + + /* make sure we don't leak data via the padding */ + memset(req->out.data, 0, padding); + /* Watch out, this changes the req->out.* pointers */ if (command == SMBtrans && parms->in.trans_name) { namelen = smbcli_req_append_string(req, parms->in.trans_name, STR_TERMINATE); } - /* fill in SMB parameters */ - outparam = req->out.data + padding; - outdata = outparam + parms->in.params.length; + ofs = PTR_DIFF(req->out.data,req->out.hdr)+padding+namelen; - /* make sure we don't leak data via the padding */ - memset(req->out.data, 0, padding); + /* see how much bytes of the params block we can ship in the first request */ + space_left = raw_trans_space_left(req); + + params_chunk.length = MIN(parms->in.params.length, space_left); + params_chunk.data = parms->in.params.data; + params_ofs = ofs; - data_length = parms->in.data.length; + state->params_left = parms->in.params.length - params_chunk.length; - max_data = smb_raw_max_trans_data(tree, parms->in.params.length); - if (max_data < data_length) { - data_length = max_data; + if (state->params_left > 0) { + /* we copy the whole params block, if needed we can optimize that latter */ + state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length); + if (!state->io.in.params.data) { + smbcli_request_destroy(req); + return NULL; + } + memcpy(state->io.in.params.data, + parms->in.params.data, + parms->in.params.length); } + /* see how much bytes of the data block we can ship in the first request */ + space_left -= params_chunk.length; + #if TORTURE_TRANS_DATA - if (data_length > 1) { - data_length /= 2; + if (space_left > 1) { + space_left /= 2; } #endif + data_chunk.length = MIN(parms->in.data.length, space_left); + data_chunk.data = parms->in.data.data; + data_ofs = params_ofs + params_chunk.length; + + state->data_left = parms->in.data.length - data_chunk.length; + + if (state->data_left > 0) { + /* we copy the whole params block, if needed we can optimize that latter */ + state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length); + if (!state->io.in.data.data) { + smbcli_request_destroy(req); + return NULL; + } + memcpy(state->io.in.data.data, + parms->in.data.data, + parms->in.data.length); + } + + state->params_total = parms->in.params.length; + state->data_total = parms->in.data.length; + /* primary request */ SSVAL(req->out.vwv,VWV(0),parms->in.params.length); SSVAL(req->out.vwv,VWV(1),parms->in.data.length); @@ -269,96 +359,135 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, SSVAL(req->out.vwv,VWV(5),parms->in.flags); SIVAL(req->out.vwv,VWV(6),parms->in.timeout); SSVAL(req->out.vwv,VWV(8),0); /* reserved */ - SSVAL(req->out.vwv,VWV(9),parms->in.params.length); - SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)+namelen); - SSVAL(req->out.vwv,VWV(11),data_length); - SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)+namelen); + SSVAL(req->out.vwv,VWV(9),params_chunk.length); + SSVAL(req->out.vwv,VWV(10),params_ofs); + SSVAL(req->out.vwv,VWV(11),data_chunk.length); + SSVAL(req->out.vwv,VWV(12),data_ofs); SSVAL(req->out.vwv,VWV(13),parms->in.setup_count); for (i=0;iin.setup_count;i++) { - SSVAL(req->out.vwv,VWV(14)+i*2,parms->in.setup[i]); - } - if (parms->in.params.data) { - smbcli_req_append_blob(req, &parms->in.params); - } - if (parms->in.data.data) { - DATA_BLOB data; - data.data = parms->in.data.data; - data.length = data_length; - smbcli_req_append_blob(req, &data); + SSVAL(req->out.vwv,VWV(14)+VWV(i),parms->in.setup[i]); } + smbcli_req_append_blob(req, ¶ms_chunk); + smbcli_req_append_blob(req, &data_chunk); + + /* add the helper which will check that all multi-part replies are + in before an async client callack will be issued */ + req->recv_helper.fn = smb_raw_trans2_recv_helper; + req->recv_helper.private_data = state; if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } - data_disp = data_length; + return req; +} +static enum smbcli_request_state smb_raw_trans2_ship_next(struct smbcli_request *req, + struct smb_raw_trans2_recv_state *state) +{ + struct smbcli_request *req2; + size_t space_left; + DATA_BLOB params_chunk; + uint16_t ofs; + uint16_t params_ofs = 0; + uint16_t params_disp = 0; + DATA_BLOB data_chunk; + uint16_t data_ofs = 0; + uint16_t data_disp = 0; + uint8_t wct; - if (data_disp != parms->in.data.length) { - /* TODO: this should be done asynchronously .... */ - if (!smbcli_request_receive(req) || - !NT_STATUS_IS_OK(req->status)) { - return req; - } + if (state->command == SMBtrans2) { + wct = 9; + } else { + wct = 8; + } - req->state = SMBCLI_REQUEST_RECV; - DLIST_ADD(req->transport->pending_recv, req); + req2 = smbcli_request_setup(req->tree, state->command+1, wct, 0); + if (!req2) { + goto nomem; } + req2->mid = req->mid; + SSVAL(req2->out.hdr, HDR_MID, req2->mid); + ofs = PTR_DIFF(req2->out.data,req2->out.hdr); - while (data_disp != parms->in.data.length) { - data_length = parms->in.data.length - data_disp; + /* see how much bytes of the params block we can ship in the first request */ + space_left = raw_trans_space_left(req2); - max_data = smb_raw_max_trans_data(tree, 0); - if (max_data < data_length) { - data_length = max_data; - } + params_disp = state->io.in.params.length - state->params_left; + params_chunk.length = MIN(state->params_left, space_left); + params_chunk.data = state->io.in.params.data + params_disp; + params_ofs = ofs; + + state->params_left -= params_chunk.length; + + /* see how much bytes of the data block we can ship in the first request */ + space_left -= params_chunk.length; #if TORTURE_TRANS_DATA - if (data_length > 1) { - data_length /= 2; - } + if (space_left > 1) { + space_left /= 2; + } #endif - req2 = smbcli_request_setup(tree, command+1, 9, data_length); - if (!req2) { - return NULL; - } - req2->mid = req->mid; - SSVAL(req2->out.hdr, HDR_MID, req2->mid); - - outdata = req2->out.data; - - SSVAL(req2->out.vwv,VWV(0), parms->in.params.length); - SSVAL(req2->out.vwv,VWV(1), parms->in.data.length); - SSVAL(req2->out.vwv,VWV(2), 0); - SSVAL(req2->out.vwv,VWV(3), 0); - SSVAL(req2->out.vwv,VWV(4), 0); - SSVAL(req2->out.vwv,VWV(5), data_length); - SSVAL(req2->out.vwv,VWV(6), PTR_DIFF(outdata,req2->out.hdr)); - SSVAL(req2->out.vwv,VWV(7), data_disp); + data_disp = state->io.in.data.length - state->data_left; + data_chunk.length = MIN(state->data_left, space_left); + data_chunk.data = state->io.in.data.data + data_disp; + data_ofs = params_ofs+params_chunk.length; + + state->data_left -= data_chunk.length; + + SSVAL(req2->out.vwv,VWV(0), state->params_total); + SSVAL(req2->out.vwv,VWV(1), state->data_total); + SSVAL(req2->out.vwv,VWV(2), params_chunk.length); + SSVAL(req2->out.vwv,VWV(3), params_ofs); + SSVAL(req2->out.vwv,VWV(4), params_disp); + SSVAL(req2->out.vwv,VWV(5), data_chunk.length); + SSVAL(req2->out.vwv,VWV(6), data_ofs); + SSVAL(req2->out.vwv,VWV(7), data_disp); + if (wct == 9) { SSVAL(req2->out.vwv,VWV(8), 0xFFFF); + } - if (data_length != 0) { - memcpy(req2->out.data, parms->in.data.data + data_disp, - data_length); - } - - data_disp += data_length; + smbcli_req_append_blob(req2, ¶ms_chunk); + smbcli_req_append_blob(req2, &data_chunk); - req2->one_way_request = 1; + /* + * it's a one way request but we need + * the seq_num, so we destroy req2 by hand + */ + if (!smbcli_request_send(req2)) { + goto failed; + } - if (!smbcli_request_send(req2)) { - smbcli_request_destroy(req2); - return NULL; - } + req->seq_num = req2->seq_num; + smbcli_request_destroy(req2); + + return SMBCLI_REQUEST_RECV; - req->seq_num = req2->seq_num; +nomem: + req->status = NT_STATUS_NO_MEMORY; +failed: + if (req2) { + req->status = smbcli_request_destroy(req2); } - - - return req; + return SMBCLI_REQUEST_ERROR; +} + +static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req, + struct smb_raw_trans2_recv_state *state) +{ + enum smbcli_request_state ret = SMBCLI_REQUEST_ERROR; + + while (state->params_left > 0 || state->data_left > 0) { + ret = smb_raw_trans2_ship_next(req, state); + if (ret != SMBCLI_REQUEST_RECV) { + break; + } + } + + return ret; } -- cgit From fd1ce8c263adf84c665753bd7635d39d7ec533bc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jul 2008 20:47:24 +0200 Subject: libcli/raw: remove unused smbcli_request_receive_more() function metze (This used to be commit e1d81388fcabba9a947ed0be9ccae875e2b19135) --- source4/libcli/raw/rawrequest.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index ef856c6ea1..a0e6452748 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -364,19 +364,6 @@ bool smbcli_request_receive(struct smbcli_request *req) } -/* - receive another reply to a request - this is used for requests that - have multi-part replies (such as SMBtrans2) -*/ -bool smbcli_request_receive_more(struct smbcli_request *req) -{ - req->state = SMBCLI_REQUEST_RECV; - DLIST_ADD(req->transport->pending_recv, req); - - return smbcli_request_receive(req); -} - - /* handle oplock break requests from the server - return true if the request was an oplock break -- cgit From 848ab7fa3be4c4fe2a103df365f0b6b41ee0736d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Jul 2008 14:00:09 +0200 Subject: libcli/raw: trans(2) setup count is uint8_t metze (This used to be commit 48ccb51caf7976ec07c8a9bfc1afd3076bf4ee22) --- source4/libcli/raw/rawtrans.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 9f5e1da293..fb5f9fa8d0 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -109,7 +109,7 @@ static enum smbcli_request_state smb_raw_trans2_recv_helper(struct smbcli_reques uint16_t param_count, param_ofs, param_disp; uint16_t data_count, data_ofs, data_disp; uint16_t total_data, total_param; - uint16_t setup_count; + uint8_t setup_count; /* * An NT RPC pipe call can return ERRDOS, ERRmoredata @@ -128,7 +128,7 @@ static enum smbcli_request_state smb_raw_trans2_recv_helper(struct smbcli_reques total_data = SVAL(req->in.vwv, VWV(1)); total_param = SVAL(req->in.vwv, VWV(0)); - setup_count = SVAL(req->in.vwv, VWV(9)); + setup_count = CVAL(req->in.vwv, VWV(9)); param_count = SVAL(req->in.vwv, VWV(3)); param_ofs = SVAL(req->in.vwv, VWV(4)); @@ -355,7 +355,8 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, SSVAL(req->out.vwv,VWV(1),parms->in.data.length); SSVAL(req->out.vwv,VWV(2),parms->in.max_param); SSVAL(req->out.vwv,VWV(3),parms->in.max_data); - SSVAL(req->out.vwv,VWV(4),parms->in.max_setup); + SCVAL(req->out.vwv,VWV(4),parms->in.max_setup); + SCVAL(req->out.vwv,VWV(4)+1,0); /* reserved */ SSVAL(req->out.vwv,VWV(5),parms->in.flags); SIVAL(req->out.vwv,VWV(6),parms->in.timeout); SSVAL(req->out.vwv,VWV(8),0); /* reserved */ @@ -363,7 +364,8 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, SSVAL(req->out.vwv,VWV(10),params_ofs); SSVAL(req->out.vwv,VWV(11),data_chunk.length); SSVAL(req->out.vwv,VWV(12),data_ofs); - SSVAL(req->out.vwv,VWV(13),parms->in.setup_count); + SCVAL(req->out.vwv,VWV(13),parms->in.setup_count); + SCVAL(req->out.vwv,VWV(13)+1,0); /* reserved */ for (i=0;iin.setup_count;i++) { SSVAL(req->out.vwv,VWV(14)+VWV(i),parms->in.setup[i]); } -- cgit From efaf4cedb27f6ffade8c5212919ff08602bd3e7a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Jul 2008 15:04:59 +0200 Subject: libcli/raw: make multi fragmented nttrans requests possible metze (This used to be commit a6aa055097313975299f214d8ebe8d45aa51d10a) --- source4/libcli/raw/rawtrans.c | 195 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 178 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index fb5f9fa8d0..7a90236c9c 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -537,6 +537,10 @@ _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, } struct smb_raw_nttrans_recv_state { + uint32_t params_total; + uint32_t data_total; + uint32_t params_left; + uint32_t data_left; bool got_first; uint32_t recvd_data; uint32_t recvd_param; @@ -569,6 +573,9 @@ failed: return smbcli_request_destroy(req); } +static enum smbcli_request_state smb_raw_nttrans_ship_rest(struct smbcli_request *req, + struct smb_raw_nttrans_recv_state *state); + /* * This helper returns SMBCLI_REQUEST_RECV until all data has arrived */ @@ -599,6 +606,10 @@ static enum smbcli_request_state smb_raw_nttrans_recv_helper(struct smbcli_reque goto failed; } + if (state->params_left > 0 || state->data_left > 0) { + return smb_raw_nttrans_ship_rest(req, state); + } + /* this is the first packet of the response */ SMBCLI_CHECK_MIN_WCT(req, 18); @@ -716,7 +727,12 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, { struct smbcli_request *req; struct smb_raw_nttrans_recv_state *state; - uint8_t *outdata, *outparam; + uint32_t ofs; + size_t space_left; + DATA_BLOB params_chunk; + uint32_t params_ofs; + DATA_BLOB data_chunk; + uint32_t data_ofs; int align = 0; /* only align if there are parameters or data */ @@ -725,10 +741,7 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, } req = smbcli_request_setup(tree, SMBnttrans, - 19 + parms->in.setup_count, - align + - parms->in.params.length + - parms->in.data.length); + 19 + parms->in.setup_count, align); if (!req) { return NULL; } @@ -740,33 +753,81 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, } /* fill in SMB parameters */ - outparam = req->out.data + align; - outdata = outparam + parms->in.params.length; if (align != 0) { memset(req->out.data, 0, align); } + ofs = PTR_DIFF(req->out.data,req->out.hdr)+align; + + /* see how much bytes of the params block we can ship in the first request */ + space_left = raw_trans_space_left(req); + + params_chunk.length = MIN(parms->in.params.length, space_left); + params_chunk.data = parms->in.params.data; + params_ofs = ofs; + + state->params_left = parms->in.params.length - params_chunk.length; + + if (state->params_left > 0) { + /* we copy the whole params block, if needed we can optimize that latter */ + state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length); + if (!state->io.in.params.data) { + smbcli_request_destroy(req); + return NULL; + } + memcpy(state->io.in.params.data, + parms->in.params.data, + parms->in.params.length); + } + + /* see how much bytes of the data block we can ship in the first request */ + space_left -= params_chunk.length; + +#if TORTURE_TRANS_DATA + if (space_left > 1) { + space_left /= 2; + } +#endif + + data_chunk.length = MIN(parms->in.data.length, space_left); + data_chunk.data = parms->in.data.data; + data_ofs = params_ofs + params_chunk.length; + + state->data_left = parms->in.data.length - data_chunk.length; + + if (state->data_left > 0) { + /* we copy the whole params block, if needed we can optimize that latter */ + state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length); + if (!state->io.in.data.data) { + smbcli_request_destroy(req); + return NULL; + } + memcpy(state->io.in.data.data, + parms->in.data.data, + parms->in.data.length); + } + + state->params_total = parms->in.params.length; + state->data_total = parms->in.data.length; + SCVAL(req->out.vwv, 0, parms->in.max_setup); SSVAL(req->out.vwv, 1, 0); /* reserved */ SIVAL(req->out.vwv, 3, parms->in.params.length); SIVAL(req->out.vwv, 7, parms->in.data.length); SIVAL(req->out.vwv, 11, parms->in.max_param); SIVAL(req->out.vwv, 15, parms->in.max_data); - SIVAL(req->out.vwv, 19, parms->in.params.length); - SIVAL(req->out.vwv, 23, PTR_DIFF(outparam,req->out.hdr)); - SIVAL(req->out.vwv, 27, parms->in.data.length); - SIVAL(req->out.vwv, 31, PTR_DIFF(outdata,req->out.hdr)); + SIVAL(req->out.vwv, 19, params_chunk.length); + SIVAL(req->out.vwv, 23, params_ofs); + SIVAL(req->out.vwv, 27, data_chunk.length); + SIVAL(req->out.vwv, 31, data_ofs); SCVAL(req->out.vwv, 35, parms->in.setup_count); SSVAL(req->out.vwv, 36, parms->in.function); memcpy(req->out.vwv + VWV(19), parms->in.setup, sizeof(uint16_t) * parms->in.setup_count); - if (parms->in.params.length) { - memcpy(outparam, parms->in.params.data, parms->in.params.length); - } - if (parms->in.data.length) { - memcpy(outdata, parms->in.data.data, parms->in.data.length); - } + + smbcli_req_append_blob(req, ¶ms_chunk); + smbcli_req_append_blob(req, &data_chunk); /* add the helper which will check that all multi-part replies are in before an async client callack will be issued */ @@ -781,6 +842,106 @@ struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, return req; } +static enum smbcli_request_state smb_raw_nttrans_ship_next(struct smbcli_request *req, + struct smb_raw_nttrans_recv_state *state) +{ + struct smbcli_request *req2; + size_t space_left; + DATA_BLOB params_chunk; + uint32_t ofs; + uint32_t params_ofs = 0; + uint32_t params_disp = 0; + DATA_BLOB data_chunk; + uint32_t data_ofs = 0; + uint32_t data_disp = 0; + + req2 = smbcli_request_setup(req->tree, SMBnttranss, 18, 0); + if (!req2) { + goto nomem; + } + req2->mid = req->mid; + SSVAL(req2->out.hdr, HDR_MID, req2->mid); + + ofs = PTR_DIFF(req2->out.data,req2->out.hdr); + + /* see how much bytes of the params block we can ship in the first request */ + space_left = raw_trans_space_left(req2); + + params_disp = state->io.in.params.length - state->params_left; + params_chunk.length = MIN(state->params_left, space_left); + params_chunk.data = state->io.in.params.data + params_disp; + params_ofs = ofs; + + state->params_left -= params_chunk.length; + + /* see how much bytes of the data block we can ship in the first request */ + space_left -= params_chunk.length; + +#if TORTURE_TRANS_DATA + if (space_left > 1) { + space_left /= 2; + } +#endif + + data_disp = state->io.in.data.length - state->data_left; + data_chunk.length = MIN(state->data_left, space_left); + data_chunk.data = state->io.in.data.data + data_disp; + data_ofs = params_ofs+params_chunk.length; + + state->data_left -= data_chunk.length; + + SSVAL(req2->out.vwv,0, 0); /* reserved */ + SCVAL(req2->out.vwv,2, 0); /* reserved */ + SIVAL(req2->out.vwv,3, state->params_total); + SIVAL(req2->out.vwv,7, state->data_total); + SIVAL(req2->out.vwv,11, params_chunk.length); + SIVAL(req2->out.vwv,15, params_ofs); + SIVAL(req2->out.vwv,19, params_disp); + SIVAL(req2->out.vwv,23, data_chunk.length); + SIVAL(req2->out.vwv,27, data_ofs); + SIVAL(req2->out.vwv,31, data_disp); + SCVAL(req2->out.vwv,35, 0); /* reserved */ + + smbcli_req_append_blob(req2, ¶ms_chunk); + smbcli_req_append_blob(req2, &data_chunk); + + /* + * it's a one way request but we need + * the seq_num, so we destroy req2 by hand + */ + if (!smbcli_request_send(req2)) { + goto failed; + } + + req->seq_num = req2->seq_num; + smbcli_request_destroy(req2); + + return SMBCLI_REQUEST_RECV; + +nomem: + req->status = NT_STATUS_NO_MEMORY; +failed: + if (req2) { + req->status = smbcli_request_destroy(req2); + } + return SMBCLI_REQUEST_ERROR; +} + +static enum smbcli_request_state smb_raw_nttrans_ship_rest(struct smbcli_request *req, + struct smb_raw_nttrans_recv_state *state) +{ + enum smbcli_request_state ret = SMBCLI_REQUEST_ERROR; + + while (state->params_left > 0 || state->data_left > 0) { + ret = smb_raw_nttrans_ship_next(req, state); + if (ret != SMBCLI_REQUEST_RECV) { + break; + } + } + + return ret; +} + /**************************************************************************** receive a SMB nttrans response allocating the necessary memory -- cgit From 997f539bf568f555f9e7a7f51de23cd13c732b1c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Jul 2008 16:34:36 +0200 Subject: libcli/raw: remove unused smb_raw_max_trans_data() function metze (This used to be commit d235ce673705641e06b4ad5f5679e146b59a19e1) --- source4/libcli/raw/rawtrans.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index 7a90236c9c..2f529863dc 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -959,15 +959,3 @@ NTSTATUS smb_raw_nttrans(struct smbcli_tree *tree, return smb_raw_nttrans_recv(req, mem_ctx, parms); } - -/* - work out the maximum data size for a trans request while avoiding - multi-part replies - - TODO: we only need to avoid multi-part replies because the - multi-part trans receive code is broken. -*/ -_PUBLIC_ size_t smb_raw_max_trans_data(struct smbcli_tree *tree, size_t param_size) -{ - return tree->session->transport->negotiate.max_xmit - (70 + param_size); -} -- cgit From ab00b65dde3fad666425cd9b4b6e45dabc33b279 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:08:57 +1000 Subject: Cleanup ldap_bind_sasl. With these changes, we don't leak the LDAP socket, and don't reset all credentials feature flags, just the ones we are actually incompatible with. Andrew Bartlett (This used to be commit 72e52a301102941c41ab423e0212fe9a1aed0405) --- source4/libcli/ldap/ldap_bind.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index e1569e7296..65673116be 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -234,7 +234,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, * Windows seem not to like double encryption */ old_gensec_features = cli_credentials_get_gensec_features(creds); if (tls_enabled(conn->sock)) { - cli_credentials_set_gensec_features(creds, 0); + cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); } /* this call also sets the gensec_want_features */ @@ -245,7 +245,8 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, goto failed; } - /* reset the original gensec_features */ + /* reset the original gensec_features (on the credentials + * context, so we don't tatoo it ) */ cli_credentials_set_gensec_features(creds, old_gensec_features); if (conn->host) { @@ -393,8 +394,6 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, &sasl_socket); if (!NT_STATUS_IS_OK(status)) goto failed; - talloc_steal(conn->sock, sasl_socket); - talloc_unlink(conn, conn->sock); conn->sock = sasl_socket; packet_set_socket(conn->packet, conn->sock); -- cgit From 403f4f94ffec28d1c1dc910e1960531f4c14534b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:10:29 +1000 Subject: Make up a full hostname for ldapi connections. The DIGEST-MD5 SASL method requires a hostname, so provide one. Andrew Bartlett (This used to be commit edfb2ed1f22bc735af5a0c3d3ae6ab6771d28f2c) --- source4/libcli/ldap/ldap_client.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index bca867b033..844238afdb 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -38,7 +38,6 @@ #include "param/param.h" #include "libcli/resolve/resolve.h" - /** create a new ldap_connection stucture. The event context is optional */ @@ -298,7 +297,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con char protocol[11]; int ret; - result = talloc_zero(NULL, struct composite_context); + result = talloc_zero(conn, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -336,6 +335,12 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con SMB_ASSERT(sizeof(protocol)>10); SMB_ASSERT(sizeof(path)>1024); + /* LDAPI connections are to localhost, so give the local host name as the target for gensec */ + conn->host = talloc_asprintf(conn, "%s.%s", lp_netbios_name(conn->lp_ctx), lp_realm(conn->lp_ctx)); + if (composite_nomem(conn->host, state->ctx)) { + return result; + } + /* The %c specifier doesn't null terminate :-( */ ZERO_STRUCT(path); ret = sscanf(url, "%10[^:]://%1025c", protocol, path); -- cgit From e92125e6319d49185a3d0456a8a0e5c1b8d364e7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jul 2008 14:00:18 +1000 Subject: Ignore and handle more NT Create & X options. The MS-SMB document explains that some of these options should be ignored. The test proves it. /* Must be ignored by the server, per MS-SMB 2.2.8 */ /* Must be ignored by the server, per MS-SMB 2.2.8 */ If we implement HSM in samba4 (likely) we should honour this bit. /* Don't pull this file off tape in a HSM system */ Andrew Bartlett (This used to be commit 502739ff90d56d2c9aabe8e224317f6ceb175c17) --- source4/libcli/raw/smb.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 5a92b99757..f54e979de2 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -156,15 +156,20 @@ #define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000 #define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000 #define NTCREATEX_OPTIONS_BACKUP_INTENT 0x4000 -#define NTCREATEX_OPTIONS_REPARSE_POINT 0x200000 -#define NTCREATEX_OPTIONS_UNKNOWN_400000 0x400000 +/* Must be ignored by the server, per MS-SMB 2.2.8 */ +#define NTCREATEX_OPTIONS_OPFILTER 0x00100000 +#define NTCREATEX_OPTIONS_REPARSE_POINT 0x00200000 +/* Don't pull this file off tape in a HSM system */ +#define NTCREATEX_OPTIONS_NO_RECALL 0x00400000 +/* Must be ignored by the server, per MS-SMB 2.2.8 */ +#define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000 /* create options these bits are for private use by backends, they are not valid on the wire */ #define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000 #define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 #define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 -#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK 0x00DFA188 +#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK 0x000FA188 -- cgit From 853194c308a0f2171808b78b17aed50c5fab1b3b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jul 2008 18:40:19 +1000 Subject: More 'must be ignored' options from the MS-SMB doc. Also in particular the 'sync' flags (which Samba has traditionally ignored). Thanks to Olivier Salamin for pointing out more flags that needed to be handled. Andrew Bartlett (This used to be commit 370bb39cd79fe49efd36a1ceb3e896d386e6d3ce) --- source4/libcli/raw/smb.h | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index f54e979de2..8663792f78 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -144,32 +144,38 @@ #define NTCREATEX_DISP_OVERWRITE_IF 5 /* if exists overwrite, else create */ /* ntcreatex create_options field */ -#define NTCREATEX_OPTIONS_DIRECTORY 0x0001 -#define NTCREATEX_OPTIONS_WRITE_THROUGH 0x0002 -#define NTCREATEX_OPTIONS_SEQUENTIAL_ONLY 0x0004 -#define NTCREATEX_OPTIONS_SYNC_ALERT 0x0010 -#define NTCREATEX_OPTIONS_ASYNC_ALERT 0x0020 -#define NTCREATEX_OPTIONS_NON_DIRECTORY_FILE 0x0040 -#define NTCREATEX_OPTIONS_NO_EA_KNOWLEDGE 0x0200 -#define NTCREATEX_OPTIONS_EIGHT_DOT_THREE_ONLY 0x0400 -#define NTCREATEX_OPTIONS_RANDOM_ACCESS 0x0800 -#define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000 -#define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000 -#define NTCREATEX_OPTIONS_BACKUP_INTENT 0x4000 +#define NTCREATEX_OPTIONS_DIRECTORY 0x0001 +#define NTCREATEX_OPTIONS_WRITE_THROUGH 0x0002 +#define NTCREATEX_OPTIONS_SEQUENTIAL_ONLY 0x0004 +#define NTCREATEX_OPTIONS_NO_INTERMEDIATE_BUFFERING 0x0008 +#define NTCREATEX_OPTIONS_SYNC_ALERT 0x0010 +#define NTCREATEX_OPTIONS_ASYNC_ALERT 0x0020 +#define NTCREATEX_OPTIONS_NON_DIRECTORY_FILE 0x0040 +#define NTCREATEX_OPTIONS_TREE_CONNECTION 0x0080 +#define NTCREATEX_OPTIONS_COMPLETE_IF_OPLOCKED 0x0100 +#define NTCREATEX_OPTIONS_NO_EA_KNOWLEDGE 0x0200 +#define NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY 0x0400 +#define NTCREATEX_OPTIONS_RANDOM_ACCESS 0x0800 +#define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000 +#define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000 +#define NTCREATEX_OPTIONS_BACKUP_INTENT 0x4000 +#define NTCREATEX_OPTIONS_NO_COMPRESSION 0x8000 /* Must be ignored by the server, per MS-SMB 2.2.8 */ -#define NTCREATEX_OPTIONS_OPFILTER 0x00100000 -#define NTCREATEX_OPTIONS_REPARSE_POINT 0x00200000 +#define NTCREATEX_OPTIONS_OPFILTER 0x00100000 +#define NTCREATEX_OPTIONS_REPARSE_POINT 0x00200000 /* Don't pull this file off tape in a HSM system */ -#define NTCREATEX_OPTIONS_NO_RECALL 0x00400000 +#define NTCREATEX_OPTIONS_NO_RECALL 0x00400000 /* Must be ignored by the server, per MS-SMB 2.2.8 */ -#define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000 +#define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000 /* create options these bits are for private use by backends, they are not valid on the wire */ -#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000 -#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 -#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 +#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 -#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK 0x000FA188 +#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK ( NTCREATEX_OPTIONS_TREE_CONNECTION | NTCREATEX_OPTIONS_COMPLETE_IF_OPLOCKED | NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY | NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER ) + +#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK (0x000F0000 | NTCREATEX_OPTIONS_OPEN_BY_FILE_ID) -- cgit From 4355b31730f900fcae1ccb58df4feb387489e1e9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Jun 2008 21:41:06 +0200 Subject: libcli/smb2: sign SMB2 Logoff requests metze (This used to be commit 35ee165b146b9157b0cff49e1139a0cb37d98926) --- source4/libcli/smb2/logoff.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c index b38a08ca43..e3f83f27d8 100644 --- a/source4/libcli/smb2/logoff.c +++ b/source4/libcli/smb2/logoff.c @@ -33,6 +33,8 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session) req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, false, 0); if (req == NULL) return NULL; + req->session = session; + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid); SSVAL(req->out.body, 0x02, 0); -- cgit From 35bd7a6378cc25ed6b24d153c3cf1557d6126788 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Jun 2008 21:57:41 +0200 Subject: libcli/smb2: fix per session signing state metze (This used to be commit 8bc12dc77a59e792830d96e84a4e8d1b2c651505) --- source4/libcli/smb2/connect.c | 8 ++++---- source4/libcli/smb2/session.c | 6 +++--- source4/libcli/smb2/smb2.h | 9 +++------ source4/libcli/smb2/transport.c | 6 ++---- 4 files changed, 12 insertions(+), 17 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index cdb5e3b5d4..c89c109b72 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -112,19 +112,19 @@ static void continue_negprot(struct smb2_request *req) composite_error(c, NT_STATUS_ACCESS_DENIED); return; } - transport->signing.doing_signing = false; + transport->signing_required = false; break; case SMB_SIGNING_SUPPORTED: case SMB_SIGNING_AUTO: if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { - transport->signing.doing_signing = true; + transport->signing_required = true; } else { - transport->signing.doing_signing = false; + transport->signing_required = false; } break; case SMB_SIGNING_REQUIRED: if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { - transport->signing.doing_signing = true; + transport->signing_required = true; } else { composite_error(c, NT_STATUS_ACCESS_DENIED); return; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 91616319d5..6c573bf6d5 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -187,14 +187,14 @@ static void session_request_handler(struct smb2_request *req) return; } - if (session->transport->signing.doing_signing) { + if (session->transport->signing_required) { if (session->session_key.length != 16) { DEBUG(2,("Wrong session key length %u for SMB2 signing\n", (unsigned)session->session_key.length)); composite_error(c, NT_STATUS_ACCESS_DENIED); return; } - session->transport->signing.signing_started = true; + session->signing_active = true; } composite_done(c); @@ -218,7 +218,7 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se ZERO_STRUCT(state->io); state->io.in.vc_number = 0; - if (session->transport->signing.doing_signing) { + if (session->transport->signing_required) { state->io.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; } diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 2b468d3dc9..5d6341a15b 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -27,11 +27,6 @@ struct smb2_handle; -struct smb2_signing_context { - bool doing_signing; - bool signing_started; -}; - /* information returned from the negotiate process */ @@ -78,7 +73,8 @@ struct smb2_transport { } oplock; struct smbcli_options options; - struct smb2_signing_context signing; + + bool signing_required; }; @@ -98,6 +94,7 @@ struct smb2_session { struct gensec_security *gensec; uint64_t uid; DATA_BLOB session_key; + bool signing_active; }; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 6e0d523e21..d9691bec7c 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -235,7 +235,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); - if (req->session && transport->signing.doing_signing) { + if (req->session && req->session->signing_active) { status = smb2_check_signature(&req->in, req->session->session_key); if (!NT_STATUS_IS_OK(status)) { @@ -352,9 +352,7 @@ void smb2_transport_send(struct smb2_request *req) } /* possibly sign the message */ - if (req->transport->signing.doing_signing && - req->transport->signing.signing_started && - req->session) { + if (req->session && req->session->signing_active) { status = smb2_sign_message(&req->out, req->session->session_key); if (!NT_STATUS_IS_OK(status)) { req->state = SMB2_REQUEST_ERROR; -- cgit From 2d2911c7885dc832700185e62160bc18f8abfa04 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jul 2008 15:49:46 +0200 Subject: libcli/smb2: the session key for SMB2 signing is truncated to 16 bytes To make that work (as a client) with aes128 and aes256 krb5 keys we need to use gsskrb5_get_subkey(). metze (This used to be commit 0c6d988f2083067e1ac7b07a492f88cefd3ba906) --- source4/libcli/smb2/session.c | 4 ++-- source4/libcli/smb2/signing.c | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 6c573bf6d5..31b3e942e9 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -188,8 +188,8 @@ static void session_request_handler(struct smb2_request *req) } if (session->transport->signing_required) { - if (session->session_key.length != 16) { - DEBUG(2,("Wrong session key length %u for SMB2 signing\n", + if (session->session_key.length == 0) { + DEBUG(0,("Wrong session key length %u for SMB2 signing\n", (unsigned)session->session_key.length)); composite_error(c, NT_STATUS_ACCESS_DENIED); return; diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c index fb2c22db4e..0d655d1a86 100644 --- a/source4/libcli/smb2/signing.c +++ b/source4/libcli/smb2/signing.c @@ -46,7 +46,7 @@ NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_ke return NT_STATUS_OK; } - if (session_key.length != 16) { + if (session_key.length == 0) { DEBUG(2,("Wrong session key length %u for SMB2 signing\n", (unsigned)session_key.length)); return NT_STATUS_ACCESS_DENIED; @@ -57,10 +57,9 @@ NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_ke SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED); ZERO_STRUCT(m); - hmac_sha256_init(session_key.data, 16, &m); + hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m); hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m); hmac_sha256_final(res, &m); - DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE)); memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16); @@ -95,7 +94,7 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session return NT_STATUS_OK; } - if (session_key.length != 16) { + if (session_key.length == 0) { DEBUG(2,("Wrong session key length %u for SMB2 signing\n", (unsigned)session_key.length)); return NT_STATUS_ACCESS_DENIED; @@ -106,7 +105,7 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16); ZERO_STRUCT(m); - hmac_sha256_init(session_key.data, 16, &m); + hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m); hmac_sha256_update(buf->hdr, buf->size-NBT_HDR_SIZE, &m); hmac_sha256_final(res, &m); -- cgit From bf002d1173519a48bbcf00bfb9ec4164cea47d2c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Aug 2008 16:16:59 +1000 Subject: Rework the trustAuthInOutBlob with the help of a hand parser. This produces a C structure that is sane, while still parsing the wire blobs (as far as I can tell). Andrew Bartlett (This used to be commit b5dbe815e5dd3f865c7735bc76e02017a869f09b) --- source4/libcli/config.mk | 8 +++ source4/libcli/drsblobs.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++ source4/libcli/drsblobs.h | 28 ++++++++ 3 files changed, 215 insertions(+) create mode 100644 source4/libcli/drsblobs.c create mode 100644 source4/libcli/drsblobs.h (limited to 'source4/libcli') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index affd8e277d..262a2cfa22 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -73,6 +73,14 @@ LIBCLI_NETLOGON_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ $(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) +[SUBSYSTEM::LIBCLI_DRSBLOBS] +PUBLIC_DEPENDENCIES = LIBNDR + +LIBCLI_DRSBLOBS_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ + drsblobs.o) + +$(eval $(call proto_header_template,$(libclisrcdir)/drsblobs_proto.h,$(LIBCLI_DRSBLOBS_OBJ_FILES:.o=.c))) + [PYTHON::python_netbios] LIBRARY_REALNAME = samba/netbios.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG diff --git a/source4/libcli/drsblobs.c b/source4/libcli/drsblobs.c new file mode 100644 index 0000000000..126f2ccc40 --- /dev/null +++ b/source4/libcli/drsblobs.c @@ -0,0 +1,179 @@ +/* + Unix SMB/CIFS implementation. + + Manually parsed structures found in the DRS protocol + + Copyright (C) Andrew Bartlett 2008 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/drsblobs.h" + +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +/* Modified to have 'count' specified */ +static enum ndr_err_code ndr_push_AuthenticationInformationArray_with_count(struct ndr_push *ndr, int ndr_flags, int count, + const struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); + } + } + return NDR_ERR_SUCCESS; +} + +/* Modified to have 'count' specified, and to allocate the array */ +static enum ndr_err_code ndr_pull_AuthenticationInformationArray_with_count(struct ndr_pull *ndr, int ndr_flags, int count, struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + TALLOC_CTX *_mem_save_array_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_PULL_ALLOC_N(ndr, r->array, count); + _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); + } + } + return NDR_ERR_SUCCESS; +} + +/* Modified to have 'count' specified */ +_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + ndr_print_struct(ndr, name, "AuthenticationInformationArray"); + ndr->depth++; + ndr->print(ndr, "%s: ARRAY(%d)", "array", (int)1); + ndr->depth++; + for (cntr_array_0=0;cntr_array_0array[cntr_array_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +/* Modified to call AuthenticationInformationArray with 'count' specified */ +_PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->current)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->current) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->current)); + NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); + } + if (r->previous) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous)); + NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r) +{ + uint32_t _ptr_current; + TALLOC_CTX *_mem_save_current_0; + uint32_t _ptr_previous; + TALLOC_CTX *_mem_save_previous_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_current)); + if (_ptr_current) { + NDR_PULL_ALLOC(ndr, r->current); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->current, _ptr_current)); + } else { + r->current = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous)); + if (_ptr_previous) { + NDR_PULL_ALLOC(ndr, r->previous); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous, _ptr_previous)); + } else { + r->previous = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->current) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->current)); + _mem_save_current_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->current, 0); + NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_current_0, 0); + ndr->offset = _relative_save_offset; + } + if (r->previous) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous)); + _mem_save_previous_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->previous, 0); + NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_0, 0); + ndr->offset = _relative_save_offset; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r) +{ + ndr_print_struct(ndr, name, "trustAuthInOutBlob"); + ndr->depth++; + ndr_print_uint32(ndr, "count", r->count); + ndr_print_ptr(ndr, "current", r->current); + ndr->depth++; + if (r->current) { + ndr_print_AuthenticationInformationArray_with_count(ndr, "current", r->count, r->current); + } + ndr->depth--; + ndr_print_ptr(ndr, "previous", r->previous); + ndr->depth++; + if (r->previous) { + ndr_print_AuthenticationInformationArray_with_count(ndr, "previous", r->count, r->previous); + } + ndr->depth--; + ndr->depth--; +} + + diff --git a/source4/libcli/drsblobs.h b/source4/libcli/drsblobs.h new file mode 100644 index 0000000000..8fee4114be --- /dev/null +++ b/source4/libcli/drsblobs.h @@ -0,0 +1,28 @@ +/* + Unix SMB/CIFS implementation. + + Manually parsed structures found in the DRS protocol + + Copyright (C) Andrew Bartlett 2008 + + 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 3 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, see . +*/ + +#ifndef __LIBCLI_DRSBLOBS_H__ +#define __LIBCLI_DRSBLOBS_H__ + +#include "librpc/gen_ndr/ndr_drsblobs.h" + +#include "libcli/drsblobs_proto.h" +#endif /* __CLDAP_SERVER_PROTO_H__ */ -- cgit From be0a45d865dbb78c0a82e6bcebebbbbdb4ecb2d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 13 Aug 2008 09:42:27 +0200 Subject: libcli/smb2: async replies with STATUS_PENDING are not signed metze (This used to be commit 3f6cbece4a199a42ad6583ea4bd4302629399625) --- source4/libcli/smb2/transport.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index d9691bec7c..b946a102c8 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -235,6 +235,17 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); + if ((flags & SMB2_HDR_FLAG_ASYNC) && + NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { + req->cancel.can_cancel = true; + req->cancel.pending_id = IVAL(hdr, SMB2_HDR_PID); + for (i=0; i< req->cancel.do_cancel; i++) { + smb2_cancel(req); + } + talloc_free(buffer); + return NT_STATUS_OK; + } + if (req->session && req->session->signing_active) { status = smb2_check_signature(&req->in, req->session->session_key); @@ -244,19 +255,6 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob) return status; } } - - - if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { - if (flags & 0x00000002) { - req->cancel.can_cancel = true; - req->cancel.pending_id = IVAL(hdr, SMB2_HDR_PID); - for (i=0; i< req->cancel.do_cancel; i++) { - smb2_cancel(req); - } - } - talloc_free(buffer); - return NT_STATUS_OK; - } buffer_code = SVAL(req->in.body, 0); req->in.body_fixed = (buffer_code & ~1); -- cgit From be92e7fc11c9ee55beacf8c6cc019539d3d7c486 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 13 Aug 2008 09:44:06 +0200 Subject: libcli/smb2: we don't need check the same thing twice... metze (This used to be commit 1380fb954a7d9d4b543c4650a060fef9f357af7b) --- source4/libcli/smb2/signing.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c index 0d655d1a86..de9e1e9d29 100644 --- a/source4/libcli/smb2/signing.c +++ b/source4/libcli/smb2/signing.c @@ -94,12 +94,6 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session return NT_STATUS_OK; } - if (session_key.length == 0) { - DEBUG(2,("Wrong session key length %u for SMB2 signing\n", - (unsigned)session_key.length)); - return NT_STATUS_ACCESS_DENIED; - } - memcpy(sig, buf->hdr+SMB2_HDR_SIGNATURE, 16); memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16); -- cgit From f086e796d6a933b95e36f5638b39ee261fb6a784 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 13 Aug 2008 15:19:01 +0200 Subject: libcli/smb2: use smb2 signing in auto mode if the server supports it metze (This used to be commit fe74faf13dc64eaa58d757de156aedcb24abed1f) --- source4/libcli/smb2/connect.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index c89c109b72..43151943d3 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -115,13 +115,19 @@ static void continue_negprot(struct smb2_request *req) transport->signing_required = false; break; case SMB_SIGNING_SUPPORTED: - case SMB_SIGNING_AUTO: if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { transport->signing_required = true; } else { transport->signing_required = false; } break; + case SMB_SIGNING_AUTO: + if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { + transport->signing_required = true; + } else { + transport->signing_required = false; + } + break; case SMB_SIGNING_REQUIRED: if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { transport->signing_required = true; -- cgit From dbcdbb33485b034b48b32e4801a538bbc239d1c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 14 Aug 2008 12:44:25 +0200 Subject: libcli/raw: fix the special NTCREATE_OPTIONS_*_MASK values We now reuse ignored values for the ntvfs backend private flags. metze (This used to be commit 14eda93aeface307e1ffd1ea012d8f236fa78290) --- source4/libcli/raw/smb.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 8663792f78..d4091acf48 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -167,17 +167,30 @@ #define NTCREATEX_OPTIONS_NO_RECALL 0x00400000 /* Must be ignored by the server, per MS-SMB 2.2.8 */ #define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000 -/* create options these bits are for private use by backends, they are - not valid on the wire */ -#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000 -#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 -#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 -#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK ( NTCREATEX_OPTIONS_TREE_CONNECTION | NTCREATEX_OPTIONS_COMPLETE_IF_OPLOCKED | NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY | NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER ) +#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \ + NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY | \ + NTCREATEX_OPTIONS_FREE_SPACE_QUERY | \ + 0x000F0000) -#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK (0x000F0000 | NTCREATEX_OPTIONS_OPEN_BY_FILE_ID) +#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_OPEN_BY_FILE_ID) +#define NTCREATEX_OPTIONS_INVALID_PARAM_MASK (NTCREATEX_OPTIONS_OPFILTER | \ + NTCREATEX_OPTIONS_SYNC_ALERT | \ + NTCREATEX_OPTIONS_ASYNC_ALERT | \ + NTCREATEX_OPTIONS_OPFILTER | \ + 0xFF000000) +/* + * We reuse some ignored flags for private use. + * This values have different meaning for some ntvfs backends. + * + * TODO: use values that are ignore for sure... + */ +#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x00010000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x00020000 +#define NTCREATEX_OPTIONS_PRIVATE_MASK (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | \ + NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) /* ntcreatex impersonation field */ #define NTCREATEX_IMPERSONATION_ANONYMOUS 0 -- cgit From 2a336a63d704b1a5cf8e9a2961f48285081256ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 14 Aug 2008 12:48:37 +0200 Subject: libcli/smb2: add SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK SMB2 returns NOT_SUPPORTED to some more NTCREATE_OPTIONS. metze (This used to be commit 3ea08d430370717463ffab44fed9c42db1002d97) --- source4/libcli/smb2/smb2.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 5d6341a15b..f00107de60 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -276,7 +276,9 @@ struct smb2_request { #define SMB2_CREATE_TAG_TWRP "TWrp" #define SMB2_CREATE_TAG_QFID "QFid" - +/* SMB2 Create ignore some more create_options */ +#define SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \ + NTCREATEX_OPTIONS_OPFILTER) /* check that a body has the expected size -- cgit From 4ad97a1d0593b3401a352407009a99ead23f21f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Aug 2008 19:24:58 +1000 Subject: Don't walk past the end of ldb values. This is a partial fix towards bugs due to us walking past the end of what we think are strings in ldb. There is much more work to do in this area. Andrew Bartlett (This used to be commit 5805a9a8f35fd90fa4f718f73534817fa3bbdfd2) --- source4/libcli/security/dom_sid.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c index f5457e7e0e..1a7519e362 100644 --- a/source4/libcli/security/dom_sid.c +++ b/source4/libcli/security/dom_sid.c @@ -151,6 +151,21 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr) return ret; } +/* + convert a string to a dom_sid, returning a talloc'd dom_sid +*/ +struct dom_sid *dom_sid_parse_length(TALLOC_CTX *mem_ctx, const DATA_BLOB *sid) +{ + struct dom_sid *ret; + char *p = talloc_strndup(mem_ctx, sid->data, sid->length); + if (!p) { + return NULL; + } + ret = dom_sid_parse_talloc(mem_ctx, p); + talloc_free(p); + return ret; +} + /* copy a dom_sid structure */ -- cgit From ca20c56b260e2799c40b0c7c0e3ef5f7308b586e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 27 Aug 2008 10:29:54 +1000 Subject: Add definition for NT_STATUS_DOWNGRADE_DETECTED (This used to be commit f6e227b72bb56d12cb270d76f7f458136c4ca160) --- source4/libcli/util/nterr.c | 1 + source4/libcli/util/ntstatus.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 7629a14106..ef4055adaa 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -546,6 +546,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, + { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP }, diff --git a/source4/libcli/util/ntstatus.h b/source4/libcli/util/ntstatus.h index 026b5162db..527a95bd09 100644 --- a/source4/libcli/util/ntstatus.h +++ b/source4/libcli/util/ntstatus.h @@ -593,6 +593,7 @@ typedef uint32_t NTSTATUS; #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) #define NT_STATUS_OBJECTID_NOT_FOUND NT_STATUS(0xC0000000 | 0x02F0) #define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ +#define NT_STATUS_DOWNGRADE_DETECTED NT_STATUS(0xC0000000 | 0x0388) #define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) #define NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX NT_STATUS(0xC0000000 | 0x20026) -- cgit From b7326979e9d8366eee03d967483a6513342186c4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 5 Sep 2008 16:46:12 +1000 Subject: Add a new error code (This used to be commit b52fba5b2c63a24acbfc7e3e989c16b691d98162) --- source4/libcli/util/nterr.c | 1 + source4/libcli/util/ntstatus.h | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index ef4055adaa..4e046c78ca 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -545,6 +545,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, + { "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED }, { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, diff --git a/source4/libcli/util/ntstatus.h b/source4/libcli/util/ntstatus.h index 527a95bd09..9c7bee0dfe 100644 --- a/source4/libcli/util/ntstatus.h +++ b/source4/libcli/util/ntstatus.h @@ -591,6 +591,7 @@ typedef uint32_t NTSTATUS; #define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266) #define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) +#define NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED NT_STATUS(0xC0000000 | 0x02E9) #define NT_STATUS_OBJECTID_NOT_FOUND NT_STATUS(0xC0000000 | 0x02F0) #define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ #define NT_STATUS_DOWNGRADE_DETECTED NT_STATUS(0xC0000000 | 0x0388) -- cgit From d104a706d1adb5d75abd05a9a3f938385eefc5d4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 6 Sep 2008 09:07:41 +1000 Subject: Make SMB signing work with Windows 2008 and kerberos. Pinched from b53e6387e30010509034835acf88b91b380ff44a by metze. Andrew Bartlett (This used to be commit d55602e23e7947462cb402b20b2d354b96aa7ba3) --- source4/libcli/raw/smb_signing.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 97bb688d1a..1d03686d9a 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -263,7 +263,6 @@ bool smbcli_set_signing_off(struct smb_signing_context *sign_info) { DEBUG(5, ("Shutdown SMB signing\n")); sign_info->doing_signing = false; - sign_info->next_seq_num = 0; data_blob_free(&sign_info->mac_key); sign_info->signing_state = SMB_SIGNING_ENGINE_OFF; return true; @@ -350,9 +349,6 @@ bool smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length); - /* Initialise the sequence number */ - sign_info->next_seq_num = 0; - sign_info->signing_state = SMB_SIGNING_ENGINE_ON; return true; @@ -379,6 +375,7 @@ bool smbcli_transport_simple_set_signing(struct smbcli_transport *transport, bool smbcli_init_signing(struct smbcli_transport *transport) { + transport->negotiate.sign_info.next_seq_num = 0; transport->negotiate.sign_info.mac_key = data_blob(NULL, 0); if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) { return false; -- cgit